@assistant-ui/tap 0.5.14 → 0.6.0
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.
- package/README.md +9 -8
- package/dist/core/ResourceFiber.d.ts.map +1 -1
- package/dist/core/ResourceFiber.js +3 -2
- package/dist/core/ResourceFiber.js.map +1 -1
- package/dist/core/context.d.ts +13 -6
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +19 -6
- package/dist/core/context.js.map +1 -1
- package/dist/core/createResourceRoot.d.ts +2 -1
- package/dist/core/createResourceRoot.d.ts.map +1 -1
- package/dist/core/createResourceRoot.js +2 -2
- package/dist/core/createResourceRoot.js.map +1 -1
- package/dist/core/helpers/execution-context.d.ts +2 -1
- package/dist/core/helpers/execution-context.d.ts.map +1 -1
- package/dist/core/helpers/execution-context.js +4 -1
- package/dist/core/helpers/execution-context.js.map +1 -1
- package/dist/core/react-dispatcher.d.ts +12 -0
- package/dist/core/react-dispatcher.d.ts.map +1 -0
- package/dist/core/react-dispatcher.js +62 -0
- package/dist/core/react-dispatcher.js.map +1 -0
- package/dist/core/scheduler.js +1 -1
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/types.d.ts +3 -3
- package/dist/hooks/index.d.ts +13 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/use.d.ts +9 -0
- package/dist/hooks/use.d.ts.map +1 -0
- package/dist/hooks/use.js +14 -0
- package/dist/hooks/use.js.map +1 -0
- package/dist/hooks/useCallback.d.ts +5 -0
- package/dist/hooks/useCallback.d.ts.map +1 -0
- package/dist/hooks/useCallback.js +9 -0
- package/dist/hooks/useCallback.js.map +1 -0
- package/dist/hooks/useEffect.d.ts +10 -0
- package/dist/hooks/useEffect.d.ts.map +1 -0
- package/dist/hooks/{tap-effect.js → useEffect.js} +7 -7
- package/dist/hooks/useEffect.js.map +1 -0
- package/dist/hooks/{tap-effect-event.d.ts → useEffectEvent.d.ts} +5 -5
- package/dist/hooks/useEffectEvent.d.ts.map +1 -0
- package/dist/hooks/{tap-effect-event.js → useEffectEvent.js} +12 -12
- package/dist/hooks/useEffectEvent.js.map +1 -0
- package/dist/hooks/useMemo.d.ts +5 -0
- package/dist/hooks/useMemo.d.ts.map +1 -0
- package/dist/hooks/{tap-memo.js → useMemo.js} +6 -6
- package/dist/hooks/useMemo.js.map +1 -0
- package/dist/hooks/useMemoCache.d.ts +10 -0
- package/dist/hooks/useMemoCache.d.ts.map +1 -0
- package/dist/hooks/useMemoCache.js +21 -0
- package/dist/hooks/useMemoCache.js.map +1 -0
- package/dist/hooks/useReducer.d.ts +21 -0
- package/dist/hooks/useReducer.d.ts.map +1 -0
- package/dist/hooks/{tap-reducer.js → useReducer.js} +10 -10
- package/dist/hooks/useReducer.js.map +1 -0
- package/dist/hooks/useRef.d.ts +11 -0
- package/dist/hooks/useRef.d.ts.map +1 -0
- package/dist/hooks/useRef.js +10 -0
- package/dist/hooks/useRef.js.map +1 -0
- package/dist/{react/use-resource.d.ts → hooks/useResource.d.ts} +3 -2
- package/dist/hooks/useResource.d.ts.map +1 -0
- package/dist/hooks/{tap-resource.js → useResource.js} +12 -12
- package/dist/hooks/useResource.js.map +1 -0
- package/dist/hooks/useResourceRoot.d.ts +20 -0
- package/dist/hooks/useResourceRoot.d.ts.map +1 -0
- package/dist/{tapResourceRoot.js → hooks/useResourceRoot.js} +30 -26
- package/dist/hooks/useResourceRoot.js.map +1 -0
- package/dist/hooks/{tap-resources.d.ts → useResources.d.ts} +4 -4
- package/dist/hooks/useResources.d.ts.map +1 -0
- package/dist/hooks/{tap-resources.js → useResources.js} +28 -23
- package/dist/hooks/useResources.js.map +1 -0
- package/dist/hooks/useState.d.ts +9 -0
- package/dist/hooks/useState.d.ts.map +1 -0
- package/dist/hooks/useState.js +11 -0
- package/dist/hooks/useState.js.map +1 -0
- package/dist/hooks/utils/useCell.d.ts +10 -0
- package/dist/hooks/utils/useCell.d.ts.map +1 -0
- package/dist/hooks/utils/{tapHook.js → useCell.js} +4 -4
- package/dist/hooks/utils/{tapHook.js.map → useCell.js.map} +1 -1
- package/dist/index.d.ts +3 -13
- package/dist/index.js +3 -13
- package/dist/react/hooks.d.ts +25 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/hooks.js +69 -0
- package/dist/react/hooks.js.map +1 -0
- package/dist/react-shim/index.d.ts +19 -0
- package/dist/react-shim/index.d.ts.map +1 -0
- package/dist/react-shim/index.js +28 -0
- package/dist/react-shim/index.js.map +1 -0
- package/package.json +13 -16
- package/react-shim/package.json +4 -0
- package/src/__tests__/basic/resourceHandle.test.ts +7 -3
- package/src/__tests__/basic/tapEffect.basic.test.ts +19 -19
- package/src/__tests__/basic/tapReducer.basic.test.ts +14 -14
- package/src/__tests__/basic/tapResources.basic.test.ts +19 -14
- package/src/__tests__/basic/tapState.basic.test.ts +20 -20
- package/src/__tests__/errors/errors.effect-errors.test.ts +21 -21
- package/src/__tests__/errors/errors.render-errors.test.ts +18 -18
- package/src/__tests__/lifecycle/lifecycle.dependencies.test.ts +25 -25
- package/src/__tests__/lifecycle/lifecycle.mount-unmount.test.ts +17 -18
- package/src/__tests__/react/concurrent-mode.test.tsx +7 -7
- package/src/__tests__/react/react-shim.test.tsx +65 -0
- package/src/__tests__/react/useResource.test.tsx +172 -0
- package/src/__tests__/react-dispatcher.test.ts +74 -0
- package/src/__tests__/rules/rules.hook-count.test.ts +30 -29
- package/src/__tests__/rules/rules.hook-order.test.ts +27 -27
- package/src/__tests__/strictmode/react-strictmode-behavior.test.tsx +1 -1
- package/src/__tests__/strictmode/strictmode.test.ts +42 -42
- package/src/__tests__/strictmode/tap-strictmode-rerender-sources.test.ts +55 -55
- package/src/__tests__/test-utils.ts +2 -2
- package/src/core/ResourceFiber.ts +4 -1
- package/src/core/context.ts +31 -9
- package/src/core/createResourceRoot.ts +4 -4
- package/src/core/helpers/execution-context.ts +4 -0
- package/src/core/react-dispatcher.ts +78 -0
- package/src/core/scheduler.ts +1 -1
- package/src/core/types.ts +3 -3
- package/src/hooks/index.ts +12 -0
- package/src/hooks/use.ts +13 -0
- package/src/hooks/useCallback.ts +9 -0
- package/src/hooks/{tap-effect.ts → useEffect.ts} +9 -9
- package/src/hooks/{tap-effect-event.ts → useEffectEvent.ts} +9 -9
- package/src/hooks/{tap-memo.ts → useMemo.ts} +3 -3
- package/src/hooks/useMemoCache.ts +25 -0
- package/src/hooks/{tap-reducer.ts → useReducer.ts} +23 -11
- package/src/hooks/useRef.ts +16 -0
- package/src/hooks/{tap-resource.ts → useResource.ts} +13 -12
- package/src/{tapResourceRoot.ts → hooks/useResourceRoot.ts} +26 -27
- package/src/hooks/{tap-resources.ts → useResources.ts} +21 -22
- package/src/hooks/useState.ts +29 -0
- package/src/hooks/utils/{tapHook.ts → useCell.ts} +1 -1
- package/src/index.ts +4 -24
- package/src/react/hooks.ts +112 -0
- package/src/react-shim/index.ts +64 -0
- package/dist/hooks/tap-callback.d.ts +0 -5
- package/dist/hooks/tap-callback.d.ts.map +0 -1
- package/dist/hooks/tap-callback.js +0 -9
- package/dist/hooks/tap-callback.js.map +0 -1
- package/dist/hooks/tap-const.d.ts +0 -5
- package/dist/hooks/tap-const.d.ts.map +0 -1
- package/dist/hooks/tap-const.js +0 -10
- package/dist/hooks/tap-const.js.map +0 -1
- package/dist/hooks/tap-effect-event.d.ts.map +0 -1
- package/dist/hooks/tap-effect-event.js.map +0 -1
- package/dist/hooks/tap-effect.d.ts +0 -10
- package/dist/hooks/tap-effect.d.ts.map +0 -1
- package/dist/hooks/tap-effect.js.map +0 -1
- package/dist/hooks/tap-memo.d.ts +0 -5
- package/dist/hooks/tap-memo.d.ts.map +0 -1
- package/dist/hooks/tap-memo.js.map +0 -1
- package/dist/hooks/tap-reducer.d.ts +0 -9
- package/dist/hooks/tap-reducer.d.ts.map +0 -1
- package/dist/hooks/tap-reducer.js.map +0 -1
- package/dist/hooks/tap-ref.d.ts +0 -11
- package/dist/hooks/tap-ref.d.ts.map +0 -1
- package/dist/hooks/tap-ref.js +0 -10
- package/dist/hooks/tap-ref.js.map +0 -1
- package/dist/hooks/tap-resource.d.ts +0 -8
- package/dist/hooks/tap-resource.d.ts.map +0 -1
- package/dist/hooks/tap-resource.js.map +0 -1
- package/dist/hooks/tap-resources.d.ts.map +0 -1
- package/dist/hooks/tap-resources.js.map +0 -1
- package/dist/hooks/tap-state.d.ts +0 -9
- package/dist/hooks/tap-state.d.ts.map +0 -1
- package/dist/hooks/tap-state.js +0 -11
- package/dist/hooks/tap-state.js.map +0 -1
- package/dist/hooks/utils/tapHook.d.ts +0 -10
- package/dist/hooks/utils/tapHook.d.ts.map +0 -1
- package/dist/react/index.d.ts +0 -2
- package/dist/react/index.js +0 -2
- package/dist/react/use-resource.d.ts.map +0 -1
- package/dist/react/use-resource.js +0 -46
- package/dist/react/use-resource.js.map +0 -1
- package/dist/tapResourceRoot.d.ts +0 -20
- package/dist/tapResourceRoot.d.ts.map +0 -1
- package/dist/tapResourceRoot.js.map +0 -1
- package/react/package.json +0 -5
- package/src/hooks/tap-callback.ts +0 -9
- package/src/hooks/tap-const.ts +0 -6
- package/src/hooks/tap-ref.ts +0 -16
- package/src/hooks/tap-state.ts +0 -29
- package/src/react/index.ts +0 -1
- package/src/react/use-resource.ts +0 -61
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isDevelopment } from "../core/helpers/env.js";
|
|
2
2
|
import { getCurrentResourceFiber } from "../core/helpers/execution-context.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
//#region src/hooks/
|
|
3
|
+
import { useRef } from "./useRef.js";
|
|
4
|
+
import { useCallback } from "./useCallback.js";
|
|
5
|
+
import { useEffect } from "./useEffect.js";
|
|
6
|
+
//#region src/hooks/useEffectEvent.ts
|
|
7
7
|
/**
|
|
8
8
|
* Creates a stable function reference that always calls the most recent version of the callback.
|
|
9
9
|
* Similar to React's useEffectEvent hook.
|
|
@@ -13,24 +13,24 @@ import { tapCallback } from "./tap-callback.js";
|
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```typescript
|
|
16
|
-
* const handleClick =
|
|
16
|
+
* const handleClick = useEffectEvent((value: string) => {
|
|
17
17
|
* console.log(value);
|
|
18
18
|
* });
|
|
19
19
|
* // handleClick reference is stable, but always calls the latest version
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
function
|
|
23
|
-
const callbackRef =
|
|
24
|
-
|
|
22
|
+
function useEffectEvent(callback) {
|
|
23
|
+
const callbackRef = useRef(callback);
|
|
24
|
+
useEffect(() => {
|
|
25
25
|
callbackRef.current = callback;
|
|
26
26
|
});
|
|
27
27
|
const fiber = getCurrentResourceFiber();
|
|
28
|
-
return
|
|
29
|
-
if (isDevelopment && fiber.renderContext) throw new Error("
|
|
28
|
+
return useCallback(((...args) => {
|
|
29
|
+
if (isDevelopment && fiber.renderContext) throw new Error("useEffectEvent cannot be called during render");
|
|
30
30
|
return callbackRef.current(...args);
|
|
31
31
|
}), [fiber]);
|
|
32
32
|
}
|
|
33
33
|
//#endregion
|
|
34
|
-
export {
|
|
34
|
+
export { useEffectEvent };
|
|
35
35
|
|
|
36
|
-
//# sourceMappingURL=
|
|
36
|
+
//# sourceMappingURL=useEffectEvent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useEffectEvent.js","names":[],"sources":["../../src/hooks/useEffectEvent.ts"],"sourcesContent":["import { useRef } from \"./useRef\";\nimport { useEffect } from \"./useEffect\";\nimport { isDevelopment } from \"../core/helpers/env\";\nimport { useCallback } from \"./useCallback\";\nimport { getCurrentResourceFiber } from \"../core/helpers/execution-context\";\n\n/**\n * Creates a stable function reference that always calls the most recent version of the callback.\n * Similar to React's useEffectEvent hook.\n *\n * @param callback - The callback function to wrap\n * @returns A stable function reference that always calls the latest callback\n *\n * @example\n * ```typescript\n * const handleClick = useEffectEvent((value: string) => {\n * console.log(value);\n * });\n * // handleClick reference is stable, but always calls the latest version\n * ```\n */\nexport function useEffectEvent<T extends (...args: any[]) => any>(\n callback: T,\n): T {\n const callbackRef = useRef(callback);\n\n // TODO this effect needs to run before all userland effects\n useEffect(() => {\n callbackRef.current = callback;\n });\n\n const fiber = getCurrentResourceFiber();\n return useCallback(\n ((...args: Parameters<T>) => {\n if (isDevelopment && fiber.renderContext)\n throw new Error(\"useEffectEvent cannot be called during render\");\n return callbackRef.current(...args);\n }) as T,\n [fiber],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,eACd,UACG;CACH,MAAM,cAAc,OAAO,QAAQ;CAGnC,gBAAgB;EACd,YAAY,UAAU;CACxB,CAAC;CAED,MAAM,QAAQ,wBAAwB;CACtC,OAAO,cACH,GAAG,SAAwB;EAC3B,IAAI,iBAAiB,MAAM,eACzB,MAAM,IAAI,MAAM,+CAA+C;EACjE,OAAO,YAAY,QAAQ,GAAG,IAAI;CACpC,IACA,CAAC,KAAK,CACR;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMemo.d.ts","names":[],"sources":["../../src/hooks/useMemo.ts"],"mappings":";cAWa,OAAA,MAAc,EAAA,QAAU,CAAA,EAAG,IAAA,yBAA2B,CAkBlE"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { isDevelopment } from "../core/helpers/env.js";
|
|
2
2
|
import { getCurrentResourceFiber } from "../core/helpers/execution-context.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useReducerWithDerivedState } from "./useReducer.js";
|
|
4
4
|
import { depsShallowEqual } from "./utils/depsShallowEqual.js";
|
|
5
|
-
//#region src/hooks/
|
|
5
|
+
//#region src/hooks/useMemo.ts
|
|
6
6
|
const memoReducer = () => {
|
|
7
7
|
throw new Error("Memo reducer should not be called");
|
|
8
8
|
};
|
|
9
|
-
const
|
|
9
|
+
const useMemo = (fn, deps) => {
|
|
10
10
|
const fiber = getCurrentResourceFiber();
|
|
11
|
-
const [state] =
|
|
11
|
+
const [state] = useReducerWithDerivedState(memoReducer, (state) => {
|
|
12
12
|
if (state && depsShallowEqual(state.deps, deps)) return state;
|
|
13
13
|
const value = fn();
|
|
14
14
|
if (isDevelopment && fiber.devStrictMode) fn();
|
|
@@ -20,6 +20,6 @@ const tapMemo = (fn, deps) => {
|
|
|
20
20
|
return state.value;
|
|
21
21
|
};
|
|
22
22
|
//#endregion
|
|
23
|
-
export {
|
|
23
|
+
export { useMemo };
|
|
24
24
|
|
|
25
|
-
//# sourceMappingURL=
|
|
25
|
+
//# sourceMappingURL=useMemo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMemo.js","names":[],"sources":["../../src/hooks/useMemo.ts"],"sourcesContent":["import { isDevelopment } from \"../core/helpers/env\";\nimport { getCurrentResourceFiber } from \"../core/helpers/execution-context\";\nimport { useReducerWithDerivedState } from \"./useReducer\";\nimport { depsShallowEqual } from \"./utils/depsShallowEqual\";\n\nconst memoReducer = () => {\n throw new Error(\"Memo reducer should not be called\");\n};\n\ntype MemoState<T> = { value: T; deps: readonly unknown[] };\n\nexport const useMemo = <T>(fn: () => T, deps: readonly unknown[]): T => {\n const fiber = getCurrentResourceFiber();\n const [state] = useReducerWithDerivedState(\n memoReducer,\n (state: MemoState<T> | null): MemoState<T> => {\n if (state && depsShallowEqual(state.deps, deps)) return state;\n\n const value = fn();\n\n if (isDevelopment && fiber.devStrictMode) {\n void fn();\n }\n\n return { value, deps };\n },\n null,\n );\n return state.value;\n};\n"],"mappings":";;;;;AAKA,MAAM,oBAAoB;CACxB,MAAM,IAAI,MAAM,mCAAmC;AACrD;AAIA,MAAa,WAAc,IAAa,SAAgC;CACtE,MAAM,QAAQ,wBAAwB;CACtC,MAAM,CAAC,SAAS,2BACd,cACC,UAA6C;EAC5C,IAAI,SAAS,iBAAiB,MAAM,MAAM,IAAI,GAAG,OAAO;EAExD,MAAM,QAAQ,GAAG;EAEjB,IAAI,iBAAiB,MAAM,eACzB,GAAQ;EAGV,OAAO;GAAE;GAAO;EAAK;CACvB,GACA,IACF;CACA,OAAO,MAAM;AACf"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/hooks/useMemoCache.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Backs React Compiler's memo cache. Compiled output allocates it through
|
|
4
|
+
* `react/compiler-runtime`'s `c(size)` (`ReactSharedInternals.H.useMemoCache(size)`);
|
|
5
|
+
* a tap ref persists the array so compiled resources run without `"use no memo"`.
|
|
6
|
+
*/
|
|
7
|
+
declare const useMemoCache: (size: number) => unknown[];
|
|
8
|
+
//#endregion
|
|
9
|
+
export { useMemoCache };
|
|
10
|
+
//# sourceMappingURL=useMemoCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMemoCache.d.ts","names":[],"sources":["../../src/hooks/useMemoCache.ts"],"mappings":";;AASA;;;;cAAa,YAAA,GAAgB,IAAY"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useReducerWithDerivedState } from "./useReducer.js";
|
|
2
|
+
//#region src/hooks/useMemoCache.ts
|
|
3
|
+
const MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");
|
|
4
|
+
/**
|
|
5
|
+
* Backs React Compiler's memo cache. Compiled output allocates it through
|
|
6
|
+
* `react/compiler-runtime`'s `c(size)` (`ReactSharedInternals.H.useMemoCache(size)`);
|
|
7
|
+
* a tap ref persists the array so compiled resources run without `"use no memo"`.
|
|
8
|
+
*/
|
|
9
|
+
const useMemoCache = (size) => {
|
|
10
|
+
let cloned = false;
|
|
11
|
+
const [cache] = useReducerWithDerivedState(() => [], (arr) => {
|
|
12
|
+
if (cloned) return arr;
|
|
13
|
+
cloned = true;
|
|
14
|
+
return [...arr];
|
|
15
|
+
}, size, (length) => Array.from({ length }).fill(MEMO_CACHE_SENTINEL));
|
|
16
|
+
return cache;
|
|
17
|
+
};
|
|
18
|
+
//#endregion
|
|
19
|
+
export { useMemoCache };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=useMemoCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMemoCache.js","names":[],"sources":["../../src/hooks/useMemoCache.ts"],"sourcesContent":["import { useReducerWithDerivedState } from \"./useReducer\";\n\nconst MEMO_CACHE_SENTINEL = Symbol.for(\"react.memo_cache_sentinel\");\n\n/**\n * Backs React Compiler's memo cache. Compiled output allocates it through\n * `react/compiler-runtime`'s `c(size)` (`ReactSharedInternals.H.useMemoCache(size)`);\n * a tap ref persists the array so compiled resources run without `\"use no memo\"`.\n */\nexport const useMemoCache = (size: number): unknown[] => {\n // clone the memo value once per render\n let cloned = false;\n const [cache] = useReducerWithDerivedState(\n () => [] as unknown[],\n (arr) => {\n if (cloned) return arr;\n cloned = true;\n return [...arr];\n },\n size,\n (length) => Array.from({ length }).fill(MEMO_CACHE_SENTINEL),\n );\n\n return cache;\n};\n"],"mappings":";;AAEA,MAAM,sBAAsB,OAAO,IAAI,2BAA2B;;;;;;AAOlE,MAAa,gBAAgB,SAA4B;CAEvD,IAAI,SAAS;CACb,MAAM,CAAC,SAAS,iCACR,CAAC,IACN,QAAQ;EACP,IAAI,QAAQ,OAAO;EACnB,SAAS;EACT,OAAO,CAAC,GAAG,GAAG;CAChB,GACA,OACC,WAAW,MAAM,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,mBAAmB,CAC7D;CAEA,OAAO;AACT"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/hooks/useReducer.d.ts
|
|
2
|
+
type Dispatch<A> = (action: A) => void;
|
|
3
|
+
declare function useReducer<S, A>(reducer: (state: S, action: A) => S, initialState: S): [S, Dispatch<A>];
|
|
4
|
+
declare function useReducer<S, A, I>(reducer: (state: S, action: A) => S, initialArg: I, init: (arg: I) => S): [S, Dispatch<A>];
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated experimental — a `getDerivedStateFromProps` replacement for
|
|
7
|
+
* resources: adjust state in response to props without setting during render.
|
|
8
|
+
* Tap-only for now (call it inside a resource render, not a React component) and
|
|
9
|
+
* may change before stabilizing.
|
|
10
|
+
*/
|
|
11
|
+
declare function useReducerWithDerivedState<S, A, R extends S>(reducer: (state: S, action: A) => S, getDerivedState: (state: S) => R, initialState: S): [R, Dispatch<A>];
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated experimental — a `getDerivedStateFromProps` replacement for
|
|
14
|
+
* resources: adjust state in response to props without setting during render.
|
|
15
|
+
* Tap-only for now (call it inside a resource render, not a React component) and
|
|
16
|
+
* may change before stabilizing.
|
|
17
|
+
*/
|
|
18
|
+
declare function useReducerWithDerivedState<S, A, I, R extends S>(reducer: (state: S, action: A) => S, getDerivedState: (state: S) => R, initialArg: I, init: (arg: I) => S): [R, Dispatch<A>];
|
|
19
|
+
//#endregion
|
|
20
|
+
export { useReducer, useReducerWithDerivedState };
|
|
21
|
+
//# sourceMappingURL=useReducer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useReducer.d.ts","names":[],"sources":["../../src/hooks/useReducer.ts"],"mappings":";KAMK,QAAA,OAAe,MAAA,EAAQ,CAAC;AAAA,iBAqGb,UAAA,OACd,OAAA,GAAU,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,KAAM,CAAA,EAClC,YAAA,EAAc,CAAA,IACZ,CAAA,EAAG,QAAA,CAAS,CAAA;AAAA,iBACA,UAAA,UACd,OAAA,GAAU,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,KAAM,CAAA,EAClC,UAAA,EAAY,CAAA,EACZ,IAAA,GAAO,GAAA,EAAK,CAAA,KAAM,CAAA,IAChB,CAAA,EAAG,QAAA,CAAS,CAAA;;;;;;;iBAoBA,0BAAA,iBAA2C,CAAA,EACzD,OAAA,GAAU,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,KAAM,CAAA,EAClC,eAAA,GAAkB,KAAA,EAAO,CAAA,KAAM,CAAA,EAC/B,YAAA,EAAc,CAAA,IACZ,CAAA,EAAG,QAAA,CAAS,CAAA;AAhChB;;;;;;AAAA,iBAuCgB,0BAAA,oBAA8C,CAAA,EAC5D,OAAA,GAAU,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,KAAM,CAAA,EAClC,eAAA,GAAkB,KAAA,EAAO,CAAA,KAAM,CAAA,EAC/B,UAAA,EAAY,CAAA,EACZ,IAAA,GAAO,GAAA,EAAK,CAAA,KAAM,CAAA,IAChB,CAAA,EAAG,QAAA,CAAS,CAAA"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isDevelopment } from "../core/helpers/env.js";
|
|
2
2
|
import { getCurrentResourceFiber } from "../core/helpers/execution-context.js";
|
|
3
3
|
import { markCellDirty } from "../core/helpers/root.js";
|
|
4
|
-
import {
|
|
5
|
-
//#region src/hooks/
|
|
4
|
+
import { useCell } from "./utils/useCell.js";
|
|
5
|
+
//#region src/hooks/useReducer.ts
|
|
6
6
|
const dispatchOnFiber = (fiber, callback) => {
|
|
7
7
|
if (fiber.renderContext) throw new Error("Resource updated during render");
|
|
8
8
|
if (fiber.isNeverMounted) throw new Error("Resource updated before mount");
|
|
@@ -16,8 +16,8 @@ const dispatchOnFiber = (fiber, callback) => {
|
|
|
16
16
|
return false;
|
|
17
17
|
});
|
|
18
18
|
};
|
|
19
|
-
function
|
|
20
|
-
const cell =
|
|
19
|
+
function useReducerImpl(reducer, getDerivedState, initialArg, initFn) {
|
|
20
|
+
const cell = useCell("reducer", () => {
|
|
21
21
|
const fiber = getCurrentResourceFiber();
|
|
22
22
|
const initialState = initFn ? initFn(initialArg) : initialArg;
|
|
23
23
|
if (isDevelopment && fiber.devStrictMode && initFn) initFn(initialArg);
|
|
@@ -69,13 +69,13 @@ function tapReducerImpl(reducer, getDerivedState, initialArg, initFn) {
|
|
|
69
69
|
}
|
|
70
70
|
return [cell.workInProgress, cell.dispatch];
|
|
71
71
|
}
|
|
72
|
-
function
|
|
73
|
-
return
|
|
72
|
+
function useReducer(reducer, initialArg, init) {
|
|
73
|
+
return useReducerImpl(reducer, void 0, initialArg, init);
|
|
74
74
|
}
|
|
75
|
-
function
|
|
76
|
-
return
|
|
75
|
+
function useReducerWithDerivedState(reducer, getDerivedState, initialArg, init) {
|
|
76
|
+
return useReducerImpl(reducer, getDerivedState, initialArg, init);
|
|
77
77
|
}
|
|
78
78
|
//#endregion
|
|
79
|
-
export {
|
|
79
|
+
export { useReducer, useReducerWithDerivedState };
|
|
80
80
|
|
|
81
|
-
//# sourceMappingURL=
|
|
81
|
+
//# sourceMappingURL=useReducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useReducer.js","names":[],"sources":["../../src/hooks/useReducer.ts"],"sourcesContent":["import { isDevelopment } from \"../core/helpers/env\";\nimport { getCurrentResourceFiber } from \"../core/helpers/execution-context\";\nimport type { ReducerQueueEntry, ResourceFiber } from \"../core/types\";\nimport { markCellDirty } from \"../core/helpers/root\";\nimport { useCell } from \"./utils/useCell\";\n\ntype Dispatch<A> = (action: A) => void;\n\nconst dispatchOnFiber = (\n fiber: ResourceFiber<any, any>,\n callback: () => (() => void) | null,\n): void => {\n if (fiber.renderContext) {\n throw new Error(\"Resource updated during render\");\n }\n if (fiber.isNeverMounted) {\n throw new Error(\"Resource updated before mount\");\n }\n\n fiber.root.dispatchUpdate(() => {\n const result = callback();\n if (result) {\n result();\n fiber.root.changelog.push(result);\n return true;\n }\n return false;\n });\n};\n\nfunction useReducerImpl<S, A, I, R extends S>(\n reducer: (state: S, action: A) => S,\n getDerivedState: ((state: S) => R) | undefined,\n initialArg: S | I,\n initFn: ((arg: I) => S) | undefined,\n): [R, Dispatch<A>] {\n const cell = useCell(\"reducer\", () => {\n const fiber = getCurrentResourceFiber();\n\n // First render: compute initial state\n const initialState = initFn ? initFn(initialArg as I) : initialArg;\n\n if (isDevelopment && fiber.devStrictMode && initFn) {\n void initFn(initialArg as I);\n }\n\n return {\n type: \"reducer\",\n queue: new Set(),\n dirty: false,\n workInProgress: initialState,\n current: initialState,\n reducer,\n dispatch: (action: A) => {\n const entry: ReducerQueueEntry = {\n action,\n hasEagerState: false,\n eagerState: undefined,\n };\n\n dispatchOnFiber(fiber, () => {\n if (fiber.root.dirtyCells.length === 0 && !entry.hasEagerState) {\n entry.eagerState = reducer(cell.workInProgress, action);\n entry.hasEagerState = true;\n\n if (Object.is(cell.current, entry.eagerState)) return null;\n }\n\n return () => {\n markCellDirty(fiber, cell);\n cell.queue.add(entry);\n };\n });\n },\n };\n });\n\n const fiber = getCurrentResourceFiber();\n const sameReducer = reducer === cell.reducer;\n cell.reducer = reducer;\n\n for (const item of cell.queue) {\n if (!item.hasEagerState || !sameReducer) {\n item.eagerState = reducer(cell.workInProgress, item.action);\n item.hasEagerState = true;\n }\n\n if (isDevelopment && fiber.devStrictMode) {\n void reducer(cell.workInProgress, item.action);\n }\n\n cell.workInProgress = item.eagerState;\n }\n cell.queue.clear();\n\n if (getDerivedState) {\n const derived = getDerivedState(cell.workInProgress);\n\n if (!Object.is(derived, cell.workInProgress)) {\n markCellDirty(fiber, cell);\n cell.workInProgress = derived;\n }\n }\n\n return [cell.workInProgress, cell.dispatch];\n}\n\nexport function useReducer<S, A>(\n reducer: (state: S, action: A) => S,\n initialState: S,\n): [S, Dispatch<A>];\nexport function useReducer<S, A, I>(\n reducer: (state: S, action: A) => S,\n initialArg: I,\n init: (arg: I) => S,\n): [S, Dispatch<A>];\nexport function useReducer<S, A, I>(\n reducer: (state: S, action: A) => S,\n initialArg: S | I,\n init?: (arg: I) => S,\n): [S, Dispatch<A>] {\n return useReducerImpl(\n reducer,\n undefined,\n initialArg as S,\n init as ((arg: S) => S) | undefined,\n );\n}\n\n/**\n * @deprecated experimental — a `getDerivedStateFromProps` replacement for\n * resources: adjust state in response to props without setting during render.\n * Tap-only for now (call it inside a resource render, not a React component) and\n * may change before stabilizing.\n */\nexport function useReducerWithDerivedState<S, A, R extends S>(\n reducer: (state: S, action: A) => S,\n getDerivedState: (state: S) => R,\n initialState: S,\n): [R, Dispatch<A>];\n/**\n * @deprecated experimental — a `getDerivedStateFromProps` replacement for\n * resources: adjust state in response to props without setting during render.\n * Tap-only for now (call it inside a resource render, not a React component) and\n * may change before stabilizing.\n */\nexport function useReducerWithDerivedState<S, A, I, R extends S>(\n reducer: (state: S, action: A) => S,\n getDerivedState: (state: S) => R,\n initialArg: I,\n init: (arg: I) => S,\n): [R, Dispatch<A>];\nexport function useReducerWithDerivedState<S, A, I, R extends S>(\n reducer: (state: S, action: A) => S,\n getDerivedState: (state: S) => R,\n initialArg: I,\n init?: (arg: I) => S,\n): [R, Dispatch<A>] {\n return useReducerImpl(reducer, getDerivedState, initialArg, init);\n}\n"],"mappings":";;;;;AAQA,MAAM,mBACJ,OACA,aACS;CACT,IAAI,MAAM,eACR,MAAM,IAAI,MAAM,gCAAgC;CAElD,IAAI,MAAM,gBACR,MAAM,IAAI,MAAM,+BAA+B;CAGjD,MAAM,KAAK,qBAAqB;EAC9B,MAAM,SAAS,SAAS;EACxB,IAAI,QAAQ;GACV,OAAO;GACP,MAAM,KAAK,UAAU,KAAK,MAAM;GAChC,OAAO;EACT;EACA,OAAO;CACT,CAAC;AACH;AAEA,SAAS,eACP,SACA,iBACA,YACA,QACkB;CAClB,MAAM,OAAO,QAAQ,iBAAiB;EACpC,MAAM,QAAQ,wBAAwB;EAGtC,MAAM,eAAe,SAAS,OAAO,UAAe,IAAI;EAExD,IAAI,iBAAiB,MAAM,iBAAiB,QAC1C,OAAY,UAAe;EAG7B,OAAO;GACL,MAAM;GACN,uBAAO,IAAI,IAAI;GACf,OAAO;GACP,gBAAgB;GAChB,SAAS;GACT;GACA,WAAW,WAAc;IACvB,MAAM,QAA2B;KAC/B;KACA,eAAe;KACf,YAAY,KAAA;IACd;IAEA,gBAAgB,aAAa;KAC3B,IAAI,MAAM,KAAK,WAAW,WAAW,KAAK,CAAC,MAAM,eAAe;MAC9D,MAAM,aAAa,QAAQ,KAAK,gBAAgB,MAAM;MACtD,MAAM,gBAAgB;MAEtB,IAAI,OAAO,GAAG,KAAK,SAAS,MAAM,UAAU,GAAG,OAAO;KACxD;KAEA,aAAa;MACX,cAAc,OAAO,IAAI;MACzB,KAAK,MAAM,IAAI,KAAK;KACtB;IACF,CAAC;GACH;EACF;CACF,CAAC;CAED,MAAM,QAAQ,wBAAwB;CACtC,MAAM,cAAc,YAAY,KAAK;CACrC,KAAK,UAAU;CAEf,KAAK,MAAM,QAAQ,KAAK,OAAO;EAC7B,IAAI,CAAC,KAAK,iBAAiB,CAAC,aAAa;GACvC,KAAK,aAAa,QAAQ,KAAK,gBAAgB,KAAK,MAAM;GAC1D,KAAK,gBAAgB;EACvB;EAEA,IAAI,iBAAiB,MAAM,eACzB,QAAa,KAAK,gBAAgB,KAAK,MAAM;EAG/C,KAAK,iBAAiB,KAAK;CAC7B;CACA,KAAK,MAAM,MAAM;CAEjB,IAAI,iBAAiB;EACnB,MAAM,UAAU,gBAAgB,KAAK,cAAc;EAEnD,IAAI,CAAC,OAAO,GAAG,SAAS,KAAK,cAAc,GAAG;GAC5C,cAAc,OAAO,IAAI;GACzB,KAAK,iBAAiB;EACxB;CACF;CAEA,OAAO,CAAC,KAAK,gBAAgB,KAAK,QAAQ;AAC5C;AAWA,SAAgB,WACd,SACA,YACA,MACkB;CAClB,OAAO,eACL,SACA,KAAA,GACA,YACA,IACF;AACF;AAyBA,SAAgB,2BACd,SACA,iBACA,YACA,MACkB;CAClB,OAAO,eAAe,SAAS,iBAAiB,YAAY,IAAI;AAClE"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/hooks/useRef.d.ts
|
|
2
|
+
declare namespace useRef {
|
|
3
|
+
interface RefObject<T> {
|
|
4
|
+
current: T;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
declare function useRef<T>(initialValue: T): useRef.RefObject<T>;
|
|
8
|
+
declare function useRef<T = undefined>(): useRef.RefObject<T | undefined>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { useRef };
|
|
11
|
+
//# sourceMappingURL=useRef.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRef.d.ts","names":[],"sources":["../../src/hooks/useRef.ts"],"mappings":";kBAEiB,MAAA;EAAA,UACE,SAAA;IACf,OAAA,EAAS,CAAC;EAAA;AAAA;AAAA,iBAIE,MAAA,IAAU,YAAA,EAAc,CAAA,GAAI,MAAA,CAAO,SAAA,CAAU,CAAA;AAAA,iBAC7C,MAAA,mBAAyB,MAAA,CAAO,SAAS,CAAC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useState } from "./useState.js";
|
|
2
|
+
//#region src/hooks/useRef.ts
|
|
3
|
+
function useRef(initialValue) {
|
|
4
|
+
const [state] = useState(() => ({ current: initialValue }));
|
|
5
|
+
return state;
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { useRef };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=useRef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRef.js","names":[],"sources":["../../src/hooks/useRef.ts"],"sourcesContent":["import { useState } from \"./useState\";\n\nexport namespace useRef {\n export interface RefObject<T> {\n current: T;\n }\n}\n\nexport function useRef<T>(initialValue: T): useRef.RefObject<T>;\nexport function useRef<T = undefined>(): useRef.RefObject<T | undefined>;\nexport function useRef<T>(initialValue?: T): useRef.RefObject<T | undefined> {\n const [state] = useState(() => ({\n current: initialValue,\n }));\n return state;\n}\n"],"mappings":";;AAUA,SAAgB,OAAU,cAAmD;CAC3E,MAAM,CAAC,SAAS,gBAAgB,EAC9B,SAAS,aACX,EAAE;CACF,OAAO;AACT"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ExtractResourceReturnType, ResourceElement } from "../core/types.js";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
3
|
+
//#region src/hooks/useResource.d.ts
|
|
4
4
|
declare function useResource<E extends ResourceElement<any, any>>(element: E): ExtractResourceReturnType<E>;
|
|
5
|
+
declare function useResource<E extends ResourceElement<any, any>>(element: E, propsDeps: readonly unknown[]): ExtractResourceReturnType<E>;
|
|
5
6
|
//#endregion
|
|
6
7
|
export { useResource };
|
|
7
|
-
//# sourceMappingURL=
|
|
8
|
+
//# sourceMappingURL=useResource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResource.d.ts","names":[],"sources":["../../src/hooks/useResource.ts"],"mappings":";;;iBAYgB,WAAA,WAAsB,eAAA,YACpC,OAAA,EAAS,CAAA,GACR,yBAAA,CAA0B,CAAA;AAAA,iBACb,WAAA,WAAsB,eAAA,YACpC,OAAA,EAAS,CAAA,EACT,SAAA,uBACC,yBAAA,CAA0B,CAAA"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getCurrentResourceFiber } from "../core/helpers/execution-context.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { useRef } from "./useRef.js";
|
|
3
|
+
import { useMemo } from "./useMemo.js";
|
|
4
|
+
import { useEffect } from "./useEffect.js";
|
|
5
5
|
import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
|
|
6
|
-
//#region src/hooks/
|
|
7
|
-
function
|
|
6
|
+
//#region src/hooks/useResource.ts
|
|
7
|
+
function useResource(element, propsDeps) {
|
|
8
8
|
const parentFiber = getCurrentResourceFiber();
|
|
9
|
-
const versionRef =
|
|
10
|
-
const fiber =
|
|
9
|
+
const versionRef = useRef(0);
|
|
10
|
+
const fiber = useMemo(() => {
|
|
11
11
|
element.key;
|
|
12
12
|
return createResourceFiber(element.type, parentFiber.root, () => {
|
|
13
13
|
versionRef.current++;
|
|
@@ -18,18 +18,18 @@ function tapResource(element, propsDeps) {
|
|
|
18
18
|
element.key,
|
|
19
19
|
parentFiber
|
|
20
20
|
]);
|
|
21
|
-
const result = propsDeps ?
|
|
21
|
+
const result = propsDeps ? useMemo(() => renderResourceFiber(fiber, element.props), [
|
|
22
22
|
fiber,
|
|
23
23
|
...propsDeps,
|
|
24
24
|
versionRef.current
|
|
25
25
|
]) : renderResourceFiber(fiber, element.props);
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
useEffect(() => () => unmountResourceFiber(fiber), [fiber]);
|
|
27
|
+
useEffect(() => {
|
|
28
28
|
commitResourceFiber(fiber, result);
|
|
29
29
|
}, [fiber, result]);
|
|
30
30
|
return result.output;
|
|
31
31
|
}
|
|
32
32
|
//#endregion
|
|
33
|
-
export {
|
|
33
|
+
export { useResource };
|
|
34
34
|
|
|
35
|
-
//# sourceMappingURL=
|
|
35
|
+
//# sourceMappingURL=useResource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResource.js","names":[],"sources":["../../src/hooks/useResource.ts"],"sourcesContent":["import type { ExtractResourceReturnType, ResourceElement } from \"../core/types\";\nimport { useEffect } from \"./useEffect\";\nimport {\n createResourceFiber,\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { useMemo } from \"./useMemo\";\nimport { useRef } from \"./useRef\";\nimport { getCurrentResourceFiber } from \"../core/helpers/execution-context\";\n\nexport function useResource<E extends ResourceElement<any, any>>(\n element: E,\n): ExtractResourceReturnType<E>;\nexport function useResource<E extends ResourceElement<any, any>>(\n element: E,\n propsDeps: readonly unknown[],\n): ExtractResourceReturnType<E>;\nexport function useResource<E extends ResourceElement<any, any>>(\n element: E,\n propsDeps?: readonly unknown[],\n): ExtractResourceReturnType<E> {\n const parentFiber = getCurrentResourceFiber();\n const versionRef = useRef(0);\n const fiber = useMemo(() => {\n void element.key;\n return createResourceFiber(element.type, parentFiber.root, () => {\n versionRef.current++;\n parentFiber.markDirty?.();\n });\n }, [element.type, element.key, parentFiber]);\n\n const result = propsDeps\n ? // oxlint-disable-next-line react/rules-of-hooks -- propsDeps presence is fixed per call site, so the conditional call order is stable\n useMemo(\n () => renderResourceFiber(fiber, element.props),\n // oxlint-disable-next-line react/exhaustive-deps -- props identity replaced by user-provided deps\n [fiber, ...propsDeps, versionRef.current],\n )\n : renderResourceFiber(fiber, element.props);\n\n useEffect(() => () => unmountResourceFiber(fiber), [fiber]);\n useEffect(() => {\n commitResourceFiber(fiber, result);\n }, [fiber, result]);\n\n return result.output;\n}\n"],"mappings":";;;;;;AAmBA,SAAgB,YACd,SACA,WAC8B;CAC9B,MAAM,cAAc,wBAAwB;CAC5C,MAAM,aAAa,OAAO,CAAC;CAC3B,MAAM,QAAQ,cAAc;EAC1B,QAAa;EACb,OAAO,oBAAoB,QAAQ,MAAM,YAAY,YAAY;GAC/D,WAAW;GACX,YAAY,YAAY;EAC1B,CAAC;CACH,GAAG;EAAC,QAAQ;EAAM,QAAQ;EAAK;CAAW,CAAC;CAE3C,MAAM,SAAS,YAEX,cACQ,oBAAoB,OAAO,QAAQ,KAAK,GAE9C;EAAC;EAAO,GAAG;EAAW,WAAW;CAAO,CAC1C,IACA,oBAAoB,OAAO,QAAQ,KAAK;CAE5C,sBAAsB,qBAAqB,KAAK,GAAG,CAAC,KAAK,CAAC;CAC1D,gBAAgB;EACd,oBAAoB,OAAO,MAAM;CACnC,GAAG,CAAC,OAAO,MAAM,CAAC;CAElB,OAAO,OAAO;AAChB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ResourceElement } from "../core/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/useResourceRoot.d.ts
|
|
4
|
+
declare namespace useResourceRoot {
|
|
5
|
+
type Unsubscribe = () => void;
|
|
6
|
+
interface SubscribableResource<TState> {
|
|
7
|
+
/**
|
|
8
|
+
* Get the current state of the store.
|
|
9
|
+
*/
|
|
10
|
+
getValue(): TState;
|
|
11
|
+
/**
|
|
12
|
+
* Subscribe to the store.
|
|
13
|
+
*/
|
|
14
|
+
subscribe(listener: () => void): Unsubscribe;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
declare const useResourceRoot: <TState>(element: ResourceElement<TState>) => useResourceRoot.SubscribableResource<TState>;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { useResourceRoot };
|
|
20
|
+
//# sourceMappingURL=useResourceRoot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResourceRoot.d.ts","names":[],"sources":["../../src/hooks/useResourceRoot.ts"],"mappings":";;;kBAmBiB,eAAA;EAAA,KACH,WAAA;EAAA,UAEK,oBAAA;IAHa;;;IAO5B,QAAA,IAAY,MAAA;IAJG;;;IASf,SAAA,CAAU,QAAA,eAAuB,WAAW;EAAA;AAAA;AAAA,cAMnC,eAAA,WACX,OAAA,EAAS,eAAA,CAAgB,MAAA,MACxB,eAAA,CAAgB,oBAAA,CAAqB,MAAA"}
|
|
@@ -1,31 +1,35 @@
|
|
|
1
|
-
import { isDevelopment } from "
|
|
2
|
-
import { commitRoot, createResourceFiberRoot, setRootVersion } from "
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const fiber = tapMemo(() => {
|
|
1
|
+
import { isDevelopment } from "../core/helpers/env.js";
|
|
2
|
+
import { commitRoot, createResourceFiberRoot, setRootVersion } from "../core/helpers/root.js";
|
|
3
|
+
import { useRef } from "./useRef.js";
|
|
4
|
+
import { useMemo } from "./useMemo.js";
|
|
5
|
+
import { useEffect } from "./useEffect.js";
|
|
6
|
+
import { useEffectEvent } from "./useEffectEvent.js";
|
|
7
|
+
import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
|
|
8
|
+
import { UpdateScheduler } from "../core/scheduler.js";
|
|
9
|
+
//#region src/hooks/useResourceRoot.ts
|
|
10
|
+
const useResourceRoot = (element) => {
|
|
11
|
+
const scheduler = useMemo(() => new UpdateScheduler(() => handleUpdate(null)), []);
|
|
12
|
+
const queue = useMemo(() => [], []);
|
|
13
|
+
const fiber = useMemo(() => {
|
|
15
14
|
element.key;
|
|
16
15
|
return createResourceFiber(element.type, createResourceFiberRoot((callback) => {
|
|
17
16
|
if (!scheduler.isDirty && !callback()) return;
|
|
18
17
|
queue.push(callback);
|
|
19
18
|
scheduler.markDirty();
|
|
20
19
|
}));
|
|
21
|
-
}, [
|
|
20
|
+
}, [
|
|
21
|
+
element.type,
|
|
22
|
+
element.key,
|
|
23
|
+
queue,
|
|
24
|
+
scheduler
|
|
25
|
+
]);
|
|
22
26
|
setRootVersion(fiber.root, fiber.root.committedVersion);
|
|
23
27
|
const render = renderResourceFiber(fiber, element.props);
|
|
24
|
-
const isMountedRef =
|
|
25
|
-
const committedPropsRef =
|
|
26
|
-
const valueRef =
|
|
27
|
-
const subscribers =
|
|
28
|
-
const handleUpdate =
|
|
28
|
+
const isMountedRef = useRef(false);
|
|
29
|
+
const committedPropsRef = useRef(element.props);
|
|
30
|
+
const valueRef = useRef(render.output);
|
|
31
|
+
const subscribers = useMemo(() => /* @__PURE__ */ new Set(), []);
|
|
32
|
+
const handleUpdate = useEffectEvent((render) => {
|
|
29
33
|
if (render === null) {
|
|
30
34
|
setRootVersion(fiber.root, 2);
|
|
31
35
|
setRootVersion(fiber.root, 1);
|
|
@@ -44,14 +48,14 @@ const tapResourceRoot = (element) => {
|
|
|
44
48
|
valueRef.current = render.output;
|
|
45
49
|
subscribers.forEach((callback) => callback());
|
|
46
50
|
});
|
|
47
|
-
|
|
51
|
+
useEffect(() => {
|
|
48
52
|
isMountedRef.current = true;
|
|
49
53
|
return () => {
|
|
50
54
|
isMountedRef.current = false;
|
|
51
55
|
unmountResourceFiber(fiber);
|
|
52
56
|
};
|
|
53
57
|
}, [fiber]);
|
|
54
|
-
|
|
58
|
+
useEffect(() => {
|
|
55
59
|
committedPropsRef.current = render.props;
|
|
56
60
|
commitRoot(fiber.root);
|
|
57
61
|
commitResourceFiber(fiber, render);
|
|
@@ -59,15 +63,15 @@ const tapResourceRoot = (element) => {
|
|
|
59
63
|
valueRef.current = render.output;
|
|
60
64
|
subscribers.forEach((callback) => callback());
|
|
61
65
|
});
|
|
62
|
-
return
|
|
66
|
+
return useMemo(() => ({
|
|
63
67
|
getValue: () => valueRef.current,
|
|
64
68
|
subscribe: (listener) => {
|
|
65
69
|
subscribers.add(listener);
|
|
66
70
|
return () => subscribers.delete(listener);
|
|
67
71
|
}
|
|
68
|
-
}), []);
|
|
72
|
+
}), [subscribers]);
|
|
69
73
|
};
|
|
70
74
|
//#endregion
|
|
71
|
-
export {
|
|
75
|
+
export { useResourceRoot };
|
|
72
76
|
|
|
73
|
-
//# sourceMappingURL=
|
|
77
|
+
//# sourceMappingURL=useResourceRoot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResourceRoot.js","names":[],"sources":["../../src/hooks/useResourceRoot.ts"],"sourcesContent":["import {\n commitResourceFiber,\n createResourceFiber,\n renderResourceFiber,\n unmountResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { UpdateScheduler } from \"../core/scheduler\";\nimport { useMemo } from \"./useMemo\";\nimport { useEffect } from \"./useEffect\";\nimport { useEffectEvent } from \"./useEffectEvent\";\nimport { useRef } from \"./useRef\";\nimport type { RenderResult, ResourceElement } from \"../core/types\";\nimport { isDevelopment } from \"../core/helpers/env\";\nimport {\n commitRoot,\n createResourceFiberRoot,\n setRootVersion,\n} from \"../core/helpers/root\";\n\nexport namespace useResourceRoot {\n export type Unsubscribe = () => void;\n\n export interface SubscribableResource<TState> {\n /**\n * Get the current state of the store.\n */\n getValue(): TState;\n\n /**\n * Subscribe to the store.\n */\n subscribe(listener: () => void): Unsubscribe;\n }\n}\n\n// The root is never reset, because rollbacks are not supported in useResourceRoot.\n\nexport const useResourceRoot = <TState>(\n element: ResourceElement<TState>,\n): useResourceRoot.SubscribableResource<TState> => {\n const scheduler = useMemo(\n () => new UpdateScheduler(() => handleUpdate(null)),\n [],\n );\n const queue = useMemo(() => [] as (() => void)[], []);\n\n const fiber = useMemo(() => {\n void element.key;\n\n return createResourceFiber(\n element.type,\n createResourceFiberRoot((callback) => {\n if (!scheduler.isDirty && !callback()) return;\n queue.push(callback);\n scheduler.markDirty();\n }),\n );\n }, [element.type, element.key, queue, scheduler]);\n\n setRootVersion(fiber.root, fiber.root.committedVersion);\n const render = renderResourceFiber(fiber, element.props);\n\n const isMountedRef = useRef(false);\n const committedPropsRef = useRef(element.props);\n const valueRef = useRef<TState>(render.output);\n const subscribers = useMemo(() => new Set<() => void>(), []);\n const handleUpdate = useEffectEvent((render: RenderResult | null) => {\n if (render === null) {\n setRootVersion(fiber.root, 2);\n setRootVersion(fiber.root, 1);\n\n queue.forEach((callback) => {\n if (isDevelopment && fiber.devStrictMode) {\n callback();\n }\n\n callback();\n });\n\n if (isDevelopment && fiber.devStrictMode) {\n void renderResourceFiber(fiber, committedPropsRef.current);\n }\n\n render = renderResourceFiber(fiber, committedPropsRef.current);\n }\n\n if (scheduler.isDirty)\n throw new Error(\"Scheduler is dirty, this should never happen\");\n\n commitRoot(fiber.root);\n queue.length = 0;\n\n if (isMountedRef.current) {\n commitResourceFiber(fiber, render);\n }\n\n if (scheduler.isDirty || valueRef.current === render.output) return;\n valueRef.current = render.output;\n subscribers.forEach((callback) => callback());\n });\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n unmountResourceFiber(fiber);\n };\n }, [fiber]);\n\n useEffect(() => {\n committedPropsRef.current = render.props;\n commitRoot(fiber.root);\n commitResourceFiber(fiber, render);\n\n if (scheduler.isDirty || valueRef.current === render.output) return;\n valueRef.current = render.output;\n subscribers.forEach((callback) => callback());\n });\n\n return useMemo(\n () => ({\n getValue: () => valueRef.current,\n subscribe: (listener: () => void) => {\n subscribers.add(listener);\n return () => subscribers.delete(listener);\n },\n }),\n [subscribers],\n );\n};\n"],"mappings":";;;;;;;;;AAqCA,MAAa,mBACX,YACiD;CACjD,MAAM,YAAY,cACV,IAAI,sBAAsB,aAAa,IAAI,CAAC,GAClD,CAAC,CACH;CACA,MAAM,QAAQ,cAAc,CAAC,GAAqB,CAAC,CAAC;CAEpD,MAAM,QAAQ,cAAc;EAC1B,QAAa;EAEb,OAAO,oBACL,QAAQ,MACR,yBAAyB,aAAa;GACpC,IAAI,CAAC,UAAU,WAAW,CAAC,SAAS,GAAG;GACvC,MAAM,KAAK,QAAQ;GACnB,UAAU,UAAU;EACtB,CAAC,CACH;CACF,GAAG;EAAC,QAAQ;EAAM,QAAQ;EAAK;EAAO;CAAS,CAAC;CAEhD,eAAe,MAAM,MAAM,MAAM,KAAK,gBAAgB;CACtD,MAAM,SAAS,oBAAoB,OAAO,QAAQ,KAAK;CAEvD,MAAM,eAAe,OAAO,KAAK;CACjC,MAAM,oBAAoB,OAAO,QAAQ,KAAK;CAC9C,MAAM,WAAW,OAAe,OAAO,MAAM;CAC7C,MAAM,cAAc,8BAAc,IAAI,IAAgB,GAAG,CAAC,CAAC;CAC3D,MAAM,eAAe,gBAAgB,WAAgC;EACnE,IAAI,WAAW,MAAM;GACnB,eAAe,MAAM,MAAM,CAAC;GAC5B,eAAe,MAAM,MAAM,CAAC;GAE5B,MAAM,SAAS,aAAa;IAC1B,IAAI,iBAAiB,MAAM,eACzB,SAAS;IAGX,SAAS;GACX,CAAC;GAED,IAAI,iBAAiB,MAAM,eACzB,oBAAyB,OAAO,kBAAkB,OAAO;GAG3D,SAAS,oBAAoB,OAAO,kBAAkB,OAAO;EAC/D;EAEA,IAAI,UAAU,SACZ,MAAM,IAAI,MAAM,8CAA8C;EAEhE,WAAW,MAAM,IAAI;EACrB,MAAM,SAAS;EAEf,IAAI,aAAa,SACf,oBAAoB,OAAO,MAAM;EAGnC,IAAI,UAAU,WAAW,SAAS,YAAY,OAAO,QAAQ;EAC7D,SAAS,UAAU,OAAO;EAC1B,YAAY,SAAS,aAAa,SAAS,CAAC;CAC9C,CAAC;CAED,gBAAgB;EACd,aAAa,UAAU;EACvB,aAAa;GACX,aAAa,UAAU;GACvB,qBAAqB,KAAK;EAC5B;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,gBAAgB;EACd,kBAAkB,UAAU,OAAO;EACnC,WAAW,MAAM,IAAI;EACrB,oBAAoB,OAAO,MAAM;EAEjC,IAAI,UAAU,WAAW,SAAS,YAAY,OAAO,QAAQ;EAC7D,SAAS,UAAU,OAAO;EAC1B,YAAY,SAAS,aAAa,SAAS,CAAC;CAC9C,CAAC;CAED,OAAO,eACE;EACL,gBAAgB,SAAS;EACzB,YAAY,aAAyB;GACnC,YAAY,IAAI,QAAQ;GACxB,aAAa,YAAY,OAAO,QAAQ;EAC1C;CACF,IACA,CAAC,WAAW,CACd;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ExtractResourceReturnType, ResourceElement } from "../core/types.js";
|
|
2
2
|
|
|
3
|
-
//#region src/hooks/
|
|
4
|
-
declare function
|
|
3
|
+
//#region src/hooks/useResources.d.ts
|
|
4
|
+
declare function useResources<E extends ResourceElement<any, any>>(getElements: () => readonly E[], getElementsDeps?: readonly unknown[]): ExtractResourceReturnType<E>[];
|
|
5
5
|
//#endregion
|
|
6
|
-
export {
|
|
7
|
-
//# sourceMappingURL=
|
|
6
|
+
export { useResources };
|
|
7
|
+
//# sourceMappingURL=useResources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResources.d.ts","names":[],"sources":["../../src/hooks/useResources.ts"],"mappings":";;;iBA0BgB,YAAA,WAAuB,eAAA,YACrC,WAAA,iBAA4B,CAAA,IAC5B,eAAA,wBACC,yBAAA,CAA0B,CAAA"}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { getCurrentResourceFiber } from "../core/helpers/execution-context.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { tapCallback } from "./tap-callback.js";
|
|
2
|
+
import { useRef } from "./useRef.js";
|
|
3
|
+
import { useMemo } from "./useMemo.js";
|
|
4
|
+
import { useCallback } from "./useCallback.js";
|
|
5
|
+
import { useEffect } from "./useEffect.js";
|
|
7
6
|
import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
|
|
8
|
-
//#region src/hooks/
|
|
9
|
-
function
|
|
10
|
-
const versionRef =
|
|
7
|
+
//#region src/hooks/useResources.ts
|
|
8
|
+
function useResources(getElements, getElementsDeps) {
|
|
9
|
+
const versionRef = useRef(0);
|
|
11
10
|
const version = versionRef.current;
|
|
12
|
-
const parentFiber =
|
|
13
|
-
const markDirty =
|
|
11
|
+
const parentFiber = useMemo(() => getCurrentResourceFiber(), []);
|
|
12
|
+
const markDirty = useMemo(() => () => {
|
|
14
13
|
versionRef.current++;
|
|
15
14
|
parentFiber.markDirty?.();
|
|
16
|
-
}, []);
|
|
17
|
-
const fibers =
|
|
18
|
-
const getElementsMemo = getElementsDeps ?
|
|
19
|
-
const res =
|
|
15
|
+
}, [parentFiber]);
|
|
16
|
+
const fibers = useMemo(() => /* @__PURE__ */ new Map(), []);
|
|
17
|
+
const getElementsMemo = getElementsDeps ? useCallback(getElements, getElementsDeps) : getElements;
|
|
18
|
+
const res = useMemo(() => {
|
|
20
19
|
const elementsArray = getElementsMemo();
|
|
21
20
|
const seenKeys = /* @__PURE__ */ new Set();
|
|
22
21
|
const results = [];
|
|
@@ -24,8 +23,8 @@ function tapResources(getElements, getElementsDeps) {
|
|
|
24
23
|
for (let i = 0; i < elementsArray.length; i++) {
|
|
25
24
|
const element = elementsArray[i];
|
|
26
25
|
const elementKey = element.key;
|
|
27
|
-
if (elementKey === void 0) throw new Error(`
|
|
28
|
-
if (seenKeys.has(elementKey)) throw new Error(`Duplicate key ${elementKey} in
|
|
26
|
+
if (elementKey === void 0) throw new Error(`useResources did not provide a key for array at index ${i}`);
|
|
27
|
+
if (seenKeys.has(elementKey)) throw new Error(`Duplicate key ${elementKey} in useResources`);
|
|
29
28
|
seenKeys.add(elementKey);
|
|
30
29
|
let state = fibers.get(elementKey);
|
|
31
30
|
if (!state) {
|
|
@@ -52,16 +51,22 @@ function tapResources(getElements, getElementsDeps) {
|
|
|
52
51
|
for (const key of fibers.keys()) if (!seenKeys.has(key)) fibers.get(key).next = "delete";
|
|
53
52
|
}
|
|
54
53
|
return results;
|
|
55
|
-
}, [
|
|
56
|
-
|
|
54
|
+
}, [
|
|
55
|
+
getElementsMemo,
|
|
56
|
+
version,
|
|
57
|
+
parentFiber,
|
|
58
|
+
markDirty,
|
|
59
|
+
fibers
|
|
60
|
+
]);
|
|
61
|
+
useEffect(() => {
|
|
57
62
|
return () => {
|
|
58
63
|
for (const key of fibers.keys()) {
|
|
59
64
|
const fiber = fibers.get(key).fiber;
|
|
60
65
|
unmountResourceFiber(fiber);
|
|
61
66
|
}
|
|
62
67
|
};
|
|
63
|
-
}, []);
|
|
64
|
-
|
|
68
|
+
}, [fibers]);
|
|
69
|
+
useEffect(() => {
|
|
65
70
|
for (const [key, state] of fibers.entries()) if (state.next === "delete") {
|
|
66
71
|
if (state.fiber.isMounted) unmountResourceFiber(state.fiber);
|
|
67
72
|
fibers.delete(key);
|
|
@@ -70,10 +75,10 @@ function tapResources(getElements, getElementsDeps) {
|
|
|
70
75
|
state.fiber = state.next[0];
|
|
71
76
|
commitResourceFiber(state.fiber, state.next[1]);
|
|
72
77
|
} else commitResourceFiber(state.fiber, state.next);
|
|
73
|
-
}, [res]);
|
|
78
|
+
}, [res, fibers]);
|
|
74
79
|
return res;
|
|
75
80
|
}
|
|
76
81
|
//#endregion
|
|
77
|
-
export {
|
|
82
|
+
export { useResources };
|
|
78
83
|
|
|
79
|
-
//# sourceMappingURL=
|
|
84
|
+
//# sourceMappingURL=useResources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResources.js","names":[],"sources":["../../src/hooks/useResources.ts"],"sourcesContent":["import type {\n ExtractResourceReturnType,\n RenderResult,\n ResourceElement,\n ResourceFiber,\n} from \"../core/types\";\nimport { useEffect } from \"./useEffect\";\nimport { useMemo } from \"./useMemo\";\nimport { useCallback } from \"./useCallback\";\nimport {\n createResourceFiber,\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { useRef } from \"./useRef\";\nimport { getCurrentResourceFiber } from \"../core/helpers/execution-context\";\n\ntype FiberState = {\n fiber: ResourceFiber<unknown, unknown>;\n next:\n | RenderResult\n | [ResourceFiber<unknown, unknown>, RenderResult]\n | \"delete\";\n};\n\nexport function useResources<E extends ResourceElement<any, any>>(\n getElements: () => readonly E[],\n getElementsDeps?: readonly unknown[],\n): ExtractResourceReturnType<E>[] {\n const versionRef = useRef(0);\n const version = versionRef.current;\n\n const parentFiber = useMemo(() => getCurrentResourceFiber(), []);\n const markDirty = useMemo(\n () => () => {\n versionRef.current++;\n parentFiber.markDirty?.();\n },\n [parentFiber],\n );\n const fibers = useMemo(() => new Map<string | number, FiberState>(), []);\n\n const getElementsMemo = getElementsDeps\n ? // oxlint-disable-next-line react/exhaustive-deps,react/rules-of-hooks -- deps forwarded by caller; getElementsDeps presence is fixed per call site\n useCallback(getElements, getElementsDeps)\n : getElements;\n\n // Process each element\n\n const res = useMemo(() => {\n void version;\n\n const elementsArray = getElementsMemo();\n const seenKeys = new Set<string | number>();\n const results: any[] = [];\n let newCount = 0;\n\n // Create/update fibers and render\n for (let i = 0; i < elementsArray.length; i++) {\n const element = elementsArray[i]!;\n\n const elementKey = element.key;\n if (elementKey === undefined) {\n throw new Error(\n `useResources did not provide a key for array at index ${i}`,\n );\n }\n\n if (seenKeys.has(elementKey))\n throw new Error(`Duplicate key ${elementKey} in useResources`);\n seenKeys.add(elementKey);\n\n let state = fibers.get(elementKey);\n if (!state) {\n const fiber = createResourceFiber(\n element.type,\n parentFiber.root,\n markDirty,\n );\n const result = renderResourceFiber(fiber, element.props);\n state = {\n fiber,\n next: result,\n };\n newCount++;\n fibers.set(elementKey, state);\n results.push(result.output);\n } else if (state.fiber.type !== element.type) {\n const fiber = createResourceFiber(\n element.type,\n parentFiber.root,\n markDirty,\n );\n const result = renderResourceFiber(fiber, element.props);\n state.next = [fiber, result];\n results.push(result.output);\n } else {\n state.next = renderResourceFiber(state.fiber, element.props);\n results.push(state.next.output);\n }\n }\n\n // Clean up removed fibers (only if there might be stale ones)\n if (fibers.size > results.length - newCount) {\n for (const key of fibers.keys()) {\n if (!seenKeys.has(key)) {\n fibers.get(key)!.next = \"delete\";\n }\n }\n }\n\n return results;\n }, [getElementsMemo, version, parentFiber, markDirty, fibers]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n for (const key of fibers.keys()) {\n const fiber = fibers.get(key)!.fiber;\n unmountResourceFiber(fiber);\n }\n };\n }, [fibers]);\n\n useEffect(() => {\n void res; // as a performance optimization, we only run if the results have changed\n\n for (const [key, state] of fibers.entries()) {\n if (state.next === \"delete\") {\n if (state.fiber.isMounted) {\n unmountResourceFiber(state.fiber);\n }\n\n fibers.delete(key);\n } else if (Array.isArray(state.next)) {\n unmountResourceFiber(state.fiber);\n state.fiber = state.next[0];\n commitResourceFiber(state.fiber, state.next[1]);\n } else {\n commitResourceFiber(state.fiber, state.next);\n }\n }\n }, [res, fibers]);\n\n return res;\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,aACd,aACA,iBACgC;CAChC,MAAM,aAAa,OAAO,CAAC;CAC3B,MAAM,UAAU,WAAW;CAE3B,MAAM,cAAc,cAAc,wBAAwB,GAAG,CAAC,CAAC;CAC/D,MAAM,YAAY,oBACJ;EACV,WAAW;EACX,YAAY,YAAY;CAC1B,GACA,CAAC,WAAW,CACd;CACA,MAAM,SAAS,8BAAc,IAAI,IAAiC,GAAG,CAAC,CAAC;CAEvE,MAAM,kBAAkB,kBAEpB,YAAY,aAAa,eAAe,IACxC;CAIJ,MAAM,MAAM,cAAc;EAGxB,MAAM,gBAAgB,gBAAgB;EACtC,MAAM,2BAAW,IAAI,IAAqB;EAC1C,MAAM,UAAiB,CAAC;EACxB,IAAI,WAAW;EAGf,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,UAAU,cAAc;GAE9B,MAAM,aAAa,QAAQ;GAC3B,IAAI,eAAe,KAAA,GACjB,MAAM,IAAI,MACR,yDAAyD,GAC3D;GAGF,IAAI,SAAS,IAAI,UAAU,GACzB,MAAM,IAAI,MAAM,iBAAiB,WAAW,iBAAiB;GAC/D,SAAS,IAAI,UAAU;GAEvB,IAAI,QAAQ,OAAO,IAAI,UAAU;GACjC,IAAI,CAAC,OAAO;IACV,MAAM,QAAQ,oBACZ,QAAQ,MACR,YAAY,MACZ,SACF;IACA,MAAM,SAAS,oBAAoB,OAAO,QAAQ,KAAK;IACvD,QAAQ;KACN;KACA,MAAM;IACR;IACA;IACA,OAAO,IAAI,YAAY,KAAK;IAC5B,QAAQ,KAAK,OAAO,MAAM;GAC5B,OAAO,IAAI,MAAM,MAAM,SAAS,QAAQ,MAAM;IAC5C,MAAM,QAAQ,oBACZ,QAAQ,MACR,YAAY,MACZ,SACF;IACA,MAAM,SAAS,oBAAoB,OAAO,QAAQ,KAAK;IACvD,MAAM,OAAO,CAAC,OAAO,MAAM;IAC3B,QAAQ,KAAK,OAAO,MAAM;GAC5B,OAAO;IACL,MAAM,OAAO,oBAAoB,MAAM,OAAO,QAAQ,KAAK;IAC3D,QAAQ,KAAK,MAAM,KAAK,MAAM;GAChC;EACF;EAGA,IAAI,OAAO,OAAO,QAAQ,SAAS;QAC5B,MAAM,OAAO,OAAO,KAAK,GAC5B,IAAI,CAAC,SAAS,IAAI,GAAG,GACnB,OAAO,IAAI,GAAG,CAAC,CAAE,OAAO;EAAA;EAK9B,OAAO;CACT,GAAG;EAAC;EAAiB;EAAS;EAAa;EAAW;CAAM,CAAC;CAG7D,gBAAgB;EACd,aAAa;GACX,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG;IAC/B,MAAM,QAAQ,OAAO,IAAI,GAAG,CAAC,CAAE;IAC/B,qBAAqB,KAAK;GAC5B;EACF;CACF,GAAG,CAAC,MAAM,CAAC;CAEX,gBAAgB;EAGd,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,GACxC,IAAI,MAAM,SAAS,UAAU;GAC3B,IAAI,MAAM,MAAM,WACd,qBAAqB,MAAM,KAAK;GAGlC,OAAO,OAAO,GAAG;EACnB,OAAO,IAAI,MAAM,QAAQ,MAAM,IAAI,GAAG;GACpC,qBAAqB,MAAM,KAAK;GAChC,MAAM,QAAQ,MAAM,KAAK;GACzB,oBAAoB,MAAM,OAAO,MAAM,KAAK,EAAE;EAChD,OACE,oBAAoB,MAAM,OAAO,MAAM,IAAI;CAGjD,GAAG,CAAC,KAAK,MAAM,CAAC;CAEhB,OAAO;AACT"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/hooks/useState.d.ts
|
|
2
|
+
declare namespace useState {
|
|
3
|
+
type StateUpdater<S> = S | ((prev: S) => S);
|
|
4
|
+
}
|
|
5
|
+
declare function useState<S = undefined>(): [S | undefined, (updater: useState.StateUpdater<S>) => void];
|
|
6
|
+
declare function useState<S>(initial: S | (() => S)): [S, (updater: useState.StateUpdater<S>) => void];
|
|
7
|
+
//#endregion
|
|
8
|
+
export { useState };
|
|
9
|
+
//# sourceMappingURL=useState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useState.d.ts","names":[],"sources":["../../src/hooks/useState.ts"],"mappings":";kBAEiB,QAAA;EAAA,KACH,YAAA,MAAkB,CAAA,KAAM,IAAA,EAAM,CAAA,KAAM,CAAA;AAAA;AAAA,iBAclC,QAAA,oBACd,CAAA,eACC,OAAA,EAAS,QAAA,CAAS,YAAA,CAAa,CAAA;AAAA,iBAElB,QAAA,IACd,OAAA,EAAS,CAAA,UAAW,CAAA,KAClB,CAAA,GAAI,OAAA,EAAS,QAAA,CAAS,YAAA,CAAa,CAAA"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useReducer } from "./useReducer.js";
|
|
2
|
+
//#region src/hooks/useState.ts
|
|
3
|
+
const stateReducer = (state, action) => typeof action === "function" ? action(state) : action;
|
|
4
|
+
const stateInit = (initial) => typeof initial === "function" ? initial() : initial;
|
|
5
|
+
function useState(initial) {
|
|
6
|
+
return useReducer(stateReducer, initial, stateInit);
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { useState };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=useState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useState.js","names":[],"sources":["../../src/hooks/useState.ts"],"sourcesContent":["import { useReducer } from \"./useReducer\";\n\nexport namespace useState {\n export type StateUpdater<S> = S | ((prev: S) => S);\n}\n\nconst stateReducer = <S>(\n state: S | undefined,\n action: useState.StateUpdater<S>,\n): S =>\n typeof action === \"function\"\n ? (action as (prev: S | undefined) => S)(state)\n : action;\n\nconst stateInit = <S>(initial: S | (() => S)): S =>\n typeof initial === \"function\" ? (initial as () => S)() : initial;\n\nexport function useState<S = undefined>(): [\n S | undefined,\n (updater: useState.StateUpdater<S>) => void,\n];\nexport function useState<S>(\n initial: S | (() => S),\n): [S, (updater: useState.StateUpdater<S>) => void];\nexport function useState<S>(\n initial?: S | (() => S),\n): [S | undefined, (updater: useState.StateUpdater<S>) => void] {\n return useReducer(stateReducer, initial, stateInit);\n}\n"],"mappings":";;AAMA,MAAM,gBACJ,OACA,WAEA,OAAO,WAAW,aACb,OAAsC,KAAK,IAC5C;AAEN,MAAM,aAAgB,YACpB,OAAO,YAAY,aAAc,QAAoB,IAAI;AAS3D,SAAgB,SACd,SAC8D;CAC9D,OAAO,WAAW,cAAc,SAAS,SAAS;AACpD"}
|