quidproquo-web-react 0.0.250 → 0.0.252

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/lib/commonjs/hooks/asmj/QpqContextProvider.d.ts +10 -0
  2. package/lib/commonjs/hooks/asmj/QpqContextProvider.js +20 -0
  3. package/lib/commonjs/hooks/asmj/QpqMappedApi.d.ts +6 -0
  4. package/lib/commonjs/hooks/asmj/QpqMappedApi.js +2 -0
  5. package/lib/commonjs/hooks/asmj/QpqRuntimeEffectCatcher.d.ts +16 -0
  6. package/lib/commonjs/hooks/asmj/QpqRuntimeEffectCatcher.js +35 -0
  7. package/lib/commonjs/hooks/asmj/actionProcessor/getStateReadActionProcessor.d.ts +2 -0
  8. package/lib/commonjs/hooks/asmj/actionProcessor/getStateReadActionProcessor.js +22 -0
  9. package/lib/commonjs/hooks/asmj/actionProcessor/index.d.ts +3 -0
  10. package/lib/commonjs/hooks/asmj/actionProcessor/index.js +18 -0
  11. package/lib/commonjs/hooks/asmj/createQpqRuntimeDefinition.d.ts +16 -0
  12. package/lib/commonjs/hooks/asmj/createQpqRuntimeDefinition.js +39 -0
  13. package/lib/commonjs/hooks/asmj/index.d.ts +6 -0
  14. package/lib/commonjs/hooks/{useQpqReducer/actionProcessor → asmj}/index.js +6 -1
  15. package/lib/commonjs/hooks/asmj/useQpqRuntime.d.ts +4 -0
  16. package/lib/commonjs/hooks/asmj/useQpqRuntime.js +36 -0
  17. package/lib/commonjs/hooks/index.d.ts +2 -2
  18. package/lib/commonjs/hooks/index.js +2 -2
  19. package/lib/commonjs/hooks/useMetadata/index.d.ts +1 -0
  20. package/lib/commonjs/hooks/{useQpqReducer → useMetadata}/index.js +1 -1
  21. package/lib/commonjs/hooks/useMetadata/useMetadata.d.ts +5 -0
  22. package/lib/commonjs/hooks/useMetadata/useMetadata.js +15 -0
  23. package/lib/commonjs/hooks/useQpq.js +5 -3
  24. package/lib/commonjs/index.d.ts +1 -0
  25. package/lib/commonjs/index.js +1 -0
  26. package/lib/esm/hooks/asmj/QpqContextProvider.d.ts +10 -0
  27. package/lib/esm/hooks/asmj/QpqContextProvider.js +15 -0
  28. package/lib/esm/hooks/asmj/QpqMappedApi.d.ts +6 -0
  29. package/lib/esm/hooks/asmj/QpqMappedApi.js +1 -0
  30. package/lib/esm/hooks/asmj/QpqRuntimeEffectCatcher.d.ts +16 -0
  31. package/lib/esm/hooks/asmj/QpqRuntimeEffectCatcher.js +30 -0
  32. package/lib/esm/hooks/asmj/actionProcessor/getStateReadActionProcessor.d.ts +2 -0
  33. package/lib/esm/hooks/asmj/actionProcessor/getStateReadActionProcessor.js +7 -0
  34. package/lib/esm/hooks/asmj/actionProcessor/index.d.ts +3 -0
  35. package/lib/esm/hooks/asmj/actionProcessor/index.js +6 -0
  36. package/lib/esm/hooks/asmj/createQpqRuntimeDefinition.d.ts +16 -0
  37. package/lib/esm/hooks/asmj/createQpqRuntimeDefinition.js +34 -0
  38. package/lib/esm/hooks/asmj/index.d.ts +6 -0
  39. package/lib/esm/hooks/asmj/index.js +6 -0
  40. package/lib/esm/hooks/asmj/useQpqRuntime.d.ts +4 -0
  41. package/lib/esm/hooks/asmj/useQpqRuntime.js +32 -0
  42. package/lib/esm/hooks/index.d.ts +2 -2
  43. package/lib/esm/hooks/index.js +2 -2
  44. package/lib/esm/hooks/useMetadata/index.d.ts +1 -0
  45. package/lib/esm/hooks/useMetadata/index.js +1 -0
  46. package/lib/esm/hooks/useMetadata/useMetadata.d.ts +5 -0
  47. package/lib/esm/hooks/useMetadata/useMetadata.js +11 -0
  48. package/lib/esm/hooks/useQpq.js +5 -3
  49. package/lib/esm/index.d.ts +1 -0
  50. package/lib/esm/index.js +1 -0
  51. package/package.json +11 -5
  52. package/lib/commonjs/hooks/useBubbleReducer.d.ts +0 -7
  53. package/lib/commonjs/hooks/useBubbleReducer.js +0 -32
  54. package/lib/commonjs/hooks/useQpqReducer/actionProcessor/index.d.ts +0 -1
  55. package/lib/commonjs/hooks/useQpqReducer/index.d.ts +0 -1
  56. package/lib/commonjs/hooks/useQpqReducer/useQpqReducer.d.ts +0 -1
  57. package/lib/commonjs/hooks/useQpqReducer/useQpqReducer.js +0 -63
  58. package/lib/esm/hooks/useBubbleReducer.d.ts +0 -7
  59. package/lib/esm/hooks/useBubbleReducer.js +0 -27
  60. package/lib/esm/hooks/useQpqReducer/actionProcessor/index.d.ts +0 -1
  61. package/lib/esm/hooks/useQpqReducer/actionProcessor/index.js +0 -1
  62. package/lib/esm/hooks/useQpqReducer/index.d.ts +0 -1
  63. package/lib/esm/hooks/useQpqReducer/index.js +0 -1
  64. package/lib/esm/hooks/useQpqReducer/useQpqReducer.d.ts +0 -1
  65. package/lib/esm/hooks/useQpqReducer/useQpqReducer.js +0 -59
  66. /package/lib/commonjs/hooks/{useQpqReducer → asmj}/actionProcessor/getStateDispatchActionProcessor.d.ts +0 -0
  67. /package/lib/commonjs/hooks/{useQpqReducer → asmj}/actionProcessor/getStateDispatchActionProcessor.js +0 -0
  68. /package/lib/esm/hooks/{useQpqReducer → asmj}/actionProcessor/getStateDispatchActionProcessor.d.ts +0 -0
  69. /package/lib/esm/hooks/{useQpqReducer → asmj}/actionProcessor/getStateDispatchActionProcessor.js +0 -0
@@ -0,0 +1,10 @@
1
+ import { QpqContext, QpqContextIdentifier } from 'quidproquo-core';
2
+ import { ReactNode } from 'react';
3
+ interface QpqContextProviderProps<T> {
4
+ contextIdentifier: QpqContextIdentifier<T>;
5
+ value: T;
6
+ children: ReactNode;
7
+ }
8
+ export declare const useQpqContextValues: () => QpqContext<any>;
9
+ export declare const QpqContextProvider: <T>({ contextIdentifier, value, children }: QpqContextProviderProps<T>) => import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QpqContextProvider = exports.useQpqContextValues = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ // Define a generic type for the React Context
7
+ const qpqReactContext = (0, react_1.createContext)({});
8
+ const useQpqContextValues = () => {
9
+ return (0, react_1.useContext)(qpqReactContext);
10
+ };
11
+ exports.useQpqContextValues = useQpqContextValues;
12
+ const QpqContextProvider = ({ contextIdentifier, value, children }) => {
13
+ // Get the parent context value
14
+ const parentContext = (0, react_1.useContext)(qpqReactContext);
15
+ // Merge parent and current value
16
+ const mergedContext = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, parentContext), { [contextIdentifier.uniqueName]: value })), [parentContext, contextIdentifier.uniqueName, value]);
17
+ // Provide the merged context down
18
+ return (0, jsx_runtime_1.jsx)(qpqReactContext.Provider, Object.assign({ value: mergedContext }, { children: children }));
19
+ };
20
+ exports.QpqContextProvider = QpqContextProvider;
@@ -0,0 +1,6 @@
1
+ import { AskResponse, AskResponseReturnType, Story } from 'quidproquo-core';
2
+ export type RemoveQpqAskPrefix<K extends string> = K extends `ask${infer R}` ? Uncapitalize<R> : never;
3
+ export type QpqApi = Record<`ask${string}`, Story<any, any>>;
4
+ export type QpqMappedApi<TApi extends QpqApi> = {
5
+ [K in Extract<keyof TApi, string> as RemoveQpqAskPrefix<K>]: TApi[K] extends (...args: infer P) => infer R ? R extends AskResponse<any> ? (...args: P) => Promise<AskResponseReturnType<R>> : never : never;
6
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { QpqApi } from './QpqMappedApi';
3
+ import { QpqRuntimeDefinition } from '.';
4
+ export type QpqBubbleReducer<S, A> = (prevState: S, action: A) => [S, boolean];
5
+ type QpqRuntimeEffectCatcher = {
6
+ runtime: QpqRuntimeDefinition<any, any, any>;
7
+ name?: string;
8
+ };
9
+ export declare const useQpqRuntimeBubblingReducer: <TState, TAction, TApi extends QpqApi>(runtimeDefinition: QpqRuntimeDefinition<TState, TAction, TApi>, name?: string) => [TState, (action: TAction) => void, () => TState];
10
+ export declare const QpqRuntimeEffectCatcherComponent: <TState, TAction, TApi extends QpqApi>({ children, runtime, name, }: QpqRuntimeEffectCatcher & {
11
+ children: ReactNode;
12
+ }) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const QpqRuntimeEffectCatcher: import("react").MemoExoticComponent<(<TState, TAction, TApi extends QpqApi>({ children, runtime, name, }: QpqRuntimeEffectCatcher & {
14
+ children: ReactNode;
15
+ }) => import("react/jsx-runtime").JSX.Element)>;
16
+ export {};
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QpqRuntimeEffectCatcher = exports.QpqRuntimeEffectCatcherComponent = exports.useQpqRuntimeBubblingReducer = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const useFastCallback_1 = require("../useFastCallback");
7
+ const _1 = require(".");
8
+ // Create a context with a default NOOP dispatcher
9
+ const BubbleReducerDispatchContext = (0, react_1.createContext)((_action) => {
10
+ // NOOP
11
+ });
12
+ const useQpqRuntimeBubblingReducer = (runtimeDefinition, name) => {
13
+ const runtimeDefinitionInfo = runtimeDefinition(name);
14
+ const [state, setState, getState] = (0, _1.useQpqRuntimeState)(runtimeDefinition, name);
15
+ // Get the parent dispatch from the context
16
+ const parentDispatch = (0, react_1.useContext)(BubbleReducerDispatchContext);
17
+ // Custom Dispatch using functional updates
18
+ const dispatch = (0, useFastCallback_1.useFastCallback)((action) => {
19
+ const [newState, preventBubble] = runtimeDefinitionInfo.reducer(getState(), action);
20
+ if (preventBubble) {
21
+ setState(newState);
22
+ }
23
+ else {
24
+ parentDispatch(action);
25
+ }
26
+ });
27
+ return [state, dispatch, getState];
28
+ };
29
+ exports.useQpqRuntimeBubblingReducer = useQpqRuntimeBubblingReducer;
30
+ const QpqRuntimeEffectCatcherComponent = ({ children, runtime, name, }) => {
31
+ const [api, state, dispatch] = (0, _1.useQpqRuntime)(runtime, undefined, name);
32
+ return (0, jsx_runtime_1.jsx)(BubbleReducerDispatchContext.Provider, Object.assign({ value: dispatch }, { children: children }));
33
+ };
34
+ exports.QpqRuntimeEffectCatcherComponent = QpqRuntimeEffectCatcherComponent;
35
+ exports.QpqRuntimeEffectCatcher = (0, react_1.memo)(exports.QpqRuntimeEffectCatcherComponent);
@@ -0,0 +1,2 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ export declare const getStateReadActionListResolver: <State>(getCurrentState: () => State) => ActionProcessorListResolver;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getStateReadActionListResolver = void 0;
13
+ const quidproquo_core_1 = require("quidproquo-core");
14
+ const getProcessStateRead = (getCurrentState) => () => __awaiter(void 0, void 0, void 0, function* () {
15
+ return (0, quidproquo_core_1.actionResult)(getCurrentState());
16
+ });
17
+ const getStateReadActionListResolver = (getCurrentState) => (_qpqConfig, _dynamicModuleLoader) => __awaiter(void 0, void 0, void 0, function* () {
18
+ return ({
19
+ [quidproquo_core_1.StateActionType.Read]: getProcessStateRead(getCurrentState),
20
+ });
21
+ });
22
+ exports.getStateReadActionListResolver = getStateReadActionListResolver;
@@ -0,0 +1,3 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ import { Dispatch } from 'react';
3
+ export declare const getStateActionProcessor: <State>(dispatch: Dispatch<any>, getCurrentState: () => State) => ActionProcessorListResolver;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getStateActionProcessor = void 0;
13
+ const getStateDispatchActionProcessor_1 = require("./getStateDispatchActionProcessor");
14
+ const getStateReadActionProcessor_1 = require("./getStateReadActionProcessor");
15
+ const getStateActionProcessor = (dispatch, getCurrentState) => (qpqConfig, dynamicModuleLoader) => __awaiter(void 0, void 0, void 0, function* () {
16
+ return (Object.assign(Object.assign({}, (yield (0, getStateDispatchActionProcessor_1.getStateDispatchActionListResolver)(dispatch)(qpqConfig, dynamicModuleLoader))), (yield (0, getStateReadActionProcessor_1.getStateReadActionListResolver)(getCurrentState)(qpqConfig, dynamicModuleLoader))));
17
+ });
18
+ exports.getStateActionProcessor = getStateActionProcessor;
@@ -0,0 +1,16 @@
1
+ import { atom } from 'jotai';
2
+ import { QpqApi } from './QpqMappedApi';
3
+ import { QpqBubbleReducer } from './QpqRuntimeEffectCatcher';
4
+ type CustomJotaiReducerAtom<TState> = ReturnType<typeof atom<TState>>;
5
+ export type QpqAsmjState<TState, TAction, TApi extends QpqApi> = {
6
+ atom: CustomJotaiReducerAtom<TState>;
7
+ reducer: QpqBubbleReducer<TState, TAction>;
8
+ initialState: TState;
9
+ api: TApi;
10
+ state: TState;
11
+ };
12
+ type AsmjStateGetter<TState, TAction, TApi extends QpqApi> = (name?: string) => QpqAsmjState<TState, TAction, TApi>;
13
+ export type QpqRuntimeDefinition<TState, TAction, TApi extends QpqApi> = AsmjStateGetter<TState, TAction, TApi>;
14
+ export declare function createQpqRuntimeDefinition<TState, TAction, TApi extends QpqApi>(api: TApi, initialState: TState, reducer?: QpqBubbleReducer<TState, TAction>): QpqRuntimeDefinition<TState, TAction, TApi>;
15
+ export declare function useQpqRuntimeState<TState, TAction, TApi extends QpqApi>(atom: QpqRuntimeDefinition<TState, TAction, TApi>, name?: string): [TState, (newState: TState) => void, () => TState];
16
+ export {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useQpqRuntimeState = exports.createQpqRuntimeDefinition = void 0;
4
+ const react_1 = require("react");
5
+ const jotai_1 = require("jotai");
6
+ function createQpqRuntimeDefinition(api, initialState, reducer = (s) => [s, false]) {
7
+ const namedAtoms = new Map();
8
+ const getCustomNamedAtom = (name) => {
9
+ const actualName = name ? name : '$$qpq-default$$';
10
+ if (!namedAtoms.has(actualName)) {
11
+ console.log('Creating Atom: ', actualName);
12
+ const winAtom = {
13
+ atom: (0, jotai_1.atom)(initialState),
14
+ reducer,
15
+ initialState,
16
+ api: api,
17
+ state: initialState,
18
+ };
19
+ namedAtoms.set(actualName, winAtom);
20
+ }
21
+ return namedAtoms.get(actualName);
22
+ };
23
+ return getCustomNamedAtom;
24
+ }
25
+ exports.createQpqRuntimeDefinition = createQpqRuntimeDefinition;
26
+ function useQpqRuntimeState(atom, name) {
27
+ const [state, setState] = (0, jotai_1.useAtom)(atom(name).atom);
28
+ const setStateWrapper = (0, react_1.useCallback)((newState) => {
29
+ const info = atom(name);
30
+ info.state = newState;
31
+ setState(newState);
32
+ }, [setState]);
33
+ const getState = (0, react_1.useCallback)(() => {
34
+ const state = atom(name).state;
35
+ return state;
36
+ }, [atom]);
37
+ return [state, setStateWrapper, getState];
38
+ }
39
+ exports.useQpqRuntimeState = useQpqRuntimeState;
@@ -0,0 +1,6 @@
1
+ export * from './actionProcessor';
2
+ export * from './createQpqRuntimeDefinition';
3
+ export * from './QpqContextProvider';
4
+ export * from './QpqMappedApi';
5
+ export * from './QpqRuntimeEffectCatcher';
6
+ export * from './useQpqRuntime';
@@ -14,4 +14,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./getStateDispatchActionProcessor"), exports);
17
+ __exportStar(require("./actionProcessor"), exports);
18
+ __exportStar(require("./createQpqRuntimeDefinition"), exports);
19
+ __exportStar(require("./QpqContextProvider"), exports);
20
+ __exportStar(require("./QpqMappedApi"), exports);
21
+ __exportStar(require("./QpqRuntimeEffectCatcher"), exports);
22
+ __exportStar(require("./useQpqRuntime"), exports);
@@ -0,0 +1,4 @@
1
+ import { Story } from 'quidproquo-core';
2
+ import { QpqApi, QpqMappedApi } from './QpqMappedApi';
3
+ import { QpqRuntimeDefinition } from '.';
4
+ export declare function useQpqRuntime<TState, TAction, TApi extends QpqApi>(atom: QpqRuntimeDefinition<TState, TAction, TApi>, mainStory?: Story<any, any>, name?: string): [QpqMappedApi<TApi>, TState, (action: any) => void];
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useQpqRuntime = void 0;
4
+ const react_1 = require("react");
5
+ const useQpq_1 = require("../useQpq");
6
+ const actionProcessor_1 = require("./actionProcessor");
7
+ const QpqRuntimeEffectCatcher_1 = require("./QpqRuntimeEffectCatcher");
8
+ function useQpqRuntime(atom, mainStory, name) {
9
+ const atomInfo = atom(name);
10
+ const [state, dispatch, getCurrentState] = (0, QpqRuntimeEffectCatcher_1.useQpqRuntimeBubblingReducer)(atom, name);
11
+ // Api generators are memoized to prevent unnecessary re-renders.
12
+ const [memoedApiGenerators] = (0, react_1.useState)(() => atomInfo.api);
13
+ const resolver = (0, useQpq_1.useQpq)((0, actionProcessor_1.getStateActionProcessor)(dispatch, getCurrentState));
14
+ // Wrap and remap each API generator using the resolver.
15
+ const api = (0, react_1.useMemo)(() => {
16
+ const wrapped = {};
17
+ for (const key in memoedApiGenerators) {
18
+ if (Object.prototype.hasOwnProperty.call(memoedApiGenerators, key)) {
19
+ // Remove the 'ask' prefix and lower-case the first character.
20
+ const withoutAsk = key.slice(3); // e.g., "FetchTodos"
21
+ const newKey = withoutAsk.charAt(0).toLowerCase() + withoutAsk.slice(1); // "fetchTodos"
22
+ // We know newKey matches our mapped type so we can assign.
23
+ // (A type assertion is used here to quiet the compiler.)
24
+ wrapped[newKey] = resolver(memoedApiGenerators[key]);
25
+ }
26
+ }
27
+ return wrapped;
28
+ }, [resolver, memoedApiGenerators]);
29
+ (0, react_1.useEffect)(() => {
30
+ if (mainStory) {
31
+ resolver(mainStory)();
32
+ }
33
+ }, []);
34
+ return [api, state, dispatch];
35
+ }
36
+ exports.useQpqRuntime = useQpqRuntime;
@@ -1,8 +1,8 @@
1
+ export * from './asmj';
1
2
  export * from './useAsyncEffect';
2
- export * from './useBubbleReducer';
3
3
  export * from './useFastCallback';
4
+ export * from './useMetadata';
4
5
  export * from './useOnKeyDownEffect';
5
6
  export * from './useQpq';
6
- export * from './useQpqReducer';
7
7
  export * from './useRunEvery';
8
8
  export * from './useThrottledMemo';
@@ -14,11 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./asmj"), exports);
17
18
  __exportStar(require("./useAsyncEffect"), exports);
18
- __exportStar(require("./useBubbleReducer"), exports);
19
19
  __exportStar(require("./useFastCallback"), exports);
20
+ __exportStar(require("./useMetadata"), exports);
20
21
  __exportStar(require("./useOnKeyDownEffect"), exports);
21
22
  __exportStar(require("./useQpq"), exports);
22
- __exportStar(require("./useQpqReducer"), exports);
23
23
  __exportStar(require("./useRunEvery"), exports);
24
24
  __exportStar(require("./useThrottledMemo"), exports);
@@ -0,0 +1 @@
1
+ export * from './useMetadata';
@@ -14,4 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./useQpqReducer"), exports);
17
+ __exportStar(require("./useMetadata"), exports);
@@ -0,0 +1,5 @@
1
+ type MetadataGetter<M> = () => M | undefined;
2
+ type MetadataSetter<M> = (value: M) => void;
3
+ type UseMetadataReturn<M> = [MetadataGetter<M>, MetadataSetter<M>];
4
+ export declare function useMetadata<M>(key: object): UseMetadataReturn<M>;
5
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useMetadata = void 0;
4
+ const react_1 = require("react");
5
+ const metadataStore = new WeakMap();
6
+ function useMetadata(key) {
7
+ return (0, react_1.useMemo)(() => {
8
+ const getMetadata = () => metadataStore.get(key);
9
+ const setMetadata = (value) => {
10
+ metadataStore.set(key, value);
11
+ };
12
+ return [getMetadata, setMetadata];
13
+ }, [key]);
14
+ }
15
+ exports.useMetadata = useMetadata;
@@ -10,11 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.useQpq = void 0;
13
- const quidproquo_actionprocessor_node_1 = require("quidproquo-actionprocessor-node");
13
+ const quidproquo_actionprocessor_web_1 = require("quidproquo-actionprocessor-web");
14
14
  const quidproquo_core_1 = require("quidproquo-core");
15
+ const asmj_1 = require("./asmj");
15
16
  // WIP ~ useFastCallback, wack things like loggers in a context, try to only make once instance of the runtime.
16
17
  // Also don't create every refresh.. useMemo / useCallback etc
17
18
  function useQpq(getActionProcessors = () => __awaiter(this, void 0, void 0, function* () { return ({}); })) {
19
+ const qpqContextValues = (0, asmj_1.useQpqContextValues)();
18
20
  const logger = {
19
21
  enableLogs: () => __awaiter(this, void 0, void 0, function* () { }),
20
22
  log: () => __awaiter(this, void 0, void 0, function* () { }),
@@ -23,9 +25,9 @@ function useQpq(getActionProcessors = () => __awaiter(this, void 0, void 0, func
23
25
  };
24
26
  const resolveStory = (0, quidproquo_core_1.createRuntime)([(0, quidproquo_core_1.defineModule)('UI')], {
25
27
  depth: 0,
26
- context: {},
28
+ context: qpqContextValues,
27
29
  }, (qpqConfig, dynamicModuleLoader) => __awaiter(this, void 0, void 0, function* () {
28
- return (Object.assign(Object.assign({}, (yield (0, quidproquo_actionprocessor_node_1.getCoreActionProcessor)(qpqConfig, dynamicModuleLoader))), (yield getActionProcessors(qpqConfig, dynamicModuleLoader))));
30
+ return (Object.assign(Object.assign({}, (yield (0, quidproquo_actionprocessor_web_1.getWebActionProcessors)(qpqConfig, dynamicModuleLoader))), (yield getActionProcessors(qpqConfig, dynamicModuleLoader))));
29
31
  }), () => new Date().toISOString(), logger, `frontend::${'uuid'}`, quidproquo_core_1.QpqRuntimeType.UI, (_runtime) => __awaiter(this, void 0, void 0, function* () {
30
32
  // noop
31
33
  }));
@@ -1,3 +1,4 @@
1
+ import 'symbol-observable';
1
2
  export * from './api';
2
3
  export * from './auth';
3
4
  export * from './baseUrl';
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ require("symbol-observable");
17
18
  __exportStar(require("./api"), exports);
18
19
  __exportStar(require("./auth"), exports);
19
20
  __exportStar(require("./baseUrl"), exports);
@@ -0,0 +1,10 @@
1
+ import { QpqContext, QpqContextIdentifier } from 'quidproquo-core';
2
+ import { ReactNode } from 'react';
3
+ interface QpqContextProviderProps<T> {
4
+ contextIdentifier: QpqContextIdentifier<T>;
5
+ value: T;
6
+ children: ReactNode;
7
+ }
8
+ export declare const useQpqContextValues: () => QpqContext<any>;
9
+ export declare const QpqContextProvider: <T>({ contextIdentifier, value, children }: QpqContextProviderProps<T>) => import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from 'react';
3
+ // Define a generic type for the React Context
4
+ const qpqReactContext = createContext({});
5
+ export const useQpqContextValues = () => {
6
+ return useContext(qpqReactContext);
7
+ };
8
+ export const QpqContextProvider = ({ contextIdentifier, value, children }) => {
9
+ // Get the parent context value
10
+ const parentContext = useContext(qpqReactContext);
11
+ // Merge parent and current value
12
+ const mergedContext = useMemo(() => ({ ...parentContext, [contextIdentifier.uniqueName]: value }), [parentContext, contextIdentifier.uniqueName, value]);
13
+ // Provide the merged context down
14
+ return _jsx(qpqReactContext.Provider, { value: mergedContext, children: children });
15
+ };
@@ -0,0 +1,6 @@
1
+ import { AskResponse, AskResponseReturnType, Story } from 'quidproquo-core';
2
+ export type RemoveQpqAskPrefix<K extends string> = K extends `ask${infer R}` ? Uncapitalize<R> : never;
3
+ export type QpqApi = Record<`ask${string}`, Story<any, any>>;
4
+ export type QpqMappedApi<TApi extends QpqApi> = {
5
+ [K in Extract<keyof TApi, string> as RemoveQpqAskPrefix<K>]: TApi[K] extends (...args: infer P) => infer R ? R extends AskResponse<any> ? (...args: P) => Promise<AskResponseReturnType<R>> : never : never;
6
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { QpqApi } from './QpqMappedApi';
3
+ import { QpqRuntimeDefinition } from '.';
4
+ export type QpqBubbleReducer<S, A> = (prevState: S, action: A) => [S, boolean];
5
+ type QpqRuntimeEffectCatcher = {
6
+ runtime: QpqRuntimeDefinition<any, any, any>;
7
+ name?: string;
8
+ };
9
+ export declare const useQpqRuntimeBubblingReducer: <TState, TAction, TApi extends QpqApi>(runtimeDefinition: QpqRuntimeDefinition<TState, TAction, TApi>, name?: string) => [TState, (action: TAction) => void, () => TState];
10
+ export declare const QpqRuntimeEffectCatcherComponent: <TState, TAction, TApi extends QpqApi>({ children, runtime, name, }: QpqRuntimeEffectCatcher & {
11
+ children: ReactNode;
12
+ }) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const QpqRuntimeEffectCatcher: import("react").MemoExoticComponent<(<TState, TAction, TApi extends QpqApi>({ children, runtime, name, }: QpqRuntimeEffectCatcher & {
14
+ children: ReactNode;
15
+ }) => import("react/jsx-runtime").JSX.Element)>;
16
+ export {};
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, memo, useContext } from 'react';
3
+ import { useFastCallback } from '../useFastCallback';
4
+ import { useQpqRuntime, useQpqRuntimeState } from '.';
5
+ // Create a context with a default NOOP dispatcher
6
+ const BubbleReducerDispatchContext = createContext((_action) => {
7
+ // NOOP
8
+ });
9
+ export const useQpqRuntimeBubblingReducer = (runtimeDefinition, name) => {
10
+ const runtimeDefinitionInfo = runtimeDefinition(name);
11
+ const [state, setState, getState] = useQpqRuntimeState(runtimeDefinition, name);
12
+ // Get the parent dispatch from the context
13
+ const parentDispatch = useContext(BubbleReducerDispatchContext);
14
+ // Custom Dispatch using functional updates
15
+ const dispatch = useFastCallback((action) => {
16
+ const [newState, preventBubble] = runtimeDefinitionInfo.reducer(getState(), action);
17
+ if (preventBubble) {
18
+ setState(newState);
19
+ }
20
+ else {
21
+ parentDispatch(action);
22
+ }
23
+ });
24
+ return [state, dispatch, getState];
25
+ };
26
+ export const QpqRuntimeEffectCatcherComponent = ({ children, runtime, name, }) => {
27
+ const [api, state, dispatch] = useQpqRuntime(runtime, undefined, name);
28
+ return _jsx(BubbleReducerDispatchContext.Provider, { value: dispatch, children: children });
29
+ };
30
+ export const QpqRuntimeEffectCatcher = memo(QpqRuntimeEffectCatcherComponent);
@@ -0,0 +1,2 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ export declare const getStateReadActionListResolver: <State>(getCurrentState: () => State) => ActionProcessorListResolver;
@@ -0,0 +1,7 @@
1
+ import { actionResult, StateActionType } from 'quidproquo-core';
2
+ const getProcessStateRead = (getCurrentState) => async () => {
3
+ return actionResult(getCurrentState());
4
+ };
5
+ export const getStateReadActionListResolver = (getCurrentState) => async (_qpqConfig, _dynamicModuleLoader) => ({
6
+ [StateActionType.Read]: getProcessStateRead(getCurrentState),
7
+ });
@@ -0,0 +1,3 @@
1
+ import { ActionProcessorListResolver } from 'quidproquo-core';
2
+ import { Dispatch } from 'react';
3
+ export declare const getStateActionProcessor: <State>(dispatch: Dispatch<any>, getCurrentState: () => State) => ActionProcessorListResolver;
@@ -0,0 +1,6 @@
1
+ import { getStateDispatchActionListResolver } from './getStateDispatchActionProcessor';
2
+ import { getStateReadActionListResolver } from './getStateReadActionProcessor';
3
+ export const getStateActionProcessor = (dispatch, getCurrentState) => async (qpqConfig, dynamicModuleLoader) => ({
4
+ ...(await getStateDispatchActionListResolver(dispatch)(qpqConfig, dynamicModuleLoader)),
5
+ ...(await getStateReadActionListResolver(getCurrentState)(qpqConfig, dynamicModuleLoader)),
6
+ });
@@ -0,0 +1,16 @@
1
+ import { atom } from 'jotai';
2
+ import { QpqApi } from './QpqMappedApi';
3
+ import { QpqBubbleReducer } from './QpqRuntimeEffectCatcher';
4
+ type CustomJotaiReducerAtom<TState> = ReturnType<typeof atom<TState>>;
5
+ export type QpqAsmjState<TState, TAction, TApi extends QpqApi> = {
6
+ atom: CustomJotaiReducerAtom<TState>;
7
+ reducer: QpqBubbleReducer<TState, TAction>;
8
+ initialState: TState;
9
+ api: TApi;
10
+ state: TState;
11
+ };
12
+ type AsmjStateGetter<TState, TAction, TApi extends QpqApi> = (name?: string) => QpqAsmjState<TState, TAction, TApi>;
13
+ export type QpqRuntimeDefinition<TState, TAction, TApi extends QpqApi> = AsmjStateGetter<TState, TAction, TApi>;
14
+ export declare function createQpqRuntimeDefinition<TState, TAction, TApi extends QpqApi>(api: TApi, initialState: TState, reducer?: QpqBubbleReducer<TState, TAction>): QpqRuntimeDefinition<TState, TAction, TApi>;
15
+ export declare function useQpqRuntimeState<TState, TAction, TApi extends QpqApi>(atom: QpqRuntimeDefinition<TState, TAction, TApi>, name?: string): [TState, (newState: TState) => void, () => TState];
16
+ export {};
@@ -0,0 +1,34 @@
1
+ import { useCallback } from 'react';
2
+ import { atom, useAtom } from 'jotai';
3
+ export function createQpqRuntimeDefinition(api, initialState, reducer = (s) => [s, false]) {
4
+ const namedAtoms = new Map();
5
+ const getCustomNamedAtom = (name) => {
6
+ const actualName = name ? name : '$$qpq-default$$';
7
+ if (!namedAtoms.has(actualName)) {
8
+ console.log('Creating Atom: ', actualName);
9
+ const winAtom = {
10
+ atom: atom(initialState),
11
+ reducer,
12
+ initialState,
13
+ api: api,
14
+ state: initialState,
15
+ };
16
+ namedAtoms.set(actualName, winAtom);
17
+ }
18
+ return namedAtoms.get(actualName);
19
+ };
20
+ return getCustomNamedAtom;
21
+ }
22
+ export function useQpqRuntimeState(atom, name) {
23
+ const [state, setState] = useAtom(atom(name).atom);
24
+ const setStateWrapper = useCallback((newState) => {
25
+ const info = atom(name);
26
+ info.state = newState;
27
+ setState(newState);
28
+ }, [setState]);
29
+ const getState = useCallback(() => {
30
+ const state = atom(name).state;
31
+ return state;
32
+ }, [atom]);
33
+ return [state, setStateWrapper, getState];
34
+ }
@@ -0,0 +1,6 @@
1
+ export * from './actionProcessor';
2
+ export * from './createQpqRuntimeDefinition';
3
+ export * from './QpqContextProvider';
4
+ export * from './QpqMappedApi';
5
+ export * from './QpqRuntimeEffectCatcher';
6
+ export * from './useQpqRuntime';
@@ -0,0 +1,6 @@
1
+ export * from './actionProcessor';
2
+ export * from './createQpqRuntimeDefinition';
3
+ export * from './QpqContextProvider';
4
+ export * from './QpqMappedApi';
5
+ export * from './QpqRuntimeEffectCatcher';
6
+ export * from './useQpqRuntime';
@@ -0,0 +1,4 @@
1
+ import { Story } from 'quidproquo-core';
2
+ import { QpqApi, QpqMappedApi } from './QpqMappedApi';
3
+ import { QpqRuntimeDefinition } from '.';
4
+ export declare function useQpqRuntime<TState, TAction, TApi extends QpqApi>(atom: QpqRuntimeDefinition<TState, TAction, TApi>, mainStory?: Story<any, any>, name?: string): [QpqMappedApi<TApi>, TState, (action: any) => void];
@@ -0,0 +1,32 @@
1
+ import { useEffect, useMemo, useState } from 'react';
2
+ import { useQpq } from '../useQpq';
3
+ import { getStateActionProcessor } from './actionProcessor';
4
+ import { useQpqRuntimeBubblingReducer } from './QpqRuntimeEffectCatcher';
5
+ export function useQpqRuntime(atom, mainStory, name) {
6
+ const atomInfo = atom(name);
7
+ const [state, dispatch, getCurrentState] = useQpqRuntimeBubblingReducer(atom, name);
8
+ // Api generators are memoized to prevent unnecessary re-renders.
9
+ const [memoedApiGenerators] = useState(() => atomInfo.api);
10
+ const resolver = useQpq(getStateActionProcessor(dispatch, getCurrentState));
11
+ // Wrap and remap each API generator using the resolver.
12
+ const api = useMemo(() => {
13
+ const wrapped = {};
14
+ for (const key in memoedApiGenerators) {
15
+ if (Object.prototype.hasOwnProperty.call(memoedApiGenerators, key)) {
16
+ // Remove the 'ask' prefix and lower-case the first character.
17
+ const withoutAsk = key.slice(3); // e.g., "FetchTodos"
18
+ const newKey = withoutAsk.charAt(0).toLowerCase() + withoutAsk.slice(1); // "fetchTodos"
19
+ // We know newKey matches our mapped type so we can assign.
20
+ // (A type assertion is used here to quiet the compiler.)
21
+ wrapped[newKey] = resolver(memoedApiGenerators[key]);
22
+ }
23
+ }
24
+ return wrapped;
25
+ }, [resolver, memoedApiGenerators]);
26
+ useEffect(() => {
27
+ if (mainStory) {
28
+ resolver(mainStory)();
29
+ }
30
+ }, []);
31
+ return [api, state, dispatch];
32
+ }
@@ -1,8 +1,8 @@
1
+ export * from './asmj';
1
2
  export * from './useAsyncEffect';
2
- export * from './useBubbleReducer';
3
3
  export * from './useFastCallback';
4
+ export * from './useMetadata';
4
5
  export * from './useOnKeyDownEffect';
5
6
  export * from './useQpq';
6
- export * from './useQpqReducer';
7
7
  export * from './useRunEvery';
8
8
  export * from './useThrottledMemo';
@@ -1,8 +1,8 @@
1
+ export * from './asmj';
1
2
  export * from './useAsyncEffect';
2
- export * from './useBubbleReducer';
3
3
  export * from './useFastCallback';
4
+ export * from './useMetadata';
4
5
  export * from './useOnKeyDownEffect';
5
6
  export * from './useQpq';
6
- export * from './useQpqReducer';
7
7
  export * from './useRunEvery';
8
8
  export * from './useThrottledMemo';
@@ -0,0 +1 @@
1
+ export * from './useMetadata';
@@ -0,0 +1 @@
1
+ export * from './useMetadata';
@@ -0,0 +1,5 @@
1
+ type MetadataGetter<M> = () => M | undefined;
2
+ type MetadataSetter<M> = (value: M) => void;
3
+ type UseMetadataReturn<M> = [MetadataGetter<M>, MetadataSetter<M>];
4
+ export declare function useMetadata<M>(key: object): UseMetadataReturn<M>;
5
+ export {};
@@ -0,0 +1,11 @@
1
+ import { useMemo } from 'react';
2
+ const metadataStore = new WeakMap();
3
+ export function useMetadata(key) {
4
+ return useMemo(() => {
5
+ const getMetadata = () => metadataStore.get(key);
6
+ const setMetadata = (value) => {
7
+ metadataStore.set(key, value);
8
+ };
9
+ return [getMetadata, setMetadata];
10
+ }, [key]);
11
+ }
@@ -1,8 +1,10 @@
1
- import { getCoreActionProcessor } from 'quidproquo-actionprocessor-node';
1
+ import { getWebActionProcessors } from 'quidproquo-actionprocessor-web';
2
2
  import { createRuntime, defineModule, QpqRuntimeType, } from 'quidproquo-core';
3
+ import { useQpqContextValues } from './asmj';
3
4
  // WIP ~ useFastCallback, wack things like loggers in a context, try to only make once instance of the runtime.
4
5
  // Also don't create every refresh.. useMemo / useCallback etc
5
6
  export function useQpq(getActionProcessors = async () => ({})) {
7
+ const qpqContextValues = useQpqContextValues();
6
8
  const logger = {
7
9
  enableLogs: async () => { },
8
10
  log: async () => { },
@@ -11,9 +13,9 @@ export function useQpq(getActionProcessors = async () => ({})) {
11
13
  };
12
14
  const resolveStory = createRuntime([defineModule('UI')], {
13
15
  depth: 0,
14
- context: {},
16
+ context: qpqContextValues,
15
17
  }, async (qpqConfig, dynamicModuleLoader) => ({
16
- ...(await getCoreActionProcessor(qpqConfig, dynamicModuleLoader)),
18
+ ...(await getWebActionProcessors(qpqConfig, dynamicModuleLoader)),
17
19
  ...(await getActionProcessors(qpqConfig, dynamicModuleLoader)),
18
20
  }), () => new Date().toISOString(), logger, `frontend::${'uuid'}`, QpqRuntimeType.UI, async (_runtime) => {
19
21
  // noop
@@ -1,3 +1,4 @@
1
+ import 'symbol-observable';
1
2
  export * from './api';
2
3
  export * from './auth';
3
4
  export * from './baseUrl';
package/lib/esm/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import 'symbol-observable';
1
2
  export * from './api';
2
3
  export * from './auth';
3
4
  export * from './baseUrl';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-web-react",
3
- "version": "0.0.250",
3
+ "version": "0.0.252",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -32,13 +32,19 @@
32
32
  },
33
33
  "homepage": "https://github.com/joe-coady/quidproquo#readme",
34
34
  "devDependencies": {
35
- "quidproquo-core": "0.0.250",
36
- "quidproquo-tsconfig": "0.0.250",
37
- "quidproquo-webserver": "0.0.250",
38
- "quidproquo-web": "0.0.250",
35
+ "quidproquo-actionprocessor-node": "0.0.252",
36
+ "quidproquo-actionprocessor-web": "0.0.252",
37
+ "quidproquo-core": "0.0.252",
38
+ "quidproquo-tsconfig": "0.0.252",
39
+ "quidproquo-web": "0.0.252",
40
+ "quidproquo-webserver": "0.0.252",
39
41
  "typescript": "^4.9.3"
40
42
  },
41
43
  "peerDependencies": {
42
44
  "react": ">=18.3.1"
45
+ },
46
+ "dependencies": {
47
+ "jotai": "^2.12.1",
48
+ "symbol-observable": "^4.0.0"
43
49
  }
44
50
  }
@@ -1,7 +0,0 @@
1
- import { ReactNode } from 'react';
2
- export type QpqBubbleReducer<S, A> = (prevState: S, action: A) => [S, boolean];
3
- export declare const useBubblingReducer: <TState, TAction>(reducer: QpqBubbleReducer<TState, TAction>, initialState: TState) => [TState, (action: TAction) => void];
4
- export declare const BubbleReducerDispatchProvider: ({ children, dispatch }: {
5
- children: ReactNode;
6
- dispatch: (action: any) => void;
7
- }) => import("react/jsx-runtime").JSX.Element;
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BubbleReducerDispatchProvider = exports.useBubblingReducer = void 0;
4
- const jsx_runtime_1 = require("react/jsx-runtime");
5
- const react_1 = require("react");
6
- // Create a context with a default NOOP dispatcher
7
- const BubbleReducerDispatchContext = (0, react_1.createContext)((_action) => {
8
- // NOOP
9
- });
10
- const useBubblingReducer = (reducer, initialState) => {
11
- const ref = (0, react_1.useRef)(initialState);
12
- // Use useState so we can leverage functional updates
13
- const [state, setState] = (0, react_1.useState)(ref.current);
14
- // Get the parent dispatch from the context
15
- const parentDispatch = (0, react_1.useContext)(BubbleReducerDispatchContext);
16
- // Custom Dispatch using functional updates
17
- const dispatch = (action) => {
18
- const [newState, preventBubble] = reducer(ref.current, action);
19
- if (preventBubble) {
20
- // If the action was handled, update state
21
- ref.current = newState;
22
- setState(newState);
23
- }
24
- else {
25
- parentDispatch(action);
26
- }
27
- };
28
- return [state, dispatch];
29
- };
30
- exports.useBubblingReducer = useBubblingReducer;
31
- const BubbleReducerDispatchProvider = ({ children, dispatch }) => ((0, jsx_runtime_1.jsx)(BubbleReducerDispatchContext.Provider, Object.assign({ value: dispatch }, { children: children })));
32
- exports.BubbleReducerDispatchProvider = BubbleReducerDispatchProvider;
@@ -1 +0,0 @@
1
- export * from './getStateDispatchActionProcessor';
@@ -1 +0,0 @@
1
- export * from './useQpqReducer';
@@ -1 +0,0 @@
1
- export declare const useQpqReducer: () => void;
@@ -1,63 +0,0 @@
1
- "use strict";
2
- /*
3
- import { AskResponseReturnType, Story } from 'quidproquo-core';
4
-
5
- import { useMemo, useState } from 'react';
6
-
7
- import { QpqBubbleReducer, useBubblingReducer } from '../useBubbleReducer';
8
- import { useQpq } from '../useQpq';
9
- import { getStateDispatchActionListResolver } from './actionProcessor';
10
-
11
- // Helper type to remap keys from "askXyz" to "xyz" (with lowercase first letter)
12
- type RemoveAskPrefix<K extends string> = K extends `ask${infer R}` ? Uncapitalize<R> : never;
13
-
14
- // Define the mapped API type.
15
- // We extract only string keys and then use a conditional type to infer parameters and return type.
16
- type MappedApi<TApi extends Record<`ask${string}`, Story<any, any>>> = {
17
- [K in Extract<keyof TApi, string> as RemoveAskPrefix<K>]: TApi[K] extends (...args: infer P) => infer R
18
- ? (...args: P) => Promise<AskResponseReturnType<R>>
19
- : never;
20
- };
21
-
22
- export function useQpqReducer<
23
- TState,
24
- TAction,
25
- // Constrain TApi so that all keys must start with "ask"
26
- TApi extends Record<`ask${string}`, Story<any, any>>,
27
- >(
28
- apiGenerators: TApi,
29
- reducer: QpqBubbleReducer<TState, TAction> = (s) => [s, false],
30
- initialState: TState = {} as TState,
31
- ): [MappedApi<TApi>, TState, (action: any) => void] {
32
- const [state, dispatch] = useBubblingReducer(reducer, initialState);
33
-
34
- // Api generators are memoized to prevent unnecessary re-renders.
35
- const [memoedApiGenerators] = useState(() => apiGenerators);
36
- const resolver = useQpq(getStateDispatchActionListResolver(dispatch));
37
-
38
- // Wrap and remap each API generator using the resolver.
39
- const api = useMemo(() => {
40
- const wrapped = {} as MappedApi<TApi>;
41
- for (const key in memoedApiGenerators) {
42
- if (Object.prototype.hasOwnProperty.call(memoedApiGenerators, key)) {
43
- // Remove the 'ask' prefix and lower-case the first character.
44
- const withoutAsk = key.slice(3); // e.g., "FetchTodos"
45
- const newKey = withoutAsk.charAt(0).toLowerCase() + withoutAsk.slice(1); // "fetchTodos"
46
- // We know newKey matches our mapped type so we can assign.
47
- // (A type assertion is used here to quiet the compiler.)
48
- wrapped[newKey as RemoveAskPrefix<typeof key>] = resolver(memoedApiGenerators[key as any]) as any;
49
- }
50
- }
51
- return wrapped;
52
- }, [resolver, memoedApiGenerators]);
53
-
54
- return [api, state, dispatch];
55
- }
56
-
57
- */
58
- Object.defineProperty(exports, "__esModule", { value: true });
59
- exports.useQpqReducer = void 0;
60
- const useQpqReducer = () => {
61
- // NOOP
62
- };
63
- exports.useQpqReducer = useQpqReducer;
@@ -1,7 +0,0 @@
1
- import { ReactNode } from 'react';
2
- export type QpqBubbleReducer<S, A> = (prevState: S, action: A) => [S, boolean];
3
- export declare const useBubblingReducer: <TState, TAction>(reducer: QpqBubbleReducer<TState, TAction>, initialState: TState) => [TState, (action: TAction) => void];
4
- export declare const BubbleReducerDispatchProvider: ({ children, dispatch }: {
5
- children: ReactNode;
6
- dispatch: (action: any) => void;
7
- }) => import("react/jsx-runtime").JSX.Element;
@@ -1,27 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useRef, useState } from 'react';
3
- // Create a context with a default NOOP dispatcher
4
- const BubbleReducerDispatchContext = createContext((_action) => {
5
- // NOOP
6
- });
7
- export const useBubblingReducer = (reducer, initialState) => {
8
- const ref = useRef(initialState);
9
- // Use useState so we can leverage functional updates
10
- const [state, setState] = useState(ref.current);
11
- // Get the parent dispatch from the context
12
- const parentDispatch = useContext(BubbleReducerDispatchContext);
13
- // Custom Dispatch using functional updates
14
- const dispatch = (action) => {
15
- const [newState, preventBubble] = reducer(ref.current, action);
16
- if (preventBubble) {
17
- // If the action was handled, update state
18
- ref.current = newState;
19
- setState(newState);
20
- }
21
- else {
22
- parentDispatch(action);
23
- }
24
- };
25
- return [state, dispatch];
26
- };
27
- export const BubbleReducerDispatchProvider = ({ children, dispatch }) => (_jsx(BubbleReducerDispatchContext.Provider, { value: dispatch, children: children }));
@@ -1 +0,0 @@
1
- export * from './getStateDispatchActionProcessor';
@@ -1 +0,0 @@
1
- export * from './getStateDispatchActionProcessor';
@@ -1 +0,0 @@
1
- export * from './useQpqReducer';
@@ -1 +0,0 @@
1
- export * from './useQpqReducer';
@@ -1 +0,0 @@
1
- export declare const useQpqReducer: () => void;
@@ -1,59 +0,0 @@
1
- /*
2
- import { AskResponseReturnType, Story } from 'quidproquo-core';
3
-
4
- import { useMemo, useState } from 'react';
5
-
6
- import { QpqBubbleReducer, useBubblingReducer } from '../useBubbleReducer';
7
- import { useQpq } from '../useQpq';
8
- import { getStateDispatchActionListResolver } from './actionProcessor';
9
-
10
- // Helper type to remap keys from "askXyz" to "xyz" (with lowercase first letter)
11
- type RemoveAskPrefix<K extends string> = K extends `ask${infer R}` ? Uncapitalize<R> : never;
12
-
13
- // Define the mapped API type.
14
- // We extract only string keys and then use a conditional type to infer parameters and return type.
15
- type MappedApi<TApi extends Record<`ask${string}`, Story<any, any>>> = {
16
- [K in Extract<keyof TApi, string> as RemoveAskPrefix<K>]: TApi[K] extends (...args: infer P) => infer R
17
- ? (...args: P) => Promise<AskResponseReturnType<R>>
18
- : never;
19
- };
20
-
21
- export function useQpqReducer<
22
- TState,
23
- TAction,
24
- // Constrain TApi so that all keys must start with "ask"
25
- TApi extends Record<`ask${string}`, Story<any, any>>,
26
- >(
27
- apiGenerators: TApi,
28
- reducer: QpqBubbleReducer<TState, TAction> = (s) => [s, false],
29
- initialState: TState = {} as TState,
30
- ): [MappedApi<TApi>, TState, (action: any) => void] {
31
- const [state, dispatch] = useBubblingReducer(reducer, initialState);
32
-
33
- // Api generators are memoized to prevent unnecessary re-renders.
34
- const [memoedApiGenerators] = useState(() => apiGenerators);
35
- const resolver = useQpq(getStateDispatchActionListResolver(dispatch));
36
-
37
- // Wrap and remap each API generator using the resolver.
38
- const api = useMemo(() => {
39
- const wrapped = {} as MappedApi<TApi>;
40
- for (const key in memoedApiGenerators) {
41
- if (Object.prototype.hasOwnProperty.call(memoedApiGenerators, key)) {
42
- // Remove the 'ask' prefix and lower-case the first character.
43
- const withoutAsk = key.slice(3); // e.g., "FetchTodos"
44
- const newKey = withoutAsk.charAt(0).toLowerCase() + withoutAsk.slice(1); // "fetchTodos"
45
- // We know newKey matches our mapped type so we can assign.
46
- // (A type assertion is used here to quiet the compiler.)
47
- wrapped[newKey as RemoveAskPrefix<typeof key>] = resolver(memoedApiGenerators[key as any]) as any;
48
- }
49
- }
50
- return wrapped;
51
- }, [resolver, memoedApiGenerators]);
52
-
53
- return [api, state, dispatch];
54
- }
55
-
56
- */
57
- export const useQpqReducer = () => {
58
- // NOOP
59
- };