@assistant-ui/tap 0.5.13 → 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/commit.d.ts.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/helpers/root.d.ts.map +1 -1
- package/dist/core/helpers/root.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/resource.d.ts.map +1 -1
- package/dist/core/scheduler.d.ts.map +1 -1
- 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/core/withKey.d.ts.map +1 -1
- 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 -21
- 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 -21
- 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 -4
- package/src/__tests__/strictmode/strictmode.test.ts +42 -42
- package/src/__tests__/strictmode/tap-strictmode-rerender-sources.test.ts +55 -58
- package/src/__tests__/test-utils.ts +2 -3
- 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/helpers/root.ts +0 -1
- 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 -29
- 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
|
@@ -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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Cell } from "../../core/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/utils/useCell.d.ts
|
|
4
|
+
declare const useCell: <T extends Cell["type"]>(type: T, init: () => Cell) => Cell & {
|
|
5
|
+
type: T;
|
|
6
|
+
};
|
|
7
|
+
declare const registerRenderMountTask: (task: () => void) => void;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { registerRenderMountTask, useCell };
|
|
10
|
+
//# sourceMappingURL=useCell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCell.d.ts","names":[],"sources":["../../../src/hooks/utils/useCell.ts"],"mappings":";;;cAGa,OAAA,aAAqB,IAAA,UAChC,IAAA,EAAM,CAAA,EACN,IAAA,QAAY,IAAA,KACX,IAAA;EAAS,IAAA,EAAM,CAAA;AAAA;AAAA,cAyBL,uBAAA,GAA2B,IAAgB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getCurrentResourceFiber } from "../../core/helpers/execution-context.js";
|
|
2
|
-
//#region src/hooks/utils/
|
|
3
|
-
const
|
|
2
|
+
//#region src/hooks/utils/useCell.ts
|
|
3
|
+
const useCell = (type, init) => {
|
|
4
4
|
const fiber = getCurrentResourceFiber();
|
|
5
5
|
const index = fiber.currentIndex++;
|
|
6
6
|
if (!fiber.isFirstRender && index >= fiber.cells.length) throw new Error("Rendered more hooks than during the previous render. Hooks must be called in the exact same order in every render.");
|
|
@@ -16,6 +16,6 @@ const registerRenderMountTask = (task) => {
|
|
|
16
16
|
getCurrentResourceFiber().renderContext.effectTasks.push(task);
|
|
17
17
|
};
|
|
18
18
|
//#endregion
|
|
19
|
-
export { registerRenderMountTask,
|
|
19
|
+
export { registerRenderMountTask, useCell };
|
|
20
20
|
|
|
21
|
-
//# sourceMappingURL=
|
|
21
|
+
//# sourceMappingURL=useCell.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"
|
|
1
|
+
{"version":3,"file":"useCell.js","names":[],"sources":["../../../src/hooks/utils/useCell.ts"],"sourcesContent":["import { getCurrentResourceFiber } from \"../../core/helpers/execution-context\";\nimport type { Cell } from \"../../core/types\";\n\nexport const useCell = <T extends Cell[\"type\"]>(\n type: T,\n init: () => Cell,\n): Cell & { type: T } => {\n const fiber = getCurrentResourceFiber();\n const index = fiber.currentIndex++;\n\n if (!fiber.isFirstRender && index >= fiber.cells.length) {\n // Check if we're trying to use more hooks than in previous renders\n throw new Error(\n \"Rendered more hooks than during the previous render. \" +\n \"Hooks must be called in the exact same order in every render.\",\n );\n }\n\n let cell = fiber.cells[index];\n if (!cell) {\n cell = init();\n fiber.cells[index] = cell;\n }\n\n if (cell.type !== type) {\n throw new Error(\"Hook order changed between renders\");\n }\n\n return cell as Cell & { type: T };\n};\n\nexport const registerRenderMountTask = (task: () => void) => {\n const fiber = getCurrentResourceFiber();\n fiber.renderContext!.effectTasks.push(task);\n};\n"],"mappings":";;AAGA,MAAa,WACX,MACA,SACuB;CACvB,MAAM,QAAQ,wBAAwB;CACtC,MAAM,QAAQ,MAAM;CAEpB,IAAI,CAAC,MAAM,iBAAiB,SAAS,MAAM,MAAM,QAE/C,MAAM,IAAI,MACR,oHAEF;CAGF,IAAI,OAAO,MAAM,MAAM;CACvB,IAAI,CAAC,MAAM;EACT,OAAO,KAAK;EACZ,MAAM,MAAM,SAAS;CACvB;CAEA,IAAI,KAAK,SAAS,MAChB,MAAM,IAAI,MAAM,oCAAoC;CAGtD,OAAO;AACT;AAEA,MAAa,2BAA2B,SAAqB;CAE3D,wBAAI,CAAC,CAAC,cAAe,YAAY,KAAK,IAAI;AAC5C"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
import { tapEffect } from "./hooks/tap-effect.js";
|
|
2
1
|
import { ContravariantResource, Resource, ResourceElement } from "./core/types.js";
|
|
3
|
-
import { createResourceContext,
|
|
2
|
+
import { createResourceContext, withContextProvider } from "./core/context.js";
|
|
4
3
|
import { createResourceRoot } from "./core/createResourceRoot.js";
|
|
5
4
|
import { resource } from "./core/resource.js";
|
|
6
5
|
import { flushResourcesSync } from "./core/scheduler.js";
|
|
7
6
|
import { withKey } from "./core/withKey.js";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import { tapEffectEvent } from "./hooks/tap-effect-event.js";
|
|
11
|
-
import { tapMemo } from "./hooks/tap-memo.js";
|
|
12
|
-
import { tapReducer, tapReducerWithDerivedState } from "./hooks/tap-reducer.js";
|
|
13
|
-
import { tapRef } from "./hooks/tap-ref.js";
|
|
14
|
-
import { tapResource } from "./hooks/tap-resource.js";
|
|
15
|
-
import { tapResources } from "./hooks/tap-resources.js";
|
|
16
|
-
import { tapState } from "./hooks/tap-state.js";
|
|
17
|
-
import { tapResourceRoot } from "./tapResourceRoot.js";
|
|
18
|
-
export { type ContravariantResource, type Resource, type ResourceElement, createResourceContext, createResourceRoot, flushResourcesSync, resource, tap, tapCallback, tapConst, tapEffect, tapEffectEvent, tapMemo, tapReducer, tapReducerWithDerivedState, tapRef, tapResource, tapResourceRoot, tapResources, tapState, withContextProvider, withKey };
|
|
7
|
+
import { useResource, useResourceRoot, useResources } from "./react/hooks.js";
|
|
8
|
+
export { type ContravariantResource, type Resource, type ResourceElement, createResourceContext, createResourceRoot, flushResourcesSync, resource, useResource, useResourceRoot, useResources, withContextProvider, withKey };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
import { resource } from "./core/resource.js";
|
|
2
2
|
import { withKey } from "./core/withKey.js";
|
|
3
|
-
import {
|
|
4
|
-
import { tapState } from "./hooks/tap-state.js";
|
|
5
|
-
import { tapEffect } from "./hooks/tap-effect.js";
|
|
6
|
-
import { tapRef } from "./hooks/tap-ref.js";
|
|
7
|
-
import { tapConst } from "./hooks/tap-const.js";
|
|
8
|
-
import { tapMemo } from "./hooks/tap-memo.js";
|
|
9
|
-
import { tapCallback } from "./hooks/tap-callback.js";
|
|
10
|
-
import { tapEffectEvent } from "./hooks/tap-effect-event.js";
|
|
11
|
-
import { tapResource } from "./hooks/tap-resource.js";
|
|
12
|
-
import { tapResources } from "./hooks/tap-resources.js";
|
|
3
|
+
import { createResourceContext, withContextProvider } from "./core/context.js";
|
|
13
4
|
import { flushResourcesSync } from "./core/scheduler.js";
|
|
14
|
-
import { tapResourceRoot } from "./tapResourceRoot.js";
|
|
15
5
|
import { createResourceRoot } from "./core/createResourceRoot.js";
|
|
16
|
-
import {
|
|
17
|
-
export { createResourceContext, createResourceRoot, flushResourcesSync, resource,
|
|
6
|
+
import { useResource, useResourceRoot, useResources } from "./react/hooks.js";
|
|
7
|
+
export { createResourceContext, createResourceRoot, flushResourcesSync, resource, useResource, useResourceRoot, useResources, withContextProvider, withKey };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useResourceRoot as useResourceRoot$1 } from "../hooks/useResourceRoot.js";
|
|
2
|
+
import { useResource as useResource$1 } from "../hooks/useResource.js";
|
|
3
|
+
import { useResources as useResources$1 } from "../hooks/useResources.js";
|
|
4
|
+
|
|
5
|
+
//#region src/react/hooks.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Hosts a resource element. Inside a resource render it hosts the element as a
|
|
8
|
+
* child resource; inside a React component it hosts it via the React bridge.
|
|
9
|
+
* `propsDeps` is a resource-render optimization and is ignored on the React side.
|
|
10
|
+
*/
|
|
11
|
+
declare const useResource: typeof useResource$1;
|
|
12
|
+
/**
|
|
13
|
+
* Hosts a keyed list of resource elements. Inside a resource render it composes
|
|
14
|
+
* them directly; inside a React component it hosts them via the React bridge.
|
|
15
|
+
*/
|
|
16
|
+
declare const useResources: typeof useResources$1;
|
|
17
|
+
/**
|
|
18
|
+
* Hosts a resource element as a subscribable root. Inside a resource render it
|
|
19
|
+
* uses the root hook directly; inside a React component it hosts that root via
|
|
20
|
+
* the React bridge (host it in one place; observe it via getValue/subscribe).
|
|
21
|
+
*/
|
|
22
|
+
declare const useResourceRoot: typeof useResourceRoot$1;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useResource, useResourceRoot, useResources };
|
|
25
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","names":[],"sources":["../../src/react/hooks.ts"],"mappings":";;;;;;;;;AA4FA;cAAa,WAAA,SAAoB,aAEhC;;;AAAA;AAMD;cAAa,YAAA,SAAqB,cAEjC;;;AAAA;AAOD;;cAAa,eAAA,SAAwB,iBAEpC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { resource } from "../core/resource.js";
|
|
2
|
+
import { isDevelopment } from "../core/helpers/env.js";
|
|
3
|
+
import { peekResourceFiber } from "../core/helpers/execution-context.js";
|
|
4
|
+
import { commitRoot, createResourceFiberRoot, setRootVersion } from "../core/helpers/root.js";
|
|
5
|
+
import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
|
|
6
|
+
import { useResourceRoot as useResourceRoot$1 } from "../hooks/useResourceRoot.js";
|
|
7
|
+
import { useResource as useResource$1 } from "../hooks/useResource.js";
|
|
8
|
+
import { useResources as useResources$1 } from "../hooks/useResources.js";
|
|
9
|
+
import { useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
10
|
+
//#region src/react/hooks.ts
|
|
11
|
+
const useDevStrictMode = () => {
|
|
12
|
+
if (!isDevelopment) return null;
|
|
13
|
+
const count = useRef(0);
|
|
14
|
+
const isFirstRender = count.current === 0;
|
|
15
|
+
useState(() => count.current++);
|
|
16
|
+
if (count.current !== 2) return null;
|
|
17
|
+
return isFirstRender ? "child" : "root";
|
|
18
|
+
};
|
|
19
|
+
const HostResource = resource(function HostResource(callback) {
|
|
20
|
+
return callback();
|
|
21
|
+
});
|
|
22
|
+
const useResourceHost = (callback) => {
|
|
23
|
+
const root = useMemo(() => {
|
|
24
|
+
return createResourceFiberRoot((cb) => dispatch(cb));
|
|
25
|
+
}, []);
|
|
26
|
+
const [version, dispatch] = useReducer((v, cb) => {
|
|
27
|
+
setRootVersion(root, v);
|
|
28
|
+
return v + (cb() ? 1 : 0);
|
|
29
|
+
}, 0);
|
|
30
|
+
setRootVersion(root, version);
|
|
31
|
+
const devStrictMode = useDevStrictMode();
|
|
32
|
+
const fiber = useMemo(() => {
|
|
33
|
+
return createResourceFiber(HostResource, root, void 0, devStrictMode);
|
|
34
|
+
}, [root, devStrictMode]);
|
|
35
|
+
const result = renderResourceFiber(fiber, callback);
|
|
36
|
+
useLayoutEffect(() => {
|
|
37
|
+
return () => unmountResourceFiber(fiber);
|
|
38
|
+
}, [fiber]);
|
|
39
|
+
useLayoutEffect(() => {
|
|
40
|
+
commitRoot(root);
|
|
41
|
+
commitResourceFiber(fiber, result);
|
|
42
|
+
});
|
|
43
|
+
return result.output;
|
|
44
|
+
};
|
|
45
|
+
const makeHook = (hook) => ((...args) => {
|
|
46
|
+
if (peekResourceFiber()) return hook(...args);
|
|
47
|
+
return useResourceHost(() => hook(...args));
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Hosts a resource element. Inside a resource render it hosts the element as a
|
|
51
|
+
* child resource; inside a React component it hosts it via the React bridge.
|
|
52
|
+
* `propsDeps` is a resource-render optimization and is ignored on the React side.
|
|
53
|
+
*/
|
|
54
|
+
const useResource = makeHook(useResource$1);
|
|
55
|
+
/**
|
|
56
|
+
* Hosts a keyed list of resource elements. Inside a resource render it composes
|
|
57
|
+
* them directly; inside a React component it hosts them via the React bridge.
|
|
58
|
+
*/
|
|
59
|
+
const useResources = makeHook(useResources$1);
|
|
60
|
+
/**
|
|
61
|
+
* Hosts a resource element as a subscribable root. Inside a resource render it
|
|
62
|
+
* uses the root hook directly; inside a React component it hosts that root via
|
|
63
|
+
* the React bridge (host it in one place; observe it via getValue/subscribe).
|
|
64
|
+
*/
|
|
65
|
+
const useResourceRoot = makeHook(useResourceRoot$1);
|
|
66
|
+
//#endregion
|
|
67
|
+
export { useResource, useResourceRoot, useResources };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","names":["hooks.useResource","hooks.useResources","hooks.useResourceRoot"],"sources":["../../src/react/hooks.ts"],"sourcesContent":["import { useLayoutEffect, useMemo, useReducer, useRef, useState } from \"react\";\nimport type { ResourceFiberRoot, Resource } from \"../core/types\";\nimport {\n createResourceFiber,\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { isDevelopment } from \"../core/helpers/env\";\nimport {\n commitRoot,\n createResourceFiberRoot,\n setRootVersion,\n} from \"../core/helpers/root\";\nimport { peekResourceFiber } from \"../core/helpers/execution-context\";\nimport * as hooks from \"../hooks\";\nimport { resource } from \"../core/resource\";\n\nconst useDevStrictMode = () => {\n if (!isDevelopment) return null;\n\n // oxlint-disable-next-line react/rules-of-hooks -- isDevelopment is a build-time constant, so this branch is stable per build\n const count = useRef(0);\n const isFirstRender = count.current === 0;\n // oxlint-disable-next-line react/rules-of-hooks -- isDevelopment is a build-time constant, so this branch is stable per build\n useState(() => count.current++);\n if (count.current !== 2) return null;\n return isFirstRender ? (\"child\" as const) : (\"root\" as const);\n};\n\nconst HostResource = resource(function HostResource<T>(callback: () => T) {\n return callback();\n});\n\n// Runs `callback` inside a resource render hosted by a React component, so the\n// resource composition hooks (useResource/useResources/useResourceRoot) work from\n// React. `callback` executes inside the resource fiber below, so it may only call\n// resource hooks, not React's own hooks (which would have no fiber to attach to).\n// This is the single React->resource bridge; the React branch of every public\n// hook goes through it.\nconst useResourceHost = <T>(callback: () => T): T => {\n const root = useMemo<ResourceFiberRoot>(() => {\n return createResourceFiberRoot((cb) => dispatch(cb));\n }, []);\n\n const [version, dispatch] = useReducer((v: number, cb: () => boolean) => {\n setRootVersion(root, v);\n return v + (cb() ? 1 : 0);\n }, 0);\n setRootVersion(root, version);\n\n const devStrictMode = useDevStrictMode();\n const fiber = useMemo(() => {\n return createResourceFiber(\n HostResource as unknown as Resource<T, () => T>,\n root,\n undefined,\n devStrictMode,\n );\n }, [root, devStrictMode]);\n\n const result = renderResourceFiber(fiber, callback);\n useLayoutEffect(() => {\n return () => unmountResourceFiber(fiber);\n }, [fiber]);\n useLayoutEffect(() => {\n commitRoot(root);\n commitResourceFiber(fiber, result);\n });\n\n return result.output;\n};\n\n// Turns a resource hook into an isomorphic hook with the SAME type (overloads\n// included): inside a resource render it calls the hook directly; inside a React\n// component it hosts it via the `useResourceHost` bridge. peekResourceFiber() is\n// stable per call site (a given call always renders in the same environment), so\n// the branch order across renders is fixed even though rules-of-hooks can't prove\n// it.\nconst makeHook = <F extends (...args: any[]) => any>(hook: F): F =>\n ((...args: any[]) => {\n /* oxlint-disable react/rules-of-hooks */\n if (peekResourceFiber()) return hook(...args);\n return useResourceHost(() => hook(...args));\n /* oxlint-enable react/rules-of-hooks */\n }) as F;\n\n/**\n * Hosts a resource element. Inside a resource render it hosts the element as a\n * child resource; inside a React component it hosts it via the React bridge.\n * `propsDeps` is a resource-render optimization and is ignored on the React side.\n */\nexport const useResource: typeof hooks.useResource = makeHook(\n hooks.useResource,\n);\n\n/**\n * Hosts a keyed list of resource elements. Inside a resource render it composes\n * them directly; inside a React component it hosts them via the React bridge.\n */\nexport const useResources: typeof hooks.useResources = makeHook(\n hooks.useResources,\n);\n\n/**\n * Hosts a resource element as a subscribable root. Inside a resource render it\n * uses the root hook directly; inside a React component it hosts that root via\n * the React bridge (host it in one place; observe it via getValue/subscribe).\n */\nexport const useResourceRoot: typeof hooks.useResourceRoot = makeHook(\n hooks.useResourceRoot,\n);\n"],"mappings":";;;;;;;;;;AAkBA,MAAM,yBAAyB;CAC7B,IAAI,CAAC,eAAe,OAAO;CAG3B,MAAM,QAAQ,OAAO,CAAC;CACtB,MAAM,gBAAgB,MAAM,YAAY;CAExC,eAAe,MAAM,SAAS;CAC9B,IAAI,MAAM,YAAY,GAAG,OAAO;CAChC,OAAO,gBAAiB,UAAqB;AAC/C;AAEA,MAAM,eAAe,SAAS,SAAS,aAAgB,UAAmB;CACxE,OAAO,SAAS;AAClB,CAAC;AAQD,MAAM,mBAAsB,aAAyB;CACnD,MAAM,OAAO,cAAiC;EAC5C,OAAO,yBAAyB,OAAO,SAAS,EAAE,CAAC;CACrD,GAAG,CAAC,CAAC;CAEL,MAAM,CAAC,SAAS,YAAY,YAAY,GAAW,OAAsB;EACvE,eAAe,MAAM,CAAC;EACtB,OAAO,KAAK,GAAG,IAAI,IAAI;CACzB,GAAG,CAAC;CACJ,eAAe,MAAM,OAAO;CAE5B,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,QAAQ,cAAc;EAC1B,OAAO,oBACL,cACA,MACA,KAAA,GACA,aACF;CACF,GAAG,CAAC,MAAM,aAAa,CAAC;CAExB,MAAM,SAAS,oBAAoB,OAAO,QAAQ;CAClD,sBAAsB;EACpB,aAAa,qBAAqB,KAAK;CACzC,GAAG,CAAC,KAAK,CAAC;CACV,sBAAsB;EACpB,WAAW,IAAI;EACf,oBAAoB,OAAO,MAAM;CACnC,CAAC;CAED,OAAO,OAAO;AAChB;AAQA,MAAM,YAA+C,WACjD,GAAG,SAAgB;CAEnB,IAAI,kBAAkB,GAAG,OAAO,KAAK,GAAG,IAAI;CAC5C,OAAO,sBAAsB,KAAK,GAAG,IAAI,CAAC;AAE5C;;;;;;AAOF,MAAa,cAAwC,SACnDA,aACF;;;;;AAMA,MAAa,eAA0C,SACrDC,cACF;;;;;;AAOA,MAAa,kBAAgD,SAC3DC,iBACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useRef as useRef$2 } from "../hooks/useRef.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import react_default from "react";
|
|
4
|
+
export * from "react";
|
|
5
|
+
|
|
6
|
+
//#region src/react-shim/index.d.ts
|
|
7
|
+
declare const useState: (initialState?: any) => [any, (updater: any) => void];
|
|
8
|
+
declare const useReducer: (reducer: any, initialArg: any, init?: any) => [unknown, (action: unknown) => void] | [unknown, React.ActionDispatch<React.AnyActionArg>];
|
|
9
|
+
declare const useRef: (initialValue?: any) => useRef$2.RefObject<any>;
|
|
10
|
+
declare const useMemo: (factory: any, deps: any) => unknown;
|
|
11
|
+
declare const useCallback: (callback: any, deps: any) => any;
|
|
12
|
+
declare const useEffect: (effect: any, deps?: any) => void;
|
|
13
|
+
declare const useLayoutEffect: (effect: any, deps?: any) => void;
|
|
14
|
+
declare const useEffectEvent: (callback: any) => any;
|
|
15
|
+
declare const use: (usable: any) => unknown;
|
|
16
|
+
declare const useContext: (context: any) => unknown;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { react_default as default, use, useCallback, useContext, useEffect, useEffectEvent, useLayoutEffect, useMemo, useReducer, useRef, useState };
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/react-shim/index.ts"],"mappings":";;;;;;cAuBa,QAAA,GAAY,YAAA,kBAAkB,OAAA;AAAA,cAG9B,UAAA,GAAc,OAAA,OAAc,UAAA,OAAiB,IAAA,sBAAU,MAAA,gCAAA,KAAA,CAAA,cAAA,CAAA,KAAA,CAAA,YAAA;AAAA,cAKvD,MAAA,GAAU,YAAA,WAC4C,QAAA,CAD1B,SAAA;AAAA,cAG5B,OAAA,GAAW,OAAA,OAAc,IAAS;AAAA,cAGlC,WAAA,GAAe,QAAA,OAAe,IAAS;AAAA,cAKvC,SAAA,GAAa,MAAA,OAAa,IAAU;AAAA,cAIpC,eAAA,GAAmB,MAAA,OAAa,IAAU;AAAA,cAG1C,cAAA,GAAkB,QAAa;AAAA,cAM/B,GAAA,GAAO,MAAW;AAAA,cAKlB,UAAA,GAAc,OAAY"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { peekResourceFiber } from "../core/helpers/execution-context.js";
|
|
2
|
+
import { useReducer as useReducer$2 } from "../hooks/useReducer.js";
|
|
3
|
+
import { useState as useState$2 } from "../hooks/useState.js";
|
|
4
|
+
import { useRef as useRef$2 } from "../hooks/useRef.js";
|
|
5
|
+
import { useMemo as useMemo$2 } from "../hooks/useMemo.js";
|
|
6
|
+
import { useCallback as useCallback$1 } from "../hooks/useCallback.js";
|
|
7
|
+
import { useEffect as useEffect$1 } from "../hooks/useEffect.js";
|
|
8
|
+
import { useEffectEvent as useEffectEvent$1 } from "../hooks/useEffectEvent.js";
|
|
9
|
+
import { isResourceContext, useResourceContext } from "../core/context.js";
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import react_default from "react";
|
|
12
|
+
export * from "react";
|
|
13
|
+
//#region src/react-shim/index.ts
|
|
14
|
+
const inTap = () => peekResourceFiber() !== null;
|
|
15
|
+
const useState = (initialState) => inTap() ? useState$2(initialState) : React.useState(initialState);
|
|
16
|
+
const useReducer = (reducer, initialArg, init) => inTap() ? useReducer$2(reducer, initialArg, init) : React.useReducer(reducer, initialArg, init);
|
|
17
|
+
const useRef = (initialValue) => inTap() ? useRef$2(initialValue) : React.useRef(initialValue);
|
|
18
|
+
const useMemo = (factory, deps) => inTap() ? useMemo$2(factory, deps) : React.useMemo(factory, deps);
|
|
19
|
+
const useCallback = (callback, deps) => inTap() ? useCallback$1(callback, deps) : React.useCallback(callback, deps);
|
|
20
|
+
const useEffect = (effect, deps) => inTap() ? useEffect$1(effect, deps) : React.useEffect(effect, deps);
|
|
21
|
+
const useLayoutEffect = (effect, deps) => inTap() ? useEffect$1(effect, deps) : React.useLayoutEffect(effect, deps);
|
|
22
|
+
const useEffectEvent = (callback) => inTap() ? useEffectEvent$1(callback) : React.useEffectEvent(callback);
|
|
23
|
+
const use = (usable) => isResourceContext(usable) ? useResourceContext(usable) : React.use(usable);
|
|
24
|
+
const useContext = (context) => isResourceContext(context) ? useResourceContext(context) : React.useContext(context);
|
|
25
|
+
//#endregion
|
|
26
|
+
export { react_default as default, use, useCallback, useContext, useEffect, useEffectEvent, useLayoutEffect, useMemo, useReducer, useRef, useState };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["hooks.useState","hooks.useReducer","hooks.useRef","hooks.useMemo","hooks.useCallback","hooks.useEffect","hooks.useEffectEvent"],"sources":["../../src/react-shim/index.ts"],"sourcesContent":["/* oxlint-disable react/rules-of-hooks -- this module deliberately routes hook calls between tap and React at runtime */\n/* oxlint-disable react/exhaustive-deps -- dependency arrays are forwarded verbatim from the caller */\n// Runtime drop-in for \"react\": forward everything from react, then override the\n// hooks that have a tap equivalent so they route to tap inside a resource render\n// and to React otherwise. Alias `react` to this module (build `output.paths` /\n// vitest resolver) in code that can run inside a tap resource.\n//\n// This subpath ships no type declarations: the build reverts the aliased\n// specifier back to `\"react\"` in emitted `.d.ts`, so consumer types resolve to\n// React's own. The source-level TS2498 from the `export *` below is suppressed.\nimport * as React from \"react\";\nimport { peekResourceFiber } from \"../core/helpers/execution-context\";\nimport * as hooks from \"../hooks\";\nimport { useResourceContext, isResourceContext } from \"../core/context\";\n\n// @ts-expect-error -- @types/react uses `export =`; this is valid at runtime.\nexport * from \"react\";\nexport { default } from \"react\";\n\nconst inTap = () => peekResourceFiber() !== null;\n\n// --- hooks with a tap equivalent: override the star-exported react hooks ---\n\nexport const useState = (initialState?: any) =>\n inTap() ? hooks.useState(initialState) : React.useState(initialState);\n\nexport const useReducer = (reducer: any, initialArg: any, init?: any) =>\n inTap()\n ? hooks.useReducer(reducer, initialArg, init)\n : React.useReducer(reducer, initialArg, init);\n\nexport const useRef = (initialValue?: any) =>\n inTap() ? hooks.useRef(initialValue) : React.useRef(initialValue);\n\nexport const useMemo = (factory: any, deps: any) =>\n inTap() ? hooks.useMemo(factory, deps) : React.useMemo(factory, deps);\n\nexport const useCallback = (callback: any, deps: any) =>\n inTap()\n ? hooks.useCallback(callback, deps)\n : React.useCallback(callback, deps);\n\nexport const useEffect = (effect: any, deps?: any) =>\n inTap() ? hooks.useEffect(effect, deps) : React.useEffect(effect, deps);\n\n// tap has a single effect primitive; layout effects collapse onto it\nexport const useLayoutEffect = (effect: any, deps?: any) =>\n inTap() ? hooks.useEffect(effect, deps) : React.useLayoutEffect(effect, deps);\n\nexport const useEffectEvent = (callback: any) =>\n inTap() ? hooks.useEffectEvent(callback) : React.useEffectEvent(callback);\n\n// `use(usable)` reads tap resource context when handed a tap context (routed by\n// its brand, not by ambient render state), and falls back to React's `use`\n// (promises / React context) for everything else.\nexport const use = (usable: any) =>\n isResourceContext(usable) ? useResourceContext(usable) : React.use(usable);\n\n// `useContext(context)` reads tap resource context when handed a tap context\n// (routed by its brand), and falls back to React's `useContext` otherwise.\nexport const useContext = (context: any) =>\n isResourceContext(context)\n ? useResourceContext(context)\n : React.useContext(context);\n"],"mappings":";;;;;;;;;;;;;AAmBA,MAAM,cAAc,kBAAkB,MAAM;AAI5C,MAAa,YAAY,iBACvB,MAAM,IAAIA,WAAe,YAAY,IAAI,MAAM,SAAS,YAAY;AAEtE,MAAa,cAAc,SAAc,YAAiB,SACxD,MAAM,IACFC,aAAiB,SAAS,YAAY,IAAI,IAC1C,MAAM,WAAW,SAAS,YAAY,IAAI;AAEhD,MAAa,UAAU,iBACrB,MAAM,IAAIC,SAAa,YAAY,IAAI,MAAM,OAAO,YAAY;AAElE,MAAa,WAAW,SAAc,SACpC,MAAM,IAAIC,UAAc,SAAS,IAAI,IAAI,MAAM,QAAQ,SAAS,IAAI;AAEtE,MAAa,eAAe,UAAe,SACzC,MAAM,IACFC,cAAkB,UAAU,IAAI,IAChC,MAAM,YAAY,UAAU,IAAI;AAEtC,MAAa,aAAa,QAAa,SACrC,MAAM,IAAIC,YAAgB,QAAQ,IAAI,IAAI,MAAM,UAAU,QAAQ,IAAI;AAGxE,MAAa,mBAAmB,QAAa,SAC3C,MAAM,IAAIA,YAAgB,QAAQ,IAAI,IAAI,MAAM,gBAAgB,QAAQ,IAAI;AAE9E,MAAa,kBAAkB,aAC7B,MAAM,IAAIC,iBAAqB,QAAQ,IAAI,MAAM,eAAe,QAAQ;AAK1E,MAAa,OAAO,WAClB,kBAAkB,MAAM,IAAI,mBAAmB,MAAM,IAAI,MAAM,IAAI,MAAM;AAI3E,MAAa,cAAc,YACzB,kBAAkB,OAAO,IACrB,mBAAmB,OAAO,IAC1B,MAAM,WAAW,OAAO"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assistant-ui/tap",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Reactive state management inspired by React hooks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"state-management",
|
|
7
7
|
"reactive",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
18
|
"default": "./dist/index.js"
|
|
19
19
|
},
|
|
20
|
-
"./react": {
|
|
21
|
-
"types":
|
|
22
|
-
"default": "./dist/react/index.js"
|
|
20
|
+
"./react-shim": {
|
|
21
|
+
"types": null,
|
|
22
|
+
"default": "./dist/react-shim/index.js"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"main": "./dist/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"files": [
|
|
28
28
|
"dist",
|
|
29
29
|
"src",
|
|
30
|
-
"react",
|
|
30
|
+
"react-shim",
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"sideEffects": false,
|
|
@@ -38,23 +38,20 @@
|
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@types/react": {
|
|
40
40
|
"optional": true
|
|
41
|
-
},
|
|
42
|
-
"react": {
|
|
43
|
-
"optional": true
|
|
44
41
|
}
|
|
45
42
|
},
|
|
46
43
|
"devDependencies": {
|
|
47
44
|
"@testing-library/dom": "^10.4.1",
|
|
48
45
|
"@testing-library/react": "^16.3.2",
|
|
49
|
-
"@types/node": "^25.9.
|
|
50
|
-
"@types/react": "^19.2.
|
|
46
|
+
"@types/node": "^25.9.2",
|
|
47
|
+
"@types/react": "^19.2.17",
|
|
51
48
|
"@types/react-dom": "^19.2.3",
|
|
52
|
-
"@vitest/ui": "^4.1.
|
|
49
|
+
"@vitest/ui": "^4.1.8",
|
|
53
50
|
"jsdom": "^29.1.1",
|
|
54
|
-
"react": "^19.2.
|
|
55
|
-
"react-dom": "^19.2.
|
|
56
|
-
"vitest": "^4.1.
|
|
57
|
-
"@assistant-ui/x-buildutils": "0.0.
|
|
51
|
+
"react": "^19.2.7",
|
|
52
|
+
"react-dom": "^19.2.7",
|
|
53
|
+
"vitest": "^4.1.8",
|
|
54
|
+
"@assistant-ui/x-buildutils": "0.0.12"
|
|
58
55
|
},
|
|
59
56
|
"publishConfig": {
|
|
60
57
|
"access": "public",
|
|
@@ -4,7 +4,7 @@ import { resource } from "../../core/resource";
|
|
|
4
4
|
|
|
5
5
|
describe("ResourceHandle - Basic Usage", () => {
|
|
6
6
|
it("should create a resource handle with const API", () => {
|
|
7
|
-
const TestResource = resource((props: number)
|
|
7
|
+
const TestResource = resource(function TestResource(props: number) {
|
|
8
8
|
return {
|
|
9
9
|
value: props * 2,
|
|
10
10
|
propsUsed: props,
|
|
@@ -24,7 +24,9 @@ describe("ResourceHandle - Basic Usage", () => {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it("should allow updating props", () => {
|
|
27
|
-
const TestResource = resource((props: {
|
|
27
|
+
const TestResource = resource(function TestResource(props: {
|
|
28
|
+
multiplier: number;
|
|
29
|
+
}) {
|
|
28
30
|
return { result: 10 * props.multiplier };
|
|
29
31
|
});
|
|
30
32
|
const root = createResourceRoot();
|
|
@@ -38,7 +40,9 @@ describe("ResourceHandle - Basic Usage", () => {
|
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
it("should support subscribing and unsubscribing", () => {
|
|
41
|
-
const TestResource = resource(()
|
|
43
|
+
const TestResource = resource(function TestResource() {
|
|
44
|
+
return { timestamp: Date.now() };
|
|
45
|
+
});
|
|
42
46
|
const root = createResourceRoot();
|
|
43
47
|
const sub = root.render(TestResource());
|
|
44
48
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useEffect } from "../../hooks/useEffect";
|
|
3
|
+
import { useState } from "../../hooks/useState";
|
|
4
4
|
import {
|
|
5
5
|
createTestResource,
|
|
6
6
|
renderTest,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
TestResourceManager,
|
|
9
9
|
} from "../test-utils";
|
|
10
10
|
|
|
11
|
-
describe("
|
|
11
|
+
describe("useEffect - Basic Functionality", () => {
|
|
12
12
|
afterEach(() => {
|
|
13
13
|
cleanupAllResources();
|
|
14
14
|
});
|
|
@@ -20,7 +20,7 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
20
20
|
const testFiber = createTestResource(() => {
|
|
21
21
|
executionOrder.push("render");
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
useEffect(() => {
|
|
24
24
|
executionOrder.push("effect");
|
|
25
25
|
});
|
|
26
26
|
|
|
@@ -44,7 +44,7 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
44
44
|
const effect = vi.fn(() => cleanup);
|
|
45
45
|
|
|
46
46
|
const testFiber = createTestResource(() => {
|
|
47
|
-
|
|
47
|
+
useEffect(effect);
|
|
48
48
|
return null;
|
|
49
49
|
});
|
|
50
50
|
|
|
@@ -64,15 +64,15 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
64
64
|
const cleanupOrder: string[] = [];
|
|
65
65
|
|
|
66
66
|
const testFiber = createTestResource(() => {
|
|
67
|
-
|
|
67
|
+
useEffect(() => {
|
|
68
68
|
return () => cleanupOrder.push("first");
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
useEffect(() => {
|
|
72
72
|
return () => cleanupOrder.push("second");
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
useEffect(() => {
|
|
76
76
|
return () => cleanupOrder.push("third");
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -91,7 +91,7 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
91
91
|
describe("Multiple Effects", () => {
|
|
92
92
|
it("should execute multiple effects in registration order", () => {
|
|
93
93
|
const executionOrder: string[] = [];
|
|
94
|
-
const effects:
|
|
94
|
+
const effects: useEffect.EffectCallback[] = [
|
|
95
95
|
() => {
|
|
96
96
|
executionOrder.push("effect1");
|
|
97
97
|
return undefined;
|
|
@@ -107,8 +107,7 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
107
107
|
];
|
|
108
108
|
|
|
109
109
|
const testFiber = createTestResource(() => {
|
|
110
|
-
|
|
111
|
-
effects.forEach((fn) => tapEffect(fn));
|
|
110
|
+
effects.forEach((fn) => useEffect(fn));
|
|
112
111
|
return null;
|
|
113
112
|
});
|
|
114
113
|
|
|
@@ -125,18 +124,17 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
125
124
|
|
|
126
125
|
const testFiber = createTestResource((props: { value: number }) => {
|
|
127
126
|
// Effect without deps - runs on every render
|
|
128
|
-
|
|
127
|
+
useEffect(() => {
|
|
129
128
|
effectCalls.always++;
|
|
130
129
|
});
|
|
131
130
|
|
|
132
131
|
// Effect with empty deps - runs only once
|
|
133
|
-
|
|
132
|
+
useEffect(() => {
|
|
134
133
|
effectCalls.once++;
|
|
135
134
|
}, []);
|
|
136
135
|
|
|
137
136
|
// Effect with deps - runs when deps change
|
|
138
|
-
|
|
139
|
-
tapEffect(() => {
|
|
137
|
+
useEffect(() => {
|
|
140
138
|
effectCalls.conditional++;
|
|
141
139
|
}, [props.value]);
|
|
142
140
|
|
|
@@ -163,13 +161,13 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
163
161
|
let triggerRerender: (() => void) | null = null;
|
|
164
162
|
|
|
165
163
|
const testFiber = createTestResource(() => {
|
|
166
|
-
const [, setState] =
|
|
164
|
+
const [, setState] = useState(0);
|
|
167
165
|
|
|
168
|
-
|
|
166
|
+
useEffect(() => {
|
|
169
167
|
triggerRerender = () => setState((prev) => prev + 1);
|
|
170
168
|
});
|
|
171
169
|
|
|
172
|
-
|
|
170
|
+
useEffect(effect, []);
|
|
173
171
|
|
|
174
172
|
return null;
|
|
175
173
|
});
|
|
@@ -189,7 +187,7 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
189
187
|
const effect = vi.fn();
|
|
190
188
|
|
|
191
189
|
const testFiber = createTestResource((props: { dep: string }) => {
|
|
192
|
-
|
|
190
|
+
useEffect(() => {
|
|
193
191
|
effect(props.dep);
|
|
194
192
|
}, [props.dep]);
|
|
195
193
|
|
|
@@ -217,11 +215,11 @@ describe("tapEffect - Basic Functionality", () => {
|
|
|
217
215
|
const events: string[] = [];
|
|
218
216
|
|
|
219
217
|
const testFiber = createTestResource(() => {
|
|
220
|
-
const [count, setCount] =
|
|
218
|
+
const [count, setCount] = useState(0);
|
|
221
219
|
|
|
222
220
|
events.push(`render: ${count}`);
|
|
223
221
|
|
|
224
|
-
|
|
222
|
+
useEffect(() => {
|
|
225
223
|
events.push(`effect: ${count}`);
|
|
226
224
|
|
|
227
225
|
// Only update on first effect to avoid infinite loop
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, afterEach } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { useReducer } from "../../hooks/useReducer";
|
|
3
|
+
import { useEffect } from "../../hooks/useEffect";
|
|
4
4
|
import {
|
|
5
5
|
createTestResource,
|
|
6
6
|
renderTest,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
getCommittedOutput,
|
|
10
10
|
} from "../test-utils";
|
|
11
11
|
|
|
12
|
-
describe("
|
|
12
|
+
describe("useReducer - Basic Functionality", () => {
|
|
13
13
|
afterEach(() => {
|
|
14
14
|
cleanupAllResources();
|
|
15
15
|
});
|
|
@@ -19,7 +19,7 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
19
19
|
const reducer = (state: number, action: number) => state + action;
|
|
20
20
|
|
|
21
21
|
const testFiber = createTestResource(() => {
|
|
22
|
-
const [count] =
|
|
22
|
+
const [count] = useReducer(reducer, 0);
|
|
23
23
|
return count;
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -32,7 +32,7 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
32
32
|
const reducer = (state: number, action: number) => state + action;
|
|
33
33
|
|
|
34
34
|
const testFiber = createTestResource(() => {
|
|
35
|
-
const [count] =
|
|
35
|
+
const [count] = useReducer(reducer, 10, (arg) => {
|
|
36
36
|
initCalled++;
|
|
37
37
|
return arg * 2;
|
|
38
38
|
});
|
|
@@ -64,9 +64,9 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
64
64
|
let dispatchFn: ((action: Action) => void) | null = null;
|
|
65
65
|
|
|
66
66
|
const testFiber = createTestResource(() => {
|
|
67
|
-
const [count, dispatch] =
|
|
67
|
+
const [count, dispatch] = useReducer(reducer, 0);
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
useEffect(() => {
|
|
70
70
|
dispatchFn = dispatch;
|
|
71
71
|
});
|
|
72
72
|
|
|
@@ -100,9 +100,9 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
100
100
|
|
|
101
101
|
const testFiber = createTestResource(() => {
|
|
102
102
|
renderCount++;
|
|
103
|
-
const [count, dispatch] =
|
|
103
|
+
const [count, dispatch] = useReducer(reducer, 42);
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
useEffect(() => {
|
|
106
106
|
dispatchFn = dispatch;
|
|
107
107
|
});
|
|
108
108
|
|
|
@@ -127,9 +127,9 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
127
127
|
const testFiber = createTestResource(() => {
|
|
128
128
|
const reducer = (state: number, action: number) =>
|
|
129
129
|
state + action * multiplier;
|
|
130
|
-
const [count, dispatch] =
|
|
130
|
+
const [count, dispatch] = useReducer(reducer, 0);
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
useEffect(() => {
|
|
133
133
|
dispatchFn = dispatch;
|
|
134
134
|
});
|
|
135
135
|
|
|
@@ -159,9 +159,9 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
159
159
|
let dispatchFn: ((action: number) => void) | null = null;
|
|
160
160
|
|
|
161
161
|
const testFiber = createTestResource(() => {
|
|
162
|
-
const [count, dispatch] =
|
|
162
|
+
const [count, dispatch] = useReducer(reducer, 0);
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
useEffect(() => {
|
|
165
165
|
dispatchFn = dispatch;
|
|
166
166
|
});
|
|
167
167
|
|
|
@@ -186,7 +186,7 @@ describe("tapReducer - Basic Functionality", () => {
|
|
|
186
186
|
const dispatches: ((action: number) => void)[] = [];
|
|
187
187
|
|
|
188
188
|
const testFiber = createTestResource(() => {
|
|
189
|
-
const [count, dispatch] =
|
|
189
|
+
const [count, dispatch] = useReducer(reducer, 0);
|
|
190
190
|
dispatches.push(dispatch);
|
|
191
191
|
return count;
|
|
192
192
|
});
|