@assistant-ui/tap 0.6.0 → 0.7.1
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 -6
- package/dist/core/ResourceFiber.d.ts +5 -5
- package/dist/core/ResourceFiber.d.ts.map +1 -1
- package/dist/core/ResourceFiber.js +26 -18
- package/dist/core/ResourceFiber.js.map +1 -1
- package/dist/core/createTapRoot.d.ts +9 -0
- package/dist/core/createTapRoot.d.ts.map +1 -0
- package/dist/core/createTapRoot.js +27 -0
- package/dist/core/createTapRoot.js.map +1 -0
- package/dist/core/helpers/commit.d.ts +1 -1
- package/dist/core/helpers/commit.d.ts.map +1 -1
- package/dist/core/helpers/commit.js +6 -1
- package/dist/core/helpers/commit.js.map +1 -1
- package/dist/core/helpers/execution-context.d.ts +4 -5
- package/dist/core/helpers/execution-context.d.ts.map +1 -1
- package/dist/core/helpers/execution-context.js +1 -7
- package/dist/core/helpers/execution-context.js.map +1 -1
- package/dist/core/helpers/root.d.ts +3 -2
- package/dist/core/helpers/root.d.ts.map +1 -1
- package/dist/core/helpers/root.js +19 -15
- package/dist/core/helpers/root.js.map +1 -1
- package/dist/core/react-dispatcher.d.ts.map +1 -1
- package/dist/core/react-dispatcher.js +17 -16
- package/dist/core/react-dispatcher.js.map +1 -1
- package/dist/core/resource.d.ts +2 -4
- package/dist/core/resource.d.ts.map +1 -1
- package/dist/core/resource.js +5 -10
- package/dist/core/resource.js.map +1 -1
- package/dist/core/scheduler.d.ts +2 -2
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +2 -2
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/types.d.ts +27 -25
- package/dist/core/types.d.ts.map +1 -1
- package/dist/hooks/useResource.d.ts +2 -2
- package/dist/hooks/useResource.d.ts.map +1 -1
- package/dist/hooks/useResource.js +14 -20
- package/dist/hooks/useResource.js.map +1 -1
- package/dist/hooks/useResources.d.ts +1 -1
- package/dist/hooks/useResources.d.ts.map +1 -1
- package/dist/hooks/useResources.js +18 -27
- package/dist/hooks/useResources.js.map +1 -1
- package/dist/hooks/useTapHost.d.ts +21 -0
- package/dist/hooks/useTapHost.d.ts.map +1 -0
- package/dist/hooks/useTapHost.js +30 -0
- package/dist/hooks/useTapHost.js.map +1 -0
- package/dist/hooks/useTapRoot.d.ts +18 -0
- package/dist/hooks/useTapRoot.d.ts.map +1 -0
- package/dist/hooks/useTapRoot.js +77 -0
- package/dist/hooks/useTapRoot.js.map +1 -0
- package/dist/hooks/utils/depsShallowEqual.d.ts.map +1 -1
- package/dist/hooks/utils/depsShallowEqual.js +5 -2
- package/dist/hooks/utils/depsShallowEqual.js.map +1 -1
- package/dist/hooks/utils/useCell.d.ts +2 -2
- package/dist/hooks/utils/useCell.d.ts.map +1 -1
- package/dist/hooks/utils/useCell.js.map +1 -1
- package/dist/hooks/utils/useDevStrictMode.d.ts +5 -0
- package/dist/hooks/utils/useDevStrictMode.d.ts.map +1 -0
- package/dist/hooks/utils/useDevStrictMode.js +25 -0
- package/dist/hooks/utils/useDevStrictMode.js.map +1 -0
- package/dist/hooks/utils/useRenderMemo.d.ts +5 -0
- package/dist/hooks/utils/useRenderMemo.d.ts.map +1 -0
- package/dist/hooks/utils/useRenderMemo.js +25 -0
- package/dist/hooks/utils/useRenderMemo.js.map +1 -0
- package/dist/hooks/utils/useResourceFiberHostUtils.d.ts +10 -0
- package/dist/hooks/utils/useResourceFiberHostUtils.d.ts.map +1 -0
- package/dist/hooks/utils/useResourceFiberHostUtils.js +46 -0
- package/dist/hooks/utils/useResourceFiberHostUtils.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.js +7 -4
- package/dist/{hooks → react-hooks}/index.d.ts +6 -6
- package/dist/{hooks → react-hooks}/index.js +5 -5
- package/dist/{hooks → react-hooks}/use.d.ts +1 -1
- package/dist/{hooks → react-hooks}/use.d.ts.map +1 -1
- package/dist/{hooks → react-hooks}/use.js +1 -1
- package/dist/react-hooks/use.js.map +1 -0
- package/dist/{hooks → react-hooks}/useCallback.d.ts +1 -1
- package/dist/react-hooks/useCallback.d.ts.map +1 -0
- package/dist/{hooks → react-hooks}/useCallback.js +1 -1
- package/dist/react-hooks/useCallback.js.map +1 -0
- package/dist/{hooks → react-hooks}/useEffect.d.ts +1 -1
- package/dist/react-hooks/useEffect.d.ts.map +1 -0
- package/dist/react-hooks/useEffect.js +35 -0
- package/dist/react-hooks/useEffect.js.map +1 -0
- package/dist/{hooks → react-hooks}/useEffectEvent.d.ts +1 -1
- package/dist/react-hooks/useEffectEvent.d.ts.map +1 -0
- package/dist/{hooks → react-hooks}/useEffectEvent.js +2 -2
- package/dist/react-hooks/useEffectEvent.js.map +1 -0
- package/dist/{hooks → react-hooks}/useMemo.d.ts +1 -1
- package/dist/react-hooks/useMemo.d.ts.map +1 -0
- package/dist/{hooks → react-hooks}/useMemo.js +3 -3
- package/dist/react-hooks/useMemo.js.map +1 -0
- package/dist/{hooks → react-hooks}/useMemoCache.d.ts +1 -1
- package/dist/react-hooks/useMemoCache.d.ts.map +1 -0
- package/dist/{hooks → react-hooks}/useMemoCache.js +1 -1
- package/dist/react-hooks/useMemoCache.js.map +1 -0
- package/dist/react-hooks/useReducer.d.ts +9 -0
- package/dist/react-hooks/useReducer.d.ts.map +1 -0
- package/dist/react-hooks/useReducer.js +120 -0
- package/dist/react-hooks/useReducer.js.map +1 -0
- package/dist/{hooks → react-hooks}/useRef.d.ts +1 -1
- package/dist/react-hooks/useRef.d.ts.map +1 -0
- package/dist/{hooks → react-hooks}/useRef.js +1 -1
- package/dist/react-hooks/useRef.js.map +1 -0
- package/dist/{hooks → react-hooks}/useState.d.ts +1 -1
- package/dist/react-hooks/useState.d.ts.map +1 -0
- package/dist/{hooks → react-hooks}/useState.js +3 -3
- package/dist/react-hooks/useState.js.map +1 -0
- package/dist/react-shim/index.d.ts +8 -10
- package/dist/react-shim/index.d.ts.map +1 -1
- package/dist/react-shim/index.js +19 -19
- package/dist/react-shim/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/basic/resourceHandle.test.ts +32 -22
- package/src/__tests__/basic/tapEffect.basic.test.ts +8 -8
- package/src/__tests__/basic/tapReducer.basic.test.ts +16 -14
- package/src/__tests__/basic/tapResources.basic.test.ts +19 -16
- package/src/__tests__/basic/tapState.basic.test.ts +11 -11
- package/src/__tests__/bench/hosts.bench.tsx +124 -0
- package/src/__tests__/bench/tree.bench.tsx +166 -0
- package/src/__tests__/errors/errors.effect-errors.test.ts +12 -13
- package/src/__tests__/errors/errors.render-errors.test.ts +65 -22
- package/src/__tests__/lifecycle/lifecycle.dependencies.test.ts +19 -19
- package/src/__tests__/lifecycle/lifecycle.mount-unmount.test.ts +14 -14
- package/src/__tests__/parity/describeParity.tsx +217 -0
- package/src/__tests__/parity/parity.adversarial.test.tsx +375 -0
- package/src/__tests__/parity/parity.basics.test.tsx +281 -0
- package/src/__tests__/parity/parity.divergences.test.tsx +208 -0
- package/src/__tests__/parity/parity.smoke.test.tsx +43 -0
- package/src/__tests__/react/concurrent-mode.test.tsx +10 -6
- package/src/__tests__/react/concurrent-pending-updates.test.tsx +351 -0
- package/src/__tests__/react/concurrent-render-phase.test.tsx +350 -0
- package/src/__tests__/react/react-shim.test.tsx +1 -1
- package/src/__tests__/react/useResource.test.tsx +41 -26
- package/src/__tests__/react/useTapHost.test.tsx +233 -0
- package/src/__tests__/react-dispatcher.test.ts +4 -4
- package/src/__tests__/rules/rules.hook-count.test.ts +21 -21
- package/src/__tests__/rules/rules.hook-order.test.ts +17 -17
- package/src/__tests__/strictmode/strictmode-parity.test.tsx +420 -0
- package/src/__tests__/strictmode/strictmode.test.ts +39 -209
- package/src/__tests__/test-utils.ts +33 -23
- package/src/core/ResourceFiber.ts +43 -35
- package/src/core/createTapRoot.ts +45 -0
- package/src/core/helpers/commit.ts +12 -2
- package/src/core/helpers/execution-context.ts +4 -13
- package/src/core/helpers/root.ts +24 -12
- package/src/core/react-dispatcher.ts +14 -13
- package/src/core/resource.ts +5 -20
- package/src/core/scheduler.ts +1 -1
- package/src/core/types.ts +27 -21
- package/src/hooks/useResource.ts +18 -27
- package/src/hooks/useResources.ts +18 -42
- package/src/hooks/useTapHost.ts +60 -0
- package/src/hooks/useTapRoot.ts +135 -0
- package/src/hooks/utils/depsShallowEqual.ts +12 -2
- package/src/hooks/utils/useCell.ts +2 -2
- package/src/hooks/utils/useDevStrictMode.ts +34 -0
- package/src/hooks/utils/useRenderMemo.ts +27 -0
- package/src/hooks/utils/useResourceFiberHostUtils.ts +61 -0
- package/src/index.ts +6 -3
- package/src/{hooks → react-hooks}/index.ts +4 -4
- package/src/react-hooks/useEffect.ts +58 -0
- package/src/{hooks → react-hooks}/useMemo.ts +1 -1
- package/src/react-hooks/useReducer.ts +254 -0
- package/src/{hooks → react-hooks}/useState.ts +2 -2
- package/src/react-shim/index.ts +24 -13
- package/dist/core/createResourceRoot.d.ts +0 -11
- package/dist/core/createResourceRoot.d.ts.map +0 -1
- package/dist/core/createResourceRoot.js +0 -31
- package/dist/core/createResourceRoot.js.map +0 -1
- package/dist/core/helpers/callResourceFn.d.ts +0 -1
- package/dist/core/helpers/callResourceFn.js +0 -19
- package/dist/core/helpers/callResourceFn.js.map +0 -1
- package/dist/hooks/use.js.map +0 -1
- package/dist/hooks/useCallback.d.ts.map +0 -1
- package/dist/hooks/useCallback.js.map +0 -1
- package/dist/hooks/useEffect.d.ts.map +0 -1
- package/dist/hooks/useEffect.js +0 -40
- package/dist/hooks/useEffect.js.map +0 -1
- package/dist/hooks/useEffectEvent.d.ts.map +0 -1
- package/dist/hooks/useEffectEvent.js.map +0 -1
- package/dist/hooks/useMemo.d.ts.map +0 -1
- package/dist/hooks/useMemo.js.map +0 -1
- package/dist/hooks/useMemoCache.d.ts.map +0 -1
- package/dist/hooks/useMemoCache.js.map +0 -1
- package/dist/hooks/useReducer.d.ts +0 -21
- package/dist/hooks/useReducer.d.ts.map +0 -1
- package/dist/hooks/useReducer.js +0 -81
- package/dist/hooks/useReducer.js.map +0 -1
- package/dist/hooks/useRef.d.ts.map +0 -1
- package/dist/hooks/useRef.js.map +0 -1
- package/dist/hooks/useResourceRoot.d.ts +0 -20
- package/dist/hooks/useResourceRoot.d.ts.map +0 -1
- package/dist/hooks/useResourceRoot.js +0 -77
- package/dist/hooks/useResourceRoot.js.map +0 -1
- package/dist/hooks/useState.d.ts.map +0 -1
- package/dist/hooks/useState.js.map +0 -1
- package/dist/react/hooks.d.ts +0 -25
- package/dist/react/hooks.d.ts.map +0 -1
- package/dist/react/hooks.js +0 -69
- package/dist/react/hooks.js.map +0 -1
- package/src/__tests__/strictmode/react-strictmode-behavior.test.tsx +0 -920
- package/src/__tests__/strictmode/react-strictmode-rerender-sources.test.tsx +0 -488
- package/src/__tests__/strictmode/tap-strictmode-rerender-sources.test.ts +0 -687
- package/src/core/createResourceRoot.ts +0 -53
- package/src/core/helpers/callResourceFn.ts +0 -21
- package/src/hooks/useEffect.ts +0 -72
- package/src/hooks/useReducer.ts +0 -160
- package/src/hooks/useResourceRoot.ts +0 -130
- package/src/react/hooks.ts +0 -112
- /package/src/{hooks → react-hooks}/use.ts +0 -0
- /package/src/{hooks → react-hooks}/useCallback.ts +0 -0
- /package/src/{hooks → react-hooks}/useEffectEvent.ts +0 -0
- /package/src/{hooks → react-hooks}/useMemoCache.ts +0 -0
- /package/src/{hooks → react-hooks}/useRef.ts +0 -0
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import { isDevelopment } from "../../core/helpers/env";
|
|
2
|
+
|
|
1
3
|
export const depsShallowEqual = (
|
|
2
4
|
a: readonly unknown[],
|
|
3
5
|
b: readonly unknown[],
|
|
4
6
|
) => {
|
|
5
|
-
if (a.length !== b.length)
|
|
6
|
-
|
|
7
|
+
if (isDevelopment && a.length !== b.length) {
|
|
8
|
+
console.error(
|
|
9
|
+
"The final argument passed to a hook changed size between renders. " +
|
|
10
|
+
"The order and size of this array must remain constant.\n\n" +
|
|
11
|
+
`Previous: [${a.join(", ")}]\n` +
|
|
12
|
+
`Incoming: [${b.join(", ")}]`,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
for (let i = 0; i < a.length && i < b.length; i++) {
|
|
7
17
|
if (!Object.is(a[i], b[i])) return false;
|
|
8
18
|
}
|
|
9
19
|
return true;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getCurrentResourceFiber } from "../../core/helpers/execution-context";
|
|
2
|
-
import type { Cell } from "../../core/types";
|
|
2
|
+
import type { Cell, EffectTask } from "../../core/types";
|
|
3
3
|
|
|
4
4
|
export const useCell = <T extends Cell["type"]>(
|
|
5
5
|
type: T,
|
|
@@ -29,7 +29,7 @@ export const useCell = <T extends Cell["type"]>(
|
|
|
29
29
|
return cell as Cell & { type: T };
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
export const registerRenderMountTask = (task:
|
|
32
|
+
export const registerRenderMountTask = (task: EffectTask) => {
|
|
33
33
|
const fiber = getCurrentResourceFiber();
|
|
34
34
|
fiber.renderContext!.effectTasks.push(task);
|
|
35
35
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
import { isDevelopment } from "../../core/helpers/env";
|
|
3
|
+
import {
|
|
4
|
+
getCurrentResourceFiber,
|
|
5
|
+
peekResourceFiber,
|
|
6
|
+
} from "../../core/helpers/execution-context";
|
|
7
|
+
|
|
8
|
+
const getTapDevMode = () => {
|
|
9
|
+
const currentResourceFiber = getCurrentResourceFiber();
|
|
10
|
+
if (currentResourceFiber.devStrictMode)
|
|
11
|
+
return currentResourceFiber.isFirstRender
|
|
12
|
+
? ("child" as const)
|
|
13
|
+
: ("root" as const);
|
|
14
|
+
return null;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const child = () => "child" as const;
|
|
18
|
+
const notDevMode = () => null;
|
|
19
|
+
|
|
20
|
+
const useDevStrictModeReact = () => {
|
|
21
|
+
if (!isDevelopment) return notDevMode;
|
|
22
|
+
|
|
23
|
+
// oxlint-disable-next-line react/rules-of-hooks -- isDevelopment is a build-time constant, so this branch is stable per build
|
|
24
|
+
const count = useRef(0);
|
|
25
|
+
// oxlint-disable-next-line react/rules-of-hooks -- isDevelopment is a build-time constant, so this branch is stable per build
|
|
26
|
+
useState(() => count.current++);
|
|
27
|
+
if (count.current !== 2) return notDevMode;
|
|
28
|
+
return child;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const useDevStrictMode = () => {
|
|
32
|
+
// oxlint-disable-next-line react-hooks/rules-of-hooks
|
|
33
|
+
return peekResourceFiber() ? getTapDevMode : useDevStrictModeReact();
|
|
34
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { depsShallowEqual } from "./depsShallowEqual";
|
|
3
|
+
|
|
4
|
+
export const useRenderMemo = <T>(callback: () => T, deps: unknown[]) => {
|
|
5
|
+
const [state] = useState(() => ({
|
|
6
|
+
wipDeps: null as unknown[] | null,
|
|
7
|
+
wip: null as T,
|
|
8
|
+
currentDeps: null as unknown[] | null,
|
|
9
|
+
current: null as T,
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
state.wipDeps = state.currentDeps;
|
|
13
|
+
state.wip = state.current;
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
state.currentDeps = state.wipDeps;
|
|
17
|
+
state.current = state.wip;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (state.currentDeps && depsShallowEqual(state.currentDeps, deps))
|
|
21
|
+
return state.current;
|
|
22
|
+
|
|
23
|
+
state.wipDeps = deps;
|
|
24
|
+
state.wip = callback();
|
|
25
|
+
|
|
26
|
+
return state.wip;
|
|
27
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useRef, useMemo, useReducer, useCallback } from "react";
|
|
2
|
+
import {
|
|
3
|
+
getCurrentResourceFiber,
|
|
4
|
+
peekResourceFiber,
|
|
5
|
+
} from "../../core/helpers/execution-context";
|
|
6
|
+
import {
|
|
7
|
+
createResourceFiberRoot,
|
|
8
|
+
setRootVersion,
|
|
9
|
+
} from "../../core/helpers/root";
|
|
10
|
+
import { createResourceFiber } from "../../core/ResourceFiber";
|
|
11
|
+
import type { ResourceFiberRoot } from "../../core/types";
|
|
12
|
+
import { useDevStrictMode } from "./useDevStrictMode";
|
|
13
|
+
|
|
14
|
+
const useResourceFiberHostUtilsTap = () => {
|
|
15
|
+
const versionRef = useRef(0);
|
|
16
|
+
const version = versionRef.current;
|
|
17
|
+
const parent = getCurrentResourceFiber();
|
|
18
|
+
const markDirty = useMemo(
|
|
19
|
+
() => () => {
|
|
20
|
+
versionRef.current++;
|
|
21
|
+
parent?.markDirty?.();
|
|
22
|
+
},
|
|
23
|
+
[parent],
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return { version, markDirty, root: parent.root };
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const useResourceFiberHostUtilsReact = () => {
|
|
30
|
+
const root = useMemo<ResourceFiberRoot>(() => {
|
|
31
|
+
return createResourceFiberRoot((cb) => dispatch(cb));
|
|
32
|
+
}, []);
|
|
33
|
+
|
|
34
|
+
const [version, dispatch] = useReducer((v: number, cb: () => boolean) => {
|
|
35
|
+
setRootVersion(root!, v);
|
|
36
|
+
return v + (cb() ? 1 : 0);
|
|
37
|
+
}, 0);
|
|
38
|
+
setRootVersion(root, version);
|
|
39
|
+
|
|
40
|
+
return { root, version, markDirty: undefined };
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const useResourceFiberHost = () => {
|
|
44
|
+
const getDevMode = useDevStrictMode();
|
|
45
|
+
const { root, version, markDirty } = peekResourceFiber()
|
|
46
|
+
? // oxlint-disable-next-line react-hooks/rules-of-hooks
|
|
47
|
+
useResourceFiberHostUtilsTap()
|
|
48
|
+
: // oxlint-disable-next-line react-hooks/rules-of-hooks
|
|
49
|
+
useResourceFiberHostUtilsReact();
|
|
50
|
+
|
|
51
|
+
const createFiber = useCallback(
|
|
52
|
+
<R, A extends readonly any[]>(
|
|
53
|
+
hook: (...props: A) => R,
|
|
54
|
+
_key: string | number | undefined,
|
|
55
|
+
) => createResourceFiber(hook, root, markDirty, getDevMode()),
|
|
56
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
[],
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
return { version, createFiber };
|
|
61
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -2,14 +2,17 @@ export { resource } from "./core/resource";
|
|
|
2
2
|
export { withKey } from "./core/withKey";
|
|
3
3
|
|
|
4
4
|
// imperative
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
5
|
+
export { createTapRoot } from "./core/createTapRoot";
|
|
6
|
+
export { flushTapSync } from "./core/scheduler";
|
|
7
7
|
|
|
8
8
|
// context
|
|
9
9
|
export { createResourceContext, withContextProvider } from "./core/context";
|
|
10
10
|
|
|
11
11
|
// hooks
|
|
12
|
-
export { useResource
|
|
12
|
+
export { useResource } from "./hooks/useResource";
|
|
13
|
+
export { useResources } from "./hooks/useResources";
|
|
14
|
+
export { useTapRoot } from "./hooks/useTapRoot";
|
|
15
|
+
export { useTapHost } from "./hooks/useTapHost";
|
|
13
16
|
|
|
14
17
|
// types
|
|
15
18
|
export type {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { useState } from "./useState";
|
|
2
|
-
export { useReducer
|
|
2
|
+
export { useReducer } from "./useReducer";
|
|
3
3
|
export { useRef } from "./useRef";
|
|
4
4
|
export { useMemo } from "./useMemo";
|
|
5
5
|
export { useCallback } from "./useCallback";
|
|
@@ -7,6 +7,6 @@ export { useEffect } from "./useEffect";
|
|
|
7
7
|
export { useEffectEvent } from "./useEffectEvent";
|
|
8
8
|
export { use } from "./use";
|
|
9
9
|
export { useMemoCache } from "./useMemoCache";
|
|
10
|
-
export { useResource } from "
|
|
11
|
-
export { useResources } from "
|
|
12
|
-
export {
|
|
10
|
+
export { useResource } from "../hooks/useResource";
|
|
11
|
+
export { useResources } from "../hooks/useResources";
|
|
12
|
+
export { useTapRoot } from "../hooks/useTapRoot";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Cell } from "../core/types";
|
|
2
|
+
import { depsShallowEqual } from "../hooks/utils/depsShallowEqual";
|
|
3
|
+
import { useCell, registerRenderMountTask } from "../hooks/utils/useCell";
|
|
4
|
+
|
|
5
|
+
const newEffect = (): Cell & { type: "effect" } => ({
|
|
6
|
+
type: "effect",
|
|
7
|
+
cleanup: undefined,
|
|
8
|
+
deps: null, // null means the effect has never been run
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export namespace useEffect {
|
|
12
|
+
export type Destructor = () => void;
|
|
13
|
+
export type EffectCallback = () => Destructor | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function useEffect(effect: useEffect.EffectCallback): void;
|
|
17
|
+
export function useEffect(
|
|
18
|
+
effect: useEffect.EffectCallback,
|
|
19
|
+
deps: readonly unknown[],
|
|
20
|
+
): void;
|
|
21
|
+
export function useEffect(
|
|
22
|
+
effect: useEffect.EffectCallback,
|
|
23
|
+
deps?: readonly unknown[],
|
|
24
|
+
): void {
|
|
25
|
+
const cell = useCell("effect", newEffect);
|
|
26
|
+
|
|
27
|
+
if (deps && cell.deps && depsShallowEqual(cell.deps, deps)) return;
|
|
28
|
+
if (cell.deps !== null && !!deps !== !!cell.deps)
|
|
29
|
+
throw new Error(
|
|
30
|
+
"useEffect called with and without dependencies across re-renders",
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
registerRenderMountTask({
|
|
34
|
+
cleanup: () => {
|
|
35
|
+
try {
|
|
36
|
+
cell.cleanup?.();
|
|
37
|
+
} finally {
|
|
38
|
+
cell.cleanup = undefined;
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
setup: () => {
|
|
42
|
+
try {
|
|
43
|
+
const cleanup = effect();
|
|
44
|
+
|
|
45
|
+
if (cleanup !== undefined && typeof cleanup !== "function") {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"An effect function must either return a cleanup function or nothing. " +
|
|
48
|
+
`Received: ${typeof cleanup}`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
cell.cleanup = cleanup;
|
|
53
|
+
} finally {
|
|
54
|
+
cell.deps = deps;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isDevelopment } from "../core/helpers/env";
|
|
2
2
|
import { getCurrentResourceFiber } from "../core/helpers/execution-context";
|
|
3
3
|
import { useReducerWithDerivedState } from "./useReducer";
|
|
4
|
-
import { depsShallowEqual } from "
|
|
4
|
+
import { depsShallowEqual } from "../hooks/utils/depsShallowEqual";
|
|
5
5
|
|
|
6
6
|
const memoReducer = () => {
|
|
7
7
|
throw new Error("Memo reducer should not be called");
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { isDevelopment } from "../core/helpers/env";
|
|
2
|
+
import {
|
|
3
|
+
getCurrentResourceFiber,
|
|
4
|
+
peekResourceFiber,
|
|
5
|
+
} from "../core/helpers/execution-context";
|
|
6
|
+
import type { Cell, ChangelogRecord, ResourceFiber } from "../core/types";
|
|
7
|
+
import { applyChangelogRecord, markCellDirty } from "../core/helpers/root";
|
|
8
|
+
|
|
9
|
+
type Dispatch<A> = (action: A) => void;
|
|
10
|
+
|
|
11
|
+
const dispatchOnFiber = (
|
|
12
|
+
fiber: ResourceFiber<any, any>,
|
|
13
|
+
callback: () => ChangelogRecord | null,
|
|
14
|
+
): void => {
|
|
15
|
+
if (fiber.isNeverMounted) {
|
|
16
|
+
throw new Error("Resource updated before mount");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fiber.root.dispatchUpdate(() => {
|
|
20
|
+
const record = callback();
|
|
21
|
+
if (record) {
|
|
22
|
+
applyChangelogRecord(record);
|
|
23
|
+
fiber.root.changelog.push(record);
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const createReducerCell = (
|
|
31
|
+
fiber: ResourceFiber<any, any>,
|
|
32
|
+
reducer: (state: any, action: any) => any,
|
|
33
|
+
initialArg: any,
|
|
34
|
+
initFn: ((arg: any) => any) | undefined,
|
|
35
|
+
eagerDispatch: boolean,
|
|
36
|
+
): Cell & { type: "reducer" } => {
|
|
37
|
+
const initialState = initFn ? initFn(initialArg) : initialArg;
|
|
38
|
+
|
|
39
|
+
if (isDevelopment && fiber.devStrictMode && initFn) {
|
|
40
|
+
void initFn(initialArg);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const cell: Cell & { type: "reducer" } = {
|
|
44
|
+
type: "reducer",
|
|
45
|
+
queue: null,
|
|
46
|
+
renderQueue: null,
|
|
47
|
+
workInProgress: initialState,
|
|
48
|
+
current: initialState,
|
|
49
|
+
reducer,
|
|
50
|
+
dispatch: (action) => {
|
|
51
|
+
const currentFiber = peekResourceFiber();
|
|
52
|
+
if (currentFiber !== null) {
|
|
53
|
+
if (currentFiber !== fiber)
|
|
54
|
+
throw new Error(
|
|
55
|
+
"Cannot update a resource while rendering a different resource.",
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
(fiber.renderPendingCells ??= new Set()).add(cell);
|
|
59
|
+
(cell.renderQueue ??= []).push(action);
|
|
60
|
+
} else {
|
|
61
|
+
const record: ChangelogRecord = {
|
|
62
|
+
fiber,
|
|
63
|
+
cell,
|
|
64
|
+
action,
|
|
65
|
+
hasEagerState: false,
|
|
66
|
+
eagerState: undefined,
|
|
67
|
+
queued: false,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
dispatchOnFiber(fiber, () => {
|
|
71
|
+
if (
|
|
72
|
+
eagerDispatch &&
|
|
73
|
+
fiber.root.dirtyCells.size === 0 &&
|
|
74
|
+
!record.hasEagerState
|
|
75
|
+
) {
|
|
76
|
+
record.eagerState = reducer(cell.workInProgress, action);
|
|
77
|
+
record.hasEagerState = true;
|
|
78
|
+
|
|
79
|
+
if (Object.is(cell.current, record.eagerState)) return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return record;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
return cell;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
function useReducerImpl<S, A, I, R extends S>(
|
|
91
|
+
reducer: (state: S, action: A) => S,
|
|
92
|
+
getDerivedState: ((state: S) => R) | undefined,
|
|
93
|
+
initialArg: S | I,
|
|
94
|
+
initFn: ((arg: I) => S) | undefined,
|
|
95
|
+
eagerDispatch: boolean,
|
|
96
|
+
): [R, Dispatch<A>] {
|
|
97
|
+
const fiber = getCurrentResourceFiber();
|
|
98
|
+
const index = fiber.currentIndex++;
|
|
99
|
+
|
|
100
|
+
const existing = fiber.cells[index];
|
|
101
|
+
let cell: Cell & { type: "reducer" };
|
|
102
|
+
if (existing === undefined) {
|
|
103
|
+
if (!fiber.isFirstRender && index >= fiber.cells.length) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
"Rendered more hooks than during the previous render. " +
|
|
106
|
+
"Hooks must be called in the exact same order in every render.",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
cell = createReducerCell(fiber, reducer, initialArg, initFn, eagerDispatch);
|
|
110
|
+
fiber.cells[index] = cell;
|
|
111
|
+
} else {
|
|
112
|
+
if (existing.type !== "reducer") {
|
|
113
|
+
throw new Error("Hook order changed between renders");
|
|
114
|
+
}
|
|
115
|
+
cell = existing;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const queue = cell.queue;
|
|
119
|
+
if (queue !== null) {
|
|
120
|
+
const sameReducer = reducer === cell.reducer;
|
|
121
|
+
|
|
122
|
+
// The drain consumes entries: a re-render of the same uncommitted lineage
|
|
123
|
+
// sees an empty queue and must not re-apply them. Rollback replays them
|
|
124
|
+
// into the queue via the changelog.
|
|
125
|
+
for (let i = 0; i < queue.length; i++) {
|
|
126
|
+
const item = queue[i]!;
|
|
127
|
+
if (!item.hasEagerState || !sameReducer) {
|
|
128
|
+
item.eagerState = reducer(cell.workInProgress, item.action);
|
|
129
|
+
item.hasEagerState = true;
|
|
130
|
+
|
|
131
|
+
if (isDevelopment && fiber.devStrictMode) {
|
|
132
|
+
// React keeps the strict re-invocation's result for render-computed
|
|
133
|
+
// actions (unlike eager-computed ones, whose ghost is discarded).
|
|
134
|
+
item.eagerState = reducer(cell.workInProgress, item.action);
|
|
135
|
+
}
|
|
136
|
+
} else if (isDevelopment && fiber.devStrictMode) {
|
|
137
|
+
void reducer(cell.workInProgress, item.action);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
item.queued = false;
|
|
141
|
+
cell.workInProgress = item.eagerState;
|
|
142
|
+
}
|
|
143
|
+
cell.queue = null;
|
|
144
|
+
}
|
|
145
|
+
cell.reducer = reducer;
|
|
146
|
+
|
|
147
|
+
if (cell.renderQueue !== null || getDerivedState !== undefined) {
|
|
148
|
+
let derived = cell.workInProgress;
|
|
149
|
+
if (cell.renderQueue !== null) {
|
|
150
|
+
for (const action of cell.renderQueue) {
|
|
151
|
+
derived = reducer(derived, action);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
cell.renderQueue = null;
|
|
155
|
+
fiber.renderPendingCells?.delete(cell);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (getDerivedState) {
|
|
159
|
+
let changed;
|
|
160
|
+
let passes = 0;
|
|
161
|
+
do {
|
|
162
|
+
if (++passes > 25) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
"Too many derivations. getDerivedState must reach a fixpoint; " +
|
|
165
|
+
"tap limits the number of iterations to prevent an infinite loop.",
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const result = getDerivedState(derived);
|
|
169
|
+
changed = !Object.is(result, derived);
|
|
170
|
+
derived = result;
|
|
171
|
+
} while (changed);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (!Object.is(derived, cell.workInProgress)) {
|
|
175
|
+
markCellDirty(fiber, cell);
|
|
176
|
+
cell.workInProgress = derived;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return [cell.workInProgress, cell.dispatch];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function useReducer<S, A>(
|
|
184
|
+
reducer: (state: S, action: A) => S,
|
|
185
|
+
initialState: S,
|
|
186
|
+
): [S, Dispatch<A>];
|
|
187
|
+
export function useReducer<S, A, I>(
|
|
188
|
+
reducer: (state: S, action: A) => S,
|
|
189
|
+
initialArg: I,
|
|
190
|
+
init: (arg: I) => S,
|
|
191
|
+
): [S, Dispatch<A>];
|
|
192
|
+
export function useReducer<S, A, I>(
|
|
193
|
+
reducer: (state: S, action: A) => S,
|
|
194
|
+
initialArg: S | I,
|
|
195
|
+
init?: (arg: I) => S,
|
|
196
|
+
): [S, Dispatch<A>] {
|
|
197
|
+
return useReducerImpl(
|
|
198
|
+
reducer,
|
|
199
|
+
undefined,
|
|
200
|
+
initialArg as S,
|
|
201
|
+
init as ((arg: S) => S) | undefined,
|
|
202
|
+
false,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** @internal useState's entry point: eager dispatch, like React's basic state reducer. */
|
|
207
|
+
export function useEagerReducer<S, A>(
|
|
208
|
+
reducer: (state: S, action: A) => S,
|
|
209
|
+
initialState: S,
|
|
210
|
+
): [S, Dispatch<A>];
|
|
211
|
+
export function useEagerReducer<S, A, I>(
|
|
212
|
+
reducer: (state: S, action: A) => S,
|
|
213
|
+
initialArg: I,
|
|
214
|
+
init: (arg: I) => S,
|
|
215
|
+
): [S, Dispatch<A>];
|
|
216
|
+
export function useEagerReducer<S, A, I>(
|
|
217
|
+
reducer: (state: S, action: A) => S,
|
|
218
|
+
initialArg: S | I,
|
|
219
|
+
init?: (arg: I) => S,
|
|
220
|
+
): [S, Dispatch<A>] {
|
|
221
|
+
return useReducerImpl(
|
|
222
|
+
reducer,
|
|
223
|
+
undefined,
|
|
224
|
+
initialArg as S,
|
|
225
|
+
init as ((arg: S) => S) | undefined,
|
|
226
|
+
true,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @internal Backs useMemo and useMemoCache: a reducer cell whose state is
|
|
232
|
+
* recomputed during render via getDerivedState. Not part of the public API;
|
|
233
|
+
* user-facing state adjustment during render uses render-phase updates
|
|
234
|
+
* (setState during render), like React.
|
|
235
|
+
*/
|
|
236
|
+
export function useReducerWithDerivedState<S, A, R extends S>(
|
|
237
|
+
reducer: (state: S, action: A) => S,
|
|
238
|
+
getDerivedState: (state: S) => R,
|
|
239
|
+
initialState: S,
|
|
240
|
+
): [R, Dispatch<A>];
|
|
241
|
+
export function useReducerWithDerivedState<S, A, I, R extends S>(
|
|
242
|
+
reducer: (state: S, action: A) => S,
|
|
243
|
+
getDerivedState: (state: S) => R,
|
|
244
|
+
initialArg: I,
|
|
245
|
+
init: (arg: I) => S,
|
|
246
|
+
): [R, Dispatch<A>];
|
|
247
|
+
export function useReducerWithDerivedState<S, A, I, R extends S>(
|
|
248
|
+
reducer: (state: S, action: A) => S,
|
|
249
|
+
getDerivedState: (state: S) => R,
|
|
250
|
+
initialArg: I,
|
|
251
|
+
init?: (arg: I) => S,
|
|
252
|
+
): [R, Dispatch<A>] {
|
|
253
|
+
return useReducerImpl(reducer, getDerivedState, initialArg, init, true);
|
|
254
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEagerReducer } from "./useReducer";
|
|
2
2
|
|
|
3
3
|
export namespace useState {
|
|
4
4
|
export type StateUpdater<S> = S | ((prev: S) => S);
|
|
@@ -25,5 +25,5 @@ export function useState<S>(
|
|
|
25
25
|
export function useState<S>(
|
|
26
26
|
initial?: S | (() => S),
|
|
27
27
|
): [S | undefined, (updater: useState.StateUpdater<S>) => void] {
|
|
28
|
-
return
|
|
28
|
+
return useEagerReducer(stateReducer, initial, stateInit);
|
|
29
29
|
}
|
package/src/react-shim/index.ts
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
// This subpath ships no type declarations: the build reverts the aliased
|
|
9
9
|
// specifier back to `"react"` in emitted `.d.ts`, so consumer types resolve to
|
|
10
10
|
// React's own. The source-level TS2498 from the `export *` below is suppressed.
|
|
11
|
-
import
|
|
11
|
+
import React from "react";
|
|
12
12
|
import { peekResourceFiber } from "../core/helpers/execution-context";
|
|
13
|
-
import * as hooks from "../hooks";
|
|
13
|
+
import * as hooks from "../react-hooks";
|
|
14
14
|
import { useResourceContext, isResourceContext } from "../core/context";
|
|
15
15
|
|
|
16
16
|
// @ts-expect-error -- @types/react uses `export =`; this is valid at runtime.
|
|
@@ -18,47 +18,58 @@ export * from "react";
|
|
|
18
18
|
export { default } from "react";
|
|
19
19
|
|
|
20
20
|
const inTap = () => peekResourceFiber() !== null;
|
|
21
|
+
const ReactRuntime = React as any;
|
|
21
22
|
|
|
22
23
|
// --- hooks with a tap equivalent: override the star-exported react hooks ---
|
|
23
24
|
|
|
24
25
|
export const useState = (initialState?: any) =>
|
|
25
|
-
inTap() ? hooks.useState(initialState) :
|
|
26
|
+
inTap() ? hooks.useState(initialState) : ReactRuntime.useState(initialState);
|
|
26
27
|
|
|
27
28
|
export const useReducer = (reducer: any, initialArg: any, init?: any) =>
|
|
28
29
|
inTap()
|
|
29
30
|
? hooks.useReducer(reducer, initialArg, init)
|
|
30
|
-
:
|
|
31
|
+
: ReactRuntime.useReducer(reducer, initialArg, init);
|
|
31
32
|
|
|
32
33
|
export const useRef = (initialValue?: any) =>
|
|
33
|
-
inTap() ? hooks.useRef(initialValue) :
|
|
34
|
+
inTap() ? hooks.useRef(initialValue) : ReactRuntime.useRef(initialValue);
|
|
34
35
|
|
|
35
36
|
export const useMemo = (factory: any, deps: any) =>
|
|
36
|
-
inTap() ? hooks.useMemo(factory, deps) :
|
|
37
|
+
inTap() ? hooks.useMemo(factory, deps) : ReactRuntime.useMemo(factory, deps);
|
|
37
38
|
|
|
38
39
|
export const useCallback = (callback: any, deps: any) =>
|
|
39
40
|
inTap()
|
|
40
41
|
? hooks.useCallback(callback, deps)
|
|
41
|
-
:
|
|
42
|
+
: ReactRuntime.useCallback(callback, deps);
|
|
42
43
|
|
|
43
44
|
export const useEffect = (effect: any, deps?: any) =>
|
|
44
|
-
inTap()
|
|
45
|
+
inTap()
|
|
46
|
+
? hooks.useEffect(effect, deps)
|
|
47
|
+
: ReactRuntime.useEffect(effect, deps);
|
|
45
48
|
|
|
46
49
|
// tap has a single effect primitive; layout effects collapse onto it
|
|
47
50
|
export const useLayoutEffect = (effect: any, deps?: any) =>
|
|
48
|
-
inTap()
|
|
51
|
+
inTap()
|
|
52
|
+
? hooks.useEffect(effect, deps)
|
|
53
|
+
: ReactRuntime.useLayoutEffect(effect, deps);
|
|
49
54
|
|
|
55
|
+
// The non-tap fallback requires a React version that provides useEffectEvent.
|
|
50
56
|
export const useEffectEvent = (callback: any) =>
|
|
51
|
-
inTap()
|
|
57
|
+
inTap()
|
|
58
|
+
? hooks.useEffectEvent(callback)
|
|
59
|
+
: ReactRuntime.useEffectEvent(callback);
|
|
52
60
|
|
|
53
61
|
// `use(usable)` reads tap resource context when handed a tap context (routed by
|
|
54
62
|
// its brand, not by ambient render state), and falls back to React's `use`
|
|
55
|
-
// (promises / React context) for everything else.
|
|
63
|
+
// (promises / React context) for everything else. The non-tap fallback requires
|
|
64
|
+
// React 19.
|
|
56
65
|
export const use = (usable: any) =>
|
|
57
|
-
isResourceContext(usable)
|
|
66
|
+
isResourceContext(usable)
|
|
67
|
+
? useResourceContext(usable)
|
|
68
|
+
: ReactRuntime.use(usable);
|
|
58
69
|
|
|
59
70
|
// `useContext(context)` reads tap resource context when handed a tap context
|
|
60
71
|
// (routed by its brand), and falls back to React's `useContext` otherwise.
|
|
61
72
|
export const useContext = (context: any) =>
|
|
62
73
|
isResourceContext(context)
|
|
63
74
|
? useResourceContext(context)
|
|
64
|
-
:
|
|
75
|
+
: ReactRuntime.useContext(context);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ResourceElement } from "./types.js";
|
|
2
|
-
import { useResourceRoot } from "../hooks/useResourceRoot.js";
|
|
3
|
-
|
|
4
|
-
//#region src/core/createResourceRoot.d.ts
|
|
5
|
-
declare const createResourceRoot: () => {
|
|
6
|
-
render: <R, P>(element: ResourceElement<R, P>) => useResourceRoot.SubscribableResource<R>;
|
|
7
|
-
unmount: () => void;
|
|
8
|
-
};
|
|
9
|
-
//#endregion
|
|
10
|
-
export { createResourceRoot };
|
|
11
|
-
//# sourceMappingURL=createResourceRoot.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createResourceRoot.d.ts","names":[],"sources":["../../src/core/createResourceRoot.ts"],"mappings":";;;;cAea,kBAAA;iBAqBI,OAAA,EAAW,eAAA,CAAgB,CAAA,EAAG,CAAA,MAUjB,eAAA,CAAgB,oBAAA,CAAqB,CAAA"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { resource } from "./resource.js";
|
|
2
|
-
import { isDevelopment } from "./helpers/env.js";
|
|
3
|
-
import { createResourceFiberRoot } from "./helpers/root.js";
|
|
4
|
-
import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "./ResourceFiber.js";
|
|
5
|
-
import { UpdateScheduler, flushResourcesSync } from "./scheduler.js";
|
|
6
|
-
import { useResourceRoot } from "../hooks/useResourceRoot.js";
|
|
7
|
-
//#region src/core/createResourceRoot.ts
|
|
8
|
-
const SubscribableResource = resource(useResourceRoot);
|
|
9
|
-
const createResourceRoot = () => {
|
|
10
|
-
const fiber = createResourceFiber(SubscribableResource, createResourceFiberRoot((callback) => {
|
|
11
|
-
new UpdateScheduler(() => {
|
|
12
|
-
if (callback()) throw new Error("Unexpected rerender of createResourceRoot outer fiber");
|
|
13
|
-
return false;
|
|
14
|
-
}).markDirty();
|
|
15
|
-
}), void 0, isDevelopment ? "root" : null);
|
|
16
|
-
return {
|
|
17
|
-
render: (element) => {
|
|
18
|
-
if (isDevelopment && fiber.devStrictMode === "root") renderResourceFiber(fiber, element);
|
|
19
|
-
const render = renderResourceFiber(fiber, element);
|
|
20
|
-
flushResourcesSync(() => commitResourceFiber(fiber, render));
|
|
21
|
-
return render.output;
|
|
22
|
-
},
|
|
23
|
-
unmount: () => {
|
|
24
|
-
unmountResourceFiber(fiber);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
//#endregion
|
|
29
|
-
export { createResourceRoot };
|
|
30
|
-
|
|
31
|
-
//# sourceMappingURL=createResourceRoot.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createResourceRoot.js","names":[],"sources":["../../src/core/createResourceRoot.ts"],"sourcesContent":["import type { ResourceElement } from \"./types\";\nimport {\n createResourceFiber,\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"./ResourceFiber\";\nimport { useResourceRoot } from \"../hooks/useResourceRoot\";\nimport { resource } from \"./resource\";\nimport { isDevelopment } from \"./helpers/env\";\nimport { flushResourcesSync, UpdateScheduler } from \"./scheduler\";\nimport { createResourceFiberRoot } from \"./helpers/root\";\n\nconst SubscribableResource = resource(useResourceRoot);\n\nexport const createResourceRoot = () => {\n const fiber = createResourceFiber<\n useResourceRoot.SubscribableResource<any>,\n ResourceElement<any>\n >(\n SubscribableResource,\n createResourceFiberRoot((callback) => {\n new UpdateScheduler(() => {\n if (callback()) {\n throw new Error(\n \"Unexpected rerender of createResourceRoot outer fiber\",\n );\n }\n return false;\n }).markDirty();\n }),\n undefined,\n isDevelopment ? \"root\" : null,\n );\n\n return {\n render: <R, P>(element: ResourceElement<R, P>) => {\n // In strict mode, render twice to detect side effects\n if (isDevelopment && fiber.devStrictMode === \"root\") {\n void renderResourceFiber(fiber, element);\n }\n\n const render = renderResourceFiber(fiber, element);\n\n flushResourcesSync(() => commitResourceFiber(fiber, render));\n\n return render.output as useResourceRoot.SubscribableResource<R>;\n },\n unmount: () => {\n unmountResourceFiber(fiber);\n },\n };\n};\n"],"mappings":";;;;;;;AAaA,MAAM,uBAAuB,SAAS,eAAe;AAErD,MAAa,2BAA2B;CACtC,MAAM,QAAQ,oBAIZ,sBACA,yBAAyB,aAAa;EACpC,IAAI,sBAAsB;GACxB,IAAI,SAAS,GACX,MAAM,IAAI,MACR,uDACF;GAEF,OAAO;EACT,CAAC,CAAC,CAAC,UAAU;CACf,CAAC,GACD,KAAA,GACA,gBAAgB,SAAS,IAC3B;CAEA,OAAO;EACL,SAAe,YAAmC;GAEhD,IAAI,iBAAiB,MAAM,kBAAkB,QAC3C,oBAAyB,OAAO,OAAO;GAGzC,MAAM,SAAS,oBAAoB,OAAO,OAAO;GAEjD,yBAAyB,oBAAoB,OAAO,MAAM,CAAC;GAE3D,OAAO,OAAO;EAChB;EACA,eAAe;GACb,qBAAqB,KAAK;EAC5B;CACF;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|