From 00259a46b641172edea7aa2be900c44b9d7b96f0 Mon Sep 17 00:00:00 2001 From: dilane3 Date: Tue, 19 Sep 2023 00:00:00 +0100 Subject: [PATCH 1/2] Add: Async State v1 --- dist/contexts/index.js | 1 + dist/contexts/index.js.map | 2 +- dist/contexts/types.d.ts | 27 ++++++- dist/helpers/createAsyncAction.d.ts | 8 ++ dist/helpers/createAsyncAction.js | 18 +++++ dist/helpers/createAsyncAction.js.map | 1 + dist/helpers/createSignal.d.ts | 3 +- dist/helpers/createSignal.js | 14 +++- dist/helpers/createSignal.js.map | 2 +- dist/helpers/createStore.d.ts | 5 ++ dist/helpers/createStore.js | 5 ++ dist/helpers/createStore.js.map | 2 +- dist/helpers/types.d.ts | 36 ++++++++- dist/helpers/types.js | 6 ++ dist/helpers/types.js.map | 2 +- dist/hooks/types.d.ts | 7 ++ dist/hooks/useActions.js | 1 + dist/hooks/useActions.js.map | 2 +- dist/hooks/useAsyncActions.d.ts | 3 + dist/hooks/useAsyncActions.js | 94 +++++++++++++++++++++++ dist/hooks/useAsyncActions.js.map | 1 + dist/index.d.ts | 6 +- dist/index.js | 11 ++- dist/index.js.map | 2 +- dist/interfaces/builder.d.ts | 10 +++ dist/interfaces/builder.js | 15 ++++ dist/interfaces/builder.js.map | 1 + dist/interfaces/builderCase.d.ts | 47 ++++++++++++ dist/interfaces/builderCase.js | 55 +++++++++++++ dist/interfaces/builderCase.js.map | 1 + dist/providers/index.js | 43 ++++++++++- dist/providers/index.js.map | 2 +- dist/providers/reducer.js | 27 ++++--- dist/providers/reducer.js.map | 2 +- dist/providers/types.d.ts | 12 ++- src/contexts/index.ts | 1 + src/contexts/types.ts | 67 +++++++++++----- src/helpers/createAsyncAction.ts | 23 ++++++ src/helpers/createSignal.ts | 25 +++++- src/helpers/createStore.ts | 5 ++ src/helpers/types.ts | 66 ++++++++++++++-- src/hooks/types.ts | 17 ++++- src/hooks/useActions.ts | 1 + src/hooks/useAsyncActions.ts | 106 ++++++++++++++++++++++++++ src/index.ts | 10 ++- src/interfaces/builder.ts | 20 +++++ src/interfaces/builderCase.ts | 87 +++++++++++++++++++++ src/providers/index.tsx | 59 +++++++++++++- src/providers/reducer.ts | 34 ++++++--- src/providers/types.ts | 21 ++++- 50 files changed, 935 insertions(+), 81 deletions(-) create mode 100644 dist/helpers/createAsyncAction.d.ts create mode 100644 dist/helpers/createAsyncAction.js create mode 100644 dist/helpers/createAsyncAction.js.map create mode 100644 dist/hooks/useAsyncActions.d.ts create mode 100644 dist/hooks/useAsyncActions.js create mode 100644 dist/hooks/useAsyncActions.js.map create mode 100644 dist/interfaces/builder.d.ts create mode 100644 dist/interfaces/builder.js create mode 100644 dist/interfaces/builder.js.map create mode 100644 dist/interfaces/builderCase.d.ts create mode 100644 dist/interfaces/builderCase.js create mode 100644 dist/interfaces/builderCase.js.map create mode 100644 src/helpers/createAsyncAction.ts create mode 100644 src/hooks/useAsyncActions.ts create mode 100644 src/interfaces/builder.ts create mode 100644 src/interfaces/builderCase.ts diff --git a/dist/contexts/index.js b/dist/contexts/index.js index c8d630f..932d1d0 100644 --- a/dist/contexts/index.js +++ b/dist/contexts/index.js @@ -4,6 +4,7 @@ const react_1 = require("react"); const GXContext = (0, react_1.createContext)({ signals: [], dispatch: () => { }, + asyncDispatch: () => { }, }); exports.default = GXContext; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/contexts/index.js.map b/dist/contexts/index.js.map index 61f6ff0..84981a9 100644 --- a/dist/contexts/index.js.map +++ b/dist/contexts/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":";;AAAA,iCAAsC;AAGtC,MAAM,SAAS,GAAG,IAAA,qBAAa,EAAgB;IAC7C,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;CACnB,CAAC,CAAC;AAEH,kBAAe,SAAS,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contexts/index.ts"],"names":[],"mappings":";;AAAA,iCAAsC;AAGtC,MAAM,SAAS,GAAG,IAAA,qBAAa,EAAgB;IAC7C,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,GAAG,EAAE,GAAE,CAAC;IAClB,aAAa,EAAE,GAAG,EAAE,GAAE,CAAC;CACxB,CAAC,CAAC;AAEH,kBAAe,SAAS,CAAC"} \ No newline at end of file diff --git a/dist/contexts/types.d.ts b/dist/contexts/types.d.ts index cc94f32..9ea3477 100644 --- a/dist/contexts/types.d.ts +++ b/dist/contexts/types.d.ts @@ -1,24 +1,49 @@ /// +import IBuilderCase from "../interfaces/builderCase.js"; import { GXAction } from "../providers/types.js"; +/** + * Type that represents a signal + */ export type GXSignalType = { name: string; state: T; - actions: GXActionType[]; + actions?: GXActionType[]; operations?: GXOperationType[]; + asyncActions?: GXAsyncActionType[]; }; +/** + * Type that represents Actions + */ export type GXActionType = { type: string; handler: (state: T, payload: P) => T; }; +/** + * Type that represents operations + */ export type GXOperationType = { type: string; handler: (state: T, payload: P) => Q; }; +/** + * Type that represents async actions + */ +export type GXAsyncActionType = { + type: string; + steps: IBuilderCase; +}; +/** + * Type of dispatched action + */ export type DispatchedActionType = { type: string; payload: any; }; +/** + * Type of the signals context + */ export type GXContextType = { signals: GXSignalType[]; dispatch: React.Dispatch; + asyncDispatch: (action: GXAction) => any; }; diff --git a/dist/helpers/createAsyncAction.d.ts b/dist/helpers/createAsyncAction.d.ts new file mode 100644 index 0000000..629d6e6 --- /dev/null +++ b/dist/helpers/createAsyncAction.d.ts @@ -0,0 +1,8 @@ +import { CreateAsyncActionProp, CreateAsyncActionReturnType } from "./types.js"; +/** + * This function create an async action with different statuses + * @param handler Function that perform asynchronous task + * @returns + */ +declare const createAsyncAction: (handler: CreateAsyncActionProp) => CreateAsyncActionReturnType; +export default createAsyncAction; diff --git a/dist/helpers/createAsyncAction.js b/dist/helpers/createAsyncAction.js new file mode 100644 index 0000000..3b06b28 --- /dev/null +++ b/dist/helpers/createAsyncAction.js @@ -0,0 +1,18 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const types_js_1 = require("./types.js"); +/** + * This function create an async action with different statuses + * @param handler Function that perform asynchronous task + * @returns + */ +const createAsyncAction = (handler) => { + return { + pending: types_js_1.AsyncActionStatuses.PENDING, + fulfilled: types_js_1.AsyncActionStatuses.FULFILLED, + rejected: types_js_1.AsyncActionStatuses.REJECTED, + handler, + }; +}; +exports.default = createAsyncAction; +//# sourceMappingURL=createAsyncAction.js.map \ No newline at end of file diff --git a/dist/helpers/createAsyncAction.js.map b/dist/helpers/createAsyncAction.js.map new file mode 100644 index 0000000..51a6c0b --- /dev/null +++ b/dist/helpers/createAsyncAction.js.map @@ -0,0 +1 @@ +{"version":3,"file":"createAsyncAction.js","sourceRoot":"","sources":["../../src/helpers/createAsyncAction.ts"],"names":[],"mappings":";;AAAA,yCAIoB;AAEpB;;;;GAIG;AACH,MAAM,iBAAiB,GAAG,CACxB,OAA8B,EACD,EAAE;IAC/B,OAAO;QACL,OAAO,EAAE,8BAAmB,CAAC,OAAO;QACpC,SAAS,EAAE,8BAAmB,CAAC,SAAS;QACxC,QAAQ,EAAE,8BAAmB,CAAC,QAAQ;QACtC,OAAO;KACR,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,iBAAiB,CAAC"} \ No newline at end of file diff --git a/dist/helpers/createSignal.d.ts b/dist/helpers/createSignal.d.ts index 41241bb..272b27a 100644 --- a/dist/helpers/createSignal.d.ts +++ b/dist/helpers/createSignal.d.ts @@ -1,5 +1,5 @@ import { CreateSignalOptionType } from "./types.js"; -import { GXActionType, GXOperationType } from "../contexts/types.js"; +import { GXActionType, GXAsyncActionType, GXOperationType } from "../contexts/types.js"; /** * Create a signal with a state and actions for managing this state * @param options @@ -10,5 +10,6 @@ declare const createSignal: (options: CreateSignalOptionType) => { state: T; actions: GXActionType[]; operations: GXOperationType[]; + asyncActions: GXAsyncActionType[]; }; export default createSignal; diff --git a/dist/helpers/createSignal.js b/dist/helpers/createSignal.js index 3157c8d..cf89b35 100644 --- a/dist/helpers/createSignal.js +++ b/dist/helpers/createSignal.js @@ -1,5 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const builder_js_1 = require("../interfaces/builder.js"); /** * Create a signal with a state and actions for managing this state * @param options @@ -8,8 +9,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); const createSignal = (options) => { const actions = []; const operations = []; + const asyncActions = []; // Convert the actions object to an array - const actionsTable = Object.entries(options.actions); + const actionsTable = Object.entries(options.actions || {}); for (let action of actionsTable) { actions.push({ type: `${options.name}/${action[0]}`, @@ -24,12 +26,22 @@ const createSignal = (options) => { handler: operation[1], }); } + // Convert the async Actions object to an array + const builder = new builder_js_1.Builder(); + const asyncActionsTable = Object.entries(options.asyncActions ? options.asyncActions(builder) : {}); + for (let action of asyncActionsTable) { + asyncActions.push({ + type: `${options.name}/${action[0]}`, + steps: action[1], + }); + } // Create a signal const signal = { name: options.name, state: options.state, actions, operations, + asyncActions, }; return signal; }; diff --git a/dist/helpers/createSignal.js.map b/dist/helpers/createSignal.js.map index 1df9385..a8cc960 100644 --- a/dist/helpers/createSignal.js.map +++ b/dist/helpers/createSignal.js.map @@ -1 +1 @@ -{"version":3,"file":"createSignal.js","sourceRoot":"","sources":["../../src/helpers/createSignal.ts"],"names":[],"mappings":";;AAGA;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAI,OAAkC,EAAE,EAAE;IAC7D,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,UAAU,GAA8B,EAAE,CAAC;IAEjD,yCAAyC;IACzC,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAErD,KAAK,IAAI,MAAM,IAAI,YAAY,EAAE;QAC/B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;YACpC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;SACnB,CAAC,CAAC;KACJ;IAED,4CAA4C;IAC5C,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IAEjE,KAAK,IAAI,SAAS,IAAI,eAAe,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE;YACvC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;SACtB,CAAC,CAAC;KACJ;IAED,kBAAkB;IAClB,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO;QACP,UAAU;KACX,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,kBAAe,YAAY,CAAC"} \ No newline at end of file +{"version":3,"file":"createSignal.js","sourceRoot":"","sources":["../../src/helpers/createSignal.ts"],"names":[],"mappings":";;AAMA,yDAAmD;AAEnD;;;;GAIG;AACH,MAAM,YAAY,GAAG,CAAI,OAAkC,EAAE,EAAE;IAC7D,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,UAAU,GAA8B,EAAE,CAAC;IACjD,MAAM,YAAY,GAA2B,EAAE,CAAC;IAEhD,yCAAyC;IACzC,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAE3D,KAAK,IAAI,MAAM,IAAI,YAAY,EAAE;QAC/B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;YACpC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;SACnB,CAAC,CAAC;KACJ;IAED,4CAA4C;IAC5C,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;IAEjE,KAAK,IAAI,SAAS,IAAI,eAAe,EAAE;QACrC,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE;YACvC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;SACtB,CAAC,CAAC;KACJ;IAED,+CAA+C;IAC/C,MAAM,OAAO,GAAG,IAAI,oBAAO,EAAK,CAAC;IAEjC,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CACtC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAC1D,CAAC;IAEF,KAAK,IAAI,MAAM,IAAI,iBAAiB,EAAE;QACpC,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE;YACpC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;SACjB,CAAC,CAAC;KACJ;IAED,kBAAkB;IAClB,MAAM,MAAM,GAAG;QACb,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO;QACP,UAAU;QACV,YAAY;KACb,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,kBAAe,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/helpers/createStore.d.ts b/dist/helpers/createStore.d.ts index 2295848..a2b0030 100644 --- a/dist/helpers/createStore.d.ts +++ b/dist/helpers/createStore.d.ts @@ -1,4 +1,9 @@ import { GXSignalType } from "../contexts/types.js"; import { CreateStoreType } from "./types.js"; +/** + * Function that create a store by collection a list of signals + * @param signals List of signals + * @returns + */ declare const createStore: (signals: GXSignalType[]) => CreateStoreType; export default createStore; diff --git a/dist/helpers/createStore.js b/dist/helpers/createStore.js index 0bf40e1..ce9a0c7 100644 --- a/dist/helpers/createStore.js +++ b/dist/helpers/createStore.js @@ -1,5 +1,10 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Function that create a store by collection a list of signals + * @param signals List of signals + * @returns + */ const createStore = (signals) => { return { getSignals: () => signals, diff --git a/dist/helpers/createStore.js.map b/dist/helpers/createStore.js.map index 90cccb2..f55d999 100644 --- a/dist/helpers/createStore.js.map +++ b/dist/helpers/createStore.js.map @@ -1 +1 @@ -{"version":3,"file":"createStore.js","sourceRoot":"","sources":["../../src/helpers/createStore.ts"],"names":[],"mappings":";;AAGA,MAAM,WAAW,GAAG,CAAC,OAAuB,EAAmB,EAAE;IAC/D,OAAO;QACL,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO;KAC1B,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC"} \ No newline at end of file +{"version":3,"file":"createStore.js","sourceRoot":"","sources":["../../src/helpers/createStore.ts"],"names":[],"mappings":";;AAGA;;;;GAIG;AACH,MAAM,WAAW,GAAG,CAAC,OAAuB,EAAmB,EAAE;IAC/D,OAAO;QACL,UAAU,EAAE,GAAG,EAAE,CAAC,OAAO;KAC1B,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/helpers/types.d.ts b/dist/helpers/types.d.ts index aa95e5b..5cb0e7a 100644 --- a/dist/helpers/types.d.ts +++ b/dist/helpers/types.d.ts @@ -1,16 +1,50 @@ import { GXSignalType } from "../contexts/types.js"; +import { Builder } from "../interfaces/builder.js"; +import IBuilderCase from "../interfaces/builderCase.js"; +/** + * Type of the create signal option function + */ export type CreateSignalOptionType = { name: string; state: T; - actions: Action; + actions?: Action; operations?: Operation; + asyncActions?: AsyncAction; }; +/** + * Type of the returned data of create store function + */ export type CreateStoreType = { getSignals: () => GXSignalType[]; }; +/** + * Type of Action + */ export type Action = { [key: string]: (state: T, payload: any) => T; }; +/** + * Type of Operation + */ export type Operation = { [key: string]: (state: T, payload?: any) => any; }; +/** + * Type of Async Action + */ +export type AsyncAction = (builder: Builder) => { + [key: string]: IBuilderCase; +}; +export type CreateAsyncActionProp = (payload?: any) => Promise; +export type CreateAsyncActionReturnType = { + pending: AsyncActionStatusesType; + fulfilled: AsyncActionStatusesType; + rejected: AsyncActionStatusesType; + handler: CreateAsyncActionProp; +}; +export declare const AsyncActionStatuses: { + readonly PENDING: "PENDING"; + readonly FULFILLED: "FULFILLED"; + readonly REJECTED: "REJECTED"; +}; +export type AsyncActionStatusesType = (typeof AsyncActionStatuses)[keyof typeof AsyncActionStatuses]; diff --git a/dist/helpers/types.js b/dist/helpers/types.js index 11e638d..5cb4c54 100644 --- a/dist/helpers/types.js +++ b/dist/helpers/types.js @@ -1,3 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +exports.AsyncActionStatuses = void 0; +exports.AsyncActionStatuses = { + PENDING: "PENDING", + FULFILLED: "FULFILLED", + REJECTED: "REJECTED", +}; //# sourceMappingURL=types.js.map \ No newline at end of file diff --git a/dist/helpers/types.js.map b/dist/helpers/types.js.map index bc4cff3..f3852c4 100644 --- a/dist/helpers/types.js.map +++ b/dist/helpers/types.js.map @@ -1 +1 @@ -{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/helpers/types.ts"],"names":[],"mappings":""} \ No newline at end of file +{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/helpers/types.ts"],"names":[],"mappings":";;;AA8Da,QAAA,mBAAmB,GAAG;IACjC,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;CACZ,CAAC"} \ No newline at end of file diff --git a/dist/hooks/types.d.ts b/dist/hooks/types.d.ts index bbaef3b..2378e95 100644 --- a/dist/hooks/types.d.ts +++ b/dist/hooks/types.d.ts @@ -1,6 +1,13 @@ +import { AsyncActionStatusesType } from "../helpers/types"; export type Actions = { [key: string]: (payload?: any) => void; }; +export type AsyncActions = { + [key: string]: (payload?: any) => Promise<{ + data: T; + status: Omit; + }>; +}; export type Operations

= { [key: string]: (payload?: any) => P; }; diff --git a/dist/hooks/useActions.js b/dist/hooks/useActions.js index 4b3c6eb..b795daf 100644 --- a/dist/hooks/useActions.js +++ b/dist/hooks/useActions.js @@ -46,6 +46,7 @@ const useActions = (signalName, ...actions) => { formattedActions[actionName] = (payload) => { dispatch({ type: action.type, + isAsync: false, payload, }); }; diff --git a/dist/hooks/useActions.js.map b/dist/hooks/useActions.js.map index 8d5261f..fc8fa82 100644 --- a/dist/hooks/useActions.js.map +++ b/dist/hooks/useActions.js.map @@ -1 +1 @@ -{"version":3,"file":"useActions.js","sourceRoot":"","sources":["../../src/hooks/useActions.ts"],"names":[],"mappings":";;;;;AAAA,iCAAmC;AACnC,oEAA6C;AAI7C,MAAM,UAAU,GAAG,CAAc,UAAkB,EAAE,GAAG,OAAiB,EAAE,EAAE;IAC3E,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAC/C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAE1E,qBAAqB;IACrB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,kBAAS,CAAC,CAAC;IAEpD,gBAAgB;IAEhB;;;;OAIG;IACH,MAAM,gBAAgB,GAAG,CAAC,UAAkB,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAEpE,IAAI,MAAM,EAAE;YACV,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC,OAAO,CAAC;YAE5D,MAAM,eAAe,GAAwB,EAAE,CAAC;YAEhD,KAAK,IAAI,MAAM,IAAI,OAAO,EAAE;gBAC1B,MAAM,UAAU,GAAG,GAAG,UAAU,IAAI,MAAM,EAAE,CAAC;gBAE7C,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CACzC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CACjC,CAAC;gBAEF,IAAI,eAAe;oBAAE,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;;oBACtD,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,YAAY,CAAC,CAAC;aACxD;YAED,OAAO,eAAe,CAAC;SACxB;;YAAM,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,YAAY,CAAC,CAAC;IAC3D,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,GAAM,EAAE;QAClC,cAAc;QACd,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEzD,oBAAoB;QACpB,MAAM,gBAAgB,GAAG,EAAS,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,mBAAmB,EAAE;YACxC,kBAAkB;YAClB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAE7C,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,OAAa,EAAE,EAAE;gBAC/C,QAAQ,CAAC;oBACP,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,OAAO;iBACR,CAAC,CAAC;YACL,CAAC,CAAC;SACH;QAED,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,mBAAmB,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,kBAAe,UAAU,CAAC"} \ No newline at end of file +{"version":3,"file":"useActions.js","sourceRoot":"","sources":["../../src/hooks/useActions.ts"],"names":[],"mappings":";;;;;AAAA,iCAAmC;AACnC,oEAA6C;AAI7C,MAAM,UAAU,GAAG,CAAc,UAAkB,EAAE,GAAG,OAAiB,EAAE,EAAE;IAC3E,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAC/C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAE1E,qBAAqB;IACrB,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAA,kBAAU,EAAC,kBAAS,CAAC,CAAC;IAEpD,gBAAgB;IAEhB;;;;OAIG;IACH,MAAM,gBAAgB,GAAG,CAAC,UAAkB,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAEpE,IAAI,MAAM,EAAE;YACV,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC,OAAO,CAAC;YAE5D,MAAM,eAAe,GAAwB,EAAE,CAAC;YAEhD,KAAK,IAAI,MAAM,IAAI,OAAO,EAAE;gBAC1B,MAAM,UAAU,GAAG,GAAG,UAAU,IAAI,MAAM,EAAE,CAAC;gBAE7C,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CACzC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CACjC,CAAC;gBAEF,IAAI,eAAe;oBAAE,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;;oBACtD,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,YAAY,CAAC,CAAC;aACxD;YAED,OAAO,eAAe,CAAC;SACxB;;YAAM,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,YAAY,CAAC,CAAC;IAC3D,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,GAAM,EAAE;QAClC,cAAc;QACd,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEzD,oBAAoB;QACpB,MAAM,gBAAgB,GAAG,EAAS,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,mBAAmB,EAAE;YACxC,kBAAkB;YAClB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAE7C,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,OAAa,EAAE,EAAE;gBAC/C,QAAQ,CAAC;oBACP,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,OAAO,EAAE,KAAK;oBACd,OAAO;iBACR,CAAC,CAAC;YACL,CAAC,CAAC;SACH;QAED,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,mBAAmB,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,kBAAe,UAAU,CAAC"} \ No newline at end of file diff --git a/dist/hooks/useAsyncActions.d.ts b/dist/hooks/useAsyncActions.d.ts new file mode 100644 index 0000000..79417c9 --- /dev/null +++ b/dist/hooks/useAsyncActions.d.ts @@ -0,0 +1,3 @@ +import { AsyncActions } from "./types"; +declare const useAsyncActions: >(signalName: string, ...actions: string[]) => P; +export default useAsyncActions; diff --git a/dist/hooks/useAsyncActions.js b/dist/hooks/useAsyncActions.js new file mode 100644 index 0000000..280c018 --- /dev/null +++ b/dist/hooks/useAsyncActions.js @@ -0,0 +1,94 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const react_1 = require("react"); +const contexts_1 = __importDefault(require("../contexts")); +const types_1 = require("../helpers/types"); +const useAsyncActions = (signalName, ...actions) => { + if (!signalName || typeof signalName !== "string") + throw new Error("Provide a signalName as first argument of useAsyncActions"); + // Get Global Context + const { signals, asyncDispatch } = (0, react_1.useContext)(contexts_1.default); + // Some handlers + /** + * Get actions of a signal + * @param signalName + * @returns + */ + const handleGetActions = (signalName) => { + const signal = signals.find((signal) => signal.name === signalName); + if (signal) { + if (!actions || actions.length === 0) + return signal.asyncActions; + const filteredActions = []; + for (let action of actions) { + const actionName = `${signalName}/${action}`; + const retrievedAction = signal.asyncActions.find((act) => act.type === actionName); + if (retrievedAction) + filteredActions.push(retrievedAction); + else + throw new Error(`Async Action ${actionName} not found`); + } + return filteredActions; + } + else + throw new Error(`Signal ${signalName} not found`); + }; + const handleFormatActions = () => { + // Get actions + const nonFormattedActions = handleGetActions(signalName); + // Formatted actions + const formattedActions = {}; + for (const action of nonFormattedActions) { + // Get action name + const actionName = action.type.split("/")[1]; + formattedActions[actionName] = (payload) => __awaiter(void 0, void 0, void 0, function* () { + asyncDispatch({ + type: action.type, + isAsync: true, + status: types_1.AsyncActionStatuses.PENDING, + }); + try { + const response = yield action.steps.asyncAction.handler(payload); + const data = asyncDispatch({ + type: action.type, + isAsync: true, + status: types_1.AsyncActionStatuses.FULFILLED, + payload: response, + }); + return { + data, + status: types_1.AsyncActionStatuses.FULFILLED, + }; + } + catch (error) { + const data = asyncDispatch({ + type: action.type, + isAsync: true, + status: types_1.AsyncActionStatuses.REJECTED, + payload: error, + }); + return { + data, + status: types_1.AsyncActionStatuses.REJECTED, + }; + } + }); + } + return formattedActions; + }; + return handleFormatActions(); +}; +exports.default = useAsyncActions; +//# sourceMappingURL=useAsyncActions.js.map \ No newline at end of file diff --git a/dist/hooks/useAsyncActions.js.map b/dist/hooks/useAsyncActions.js.map new file mode 100644 index 0000000..210a82d --- /dev/null +++ b/dist/hooks/useAsyncActions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"useAsyncActions.js","sourceRoot":"","sources":["../../src/hooks/useAsyncActions.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 5adcfbc..46d8d37 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,9 +1,11 @@ +import GXProvider from "./providers/index.js"; import createSignal from "./helpers/createSignal.js"; import createStore from "./helpers/createStore.js"; -import GXProvider from "./providers/index.js"; +import createAsyncAction from "./helpers/createAsyncAction.js"; import useAction from "./hooks/useAction.js"; import useActions from "./hooks/useActions.js"; +import useAsyncActions from "./hooks/useAsyncActions.js"; import useSignal from "./hooks/useSignal.js"; import useOperations from "./hooks/useOperations.js"; export default GXProvider; -export { createSignal, createStore, useAction, useActions, useSignal, useOperations, }; +export { createSignal, createStore, createAsyncAction, useAction, useActions, useAsyncActions, useSignal, useOperations, }; diff --git a/dist/index.js b/dist/index.js index 8f1e20d..7fd6602 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3,16 +3,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.useOperations = exports.useSignal = exports.useActions = exports.useAction = exports.createStore = exports.createSignal = void 0; +exports.useOperations = exports.useSignal = exports.useAsyncActions = exports.useActions = exports.useAction = exports.createAsyncAction = exports.createStore = exports.createSignal = void 0; +// Provider +const index_js_1 = __importDefault(require("./providers/index.js")); +// Helpers functions const createSignal_js_1 = __importDefault(require("./helpers/createSignal.js")); exports.createSignal = createSignal_js_1.default; const createStore_js_1 = __importDefault(require("./helpers/createStore.js")); exports.createStore = createStore_js_1.default; -const index_js_1 = __importDefault(require("./providers/index.js")); +const createAsyncAction_js_1 = __importDefault(require("./helpers/createAsyncAction.js")); +exports.createAsyncAction = createAsyncAction_js_1.default; +// Hooks const useAction_js_1 = __importDefault(require("./hooks/useAction.js")); exports.useAction = useAction_js_1.default; const useActions_js_1 = __importDefault(require("./hooks/useActions.js")); exports.useActions = useActions_js_1.default; +const useAsyncActions_js_1 = __importDefault(require("./hooks/useAsyncActions.js")); +exports.useAsyncActions = useAsyncActions_js_1.default; const useSignal_js_1 = __importDefault(require("./hooks/useSignal.js")); exports.useSignal = useSignal_js_1.default; const useOperations_js_1 = __importDefault(require("./hooks/useOperations.js")); diff --git a/dist/index.js.map b/dist/index.js.map index 15c3f2f..76deae9 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,gFAAqD;AAYnD,uBAZK,yBAAY,CAYL;AAXd,8EAAmD;AAYjD,sBAZK,wBAAW,CAYL;AAXb,oEAA8C;AAE9C,wEAA6C;AAU3C,oBAVK,sBAAS,CAUL;AATX,0EAA+C;AAU7C,qBAVK,uBAAU,CAUL;AATZ,wEAA6C;AAU3C,oBAVK,sBAAS,CAUL;AATX,gFAAqD;AAUnD,wBAVK,0BAAa,CAUL;AARf,kBAAe,kBAAU,CAAC;AAW1B,uGAAuG"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,WAAW;AACX,oEAA8C;AAE9C,oBAAoB;AACpB,gFAAqD;AAcnD,uBAdK,yBAAY,CAcL;AAbd,8EAAmD;AAcjD,sBAdK,wBAAW,CAcL;AAbb,0FAA+D;AAc7D,4BAdK,8BAAiB,CAcL;AAZnB,QAAQ;AACR,wEAA6C;AAY3C,oBAZK,sBAAS,CAYL;AAXX,0EAA+C;AAY7C,qBAZK,uBAAU,CAYL;AAXZ,oFAAyD;AAYvD,0BAZK,4BAAe,CAYL;AAXjB,wEAA6C;AAY3C,oBAZK,sBAAS,CAYL;AAXX,gFAAqD;AAYnD,wBAZK,0BAAa,CAYL;AAVf,kBAAe,kBAAU,CAAC;AAa1B,uGAAuG"} \ No newline at end of file diff --git a/dist/interfaces/builder.d.ts b/dist/interfaces/builder.d.ts new file mode 100644 index 0000000..947f8bb --- /dev/null +++ b/dist/interfaces/builder.d.ts @@ -0,0 +1,10 @@ +import { CreateAsyncActionReturnType } from "../helpers/types.js"; +import IBuilderCase from "./builderCase.js"; +export default interface IBuilder { + use(asyncAction: CreateAsyncActionReturnType): IBuilderCase; +} +export declare class Builder implements IBuilder { + private _builderCase; + constructor(); + use(asyncAction: CreateAsyncActionReturnType): IBuilderCase; +} diff --git a/dist/interfaces/builder.js b/dist/interfaces/builder.js new file mode 100644 index 0000000..e7f71c7 --- /dev/null +++ b/dist/interfaces/builder.js @@ -0,0 +1,15 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Builder = void 0; +const builderCase_js_1 = require("./builderCase.js"); +class Builder { + constructor() { + this._builderCase = new builderCase_js_1.BuilderCase(); + } + use(asyncAction) { + this._builderCase.asyncAction = asyncAction; + return this._builderCase; + } +} +exports.Builder = Builder; +//# sourceMappingURL=builder.js.map \ No newline at end of file diff --git a/dist/interfaces/builder.js.map b/dist/interfaces/builder.js.map new file mode 100644 index 0000000..87fd195 --- /dev/null +++ b/dist/interfaces/builder.js.map @@ -0,0 +1 @@ +{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/interfaces/builder.ts"],"names":[],"mappings":";;;AACA,qDAA6D;AAM7D,MAAa,OAAO;IAGlB;QACE,IAAI,CAAC,YAAY,GAAG,IAAI,4BAAW,EAAE,CAAC;IACxC,CAAC;IAED,GAAG,CAAC,WAAwC;QAC1C,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,WAAW,CAAC;QAE5C,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF;AAZD,0BAYC"} \ No newline at end of file diff --git a/dist/interfaces/builderCase.d.ts b/dist/interfaces/builderCase.d.ts new file mode 100644 index 0000000..133ff3f --- /dev/null +++ b/dist/interfaces/builderCase.d.ts @@ -0,0 +1,47 @@ +import { AsyncActionStatusesType, CreateAsyncActionReturnType } from "../helpers/types.js"; +/** + * Interface for builder case + */ +export default interface IBuilderCase { + case(status: AsyncActionStatusesType, handler: (state: T, payload?: P) => T): IBuilderCase; +} +/** + * Builder case class for managing different cases of the asynchronous task + * @param _cases List of cases defined for a specific asynchronous task + */ +export declare class BuilderCase implements IBuilderCase { + private _cases; + private _asyncAction; + constructor(); + /** + * Get the list of cases + */ + get cases(): Case[]; + /** + * Get the async action + */ + get asyncAction(): CreateAsyncActionReturnType; + /** + * Update the async action + * @param asyncAction Async Action value + */ + set asyncAction(asyncAction: CreateAsyncActionReturnType); + /** + * Update the cases + */ + set cases(cases: Case[]); + /** + * Method that add a new case into the _cases list and return a new case builder object + * @param status Status of the asynchronous task + * @param handler Function that is executed depending on the specific status + * @returns + */ + case(status: AsyncActionStatusesType, handler: (state: T, payload?: P) => T): IBuilderCase; +} +/** + * Case interface + */ +export interface Case { + status: AsyncActionStatusesType; + handler: (state: T, payload?: P) => T; +} diff --git a/dist/interfaces/builderCase.js b/dist/interfaces/builderCase.js new file mode 100644 index 0000000..461b731 --- /dev/null +++ b/dist/interfaces/builderCase.js @@ -0,0 +1,55 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.BuilderCase = void 0; +/** + * Builder case class for managing different cases of the asynchronous task + * @param _cases List of cases defined for a specific asynchronous task + */ +class BuilderCase { + constructor() { + this._cases = []; + this._asyncAction = undefined; + } + // Getters + /** + * Get the list of cases + */ + get cases() { + return this._cases; + } + /** + * Get the async action + */ + get asyncAction() { + return this._asyncAction; + } + // Setters + /** + * Update the async action + * @param asyncAction Async Action value + */ + set asyncAction(asyncAction) { + this._asyncAction = asyncAction; + } + /** + * Update the cases + */ + set cases(cases) { + this._cases = cases; + } + /** + * Method that add a new case into the _cases list and return a new case builder object + * @param status Status of the asynchronous task + * @param handler Function that is executed depending on the specific status + * @returns + */ + case(status, handler) { + this._cases.push({ + status, + handler, + }); + return this; + } +} +exports.BuilderCase = BuilderCase; +//# sourceMappingURL=builderCase.js.map \ No newline at end of file diff --git a/dist/interfaces/builderCase.js.map b/dist/interfaces/builderCase.js.map new file mode 100644 index 0000000..de2300d --- /dev/null +++ b/dist/interfaces/builderCase.js.map @@ -0,0 +1 @@ +{"version":3,"file":"builderCase.js","sourceRoot":"","sources":["../../src/interfaces/builderCase.ts"],"names":[],"mappings":";;;AAeA;;;GAGG;AACH,MAAa,WAAW;IAItB;QACE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;IAChC,CAAC;IAED,UAAU;IAEV;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU;IAEV;;;OAGG;IACH,IAAI,WAAW,CAAC,WAAwC;QACtD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI,KAAK,CAAC,KAAmB;QAC3B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,IAAI,CACF,MAA+B,EAC/B,OAAqC;QAErC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,MAAM;YACN,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA3DD,kCA2DC"} \ No newline at end of file diff --git a/dist/providers/index.js b/dist/providers/index.js index a6be43f..ff90160 100644 --- a/dist/providers/index.js +++ b/dist/providers/index.js @@ -10,13 +10,52 @@ const reducer_js_1 = __importDefault(require("./reducer.js")); function GXProvider({ children, store }) { // Global state that manage all signals const [signals, dispatch] = (0, react_1.useReducer)(reducer_js_1.default, store.getSignals()); + // Wrap your dispatch function with useTransition + const [, startTransition] = (0, react_1.useTransition)(); + // Your state management logic using useContext and useReducer + const syncDispatch = (action) => { + startTransition(() => { + dispatch(action); + }); + }; + const asyncDispatch = (action) => { + const signalName = action.type.split("/")[0]; + // Get the signal + const signal = signals.find((signal) => signal.name === signalName); + let state = signal.state; + if (!signal) + throw new Error(`Signal "${signalName}" not found`); + if (action.isAsync) { + let actionToDispatch = null; + // Get the action + for (let act of signal.asyncActions) { + if (act.type === action.type) { + actionToDispatch = act; + break; + } + } + if (actionToDispatch) + state = actionToDispatch.steps.cases + .find((c) => c.status === action.status) + .handler(signal.state, action.payload); + else + throw new Error(`Async Action "${action.type}" not found`); + } + dispatch({ + type: action.type, + isAsync: action.isAsync, + status: action.status, + payload: state, + }); + return state; + }; // Context value const contextValue = { signals, - dispatch, + dispatch: syncDispatch, + asyncDispatch, }; return ((0, jsx_runtime_1.jsx)(index_js_1.default.Provider, Object.assign({ value: contextValue }, { children: children }))); } exports.default = GXProvider; -; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/providers/index.js.map b/dist/providers/index.js.map index a5d901b..e9bde95 100644 --- a/dist/providers/index.js.map +++ b/dist/providers/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.tsx"],"names":[],"mappings":";;;;;;AAAA,iCAAmC;AACnC,oEAA6C;AAE7C,8DAAqC;AAErC,SAAwB,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAmB;IACrE,uCAAuC;IACvC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,IAAA,kBAAU,EAAC,oBAAS,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAEtE,gBAAgB;IAChB,MAAM,YAAY,GAAG;QACnB,OAAO;QACP,QAAQ;KACT,CAAC;IAEF,OAAO,CACL,uBAAC,kBAAS,CAAC,QAAQ,kBAAC,KAAK,EAAE,YAAY,gBAAG,QAAQ,IAAsB,CACzE,CAAC;AACJ,CAAC;AAbD,6BAaC;AAAA,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.tsx"],"names":[],"mappings":";;;;;;AAAA,iCAAkD;AAClD,oEAA6C;AAE7C,8DAAqC;AAIrC,SAAwB,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAmB;IACrE,uCAAuC;IACvC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,IAAA,kBAAU,EAAC,oBAAS,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAEtE,iDAAiD;IACjD,MAAM,CAAC,EAAE,eAAe,CAAC,GAAG,IAAA,qBAAa,GAAE,CAAC;IAE5C,8DAA8D;IAC9D,MAAM,YAAY,GAAG,CAAC,MAAgB,EAAE,EAAE;QACxC,eAAe,CAAC,GAAG,EAAE;YACnB,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,MAAgB,EAAE,EAAE;QACzC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE7C,iBAAiB;QACjB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACpE,IAAI,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAEzB,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,aAAa,CAAC,CAAC;QAEjE,IAAI,MAAM,CAAC,OAAO,EAAE;YAClB,IAAI,gBAAgB,GAA2B,IAAI,CAAC;YAEpD,iBAAiB;YACjB,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,YAAY,EAAE;gBACnC,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE;oBAC5B,gBAAgB,GAAG,GAAG,CAAC;oBAEvB,MAAM;iBACP;aACF;YAED,IAAI,gBAAgB;gBAClB,KAAK,GAAI,gBAAgB,CAAC,KAA0B,CAAC,KAAK;qBACvD,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC;qBACvC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;;gBACtC,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,CAAC,IAAI,aAAa,CAAC,CAAC;SACjE;QAED,QAAQ,CAAC;YACP,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,gBAAgB;IAChB,MAAM,YAAY,GAAG;QACnB,OAAO;QACP,QAAQ,EAAE,YAAY;QACtB,aAAa;KACd,CAAC;IAEF,OAAO,CACL,uBAAC,kBAAS,CAAC,QAAQ,kBAAC,KAAK,EAAE,YAAY,gBAAG,QAAQ,IAAsB,CACzE,CAAC;AACJ,CAAC;AA9DD,6BA8DC"} \ No newline at end of file diff --git a/dist/providers/reducer.js b/dist/providers/reducer.js index 3d7f053..dd5c3c0 100644 --- a/dist/providers/reducer.js +++ b/dist/providers/reducer.js @@ -9,20 +9,25 @@ const gxReducer = (signals, action) => { const signal = prevSignals.find((signal) => signal.name === signalName); if (!signal) throw new Error(`Signal "${signalName}" not found`); - let actionToDispatch = null; - // Get the action - for (let act of signal.actions) { - if (act.type === action.type) { - actionToDispatch = act; - break; + if (!action.isAsync) { + let actionToDispatch = null; + // Get the action + for (let act of signal.actions) { + if (act.type === action.type) { + actionToDispatch = act; + break; + } } + if (actionToDispatch) { + // Dispatch the action + signal.state = actionToDispatch.handler(signal.state, action.payload); + } + else + throw new Error(`Action "${action.type}" not found`); } - if (actionToDispatch) { - // Dispatch the action - signal.state = actionToDispatch.handler(signal.state, action.payload); + else { + signal.state = action.payload; } - else - throw new Error(`Action "${action.type}" not found`); return prevSignals; }; exports.default = gxReducer; diff --git a/dist/providers/reducer.js.map b/dist/providers/reducer.js.map index f935362..6a5a6af 100644 --- a/dist/providers/reducer.js.map +++ b/dist/providers/reducer.js.map @@ -1 +1 @@ -{"version":3,"file":"reducer.js","sourceRoot":"","sources":["../../src/providers/reducer.ts"],"names":[],"mappings":";;AAGA,MAAM,SAAS,GAAG,CAAC,OAAuB,EAAE,MAAgB,EAAE,EAAE;IAC9D,eAAe;IACf,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAEjC,sBAAsB;IACtB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,iBAAiB;IACjB,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAExE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,aAAa,CAAC,CAAC;IAEjE,IAAI,gBAAgB,GAAG,IAAI,CAAC;IAE5B,iBAAiB;IACjB,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE;QAC9B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE;YAC5B,gBAAgB,GAAG,GAAG,CAAC;YAEvB,MAAM;SACP;KACF;IAED,IAAI,gBAAgB,EAAE;QACpB,sBAAsB;QACtB,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;KACvE;;QAAM,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,aAAa,CAAC,CAAC;IAE5D,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC"} \ No newline at end of file +{"version":3,"file":"reducer.js","sourceRoot":"","sources":["../../src/providers/reducer.ts"],"names":[],"mappings":";;AASA,MAAM,SAAS,GAAG,CAAC,OAAuB,EAAE,MAAgB,EAAE,EAAE;IAC9D,eAAe;IACf,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAEjC,sBAAsB;IACtB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,iBAAiB;IACjB,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAExE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,aAAa,CAAC,CAAC;IAEjE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QACnB,IAAI,gBAAgB,GAAsB,IAAI,CAAC;QAE/C,iBAAiB;QACjB,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE;YAC9B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE;gBAC5B,gBAAgB,GAAG,GAAG,CAAC;gBAEvB,MAAM;aACP;SACF;QAED,IAAI,gBAAgB,EAAE;YACpB,sBAAsB;YACtB,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;SACvE;;YAAM,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,aAAa,CAAC,CAAC;KAC7D;SAAM;QACL,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;KAC/B;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC"} \ No newline at end of file diff --git a/dist/providers/types.d.ts b/dist/providers/types.d.ts index dd63d14..58f32e0 100644 --- a/dist/providers/types.d.ts +++ b/dist/providers/types.d.ts @@ -1,10 +1,18 @@ /// -import { CreateStoreType } from '../helpers/types.js'; +import { AsyncActionStatusesType, CreateStoreType } from '../helpers/types.js'; +/** + * Props of the GX Provider + */ export type GXProviderProps = { children: React.ReactElement; store: CreateStoreType; }; +/** + * Type of the actions + */ export type GXAction = { type: string; - payload: any; + isAsync: boolean; + status?: AsyncActionStatusesType; + payload?: any; }; diff --git a/src/contexts/index.ts b/src/contexts/index.ts index e3299c4..ae837af 100644 --- a/src/contexts/index.ts +++ b/src/contexts/index.ts @@ -4,6 +4,7 @@ import { GXContextType } from "./types.js"; const GXContext = createContext({ signals: [], dispatch: () => {}, + asyncDispatch: () => {}, }); export default GXContext; diff --git a/src/contexts/types.ts b/src/contexts/types.ts index e4dccbb..028aedf 100644 --- a/src/contexts/types.ts +++ b/src/contexts/types.ts @@ -1,47 +1,80 @@ +import IBuilderCase, { BuilderCase } from "../interfaces/builderCase.js"; import { GXAction } from "../providers/types.js"; +/** + * Type that represents a signal + */ export type GXSignalType = { // Name of the signal name: string; // State inside the signal - state: T, + state: T; // Actions of the signal - actions: GXActionType[], + actions?: GXActionType[]; - // Operation of the signal - operations?: GXOperationType[] -} + // Operations of the signal + operations?: GXOperationType[]; + // Async actions of the signal + asyncActions?: GXAsyncActionType[]; +}; + +/** + * Type that represents Actions + */ export type GXActionType = { // Represent the type of the action - type: string, + type: string; // The handler function - handler: (state: T, payload: P) => T -} + handler: (state: T, payload: P) => T; +}; +/** + * Type that represents operations + */ export type GXOperationType = { // Represent the type of the operation - type: string, + type: string; // The handle function - handler: (state: T, payload: P) => Q -} + handler: (state: T, payload: P) => Q; +}; + +/** + * Type that represents async actions + */ +export type GXAsyncActionType = { + // Represent the type of the operation + type: string; + // List of cases + steps: IBuilderCase; +}; + +/** + * Type of dispatched action + */ export type DispatchedActionType = { // The type of the action - type: string, + type: string; // The payload of the action - payload: any -} + payload: any; +}; +/** + * Type of the signals context + */ export type GXContextType = { // Signals - signals: GXSignalType[], + signals: GXSignalType[]; // Dispatch - dispatch: React.Dispatch -} \ No newline at end of file + dispatch: React.Dispatch; + + // Async Dispatch + asyncDispatch: (action: GXAction) => any; +}; diff --git a/src/helpers/createAsyncAction.ts b/src/helpers/createAsyncAction.ts new file mode 100644 index 0000000..021d3ce --- /dev/null +++ b/src/helpers/createAsyncAction.ts @@ -0,0 +1,23 @@ +import { + AsyncActionStatuses, + CreateAsyncActionProp, + CreateAsyncActionReturnType, +} from "./types.js"; + +/** + * This function create an async action with different statuses + * @param handler Function that perform asynchronous task + * @returns + */ +const createAsyncAction = ( + handler: CreateAsyncActionProp +): CreateAsyncActionReturnType => { + return { + pending: AsyncActionStatuses.PENDING, + fulfilled: AsyncActionStatuses.FULFILLED, + rejected: AsyncActionStatuses.REJECTED, + handler, + }; +}; + +export default createAsyncAction; diff --git a/src/helpers/createSignal.ts b/src/helpers/createSignal.ts index 74faa4d..6e2ed03 100644 --- a/src/helpers/createSignal.ts +++ b/src/helpers/createSignal.ts @@ -1,5 +1,10 @@ import { CreateSignalOptionType } from "./types.js"; -import { GXActionType, GXOperationType } from "../contexts/types.js"; +import { + GXActionType, + GXAsyncActionType, + GXOperationType, +} from "../contexts/types.js"; +import { Builder } from "../interfaces/builder.js"; /** * Create a signal with a state and actions for managing this state @@ -9,9 +14,10 @@ import { GXActionType, GXOperationType } from "../contexts/types.js"; const createSignal = (options: CreateSignalOptionType) => { const actions: GXActionType[] = []; const operations: GXOperationType[] = []; + const asyncActions: GXAsyncActionType[] = []; // Convert the actions object to an array - const actionsTable = Object.entries(options.actions); + const actionsTable = Object.entries(options.actions || {}); for (let action of actionsTable) { actions.push({ @@ -30,12 +36,27 @@ const createSignal = (options: CreateSignalOptionType) => { }); } + // Convert the async Actions object to an array + const builder = new Builder(); + + const asyncActionsTable = Object.entries( + options.asyncActions ? options.asyncActions(builder) : {} + ); + + for (let action of asyncActionsTable) { + asyncActions.push({ + type: `${options.name}/${action[0]}`, + steps: action[1], + }); + } + // Create a signal const signal = { name: options.name, state: options.state, actions, operations, + asyncActions, }; return signal; diff --git a/src/helpers/createStore.ts b/src/helpers/createStore.ts index 1978c8f..05a4464 100644 --- a/src/helpers/createStore.ts +++ b/src/helpers/createStore.ts @@ -1,6 +1,11 @@ import { GXSignalType } from "../contexts/types.js"; import { CreateStoreType } from "./types.js"; +/** + * Function that create a store by collection a list of signals + * @param signals List of signals + * @returns + */ const createStore = (signals: GXSignalType[]): CreateStoreType => { return { getSignals: () => signals, diff --git a/src/helpers/types.ts b/src/helpers/types.ts index 4475df0..d02d879 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -1,20 +1,70 @@ import { GXSignalType } from "../contexts/types.js"; +import { Builder } from "../interfaces/builder.js"; +import IBuilderCase from "../interfaces/builderCase.js"; +/** + * Type of the create signal option function + */ export type CreateSignalOptionType = { + // Name of the signal name: string; + + // State of the signal state: T; - actions: Action; + + // Actions of the signal + actions?: Action; + + // Operations of the signal operations?: Operation; -} + // Async actions of the signal + asyncActions?: AsyncAction; +}; + +/** + * Type of the returned data of create store function + */ export type CreateStoreType = { - getSignals: () => GXSignalType[] -} + // Function that return the list of signals + getSignals: () => GXSignalType[]; +}; +/** + * Type of Action + */ export type Action = { - [key: string]: (state: T, payload: any) => T -} + [key: string]: (state: T, payload: any) => T; +}; +/** + * Type of Operation + */ export type Operation = { - [key: string]: (state: T, payload?: any) => any -} \ No newline at end of file + [key: string]: (state: T, payload?: any) => any; +}; + +/** + * Type of Async Action + */ +export type AsyncAction = (builder: Builder) => { + [key: string]: IBuilderCase; +}; + +export type CreateAsyncActionProp = (payload?: any) => Promise; + +export type CreateAsyncActionReturnType = { + pending: AsyncActionStatusesType; + fulfilled: AsyncActionStatusesType; + rejected: AsyncActionStatusesType; + handler: CreateAsyncActionProp; +}; + +export const AsyncActionStatuses = { + PENDING: "PENDING", + FULFILLED: "FULFILLED", + REJECTED: "REJECTED", +} as const; + +export type AsyncActionStatusesType = + (typeof AsyncActionStatuses)[keyof typeof AsyncActionStatuses]; diff --git a/src/hooks/types.ts b/src/hooks/types.ts index 54e955a..826399a 100644 --- a/src/hooks/types.ts +++ b/src/hooks/types.ts @@ -1,7 +1,16 @@ +import { AsyncActionStatusesType } from "../helpers/types"; + export type Actions = { - [key: string]: (payload?: any) => void -} + [key: string]: (payload?: any) => void; +}; + +export type AsyncActions = { + [key: string]: (payload?: any) => Promise<{ + data: T; + status: Omit; + }>; +}; export type Operations

= { - [key: string]: (payload?: any) => P -} \ No newline at end of file + [key: string]: (payload?: any) => P; +}; diff --git a/src/hooks/useActions.ts b/src/hooks/useActions.ts index 1498c88..e2999d8 100644 --- a/src/hooks/useActions.ts +++ b/src/hooks/useActions.ts @@ -54,6 +54,7 @@ const useActions = (signalName: string, ...actions: string[]) => { formattedActions[actionName] = (payload?: any) => { dispatch({ type: action.type, + isAsync: false, payload, }); }; diff --git a/src/hooks/useAsyncActions.ts b/src/hooks/useAsyncActions.ts new file mode 100644 index 0000000..83e0849 --- /dev/null +++ b/src/hooks/useAsyncActions.ts @@ -0,0 +1,106 @@ +import { useContext } from "react"; +import { AsyncActions } from "./types"; +import GXContext from "../contexts"; +import { GXAsyncActionType } from "../contexts/types"; +import { AsyncActionStatuses } from "../helpers/types"; +import { BuilderCase } from "../interfaces/builderCase"; + +const useAsyncActions = >( + signalName: string, + ...actions: string[] +) => { + if (!signalName || typeof signalName !== "string") + throw new Error( + "Provide a signalName as first argument of useAsyncActions" + ); + + // Get Global Context + const { signals, asyncDispatch } = useContext(GXContext); + + // Some handlers + + /** + * Get async actions of a signal + * @param signalName + * @returns + */ + const handleGetAsyncActions = (signalName: string) => { + const signal = signals.find((signal) => signal.name === signalName); + + if (signal) { + if (!actions || actions.length === 0) return signal.asyncActions; + + const filteredActions: GXAsyncActionType[] = []; + + for (let action of actions) { + const actionName = `${signalName}/${action}`; + + const retrievedAction = signal.asyncActions.find( + (act) => act.type === actionName + ); + + if (retrievedAction) filteredActions.push(retrievedAction); + else throw new Error(`Async Action ${actionName} not found`); + } + + return filteredActions; + } else throw new Error(`Signal ${signalName} not found`); + }; + + const handleFormatAsyncActions = (): P => { + // Get actions + const nonFormattedActions = handleGetAsyncActions(signalName); + + // Formatted actions + const formattedActions = {} as any; + + for (const action of nonFormattedActions) { + // Get action name + const actionName = action.type.split("/")[1]; + + formattedActions[actionName] = async (payload?: any) => { + asyncDispatch({ + type: action.type, + isAsync: true, + status: AsyncActionStatuses.PENDING, + }); + + try { + const response = await ( + action.steps as BuilderCase + ).asyncAction.handler(payload); + + const data = asyncDispatch({ + type: action.type, + isAsync: true, + status: AsyncActionStatuses.FULFILLED, + payload: response, + }); + + return { + data, + status: AsyncActionStatuses.FULFILLED, + }; + } catch (error) { + const data = asyncDispatch({ + type: action.type, + isAsync: true, + status: AsyncActionStatuses.REJECTED, + payload: error, + }); + + return { + data, + status: AsyncActionStatuses.REJECTED, + }; + } + }; + } + + return formattedActions; + }; + + return handleFormatAsyncActions(); +}; + +export default useAsyncActions; diff --git a/src/index.ts b/src/index.ts index e0ce541..14032cd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,15 @@ +// Provider +import GXProvider from "./providers/index.js"; + +// Helpers functions import createSignal from "./helpers/createSignal.js"; import createStore from "./helpers/createStore.js"; -import GXProvider from "./providers/index.js"; +import createAsyncAction from "./helpers/createAsyncAction.js"; +// Hooks import useAction from "./hooks/useAction.js"; import useActions from "./hooks/useActions.js"; +import useAsyncActions from "./hooks/useAsyncActions.js"; import useSignal from "./hooks/useSignal.js"; import useOperations from "./hooks/useOperations.js"; @@ -12,8 +18,10 @@ export default GXProvider; export { createSignal, createStore, + createAsyncAction, useAction, useActions, + useAsyncActions, useSignal, useOperations, }; diff --git a/src/interfaces/builder.ts b/src/interfaces/builder.ts new file mode 100644 index 0000000..38c7d8e --- /dev/null +++ b/src/interfaces/builder.ts @@ -0,0 +1,20 @@ +import { CreateAsyncActionReturnType } from "../helpers/types.js"; +import IBuilderCase, { BuilderCase } from "./builderCase.js"; + +export default interface IBuilder { + use(asyncAction: CreateAsyncActionReturnType): IBuilderCase; +} + +export class Builder implements IBuilder { + private _builderCase: BuilderCase; + + constructor() { + this._builderCase = new BuilderCase(); + } + + use(asyncAction: CreateAsyncActionReturnType): IBuilderCase { + this._builderCase.asyncAction = asyncAction; + + return this._builderCase; + } +} diff --git a/src/interfaces/builderCase.ts b/src/interfaces/builderCase.ts new file mode 100644 index 0000000..a2d5335 --- /dev/null +++ b/src/interfaces/builderCase.ts @@ -0,0 +1,87 @@ +import { + AsyncActionStatusesType, + CreateAsyncActionReturnType, +} from "../helpers/types.js"; + +/** + * Interface for builder case + */ +export default interface IBuilderCase { + case( + status: AsyncActionStatusesType, + handler: (state: T, payload?: P) => T + ): IBuilderCase; +} + +/** + * Builder case class for managing different cases of the asynchronous task + * @param _cases List of cases defined for a specific asynchronous task + */ +export class BuilderCase implements IBuilderCase { + private _cases: Case[]; + private _asyncAction: CreateAsyncActionReturnType | undefined; + + constructor() { + this._cases = []; + this._asyncAction = undefined; + } + + // Getters + + /** + * Get the list of cases + */ + get cases() { + return this._cases; + } + + /** + * Get the async action + */ + get asyncAction() { + return this._asyncAction; + } + + // Setters + + /** + * Update the async action + * @param asyncAction Async Action value + */ + set asyncAction(asyncAction: CreateAsyncActionReturnType) { + this._asyncAction = asyncAction; + } + + /** + * Update the cases + */ + set cases(cases: Case[]) { + this._cases = cases; + } + + /** + * Method that add a new case into the _cases list and return a new case builder object + * @param status Status of the asynchronous task + * @param handler Function that is executed depending on the specific status + * @returns + */ + case( + status: AsyncActionStatusesType, + handler: (state: T, payload?: P) => T + ): IBuilderCase { + this._cases.push({ + status, + handler, + }); + + return this; + } +} + +/** + * Case interface + */ +export interface Case { + status: AsyncActionStatusesType; + handler: (state: T, payload?: P) => T; +} diff --git a/src/providers/index.tsx b/src/providers/index.tsx index c679c6b..eaa8750 100644 --- a/src/providers/index.tsx +++ b/src/providers/index.tsx @@ -1,19 +1,70 @@ -import { useReducer } from "react"; +import { useReducer, useTransition } from "react"; import GXContext from "../contexts/index.js"; -import { GXProviderProps } from "./types.js"; +import { GXAction, GXProviderProps } from "./types.js"; import gxReducer from "./reducer.js"; +import { GXAsyncActionType } from "../contexts/types.js"; +import { BuilderCase } from "../interfaces/builderCase.js"; export default function GXProvider({ children, store }: GXProviderProps) { // Global state that manage all signals const [signals, dispatch] = useReducer(gxReducer, store.getSignals()); + // Wrap your dispatch function with useTransition + const [, startTransition] = useTransition(); + + // Your state management logic using useContext and useReducer + const syncDispatch = (action: GXAction) => { + startTransition(() => { + dispatch(action); + }); + }; + + const asyncDispatch = (action: GXAction) => { + const signalName = action.type.split("/")[0]; + + // Get the signal + const signal = signals.find((signal) => signal.name === signalName); + let state = signal.state; + + if (!signal) throw new Error(`Signal "${signalName}" not found`); + + if (action.isAsync) { + let actionToDispatch: GXAsyncActionType = null; + + // Get the action + for (let act of signal.asyncActions) { + if (act.type === action.type) { + actionToDispatch = act; + + break; + } + } + + if (actionToDispatch) + state = (actionToDispatch.steps as BuilderCase).cases + .find((c) => c.status === action.status) + .handler(signal.state, action.payload); + else throw new Error(`Async Action "${action.type}" not found`); + } + + dispatch({ + type: action.type, + isAsync: action.isAsync, + status: action.status, + payload: state, + }); + + return state; + }; + // Context value const contextValue = { signals, - dispatch, + dispatch: syncDispatch, + asyncDispatch, }; return ( {children} ); -}; +} diff --git a/src/providers/reducer.ts b/src/providers/reducer.ts index b694dac..9e7a0df 100644 --- a/src/providers/reducer.ts +++ b/src/providers/reducer.ts @@ -1,4 +1,10 @@ -import { GXSignalType } from "../contexts/types.js"; +import { + GXActionType, + GXAsyncActionType, + GXSignalType, +} from "../contexts/types.js"; +import { AsyncActionStatuses } from "../helpers/types.js"; +import { BuilderCase } from "../interfaces/builderCase.js"; import { GXAction } from "./types.js"; const gxReducer = (signals: GXSignalType[], action: GXAction) => { @@ -13,21 +19,25 @@ const gxReducer = (signals: GXSignalType[], action: GXAction) => { if (!signal) throw new Error(`Signal "${signalName}" not found`); - let actionToDispatch = null; + if (!action.isAsync) { + let actionToDispatch: GXActionType = null; - // Get the action - for (let act of signal.actions) { - if (act.type === action.type) { - actionToDispatch = act; + // Get the action + for (let act of signal.actions) { + if (act.type === action.type) { + actionToDispatch = act; - break; + break; + } } - } - if (actionToDispatch) { - // Dispatch the action - signal.state = actionToDispatch.handler(signal.state, action.payload); - } else throw new Error(`Action "${action.type}" not found`); + if (actionToDispatch) { + // Dispatch the action + signal.state = actionToDispatch.handler(signal.state, action.payload); + } else throw new Error(`Action "${action.type}" not found`); + } else { + signal.state = action.payload; + } return prevSignals; }; diff --git a/src/providers/types.ts b/src/providers/types.ts index 8830fac..d7f519b 100644 --- a/src/providers/types.ts +++ b/src/providers/types.ts @@ -1,11 +1,28 @@ -import { CreateStoreType } from '../helpers/types.js'; +import { AsyncActionStatusesType, CreateStoreType } from '../helpers/types.js'; +/** + * Props of the GX Provider + */ export type GXProviderProps = { + // Children component of the GX Provider children: React.ReactElement, + + // Collection of signals store: CreateStoreType } +/** + * Type of the actions + */ export type GXAction = { + // Type of the action type: string; - payload: any + + // Nature of the action + isAsync: boolean; + + status?: AsyncActionStatusesType; + + // Payload of the action + payload?: any } \ No newline at end of file From a8d752ae5077d8a7444e72dc72cfd2dd69651d7f Mon Sep 17 00:00:00 2001 From: dilane3 Date: Thu, 21 Sep 2023 23:04:45 +0100 Subject: [PATCH 2/2] Add: Adding three others method into builder case class to handle the different case for an async action --- .npmignore | 2 ++ dist/hooks/useAsyncActions.js | 10 ++++----- dist/hooks/useAsyncActions.js.map | 2 +- dist/index.d.ts | 3 ++- dist/index.js | 5 ++++- dist/index.js.map | 2 +- dist/interfaces/builderCase.d.ts | 21 ++++++++++++++++++ dist/interfaces/builderCase.js | 25 ++++++++++++++++++++++ dist/interfaces/builderCase.js.map | 2 +- dist/providers/reducer.js.map | 2 +- package.json | 2 +- src/index.ts | 4 ++++ src/interfaces/builderCase.ts | 34 ++++++++++++++++++++++++++++++ src/providers/reducer.ts | 3 --- 14 files changed, 102 insertions(+), 15 deletions(-) diff --git a/.npmignore b/.npmignore index 8e1cbc8..012d668 100644 --- a/.npmignore +++ b/.npmignore @@ -1,3 +1,5 @@ node_modules src tsconfig.json +.babelrc +yarn.lock diff --git a/dist/hooks/useAsyncActions.js b/dist/hooks/useAsyncActions.js index 280c018..510686f 100644 --- a/dist/hooks/useAsyncActions.js +++ b/dist/hooks/useAsyncActions.js @@ -22,11 +22,11 @@ const useAsyncActions = (signalName, ...actions) => { const { signals, asyncDispatch } = (0, react_1.useContext)(contexts_1.default); // Some handlers /** - * Get actions of a signal + * Get async actions of a signal * @param signalName * @returns */ - const handleGetActions = (signalName) => { + const handleGetAsyncActions = (signalName) => { const signal = signals.find((signal) => signal.name === signalName); if (signal) { if (!actions || actions.length === 0) @@ -45,9 +45,9 @@ const useAsyncActions = (signalName, ...actions) => { else throw new Error(`Signal ${signalName} not found`); }; - const handleFormatActions = () => { + const handleFormatAsyncActions = () => { // Get actions - const nonFormattedActions = handleGetActions(signalName); + const nonFormattedActions = handleGetAsyncActions(signalName); // Formatted actions const formattedActions = {}; for (const action of nonFormattedActions) { @@ -88,7 +88,7 @@ const useAsyncActions = (signalName, ...actions) => { } return formattedActions; }; - return handleFormatActions(); + return handleFormatAsyncActions(); }; exports.default = useAsyncActions; //# sourceMappingURL=useAsyncActions.js.map \ No newline at end of file diff --git a/dist/hooks/useAsyncActions.js.map b/dist/hooks/useAsyncActions.js.map index 210a82d..72eafa9 100644 --- a/dist/hooks/useAsyncActions.js.map +++ b/dist/hooks/useAsyncActions.js.map @@ -1 +1 @@ -{"version":3,"file":"useAsyncActions.js","sourceRoot":"","sources":["../../src/hooks/useAsyncActions.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,iCAAmC;AAEnC,2DAAoC;AAEpC,4CAAuD;AAGvD,MAAM,eAAe,GAAG,CACtB,UAAkB,EAClB,GAAG,OAAiB,EACpB,EAAE;IACF,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ;QAC/C,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IAEJ,qBAAqB;IACrB,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,IAAA,kBAAU,EAAC,kBAAS,CAAC,CAAC;IAEzD,gBAAgB;IAEhB;;;;OAIG;IACH,MAAM,gBAAgB,GAAG,CAAC,UAAkB,EAAE,EAAE;QAC9C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAEpE,IAAI,MAAM,EAAE;YACV,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAC,YAAY,CAAC;YAEjE,MAAM,eAAe,GAA2B,EAAE,CAAC;YAEnD,KAAK,IAAI,MAAM,IAAI,OAAO,EAAE;gBAC1B,MAAM,UAAU,GAAG,GAAG,UAAU,IAAI,MAAM,EAAE,CAAC;gBAE7C,MAAM,eAAe,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAC9C,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CACjC,CAAC;gBAEF,IAAI,eAAe;oBAAE,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;;oBACtD,MAAM,IAAI,KAAK,CAAC,gBAAgB,UAAU,YAAY,CAAC,CAAC;aAC9D;YAED,OAAO,eAAe,CAAC;SACxB;;YAAM,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,YAAY,CAAC,CAAC;IAC3D,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,GAAM,EAAE;QAClC,cAAc;QACd,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAEzD,oBAAoB;QACpB,MAAM,gBAAgB,GAAG,EAAS,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,mBAAmB,EAAE;YACxC,kBAAkB;YAClB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAE7C,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAO,OAAa,EAAE,EAAE;gBACrD,aAAa,CAAC;oBACZ,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,OAAO,EAAE,IAAI;oBACb,MAAM,EAAE,2BAAmB,CAAC,OAAO;iBACpC,CAAC,CAAC;gBAEH,IAAI;oBACF,MAAM,QAAQ,GAAG,MACf,MAAM,CAAC,KACR,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBAE/B,MAAM,IAAI,GAAG,aAAa,CAAC;wBACzB,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,2BAAmB,CAAC,SAAS;wBACrC,OAAO,EAAE,QAAQ;qBAClB,CAAC,CAAC;oBAEH,OAAO;wBACL,IAAI;wBACJ,MAAM,EAAE,2BAAmB,CAAC,SAAS;qBACtC,CAAC;iBACH;gBAAC,OAAO,KAAK,EAAE;oBACd,MAAM,IAAI,GAAG,aAAa,CAAC;wBACzB,IAAI,EAAE,MAAM,CAAC,IAAI;wBACjB,OAAO,EAAE,IAAI;wBACb,MAAM,EAAE,2BAAmB,CAAC,QAAQ;wBACpC,OAAO,EAAE,KAAK;qBACf,CAAC,CAAC;oBAEH,OAAO;wBACL,IAAI;wBACJ,MAAM,EAAE,2BAAmB,CAAC,QAAQ;qBACrC,CAAC;iBACH;YACH,CAAC,CAAA,CAAC;SACH;QAED,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,mBAAmB,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,kBAAe,eAAe,CAAC"} \ No newline at end of file +{"version":3,"file":"useAsyncActions.js","sourceRoot":"","sources":["../../src/hooks/useAsyncActions.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 46d8d37..a554749 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,4 +1,5 @@ import GXProvider from "./providers/index.js"; +import { AsyncActionStatuses } from "./helpers/types.js"; import createSignal from "./helpers/createSignal.js"; import createStore from "./helpers/createStore.js"; import createAsyncAction from "./helpers/createAsyncAction.js"; @@ -8,4 +9,4 @@ import useAsyncActions from "./hooks/useAsyncActions.js"; import useSignal from "./hooks/useSignal.js"; import useOperations from "./hooks/useOperations.js"; export default GXProvider; -export { createSignal, createStore, createAsyncAction, useAction, useActions, useAsyncActions, useSignal, useOperations, }; +export { createSignal, createStore, createAsyncAction, useAction, useActions, useAsyncActions, useSignal, useOperations, AsyncActionStatuses }; diff --git a/dist/index.js b/dist/index.js index 7fd6602..0833468 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3,9 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.useOperations = exports.useSignal = exports.useAsyncActions = exports.useActions = exports.useAction = exports.createAsyncAction = exports.createStore = exports.createSignal = void 0; +exports.AsyncActionStatuses = exports.useOperations = exports.useSignal = exports.useAsyncActions = exports.useActions = exports.useAction = exports.createAsyncAction = exports.createStore = exports.createSignal = void 0; // Provider const index_js_1 = __importDefault(require("./providers/index.js")); +// Constants +const types_js_1 = require("./helpers/types.js"); +Object.defineProperty(exports, "AsyncActionStatuses", { enumerable: true, get: function () { return types_js_1.AsyncActionStatuses; } }); // Helpers functions const createSignal_js_1 = __importDefault(require("./helpers/createSignal.js")); exports.createSignal = createSignal_js_1.default; diff --git a/dist/index.js.map b/dist/index.js.map index 76deae9..16c6ddf 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,WAAW;AACX,oEAA8C;AAE9C,oBAAoB;AACpB,gFAAqD;AAcnD,uBAdK,yBAAY,CAcL;AAbd,8EAAmD;AAcjD,sBAdK,wBAAW,CAcL;AAbb,0FAA+D;AAc7D,4BAdK,8BAAiB,CAcL;AAZnB,QAAQ;AACR,wEAA6C;AAY3C,oBAZK,sBAAS,CAYL;AAXX,0EAA+C;AAY7C,qBAZK,uBAAU,CAYL;AAXZ,oFAAyD;AAYvD,0BAZK,4BAAe,CAYL;AAXjB,wEAA6C;AAY3C,oBAZK,sBAAS,CAYL;AAXX,gFAAqD;AAYnD,wBAZK,0BAAa,CAYL;AAVf,kBAAe,kBAAU,CAAC;AAa1B,uGAAuG"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,WAAW;AACX,oEAA8C;AAE9C,YAAY;AACZ,iDAAyD;AAyBvD,oGAzBO,8BAAmB,OAyBP;AAvBrB,oBAAoB;AACpB,gFAAqD;AAcnD,uBAdK,yBAAY,CAcL;AAbd,8EAAmD;AAcjD,sBAdK,wBAAW,CAcL;AAbb,0FAA+D;AAc7D,4BAdK,8BAAiB,CAcL;AAZnB,QAAQ;AACR,wEAA6C;AAY3C,oBAZK,sBAAS,CAYL;AAXX,0EAA+C;AAY7C,qBAZK,uBAAU,CAYL;AAXZ,oFAAyD;AAYvD,0BAZK,4BAAe,CAYL;AAXjB,wEAA6C;AAY3C,oBAZK,sBAAS,CAYL;AAXX,gFAAqD;AAYnD,wBAZK,0BAAa,CAYL;AAVf,kBAAe,kBAAU,CAAC;AAc1B,uGAAuG"} \ No newline at end of file diff --git a/dist/interfaces/builderCase.d.ts b/dist/interfaces/builderCase.d.ts index 133ff3f..d78975b 100644 --- a/dist/interfaces/builderCase.d.ts +++ b/dist/interfaces/builderCase.d.ts @@ -4,6 +4,9 @@ import { AsyncActionStatusesType, CreateAsyncActionReturnType } from "../helpers */ export default interface IBuilderCase { case(status: AsyncActionStatusesType, handler: (state: T, payload?: P) => T): IBuilderCase; + onPending(handler: (state: T, payload?: P) => T): IBuilderCase; + onFulfilled(handler: (state: T, payload?: P) => T): IBuilderCase; + onRejected(handler: (state: T, payload?: P) => T): IBuilderCase; } /** * Builder case class for managing different cases of the asynchronous task @@ -37,6 +40,24 @@ export declare class BuilderCase implements IBuilderCase { * @returns */ case(status: AsyncActionStatusesType, handler: (state: T, payload?: P) => T): IBuilderCase; + /** + * Method that add a pending case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + */ + onPending(handler: (state: T, payload?: P) => T): IBuilderCase; + /** + * Method that add a fulfilled case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + */ + onFulfilled(handler: (state: T, payload?: P) => T): IBuilderCase; + /** + * Method that add a rejected case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + **/ + onRejected(handler: (state: T, payload?: P) => T): IBuilderCase; } /** * Case interface diff --git a/dist/interfaces/builderCase.js b/dist/interfaces/builderCase.js index 461b731..b2b6821 100644 --- a/dist/interfaces/builderCase.js +++ b/dist/interfaces/builderCase.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BuilderCase = void 0; +const types_js_1 = require("../helpers/types.js"); /** * Builder case class for managing different cases of the asynchronous task * @param _cases List of cases defined for a specific asynchronous task @@ -50,6 +51,30 @@ class BuilderCase { }); return this; } + /** + * Method that add a pending case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + */ + onPending(handler) { + return this.case(types_js_1.AsyncActionStatuses.PENDING, handler); + } + /** + * Method that add a fulfilled case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + */ + onFulfilled(handler) { + return this.case(types_js_1.AsyncActionStatuses.FULFILLED, handler); + } + /** + * Method that add a rejected case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + **/ + onRejected(handler) { + return this.case(types_js_1.AsyncActionStatuses.REJECTED, handler); + } } exports.BuilderCase = BuilderCase; //# sourceMappingURL=builderCase.js.map \ No newline at end of file diff --git a/dist/interfaces/builderCase.js.map b/dist/interfaces/builderCase.js.map index de2300d..c86b41b 100644 --- a/dist/interfaces/builderCase.js.map +++ b/dist/interfaces/builderCase.js.map @@ -1 +1 @@ -{"version":3,"file":"builderCase.js","sourceRoot":"","sources":["../../src/interfaces/builderCase.ts"],"names":[],"mappings":";;;AAeA;;;GAGG;AACH,MAAa,WAAW;IAItB;QACE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;IAChC,CAAC;IAED,UAAU;IAEV;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU;IAEV;;;OAGG;IACH,IAAI,WAAW,CAAC,WAAwC;QACtD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI,KAAK,CAAC,KAAmB;QAC3B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,IAAI,CACF,MAA+B,EAC/B,OAAqC;QAErC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,MAAM;YACN,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA3DD,kCA2DC"} \ No newline at end of file +{"version":3,"file":"builderCase.js","sourceRoot":"","sources":["../../src/interfaces/builderCase.ts"],"names":[],"mappings":";;;AAAA,kDAI6B;AAkB7B;;;GAGG;AACH,MAAa,WAAW;IAItB;QACE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;IAChC,CAAC;IAED,UAAU;IAEV;;OAEG;IACH,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU;IAEV;;;OAGG;IACH,IAAI,WAAW,CAAC,WAAwC;QACtD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI,KAAK,CAAC,KAAmB;QAC3B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,IAAI,CACF,MAA+B,EAC/B,OAAqC;QAErC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,MAAM;YACN,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,OAAqC;QAC7C,OAAO,IAAI,CAAC,IAAI,CAAC,8BAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,OAAqC;QAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,8BAAmB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED;;;;QAII;IACJ,UAAU,CAAC,OAAqC;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,8BAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;CACF;AAtFD,kCAsFC"} \ No newline at end of file diff --git a/dist/providers/reducer.js.map b/dist/providers/reducer.js.map index 6a5a6af..259c7b5 100644 --- a/dist/providers/reducer.js.map +++ b/dist/providers/reducer.js.map @@ -1 +1 @@ -{"version":3,"file":"reducer.js","sourceRoot":"","sources":["../../src/providers/reducer.ts"],"names":[],"mappings":";;AASA,MAAM,SAAS,GAAG,CAAC,OAAuB,EAAE,MAAgB,EAAE,EAAE;IAC9D,eAAe;IACf,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAEjC,sBAAsB;IACtB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,iBAAiB;IACjB,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAExE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,aAAa,CAAC,CAAC;IAEjE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QACnB,IAAI,gBAAgB,GAAsB,IAAI,CAAC;QAE/C,iBAAiB;QACjB,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE;YAC9B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE;gBAC5B,gBAAgB,GAAG,GAAG,CAAC;gBAEvB,MAAM;aACP;SACF;QAED,IAAI,gBAAgB,EAAE;YACpB,sBAAsB;YACtB,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;SACvE;;YAAM,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,aAAa,CAAC,CAAC;KAC7D;SAAM;QACL,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;KAC/B;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC"} \ No newline at end of file +{"version":3,"file":"reducer.js","sourceRoot":"","sources":["../../src/providers/reducer.ts"],"names":[],"mappings":";;AAMA,MAAM,SAAS,GAAG,CAAC,OAAuB,EAAE,MAAgB,EAAE,EAAE;IAC9D,eAAe;IACf,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAEjC,sBAAsB;IACtB,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7C,iBAAiB;IACjB,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAExE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,WAAW,UAAU,aAAa,CAAC,CAAC;IAEjE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QACnB,IAAI,gBAAgB,GAAsB,IAAI,CAAC;QAE/C,iBAAiB;QACjB,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE;YAC9B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE;gBAC5B,gBAAgB,GAAG,GAAG,CAAC;gBAEvB,MAAM;aACP;SACF;QAED,IAAI,gBAAgB,EAAE;YACpB,sBAAsB;YACtB,MAAM,CAAC,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;SACvE;;YAAM,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,IAAI,aAAa,CAAC,CAAC;KAC7D;SAAM;QACL,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;KAC/B;IAED,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC"} \ No newline at end of file diff --git a/package.json b/package.json index 26dc140..d24ef0d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dilane3/gx", - "version": "1.3.0", + "version": "1.4.0", "private": false, "license": "MIT", "main": "dist/index.js", diff --git a/src/index.ts b/src/index.ts index 14032cd..03dace9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,9 @@ // Provider import GXProvider from "./providers/index.js"; +// Constants +import { AsyncActionStatuses } from "./helpers/types.js"; + // Helpers functions import createSignal from "./helpers/createSignal.js"; import createStore from "./helpers/createStore.js"; @@ -24,6 +27,7 @@ export { useAsyncActions, useSignal, useOperations, + AsyncActionStatuses }; // "build": "tsc && npx babel dist --out-dir cjs --extensions '.js' --source-maps inline --copy-files", diff --git a/src/interfaces/builderCase.ts b/src/interfaces/builderCase.ts index a2d5335..e9f9ad2 100644 --- a/src/interfaces/builderCase.ts +++ b/src/interfaces/builderCase.ts @@ -1,4 +1,5 @@ import { + AsyncActionStatuses, AsyncActionStatusesType, CreateAsyncActionReturnType, } from "../helpers/types.js"; @@ -11,6 +12,12 @@ export default interface IBuilderCase { status: AsyncActionStatusesType, handler: (state: T, payload?: P) => T ): IBuilderCase; + + onPending(handler: (state: T, payload?: P) => T): IBuilderCase; + + onFulfilled(handler: (state: T, payload?: P) => T): IBuilderCase; + + onRejected(handler: (state: T, payload?: P) => T): IBuilderCase; } /** @@ -76,6 +83,33 @@ export class BuilderCase implements IBuilderCase { return this; } + + /** + * Method that add a pending case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + */ + onPending(handler: (state: T, payload?: P) => T): IBuilderCase { + return this.case(AsyncActionStatuses.PENDING, handler); + } + + /** + * Method that add a fulfilled case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + */ + onFulfilled(handler: (state: T, payload?: P) => T): IBuilderCase { + return this.case(AsyncActionStatuses.FULFILLED, handler); + } + + /** + * Method that add a rejected case into the _cases list and return a new case builder object + * @param handler Function that is executed depending on the specific status + * @returns + **/ + onRejected(handler: (state: T, payload?: P) => T): IBuilderCase { + return this.case(AsyncActionStatuses.REJECTED, handler); + } } /** diff --git a/src/providers/reducer.ts b/src/providers/reducer.ts index 9e7a0df..e482197 100644 --- a/src/providers/reducer.ts +++ b/src/providers/reducer.ts @@ -1,10 +1,7 @@ import { GXActionType, - GXAsyncActionType, GXSignalType, } from "../contexts/types.js"; -import { AsyncActionStatuses } from "../helpers/types.js"; -import { BuilderCase } from "../interfaces/builderCase.js"; import { GXAction } from "./types.js"; const gxReducer = (signals: GXSignalType[], action: GXAction) => {