quidproquo-web-react 0.0.258 → 0.0.259

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.
@@ -4,3 +4,4 @@ export type QpqApi = Record<`ask${string}`, Story<any, any>>;
4
4
  export type QpqMappedApi<TApi extends QpqApi> = {
5
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
6
  };
7
+ export declare const combineQpqApis: <TApiA extends QpqApi, TApiB extends QpqApi>(apiA: TApiA, apiB: TApiB) => TApiA & TApiB;
@@ -1,2 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.combineQpqApis = void 0;
4
+ const combineQpqApis = (apiA, apiB) => {
5
+ return Object.assign(Object.assign({}, apiA), apiB);
6
+ };
7
+ exports.combineQpqApis = combineQpqApis;
@@ -1,8 +1,10 @@
1
1
  export * from './asmj';
2
2
  export * from './useAsyncEffect';
3
+ export * from './useEffectCallback';
3
4
  export * from './useFastCallback';
4
5
  export * from './useMetadata';
5
6
  export * from './useOnKeyDownEffect';
6
7
  export * from './useQpq';
7
8
  export * from './useRunEvery';
8
9
  export * from './useThrottledMemo';
10
+ export * from './useZipArrays';
@@ -16,9 +16,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./asmj"), exports);
18
18
  __exportStar(require("./useAsyncEffect"), exports);
19
+ __exportStar(require("./useEffectCallback"), exports);
19
20
  __exportStar(require("./useFastCallback"), exports);
20
21
  __exportStar(require("./useMetadata"), exports);
21
22
  __exportStar(require("./useOnKeyDownEffect"), exports);
22
23
  __exportStar(require("./useQpq"), exports);
23
24
  __exportStar(require("./useRunEvery"), exports);
24
25
  __exportStar(require("./useThrottledMemo"), exports);
26
+ __exportStar(require("./useZipArrays"), exports);
@@ -0,0 +1,2 @@
1
+ import { DependencyList } from 'react';
2
+ export declare function useEffectCallback<T extends Function>(callback: T, deps?: DependencyList): T;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useEffectCallback = useEffectCallback;
4
+ const react_1 = require("react");
5
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
6
+ function useEffectCallback(callback, deps) {
7
+ const callbackRef = (0, react_1.useRef)(callback);
8
+ const depsRef = (0, react_1.useRef)(deps);
9
+ // If the deps have changed, update the callback ref
10
+ // We support undefined deps, which means they are always updated
11
+ // This is different to [] where its never updated.
12
+ const hasDepsChanged = !depsRef.current || !deps || depsRef.current.some((dep, index) => dep !== deps[index]);
13
+ if (hasDepsChanged) {
14
+ callbackRef.current = callback;
15
+ }
16
+ depsRef.current = deps;
17
+ const memoFunc = (0, react_1.useCallback)((...args) => callbackRef.current(...args), []);
18
+ return memoFunc;
19
+ }
@@ -1,19 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useFastCallback = useFastCallback;
4
- const react_1 = require("react");
5
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
4
+ const useEffectCallback_1 = require("./useEffectCallback");
5
+ // depraecated: use useEffectCallback instead
6
6
  function useFastCallback(callback, deps) {
7
- const callbackRef = (0, react_1.useRef)(callback);
8
- const depsRef = (0, react_1.useRef)(deps);
9
- // If the deps have changed, update the callback ref
10
- // We support undefined deps, which means they are always updated
11
- // This is different to [] where its never updated.
12
- const hasDepsChanged = !depsRef.current || !deps || depsRef.current.some((dep, index) => dep !== deps[index]);
13
- if (hasDepsChanged) {
14
- callbackRef.current = callback;
15
- }
16
- depsRef.current = deps;
17
- const memoFunc = (0, react_1.useCallback)((...args) => callbackRef.current(...args), []);
18
- return memoFunc;
7
+ return (0, useEffectCallback_1.useEffectCallback)(callback, deps);
19
8
  }
@@ -14,6 +14,19 @@ const quidproquo_actionprocessor_web_1 = require("quidproquo-actionprocessor-web
14
14
  const quidproquo_core_1 = require("quidproquo-core");
15
15
  const react_1 = require("react");
16
16
  const QpqContextProvider_1 = require("./asmj/QpqContextProvider");
17
+ function* withVersionCheck(story, versionRef, capturedVersion) {
18
+ let nextValue = undefined;
19
+ while (true) {
20
+ if (versionRef.current !== capturedVersion) {
21
+ return undefined;
22
+ }
23
+ const { value, done } = story.next(nextValue);
24
+ if (done) {
25
+ return value;
26
+ }
27
+ nextValue = yield value;
28
+ }
29
+ }
17
30
  // WIP ~ useFastCallback, wack things like loggers in a context, try to only make once instance of the runtime.
18
31
  // Also don't create every refresh.. useMemo / useCallback etc
19
32
  const logger = {
@@ -24,6 +37,12 @@ const logger = {
24
37
  };
25
38
  function useQpq(getActionProcessors = () => __awaiter(this, void 0, void 0, function* () { return ({}); })) {
26
39
  const qpqContextValues = (0, QpqContextProvider_1.useQpqContextValues)();
40
+ const versionRef = (0, react_1.useRef)(0);
41
+ (0, react_1.useEffect)(() => {
42
+ return () => {
43
+ versionRef.current++;
44
+ };
45
+ }, []);
27
46
  const resolveStory = (0, react_1.useMemo)(() => (0, quidproquo_core_1.createRuntime)([(0, quidproquo_core_1.defineModule)('UI')], {
28
47
  depth: 0,
29
48
  context: qpqContextValues,
@@ -34,7 +53,9 @@ function useQpq(getActionProcessors = () => __awaiter(this, void 0, void 0, func
34
53
  })), [qpqContextValues]);
35
54
  const qpq = (0, react_1.useCallback)(function getStoryExecutor(story) {
36
55
  return (...args) => __awaiter(this, void 0, void 0, function* () {
37
- const result = yield resolveStory(story, args);
56
+ const capturedVersion = versionRef.current;
57
+ const wrappedStory = (...storyArgs) => withVersionCheck(story(...storyArgs), versionRef, capturedVersion);
58
+ const result = yield resolveStory(wrappedStory, args);
38
59
  if (result.error) {
39
60
  throw new Error(result.error.errorText);
40
61
  }
@@ -0,0 +1,2 @@
1
+ import { zipArrays } from 'quidproquo-core';
2
+ export declare function useZipArrays<TLeft, TRight>(left: readonly TLeft[], right: readonly TRight[]): ReturnType<typeof zipArrays<TLeft, TRight>>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useZipArrays = useZipArrays;
4
+ const quidproquo_core_1 = require("quidproquo-core");
5
+ const react_1 = require("react");
6
+ function useZipArrays(left, right) {
7
+ const arrays = (0, react_1.useMemo)(() => (0, quidproquo_core_1.zipArrays)(left, right), [left, right]);
8
+ return arrays;
9
+ }
@@ -4,3 +4,4 @@ export type QpqApi = Record<`ask${string}`, Story<any, any>>;
4
4
  export type QpqMappedApi<TApi extends QpqApi> = {
5
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
6
  };
7
+ export declare const combineQpqApis: <TApiA extends QpqApi, TApiB extends QpqApi>(apiA: TApiA, apiB: TApiB) => TApiA & TApiB;
@@ -1 +1,3 @@
1
- export {};
1
+ export const combineQpqApis = (apiA, apiB) => {
2
+ return { ...apiA, ...apiB };
3
+ };
@@ -1,8 +1,10 @@
1
1
  export * from './asmj';
2
2
  export * from './useAsyncEffect';
3
+ export * from './useEffectCallback';
3
4
  export * from './useFastCallback';
4
5
  export * from './useMetadata';
5
6
  export * from './useOnKeyDownEffect';
6
7
  export * from './useQpq';
7
8
  export * from './useRunEvery';
8
9
  export * from './useThrottledMemo';
10
+ export * from './useZipArrays';
@@ -1,8 +1,10 @@
1
1
  export * from './asmj';
2
2
  export * from './useAsyncEffect';
3
+ export * from './useEffectCallback';
3
4
  export * from './useFastCallback';
4
5
  export * from './useMetadata';
5
6
  export * from './useOnKeyDownEffect';
6
7
  export * from './useQpq';
7
8
  export * from './useRunEvery';
8
9
  export * from './useThrottledMemo';
10
+ export * from './useZipArrays';
@@ -0,0 +1,2 @@
1
+ import { DependencyList } from 'react';
2
+ export declare function useEffectCallback<T extends Function>(callback: T, deps?: DependencyList): T;
@@ -0,0 +1,16 @@
1
+ import { useCallback, useRef } from 'react';
2
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
3
+ export function useEffectCallback(callback, deps) {
4
+ const callbackRef = useRef(callback);
5
+ const depsRef = useRef(deps);
6
+ // If the deps have changed, update the callback ref
7
+ // We support undefined deps, which means they are always updated
8
+ // This is different to [] where its never updated.
9
+ const hasDepsChanged = !depsRef.current || !deps || depsRef.current.some((dep, index) => dep !== deps[index]);
10
+ if (hasDepsChanged) {
11
+ callbackRef.current = callback;
12
+ }
13
+ depsRef.current = deps;
14
+ const memoFunc = useCallback((...args) => callbackRef.current(...args), []);
15
+ return memoFunc;
16
+ }
@@ -1,16 +1,5 @@
1
- import { useCallback, useRef } from 'react';
2
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
1
+ import { useEffectCallback } from './useEffectCallback';
2
+ // depraecated: use useEffectCallback instead
3
3
  export function useFastCallback(callback, deps) {
4
- const callbackRef = useRef(callback);
5
- const depsRef = useRef(deps);
6
- // If the deps have changed, update the callback ref
7
- // We support undefined deps, which means they are always updated
8
- // This is different to [] where its never updated.
9
- const hasDepsChanged = !depsRef.current || !deps || depsRef.current.some((dep, index) => dep !== deps[index]);
10
- if (hasDepsChanged) {
11
- callbackRef.current = callback;
12
- }
13
- depsRef.current = deps;
14
- const memoFunc = useCallback((...args) => callbackRef.current(...args), []);
15
- return memoFunc;
4
+ return useEffectCallback(callback, deps);
16
5
  }
@@ -1,7 +1,20 @@
1
1
  import { getWebActionProcessors } from 'quidproquo-actionprocessor-web';
2
2
  import { createRuntime, defineModule, QpqRuntimeType, } from 'quidproquo-core';
3
- import { useCallback, useMemo } from 'react';
3
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
4
4
  import { useQpqContextValues } from './asmj/QpqContextProvider';
5
+ function* withVersionCheck(story, versionRef, capturedVersion) {
6
+ let nextValue = undefined;
7
+ while (true) {
8
+ if (versionRef.current !== capturedVersion) {
9
+ return undefined;
10
+ }
11
+ const { value, done } = story.next(nextValue);
12
+ if (done) {
13
+ return value;
14
+ }
15
+ nextValue = yield value;
16
+ }
17
+ }
5
18
  // WIP ~ useFastCallback, wack things like loggers in a context, try to only make once instance of the runtime.
6
19
  // Also don't create every refresh.. useMemo / useCallback etc
7
20
  const logger = {
@@ -12,6 +25,12 @@ const logger = {
12
25
  };
13
26
  export function useQpq(getActionProcessors = async () => ({})) {
14
27
  const qpqContextValues = useQpqContextValues();
28
+ const versionRef = useRef(0);
29
+ useEffect(() => {
30
+ return () => {
31
+ versionRef.current++;
32
+ };
33
+ }, []);
15
34
  const resolveStory = useMemo(() => createRuntime([defineModule('UI')], {
16
35
  depth: 0,
17
36
  context: qpqContextValues,
@@ -23,7 +42,9 @@ export function useQpq(getActionProcessors = async () => ({})) {
23
42
  }), [qpqContextValues]);
24
43
  const qpq = useCallback(function getStoryExecutor(story) {
25
44
  return async (...args) => {
26
- const result = await resolveStory(story, args);
45
+ const capturedVersion = versionRef.current;
46
+ const wrappedStory = (...storyArgs) => withVersionCheck(story(...storyArgs), versionRef, capturedVersion);
47
+ const result = await resolveStory(wrappedStory, args);
27
48
  if (result.error) {
28
49
  throw new Error(result.error.errorText);
29
50
  }
@@ -0,0 +1,2 @@
1
+ import { zipArrays } from 'quidproquo-core';
2
+ export declare function useZipArrays<TLeft, TRight>(left: readonly TLeft[], right: readonly TRight[]): ReturnType<typeof zipArrays<TLeft, TRight>>;
@@ -0,0 +1,6 @@
1
+ import { zipArrays } from 'quidproquo-core';
2
+ import { useMemo } from 'react';
3
+ export function useZipArrays(left, right) {
4
+ const arrays = useMemo(() => zipArrays(left, right), [left, right]);
5
+ return arrays;
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-web-react",
3
- "version": "0.0.258",
3
+ "version": "0.0.259",
4
4
  "description": "",
5
5
  "main": "./lib/commonjs/index.js",
6
6
  "module": "./lib/esm/index.js",
@@ -32,8 +32,8 @@
32
32
  },
33
33
  "homepage": "https://github.com/joe-coady/quidproquo#readme",
34
34
  "devDependencies": {
35
- "quidproquo-core": "0.0.258",
36
- "quidproquo-tsconfig": "0.0.258",
35
+ "quidproquo-core": "0.0.259",
36
+ "quidproquo-tsconfig": "0.0.259",
37
37
  "typescript": "^5.8.2"
38
38
  },
39
39
  "peerDependencies": {
@@ -42,9 +42,9 @@
42
42
  "dependencies": {
43
43
  "jotai": "^2.12.1",
44
44
  "symbol-observable": "^4.0.0",
45
- "quidproquo-web": "0.0.258",
46
- "quidproquo-webserver": "0.0.258",
47
- "quidproquo-actionprocessor-node": "0.0.258",
48
- "quidproquo-actionprocessor-web": "0.0.258"
45
+ "quidproquo-web": "0.0.259",
46
+ "quidproquo-webserver": "0.0.259",
47
+ "quidproquo-actionprocessor-node": "0.0.259",
48
+ "quidproquo-actionprocessor-web": "0.0.259"
49
49
  }
50
50
  }