diff --git a/package.json b/package.json index f60f449..6aa9bb7 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "typescript": "^4.4.3" }, "license": "MIT", - "main": "dist/index.js", + "main": "src/index.js", "name": "updux", "description": "Updeep-friendly Redux helper framework", "scripts": { diff --git a/types/actions.d.ts b/types/actions.d.ts new file mode 100644 index 0000000..4ae7cb5 --- /dev/null +++ b/types/actions.d.ts @@ -0,0 +1,26 @@ +export type ActionGenerator = { + type: TType; +} & (TPayloadGen extends Function + ? (...args: Parameters) => { + type: TType; + payload: ReturnType; + } + : (...args: any[]) => { type: TType; payload?: unknown }); + +interface Action { + (actionType: T): ActionGenerator; + ( + actionType: T, + payloadGen: F + ): ActionGenerator; +} + +/** + * Creates an action generator. + */ +export const action: Action; + +/** + * Utility type for payload generators that are passthroughs. + */ +export type Payload = (arg: T) => T; diff --git a/types/index.d.ts b/types/index.d.ts index d939f1e..d092e49 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -5,107 +5,95 @@ type Mutation = ( action: Record ) => (state: TState) => TState; -type ActionGenerator = { type: string } & ((...args: any[]) => { - type: string; - payload?: unknown; -}); +export * from './actions'; -declare module 'updux' { +/** + * Configuration object typically passed to the constructor of the class Updux. + */ +export interface UpduxConfig { /** - * Configuration object typically passed to the constructor of the class Updux. + * Local initial state. + * @default {} */ - export interface UpduxConfig { - /** - * Local initial state. - * @default {} - */ - initial?: TState; - - /** - * Subduxes to be merged to this dux. - */ - subduxes?: Dict; - - /** - * Local actions. - */ - actions?: Record; - - /** - * Local selectors. - */ - selectors?: Record; - - /** - * Local mutations - */ - mutations?: Record; - - /** - * Selectors to apply to the mapped subduxes. Only - * applicable if the dux is a mapping dux. - */ - mappedSelectors?: Record; - - /** - * Local effects. - */ - effects?: Record; - - /** - * Local reactions. - */ - reactions?: Record; - /** - * If true, enables mapped reactions. Additionally, it can be - * a reaction function, which will treated as a regular - * reaction for the mapped dux. - */ - mappedReaction?: Function | boolean; - } - - export class Updux { - constructor(config: Partial>); - - get initial(): TState; - get selectors(): unknown; - - /** - * Sets the local mutation for the given action. - * - * The action can be specified via its type - * or its generator. - * - * Returns the same mutation function. - */ - setMutation( - actionType: string, - mutation: TMutation - ): TMutation; - setMutation( - action: ActionGenerator, - mutation: TMutation - ): TMutation; - - /** - * Registers the action for the dux. - * If no payload function is provided, whatever is - * given as an argument to the action generator will - * be set as-is in the action's payload. - */ - setAction(actionType: string, payloadFunc?: Function); - - /** - * Registers a selector for the dux. - */ - setSelector(name: string, selector: Selector); - } + initial?: TState; /** - * Creates an action generator. + * Subduxes to be merged to this dux. */ - export function action( - actionType: string, - payloadFunction?: Function - ): ActionGenerator; + subduxes?: Dict; + + /** + * Local actions. + */ + actions?: Record; + + /** + * Local selectors. + */ + selectors?: Record; + + /** + * Local mutations + */ + mutations?: Record; + + /** + * Selectors to apply to the mapped subduxes. Only + * applicable if the dux is a mapping dux. + */ + mappedSelectors?: Record; + + /** + * Local effects. + */ + effects?: Record; + + /** + * Local reactions. + */ + reactions?: Record; + /** + * If true, enables mapped reactions. Additionally, it can be + * a reaction function, which will treated as a regular + * reaction for the mapped dux. + */ + mappedReaction?: Function | boolean; } + +export class Updux { + constructor(config: Partial>); + + get initial(): TState; + get selectors(): unknown; + + /** + * Sets the local mutation for the given action. + * + * The action can be specified via its type + * or its generator. + * + * Returns the same mutation function. + */ + setMutation( + actionType: string, + mutation: TMutation + ): TMutation; + setMutation( + action: ActionGenerator, + mutation: TMutation + ): TMutation; + + /** + * Registers the action for the dux. + * If no payload function is provided, whatever is + * given as an argument to the action generator will + * be set as-is in the action's payload. + */ + setAction(actionType: string, payloadFunc?: Function); + + /** + * Registers a selector for the dux. + */ + setSelector(name: string, selector: Selector); +} + diff --git a/types/index.test-d.ts b/types/index.test-d.ts index 5896ff0..7b474bb 100644 --- a/types/index.test-d.ts +++ b/types/index.test-d.ts @@ -1,6 +1,6 @@ import { printType, expectAssignable, expectType } from 'tsd'; -import { Updux } from '.'; +import { Updux, ActionGenerator, action } from '.'; const dux = new Updux({}); expectType( dux.initial ); @@ -12,3 +12,16 @@ expectType( dux.initial ); expectAssignable<{initial: {a:string}}>(dux); } + +// ActionGenerator +() => { + let a = action('a'); + expectAssignable<{type: string}>(a); + expectAssignable<() => {payload?: unknown}>(a); + + let b = action('b', (() => ({})) as unknown as (name: string) => { name: string } ); + const c = b("foo"); + expectAssignable<{payload: { name: string } }>(c); + + +} diff --git a/types/index.ts b/types/index.ts deleted file mode 100644 index e69de29..0000000