@assistant-ui/tap 0.6.1 → 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.
Files changed (213) hide show
  1. package/README.md +9 -6
  2. package/dist/core/ResourceFiber.d.ts +5 -5
  3. package/dist/core/ResourceFiber.d.ts.map +1 -1
  4. package/dist/core/ResourceFiber.js +26 -18
  5. package/dist/core/ResourceFiber.js.map +1 -1
  6. package/dist/core/createTapRoot.d.ts +9 -0
  7. package/dist/core/createTapRoot.d.ts.map +1 -0
  8. package/dist/core/createTapRoot.js +27 -0
  9. package/dist/core/createTapRoot.js.map +1 -0
  10. package/dist/core/helpers/commit.d.ts +1 -1
  11. package/dist/core/helpers/commit.d.ts.map +1 -1
  12. package/dist/core/helpers/commit.js +6 -1
  13. package/dist/core/helpers/commit.js.map +1 -1
  14. package/dist/core/helpers/execution-context.d.ts +4 -5
  15. package/dist/core/helpers/execution-context.d.ts.map +1 -1
  16. package/dist/core/helpers/execution-context.js +1 -7
  17. package/dist/core/helpers/execution-context.js.map +1 -1
  18. package/dist/core/helpers/root.d.ts +3 -2
  19. package/dist/core/helpers/root.d.ts.map +1 -1
  20. package/dist/core/helpers/root.js +19 -15
  21. package/dist/core/helpers/root.js.map +1 -1
  22. package/dist/core/react-dispatcher.d.ts.map +1 -1
  23. package/dist/core/react-dispatcher.js +14 -14
  24. package/dist/core/react-dispatcher.js.map +1 -1
  25. package/dist/core/resource.d.ts +2 -4
  26. package/dist/core/resource.d.ts.map +1 -1
  27. package/dist/core/resource.js +5 -10
  28. package/dist/core/resource.js.map +1 -1
  29. package/dist/core/scheduler.d.ts +2 -2
  30. package/dist/core/scheduler.d.ts.map +1 -1
  31. package/dist/core/scheduler.js +2 -2
  32. package/dist/core/scheduler.js.map +1 -1
  33. package/dist/core/types.d.ts +27 -25
  34. package/dist/core/types.d.ts.map +1 -1
  35. package/dist/hooks/useResource.d.ts +2 -2
  36. package/dist/hooks/useResource.d.ts.map +1 -1
  37. package/dist/hooks/useResource.js +14 -20
  38. package/dist/hooks/useResource.js.map +1 -1
  39. package/dist/hooks/useResources.d.ts +1 -1
  40. package/dist/hooks/useResources.d.ts.map +1 -1
  41. package/dist/hooks/useResources.js +18 -27
  42. package/dist/hooks/useResources.js.map +1 -1
  43. package/dist/hooks/useTapHost.d.ts +21 -0
  44. package/dist/hooks/useTapHost.d.ts.map +1 -0
  45. package/dist/hooks/useTapHost.js +30 -0
  46. package/dist/hooks/useTapHost.js.map +1 -0
  47. package/dist/hooks/useTapRoot.d.ts +18 -0
  48. package/dist/hooks/useTapRoot.d.ts.map +1 -0
  49. package/dist/hooks/useTapRoot.js +77 -0
  50. package/dist/hooks/useTapRoot.js.map +1 -0
  51. package/dist/hooks/utils/depsShallowEqual.d.ts.map +1 -1
  52. package/dist/hooks/utils/depsShallowEqual.js +5 -2
  53. package/dist/hooks/utils/depsShallowEqual.js.map +1 -1
  54. package/dist/hooks/utils/useCell.d.ts +2 -2
  55. package/dist/hooks/utils/useCell.d.ts.map +1 -1
  56. package/dist/hooks/utils/useCell.js.map +1 -1
  57. package/dist/hooks/utils/useDevStrictMode.d.ts +5 -0
  58. package/dist/hooks/utils/useDevStrictMode.d.ts.map +1 -0
  59. package/dist/hooks/utils/useDevStrictMode.js +25 -0
  60. package/dist/hooks/utils/useDevStrictMode.js.map +1 -0
  61. package/dist/hooks/utils/useRenderMemo.d.ts +5 -0
  62. package/dist/hooks/utils/useRenderMemo.d.ts.map +1 -0
  63. package/dist/hooks/utils/useRenderMemo.js +25 -0
  64. package/dist/hooks/utils/useRenderMemo.js.map +1 -0
  65. package/dist/hooks/utils/useResourceFiberHostUtils.d.ts +10 -0
  66. package/dist/hooks/utils/useResourceFiberHostUtils.d.ts.map +1 -0
  67. package/dist/hooks/utils/useResourceFiberHostUtils.js +46 -0
  68. package/dist/hooks/utils/useResourceFiberHostUtils.js.map +1 -0
  69. package/dist/index.d.ts +7 -4
  70. package/dist/index.js +7 -4
  71. package/dist/{hooks → react-hooks}/index.d.ts +6 -6
  72. package/dist/{hooks → react-hooks}/index.js +5 -5
  73. package/dist/{hooks → react-hooks}/use.d.ts +1 -1
  74. package/dist/{hooks → react-hooks}/use.d.ts.map +1 -1
  75. package/dist/{hooks → react-hooks}/use.js +1 -1
  76. package/dist/react-hooks/use.js.map +1 -0
  77. package/dist/{hooks → react-hooks}/useCallback.d.ts +1 -1
  78. package/dist/react-hooks/useCallback.d.ts.map +1 -0
  79. package/dist/{hooks → react-hooks}/useCallback.js +1 -1
  80. package/dist/react-hooks/useCallback.js.map +1 -0
  81. package/dist/{hooks → react-hooks}/useEffect.d.ts +1 -1
  82. package/dist/react-hooks/useEffect.d.ts.map +1 -0
  83. package/dist/react-hooks/useEffect.js +35 -0
  84. package/dist/react-hooks/useEffect.js.map +1 -0
  85. package/dist/{hooks → react-hooks}/useEffectEvent.d.ts +1 -1
  86. package/dist/react-hooks/useEffectEvent.d.ts.map +1 -0
  87. package/dist/{hooks → react-hooks}/useEffectEvent.js +2 -2
  88. package/dist/react-hooks/useEffectEvent.js.map +1 -0
  89. package/dist/{hooks → react-hooks}/useMemo.d.ts +1 -1
  90. package/dist/react-hooks/useMemo.d.ts.map +1 -0
  91. package/dist/{hooks → react-hooks}/useMemo.js +3 -3
  92. package/dist/react-hooks/useMemo.js.map +1 -0
  93. package/dist/{hooks → react-hooks}/useMemoCache.d.ts +1 -1
  94. package/dist/react-hooks/useMemoCache.d.ts.map +1 -0
  95. package/dist/{hooks → react-hooks}/useMemoCache.js +1 -1
  96. package/dist/react-hooks/useMemoCache.js.map +1 -0
  97. package/dist/react-hooks/useReducer.d.ts +9 -0
  98. package/dist/react-hooks/useReducer.d.ts.map +1 -0
  99. package/dist/react-hooks/useReducer.js +120 -0
  100. package/dist/react-hooks/useReducer.js.map +1 -0
  101. package/dist/{hooks → react-hooks}/useRef.d.ts +1 -1
  102. package/dist/react-hooks/useRef.d.ts.map +1 -0
  103. package/dist/{hooks → react-hooks}/useRef.js +1 -1
  104. package/dist/react-hooks/useRef.js.map +1 -0
  105. package/dist/{hooks → react-hooks}/useState.d.ts +1 -1
  106. package/dist/react-hooks/useState.d.ts.map +1 -0
  107. package/dist/{hooks → react-hooks}/useState.js +3 -3
  108. package/dist/react-hooks/useState.js.map +1 -0
  109. package/dist/react-shim/index.js +11 -11
  110. package/dist/react-shim/index.js.map +1 -1
  111. package/package.json +1 -1
  112. package/src/__tests__/basic/resourceHandle.test.ts +32 -22
  113. package/src/__tests__/basic/tapEffect.basic.test.ts +8 -8
  114. package/src/__tests__/basic/tapReducer.basic.test.ts +16 -14
  115. package/src/__tests__/basic/tapResources.basic.test.ts +19 -16
  116. package/src/__tests__/basic/tapState.basic.test.ts +11 -11
  117. package/src/__tests__/bench/hosts.bench.tsx +124 -0
  118. package/src/__tests__/bench/tree.bench.tsx +166 -0
  119. package/src/__tests__/errors/errors.effect-errors.test.ts +12 -13
  120. package/src/__tests__/errors/errors.render-errors.test.ts +65 -22
  121. package/src/__tests__/lifecycle/lifecycle.dependencies.test.ts +19 -19
  122. package/src/__tests__/lifecycle/lifecycle.mount-unmount.test.ts +14 -14
  123. package/src/__tests__/parity/describeParity.tsx +217 -0
  124. package/src/__tests__/parity/parity.adversarial.test.tsx +375 -0
  125. package/src/__tests__/parity/parity.basics.test.tsx +281 -0
  126. package/src/__tests__/parity/parity.divergences.test.tsx +208 -0
  127. package/src/__tests__/parity/parity.smoke.test.tsx +43 -0
  128. package/src/__tests__/react/concurrent-mode.test.tsx +10 -6
  129. package/src/__tests__/react/concurrent-pending-updates.test.tsx +351 -0
  130. package/src/__tests__/react/concurrent-render-phase.test.tsx +350 -0
  131. package/src/__tests__/react/react-shim.test.tsx +1 -1
  132. package/src/__tests__/react/useResource.test.tsx +41 -26
  133. package/src/__tests__/react/useTapHost.test.tsx +233 -0
  134. package/src/__tests__/react-dispatcher.test.ts +4 -4
  135. package/src/__tests__/rules/rules.hook-count.test.ts +21 -21
  136. package/src/__tests__/rules/rules.hook-order.test.ts +17 -17
  137. package/src/__tests__/strictmode/strictmode-parity.test.tsx +420 -0
  138. package/src/__tests__/strictmode/strictmode.test.ts +39 -209
  139. package/src/__tests__/test-utils.ts +33 -23
  140. package/src/core/ResourceFiber.ts +43 -35
  141. package/src/core/createTapRoot.ts +45 -0
  142. package/src/core/helpers/commit.ts +12 -2
  143. package/src/core/helpers/execution-context.ts +4 -13
  144. package/src/core/helpers/root.ts +24 -12
  145. package/src/core/react-dispatcher.ts +10 -9
  146. package/src/core/resource.ts +5 -20
  147. package/src/core/scheduler.ts +1 -1
  148. package/src/core/types.ts +27 -21
  149. package/src/hooks/useResource.ts +18 -27
  150. package/src/hooks/useResources.ts +18 -42
  151. package/src/hooks/useTapHost.ts +60 -0
  152. package/src/hooks/useTapRoot.ts +135 -0
  153. package/src/hooks/utils/depsShallowEqual.ts +12 -2
  154. package/src/hooks/utils/useCell.ts +2 -2
  155. package/src/hooks/utils/useDevStrictMode.ts +34 -0
  156. package/src/hooks/utils/useRenderMemo.ts +27 -0
  157. package/src/hooks/utils/useResourceFiberHostUtils.ts +61 -0
  158. package/src/index.ts +6 -3
  159. package/src/{hooks → react-hooks}/index.ts +4 -4
  160. package/src/react-hooks/useEffect.ts +58 -0
  161. package/src/{hooks → react-hooks}/useMemo.ts +1 -1
  162. package/src/react-hooks/useReducer.ts +254 -0
  163. package/src/{hooks → react-hooks}/useState.ts +2 -2
  164. package/src/react-shim/index.ts +1 -1
  165. package/dist/core/createResourceRoot.d.ts +0 -11
  166. package/dist/core/createResourceRoot.d.ts.map +0 -1
  167. package/dist/core/createResourceRoot.js +0 -31
  168. package/dist/core/createResourceRoot.js.map +0 -1
  169. package/dist/core/helpers/callResourceFn.d.ts +0 -1
  170. package/dist/core/helpers/callResourceFn.js +0 -19
  171. package/dist/core/helpers/callResourceFn.js.map +0 -1
  172. package/dist/hooks/use.js.map +0 -1
  173. package/dist/hooks/useCallback.d.ts.map +0 -1
  174. package/dist/hooks/useCallback.js.map +0 -1
  175. package/dist/hooks/useEffect.d.ts.map +0 -1
  176. package/dist/hooks/useEffect.js +0 -40
  177. package/dist/hooks/useEffect.js.map +0 -1
  178. package/dist/hooks/useEffectEvent.d.ts.map +0 -1
  179. package/dist/hooks/useEffectEvent.js.map +0 -1
  180. package/dist/hooks/useMemo.d.ts.map +0 -1
  181. package/dist/hooks/useMemo.js.map +0 -1
  182. package/dist/hooks/useMemoCache.d.ts.map +0 -1
  183. package/dist/hooks/useMemoCache.js.map +0 -1
  184. package/dist/hooks/useReducer.d.ts +0 -21
  185. package/dist/hooks/useReducer.d.ts.map +0 -1
  186. package/dist/hooks/useReducer.js +0 -81
  187. package/dist/hooks/useReducer.js.map +0 -1
  188. package/dist/hooks/useRef.d.ts.map +0 -1
  189. package/dist/hooks/useRef.js.map +0 -1
  190. package/dist/hooks/useResourceRoot.d.ts +0 -20
  191. package/dist/hooks/useResourceRoot.d.ts.map +0 -1
  192. package/dist/hooks/useResourceRoot.js +0 -77
  193. package/dist/hooks/useResourceRoot.js.map +0 -1
  194. package/dist/hooks/useState.d.ts.map +0 -1
  195. package/dist/hooks/useState.js.map +0 -1
  196. package/dist/react/hooks.d.ts +0 -25
  197. package/dist/react/hooks.d.ts.map +0 -1
  198. package/dist/react/hooks.js +0 -69
  199. package/dist/react/hooks.js.map +0 -1
  200. package/src/__tests__/strictmode/react-strictmode-behavior.test.tsx +0 -920
  201. package/src/__tests__/strictmode/react-strictmode-rerender-sources.test.tsx +0 -488
  202. package/src/__tests__/strictmode/tap-strictmode-rerender-sources.test.ts +0 -687
  203. package/src/core/createResourceRoot.ts +0 -53
  204. package/src/core/helpers/callResourceFn.ts +0 -21
  205. package/src/hooks/useEffect.ts +0 -72
  206. package/src/hooks/useReducer.ts +0 -160
  207. package/src/hooks/useResourceRoot.ts +0 -130
  208. package/src/react/hooks.ts +0 -112
  209. /package/src/{hooks → react-hooks}/use.ts +0 -0
  210. /package/src/{hooks → react-hooks}/useCallback.ts +0 -0
  211. /package/src/{hooks → react-hooks}/useEffectEvent.ts +0 -0
  212. /package/src/{hooks → react-hooks}/useMemoCache.ts +0 -0
  213. /package/src/{hooks → react-hooks}/useRef.ts +0 -0
@@ -1,65 +1,67 @@
1
- import { useEffect } from "../hooks/useEffect.js";
2
-
3
1
  //#region src/core/types.d.ts
4
- type ResourceElement<R, P = any> = {
5
- readonly type: Resource<R, P>;
6
- readonly props: P;
2
+ type ResourceElement<R, A extends readonly unknown[] = any[]> = {
3
+ readonly hook: (...args: A) => R;
4
+ readonly args: Readonly<A>;
7
5
  readonly key?: string | number;
8
6
  };
9
- type Resource<R, P> = (props: P) => ResourceElement<R, P>;
10
- type ContravariantResource<R, P> = (props: P) => ResourceElement<R>;
7
+ type Resource<R, A extends readonly unknown[] = any[]> = (...args: A) => ResourceElement<R, A>;
8
+ type ContravariantResource<R, A extends readonly unknown[] = any[]> = (...args: A) => ResourceElement<R>;
11
9
  type ExtractResourceReturnType<T> = T extends ResourceElement<infer R, any> ? R : T extends Resource<infer R, any> ? R : never;
12
- interface ReducerQueueEntry {
10
+ interface ChangelogRecord {
11
+ readonly fiber: ResourceFiber<any, any>;
12
+ readonly cell: Cell & {
13
+ type: "reducer";
14
+ };
13
15
  readonly action: any;
14
16
  hasEagerState: boolean;
15
17
  eagerState: any;
18
+ queued: boolean;
16
19
  }
17
20
  type Cell = {
18
21
  readonly type: "reducer";
19
22
  readonly dispatch: (action: any) => void;
20
- readonly queue: Set<ReducerQueueEntry>;
21
- dirty: boolean;
23
+ queue: ChangelogRecord[] | null;
24
+ renderQueue: any[] | null;
22
25
  workInProgress: any;
23
26
  current: any;
24
27
  reducer: (state: any, action: any) => any;
25
28
  } | {
26
29
  readonly type: "effect";
27
- cleanup: useEffect.Destructor | undefined;
30
+ cleanup: (() => void) | undefined;
28
31
  deps: readonly unknown[] | null | undefined;
29
32
  };
30
33
  interface EffectTask {
31
- readonly effect: useEffect.EffectCallback;
32
- readonly deps: readonly unknown[] | undefined;
33
- readonly cell: Cell & {
34
- type: "effect";
35
- };
34
+ readonly cleanup: () => void;
35
+ readonly setup: () => void;
36
36
  }
37
37
  interface RenderResult {
38
- readonly output: any;
39
- readonly props: any;
40
- readonly effectTasks: (() => void)[];
38
+ value: any;
39
+ effectTasks: EffectTask[];
41
40
  }
42
41
  interface ResourceFiberRoot {
43
42
  version: number;
44
43
  committedVersion: number;
45
- readonly changelog: (() => void)[];
44
+ readonly changelog: ChangelogRecord[];
46
45
  readonly dispatchUpdate: (callback: () => boolean) => void;
47
- readonly dirtyCells: (Cell & {
46
+ readonly dirtyCells: Set<Cell & {
48
47
  type: "reducer";
49
- })[];
48
+ }>;
50
49
  }
51
- interface ResourceFiber<R, P> {
50
+ interface ResourceFiber<R, A extends readonly unknown[] = any[]> {
52
51
  readonly root: ResourceFiberRoot;
53
- readonly type: Resource<R, P>;
52
+ readonly hook: (...args: A) => R;
54
53
  readonly markDirty: (() => void) | undefined;
55
54
  readonly devStrictMode: "root" | "child" | null;
56
55
  cells: Cell[];
57
56
  currentIndex: number;
57
+ renderPendingCells: Set<Cell & {
58
+ type: "reducer";
59
+ }> | null;
58
60
  renderContext: RenderResult | undefined;
59
61
  isMounted: boolean;
60
62
  isFirstRender: boolean;
61
63
  isNeverMounted: boolean;
62
64
  }
63
65
  //#endregion
64
- export { Cell, ContravariantResource, EffectTask, ExtractResourceReturnType, ReducerQueueEntry, RenderResult, Resource, ResourceElement, ResourceFiber, ResourceFiberRoot };
66
+ export { Cell, ChangelogRecord, ContravariantResource, EffectTask, ExtractResourceReturnType, RenderResult, Resource, ResourceElement, ResourceFiber, ResourceFiberRoot };
65
67
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/core/types.ts"],"mappings":";;;KAEY,eAAA;EAAA,SACD,IAAA,EAAM,QAAA,CAAS,CAAA,EAAG,CAAA;EAAA,SAClB,KAAA,EAAO,CAAA;EAAA,SACP,GAAA;AAAA;AAAA,KAGC,QAAA,UAAkB,KAAA,EAAO,CAAA,KAAM,eAAA,CAAgB,CAAA,EAAG,CAAA;AAAA,KAClD,qBAAA,UAA+B,KAAA,EAAO,CAAA,KAAM,eAAA,CAAgB,CAAA;AAAA,KAE5D,yBAAA,MACV,CAAA,SAAU,eAAA,iBACN,CAAA,GACA,CAAA,SAAU,QAAA,iBACR,CAAA;AAAA,UAGS,iBAAA;EAAA,SACN,MAAA;EACT,aAAA;EACA,UAAA;AAAA;AAAA,KAGU,IAAA;EAAA,SAEG,IAAA;EAAA,SACA,QAAA,GAAW,MAAA;EAAA,SAEX,KAAA,EAAO,GAAA,CAAI,iBAAA;EACpB,KAAA;EACA,cAAA;EACA,OAAA;EACA,OAAA,GAAU,KAAA,OAAY,MAAA;AAAA;EAAA,SAGb,IAAA;EACT,OAAA,EAAS,SAAA,CAAU,UAAA;EACnB,IAAA;AAAA;AAAA,UAGW,UAAA;EAAA,SACN,MAAA,EAAQ,SAAA,CAAU,cAAA;EAAA,SAClB,IAAA;EAAA,SACA,IAAA,EAAM,IAAI;IAAK,IAAA;EAAA;AAAA;AAAA,UAGT,YAAA;EAAA,SACN,MAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA;AAAA;AAAA,UAGM,iBAAA;EACf,OAAA;EACA,gBAAA;EAAA,SACS,SAAA;EAAA,SAEA,cAAA,GAAiB,QAAA;EAAA,SACjB,UAAA,GAAa,IAAI;IAAK,IAAA;EAAA;AAAA;AAAA,UAGhB,aAAA;EAAA,SACN,IAAA,EAAM,iBAAA;EAAA,SACN,IAAA,EAAM,QAAA,CAAS,CAAA,EAAG,CAAA;EAAA,SAClB,SAAA;EAAA,SACA,aAAA;EAET,KAAA,EAAO,IAAA;EACP,YAAA;EAEA,aAAA,EAAe,YAAA;EAEf,SAAA;EACA,aAAA;EACA,cAAA;AAAA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/core/types.ts"],"mappings":";KAAY,eAAA;EAAA,SACD,IAAA,MAAU,IAAA,EAAM,CAAA,KAAM,CAAA;EAAA,SACtB,IAAA,EAAM,QAAA,CAAS,CAAA;EAAA,SACf,GAAA;AAAA;AAAA,KAGC,QAAA,gDACP,IAAA,EAAM,CAAA,KACN,eAAA,CAAgB,CAAA,EAAG,CAAA;AAAA,KACZ,qBAAA,gDACP,IAAA,EAAM,CAAA,KACN,eAAA,CAAgB,CAAA;AAAA,KAET,yBAAA,MACV,CAAA,SAAU,eAAA,iBACN,CAAA,GACA,CAAA,SAAU,QAAA,iBACR,CAAA;AAAA,UAGS,eAAA;EAAA,SACN,KAAA,EAAO,aAAA;EAAA,SACP,IAAA,EAAM,IAAI;IAAK,IAAA;EAAA;EAAA,SACf,MAAA;EACT,aAAA;EACA,UAAA;EACA,MAAA;AAAA;AAAA,KAGU,IAAA;EAAA,SAEG,IAAA;EAAA,SACA,QAAA,GAAW,MAAA;EAEpB,KAAA,EAAO,eAAe;EACtB,WAAA;EAEA,cAAA;EACA,OAAA;EACA,OAAA,GAAU,KAAA,OAAY,MAAA;AAAA;EAAA,SAGb,IAAA;EACT,OAAA;EACA,IAAA;AAAA;AAAA,UAGW,UAAA;EAAA,SACN,OAAA;EAAA,SACA,KAAK;AAAA;AAAA,UAGC,YAAA;EACf,KAAA;EACA,WAAA,EAAa,UAAU;AAAA;AAAA,UAGR,iBAAA;EACf,OAAA;EACA,gBAAA;EAAA,SACS,SAAA,EAAW,eAAA;EAAA,SAEX,cAAA,GAAiB,QAAA;EAAA,SACjB,UAAA,EAAY,GAAA,CAAI,IAAA;IAAS,IAAA;EAAA;AAAA;AAAA,UAGnB,aAAA;EAAA,SACN,IAAA,EAAM,iBAAA;EAAA,SACN,IAAA,MAAU,IAAA,EAAM,CAAA,KAAM,CAAA;EAAA,SACtB,SAAA;EAAA,SACA,aAAA;EAET,KAAA,EAAO,IAAA;EACP,YAAA;EAEA,kBAAA,EAAoB,GAAA,CAAI,IAAA;IAAS,IAAA;EAAA;EAEjC,aAAA,EAAe,YAAA;EAEf,SAAA;EACA,aAAA;EACA,cAAA;AAAA"}
@@ -1,8 +1,8 @@
1
1
  import { ExtractResourceReturnType, ResourceElement } from "../core/types.js";
2
2
 
3
3
  //#region src/hooks/useResource.d.ts
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>;
4
+ declare function useResource<E extends ResourceElement<any, any[]>>(element: E): ExtractResourceReturnType<E>;
5
+ declare function useResource<E extends ResourceElement<any, any[]>>(element: E, argsDeps: readonly unknown[]): ExtractResourceReturnType<E>;
6
6
  //#endregion
7
7
  export { useResource };
8
8
  //# sourceMappingURL=useResource.d.ts.map
@@ -1 +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
+ {"version":3,"file":"useResource.d.ts","names":[],"sources":["../../src/hooks/useResource.ts"],"mappings":";;;iBAUgB,WAAA,WAAsB,eAAA,cACpC,OAAA,EAAS,CAAA,GACR,yBAAA,CAA0B,CAAA;AAAA,iBACb,WAAA,WAAsB,eAAA,cACpC,OAAA,EAAS,CAAA,EACT,QAAA,uBACC,yBAAA,CAA0B,CAAA"}
@@ -1,33 +1,27 @@
1
- import { getCurrentResourceFiber } from "../core/helpers/execution-context.js";
2
- import { useRef } from "./useRef.js";
3
- import { useMemo } from "./useMemo.js";
4
- import { useEffect } from "./useEffect.js";
5
- import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
1
+ import { commitResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
2
+ import { useResourceFiberHost } from "./utils/useResourceFiberHostUtils.js";
3
+ import { useRenderMemo } from "./utils/useRenderMemo.js";
4
+ import { useEffect, useMemo } from "react";
6
5
  //#region src/hooks/useResource.ts
7
- function useResource(element, propsDeps) {
8
- const parentFiber = getCurrentResourceFiber();
9
- const versionRef = useRef(0);
6
+ function useResource(element, argsDeps) {
7
+ const { version, createFiber } = useResourceFiberHost();
10
8
  const fiber = useMemo(() => {
11
- element.key;
12
- return createResourceFiber(element.type, parentFiber.root, () => {
13
- versionRef.current++;
14
- parentFiber.markDirty?.();
15
- });
9
+ return createFiber(element.hook, element.key);
16
10
  }, [
17
- element.type,
11
+ element.hook,
18
12
  element.key,
19
- parentFiber
13
+ createFiber
20
14
  ]);
21
- const result = propsDeps ? useMemo(() => renderResourceFiber(fiber, element.props), [
15
+ const result = useRenderMemo(() => renderResourceFiber(fiber, element.args), [
22
16
  fiber,
23
- ...propsDeps,
24
- versionRef.current
25
- ]) : renderResourceFiber(fiber, element.props);
17
+ version,
18
+ ...argsDeps ?? [element.args]
19
+ ]);
26
20
  useEffect(() => () => unmountResourceFiber(fiber), [fiber]);
27
21
  useEffect(() => {
28
22
  commitResourceFiber(fiber, result);
29
23
  }, [fiber, result]);
30
- return result.output;
24
+ return result.value;
31
25
  }
32
26
  //#endregion
33
27
  export { useResource };
@@ -1 +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"}
1
+ {"version":3,"file":"useResource.js","names":[],"sources":["../../src/hooks/useResource.ts"],"sourcesContent":["import type { ExtractResourceReturnType, ResourceElement } from \"../core/types\";\nimport {\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { useResourceFiberHost } from \"./utils/useResourceFiberHostUtils\";\nimport { useEffect, useMemo } from \"react\";\nimport { useRenderMemo } from \"./utils/useRenderMemo\";\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 argsDeps: readonly unknown[],\n): ExtractResourceReturnType<E>;\nexport function useResource<E extends ResourceElement<any, any[]>>(\n element: E,\n argsDeps?: readonly unknown[],\n): ExtractResourceReturnType<E> {\n const { version, createFiber } = useResourceFiberHost();\n const fiber = useMemo(() => {\n return createFiber(element.hook, element.key);\n }, [element.hook, element.key, createFiber]);\n\n const identity = argsDeps ?? [element.args];\n\n const result = useRenderMemo(\n () => renderResourceFiber(fiber, element.args),\n [fiber, version, ...identity],\n );\n\n useEffect(() => () => unmountResourceFiber(fiber), [fiber]);\n useEffect(() => {\n commitResourceFiber(fiber, result);\n }, [fiber, result]);\n\n return result.value;\n}\n"],"mappings":";;;;;AAiBA,SAAgB,YACd,SACA,UAC8B;CAC9B,MAAM,EAAE,SAAS,gBAAgB,qBAAqB;CACtD,MAAM,QAAQ,cAAc;EAC1B,OAAO,YAAY,QAAQ,MAAM,QAAQ,GAAG;CAC9C,GAAG;EAAC,QAAQ;EAAM,QAAQ;EAAK;CAAW,CAAC;CAI3C,MAAM,SAAS,oBACP,oBAAoB,OAAO,QAAQ,IAAI,GAC7C;EAAC;EAAO;EAAS,GAJF,YAAY,CAAC,QAAQ,IAAI;CAIZ,CAC9B;CAEA,sBAAsB,qBAAqB,KAAK,GAAG,CAAC,KAAK,CAAC;CAC1D,gBAAgB;EACd,oBAAoB,OAAO,MAAM;CACnC,GAAG,CAAC,OAAO,MAAM,CAAC;CAElB,OAAO,OAAO;AAChB"}
@@ -1,7 +1,7 @@
1
1
  import { ExtractResourceReturnType, ResourceElement } from "../core/types.js";
2
2
 
3
3
  //#region src/hooks/useResources.d.ts
4
- declare function useResources<E extends ResourceElement<any, any>>(getElements: () => readonly E[], getElementsDeps?: readonly unknown[]): ExtractResourceReturnType<E>[];
4
+ declare function useResources<E extends ResourceElement<any, any[]>>(getElements: () => readonly E[], getElementsDeps?: readonly unknown[]): ExtractResourceReturnType<E>[];
5
5
  //#endregion
6
6
  export { useResources };
7
7
  //# sourceMappingURL=useResources.d.ts.map
@@ -1 +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
+ {"version":3,"file":"useResources.d.ts","names":[],"sources":["../../src/hooks/useResources.ts"],"mappings":";;;iBAoBgB,YAAA,WAAuB,eAAA,cACrC,WAAA,iBAA4B,CAAA,IAC5B,eAAA,wBACC,yBAAA,CAA0B,CAAA"}
@@ -1,21 +1,13 @@
1
- import { getCurrentResourceFiber } from "../core/helpers/execution-context.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";
6
- import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
1
+ import { commitResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
2
+ import { useResourceFiberHost } from "./utils/useResourceFiberHostUtils.js";
3
+ import { useRenderMemo } from "./utils/useRenderMemo.js";
4
+ import { useCallback, useEffect, useMemo } from "react";
7
5
  //#region src/hooks/useResources.ts
8
6
  function useResources(getElements, getElementsDeps) {
9
- const versionRef = useRef(0);
10
- const version = versionRef.current;
11
- const parentFiber = useMemo(() => getCurrentResourceFiber(), []);
12
- const markDirty = useMemo(() => () => {
13
- versionRef.current++;
14
- parentFiber.markDirty?.();
15
- }, [parentFiber]);
16
7
  const fibers = useMemo(() => /* @__PURE__ */ new Map(), []);
17
8
  const getElementsMemo = getElementsDeps ? useCallback(getElements, getElementsDeps) : getElements;
18
- const res = useMemo(() => {
9
+ const { version, createFiber } = useResourceFiberHost();
10
+ const res = useRenderMemo(() => {
19
11
  const elementsArray = getElementsMemo();
20
12
  const seenKeys = /* @__PURE__ */ new Set();
21
13
  const results = [];
@@ -28,23 +20,23 @@ function useResources(getElements, getElementsDeps) {
28
20
  seenKeys.add(elementKey);
29
21
  let state = fibers.get(elementKey);
30
22
  if (!state) {
31
- const fiber = createResourceFiber(element.type, parentFiber.root, markDirty);
32
- const result = renderResourceFiber(fiber, element.props);
23
+ const fiber = createFiber(element.hook, element.key);
24
+ const result = renderResourceFiber(fiber, element.args);
33
25
  state = {
34
26
  fiber,
35
27
  next: result
36
28
  };
37
29
  newCount++;
38
30
  fibers.set(elementKey, state);
39
- results.push(result.output);
40
- } else if (state.fiber.type !== element.type) {
41
- const fiber = createResourceFiber(element.type, parentFiber.root, markDirty);
42
- const result = renderResourceFiber(fiber, element.props);
31
+ results.push(result.value);
32
+ } else if (state.fiber.hook !== element.hook) {
33
+ const fiber = createFiber(element.hook, element.key);
34
+ const result = renderResourceFiber(fiber, element.args);
43
35
  state.next = [fiber, result];
44
- results.push(result.output);
36
+ results.push(result.value);
45
37
  } else {
46
- state.next = renderResourceFiber(state.fiber, element.props);
47
- results.push(state.next.output);
38
+ state.next = renderResourceFiber(state.fiber, element.args);
39
+ results.push(state.next.value);
48
40
  }
49
41
  }
50
42
  if (fibers.size > results.length - newCount) {
@@ -53,10 +45,9 @@ function useResources(getElements, getElementsDeps) {
53
45
  return results;
54
46
  }, [
55
47
  getElementsMemo,
56
- version,
57
- parentFiber,
58
- markDirty,
59
- fibers
48
+ fibers,
49
+ createFiber,
50
+ version
60
51
  ]);
61
52
  useEffect(() => {
62
53
  return () => {
@@ -1 +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"}
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 {\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { useResourceFiberHost } from \"./utils/useResourceFiberHostUtils\";\nimport { useCallback, useEffect, useMemo } from \"react\";\nimport { useRenderMemo } from \"./utils/useRenderMemo\";\n\ntype FiberState = {\n fiber: ResourceFiber<unknown>;\n next: RenderResult | [ResourceFiber<unknown>, RenderResult] | \"delete\";\n};\n\nexport function useResources<E extends ResourceElement<any, any[]>>(\n getElements: () => readonly E[],\n getElementsDeps?: readonly unknown[],\n): ExtractResourceReturnType<E>[] {\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 { version, createFiber } = useResourceFiberHost();\n const res = useRenderMemo(() => {\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 = createFiber(element.hook, element.key);\n const result = renderResourceFiber(fiber, element.args);\n state = {\n fiber,\n next: result,\n };\n newCount++;\n fibers.set(elementKey, state);\n results.push(result.value);\n } else if (state.fiber.hook !== element.hook) {\n const fiber = createFiber(element.hook, element.key);\n const result = renderResourceFiber(fiber, element.args);\n state.next = [fiber, result];\n results.push(result.value);\n } else {\n state.next = renderResourceFiber(state.fiber, element.args);\n results.push(state.next.value);\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, fibers, createFiber, version]);\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":";;;;;AAoBA,SAAgB,aACd,aACA,iBACgC;CAChC,MAAM,SAAS,8BAAc,IAAI,IAAiC,GAAG,CAAC,CAAC;CAEvE,MAAM,kBAAkB,kBAEpB,YAAY,aAAa,eAAe,IACxC;CAIJ,MAAM,EAAE,SAAS,gBAAgB,qBAAqB;CACtD,MAAM,MAAM,oBAAoB;EAG9B,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,YAAY,QAAQ,MAAM,QAAQ,GAAG;IACnD,MAAM,SAAS,oBAAoB,OAAO,QAAQ,IAAI;IACtD,QAAQ;KACN;KACA,MAAM;IACR;IACA;IACA,OAAO,IAAI,YAAY,KAAK;IAC5B,QAAQ,KAAK,OAAO,KAAK;GAC3B,OAAO,IAAI,MAAM,MAAM,SAAS,QAAQ,MAAM;IAC5C,MAAM,QAAQ,YAAY,QAAQ,MAAM,QAAQ,GAAG;IACnD,MAAM,SAAS,oBAAoB,OAAO,QAAQ,IAAI;IACtD,MAAM,OAAO,CAAC,OAAO,MAAM;IAC3B,QAAQ,KAAK,OAAO,KAAK;GAC3B,OAAO;IACL,MAAM,OAAO,oBAAoB,MAAM,OAAO,QAAQ,IAAI;IAC1D,QAAQ,KAAK,MAAM,KAAK,KAAK;GAC/B;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;EAAQ;EAAa;CAAO,CAAC;CAGlD,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,21 @@
1
+ //#region src/hooks/useTapHost.d.ts
2
+ declare namespace useTapHost {
3
+ interface Result<R> {
4
+ /**
5
+ * The current render output of the host resource.
6
+ */
7
+ value: R;
8
+ /**
9
+ * Commits the host's pending render result. Pass to a deps-less
10
+ * useEffect in a descendant component to land the commit ahead of
11
+ * the descendants' own effects; the first instance to run wins. A
12
+ * plain callback (not a hook) so React Compiler can compile the
13
+ * consumer; its identity changes on every host render.
14
+ */
15
+ effects: () => void;
16
+ }
17
+ }
18
+ declare const useTapHost: <R>(callback: () => R) => useTapHost.Result<R>;
19
+ //#endregion
20
+ export { useTapHost };
21
+ //# sourceMappingURL=useTapHost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTapHost.d.ts","names":[],"sources":["../../src/hooks/useTapHost.ts"],"mappings":";kBAQiB,UAAA;EAAA,UACE,MAAA;IADQ;;;IAKvB,KAAA,EAAO,CAAC;IAJc;;;;;AAaf;AAMX;IANI,OAAA;EAAA;AAAA;AAAA,cAMS,UAAA,MAAiB,QAAA,QAAgB,CAAA,KAAI,UAAA,CAAW,MAAA,CAAO,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { commitResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
2
+ import { useResourceFiberHost } from "./utils/useResourceFiberHostUtils.js";
3
+ import { useEffect, useMemo } from "react";
4
+ //#region src/hooks/useTapHost.ts
5
+ const useHostRender = (render) => render();
6
+ const useTapHost = (callback) => {
7
+ const { createFiber } = useResourceFiberHost();
8
+ const fiber = useMemo(() => createFiber(useHostRender, void 0), [createFiber]);
9
+ const render = renderResourceFiber(fiber, [callback]);
10
+ useEffect(() => {
11
+ return () => {
12
+ unmountResourceFiber(fiber);
13
+ };
14
+ }, [fiber]);
15
+ let renderCommitted = false;
16
+ const effects = () => {
17
+ if (renderCommitted && fiber.isMounted) return;
18
+ renderCommitted = true;
19
+ commitResourceFiber(fiber, render);
20
+ };
21
+ useEffect(effects);
22
+ return {
23
+ value: render.value,
24
+ effects
25
+ };
26
+ };
27
+ //#endregion
28
+ export { useTapHost };
29
+
30
+ //# sourceMappingURL=useTapHost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTapHost.js","names":[],"sources":["../../src/hooks/useTapHost.ts"],"sourcesContent":["import {\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { useResourceFiberHost } from \"./utils/useResourceFiberHostUtils\";\nimport { useEffect, useMemo } from \"react\";\n\nexport namespace useTapHost {\n export interface Result<R> {\n /**\n * The current render output of the host resource.\n */\n value: R;\n\n /**\n * Commits the host's pending render result. Pass to a deps-less\n * useEffect in a descendant component to land the commit ahead of\n * the descendants' own effects; the first instance to run wins. A\n * plain callback (not a hook) so React Compiler can compile the\n * consumer; its identity changes on every host render.\n */\n effects: () => void;\n }\n}\n\nconst useHostRender = <R>(render: () => R): R => render();\n\nexport const useTapHost = <R>(callback: () => R): useTapHost.Result<R> => {\n const { createFiber } = useResourceFiberHost();\n const fiber = useMemo(\n () => createFiber(useHostRender<R>, undefined),\n [createFiber],\n );\n\n const render = renderResourceFiber(fiber, [callback]);\n\n useEffect(() => {\n return () => {\n unmountResourceFiber(fiber);\n };\n }, [fiber]);\n\n let renderCommitted = false;\n const effects = () => {\n // !isMounted: StrictMode/Activity replays effects without a re-render\n // after unmounting the fiber; the replay must recommit it.\n if (renderCommitted && fiber.isMounted) return;\n renderCommitted = true;\n\n commitResourceFiber(fiber, render);\n };\n\n useEffect(effects);\n\n return {\n value: render.value as R,\n effects,\n };\n};\n"],"mappings":";;;;AA0BA,MAAM,iBAAoB,WAAuB,OAAO;AAExD,MAAa,cAAiB,aAA4C;CACxE,MAAM,EAAE,gBAAgB,qBAAqB;CAC7C,MAAM,QAAQ,cACN,YAAY,eAAkB,KAAA,CAAS,GAC7C,CAAC,WAAW,CACd;CAEA,MAAM,SAAS,oBAAoB,OAAO,CAAC,QAAQ,CAAC;CAEpD,gBAAgB;EACd,aAAa;GACX,qBAAqB,KAAK;EAC5B;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,IAAI,kBAAkB;CACtB,MAAM,gBAAgB;EAGpB,IAAI,mBAAmB,MAAM,WAAW;EACxC,kBAAkB;EAElB,oBAAoB,OAAO,MAAM;CACnC;CAEA,UAAU,OAAO;CAEjB,OAAO;EACL,OAAO,OAAO;EACd;CACF;AACF"}
@@ -0,0 +1,18 @@
1
+ //#region src/hooks/useTapRoot.d.ts
2
+ declare namespace useTapRoot {
3
+ type Unsubscribe = () => void;
4
+ interface Root<R> {
5
+ /**
6
+ * Get the current value of the root.
7
+ */
8
+ getValue(): R;
9
+ /**
10
+ * Subscribe to the root.
11
+ */
12
+ subscribe(listener: () => void): Unsubscribe;
13
+ }
14
+ }
15
+ declare const useTapRoot: <R>(render: () => R) => useTapRoot.Root<R>;
16
+ //#endregion
17
+ export { useTapRoot };
18
+ //# sourceMappingURL=useTapRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTapRoot.d.ts","names":[],"sources":["../../src/hooks/useTapRoot.ts"],"mappings":";kBAgBiB,UAAA;EAAA,KACH,WAAA;EAAA,UAEK,IAAA;IAHQ;;;IAOvB,QAAA,IAAY,CAAA;IAJQ;;;IASpB,SAAA,CAAU,QAAA,eAAuB,WAAW;EAAA;AAAA;AAAA,cAMnC,UAAA,MAAiB,MAAA,QAAc,CAAA,KAAI,UAAA,CAAW,IAAA,CAAK,CAAA"}
@@ -0,0 +1,77 @@
1
+ import { isDevelopment } from "../core/helpers/env.js";
2
+ import { commitRoot, createResourceFiberRoot, setRootVersion } from "../core/helpers/root.js";
3
+ import { commitResourceFiber, createResourceFiber, renderResourceFiber, unmountResourceFiber } from "../core/ResourceFiber.js";
4
+ import { UpdateScheduler } from "../core/scheduler.js";
5
+ import { useDevStrictMode } from "./utils/useDevStrictMode.js";
6
+ import { useEffect, useEffectEvent, useMemo, useRef } from "react";
7
+ //#region src/hooks/useTapRoot.ts
8
+ const useHostRoot = (render) => render();
9
+ const useTapRoot = (render) => {
10
+ const scheduler = useMemo(() => new UpdateScheduler(() => handleUpdate()), []);
11
+ const queue = useMemo(() => [], []);
12
+ const getDevStrictMode = useDevStrictMode();
13
+ const fiber = useMemo(() => {
14
+ const root = createResourceFiberRoot((callback) => {
15
+ if (!scheduler.isDirty && !callback()) return;
16
+ setRootVersion(root, root.committedVersion + root.changelog.length);
17
+ queue.push(callback);
18
+ scheduler.markDirty();
19
+ });
20
+ return createResourceFiber(useHostRoot, root, void 0, getDevStrictMode());
21
+ }, [
22
+ queue,
23
+ scheduler,
24
+ getDevStrictMode
25
+ ]);
26
+ const drainedCount = fiber.root.version - fiber.root.committedVersion;
27
+ const render2 = renderResourceFiber(fiber, [render]);
28
+ const isMountedRef = useRef(false);
29
+ const committedArgsRef = useRef([render]);
30
+ const valueRef = useRef(render2.value);
31
+ const subscribers = useMemo(() => /* @__PURE__ */ new Set(), []);
32
+ const publish = (output) => {
33
+ if (scheduler.isDirty || valueRef.current === output) return;
34
+ valueRef.current = output;
35
+ subscribers.forEach((listener) => listener());
36
+ };
37
+ const handleUpdate = useEffectEvent(() => {
38
+ setRootVersion(fiber.root, fiber.root.committedVersion);
39
+ queue.forEach((callback) => {
40
+ if (isDevelopment && fiber.devStrictMode) callback();
41
+ callback();
42
+ });
43
+ setRootVersion(fiber.root, fiber.root.committedVersion + fiber.root.changelog.length);
44
+ if (isDevelopment && fiber.devStrictMode) renderResourceFiber(fiber, committedArgsRef.current);
45
+ const render = renderResourceFiber(fiber, committedArgsRef.current);
46
+ if (scheduler.isDirty) throw new Error("Scheduler is dirty, this should never happen");
47
+ commitRoot(fiber.root);
48
+ queue.length = 0;
49
+ if (isMountedRef.current) commitResourceFiber(fiber, render);
50
+ publish(render.value);
51
+ });
52
+ useEffect(() => {
53
+ isMountedRef.current = true;
54
+ return () => {
55
+ isMountedRef.current = false;
56
+ unmountResourceFiber(fiber);
57
+ };
58
+ }, [fiber]);
59
+ useEffect(() => {
60
+ committedArgsRef.current = [render];
61
+ commitRoot(fiber.root);
62
+ queue.splice(0, drainedCount);
63
+ commitResourceFiber(fiber, render2);
64
+ publish(render2.value);
65
+ });
66
+ return useMemo(() => ({
67
+ getValue: () => valueRef.current,
68
+ subscribe: (listener) => {
69
+ subscribers.add(listener);
70
+ return () => subscribers.delete(listener);
71
+ }
72
+ }), [subscribers]);
73
+ };
74
+ //#endregion
75
+ export { useTapRoot };
76
+
77
+ //# sourceMappingURL=useTapRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTapRoot.js","names":[],"sources":["../../src/hooks/useTapRoot.ts"],"sourcesContent":["import {\n commitResourceFiber,\n createResourceFiber,\n renderResourceFiber,\n unmountResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { UpdateScheduler } from \"../core/scheduler\";\nimport { isDevelopment } from \"../core/helpers/env\";\nimport {\n commitRoot,\n createResourceFiberRoot,\n setRootVersion,\n} from \"../core/helpers/root\";\nimport { useEffect, useEffectEvent, useMemo, useRef } from \"react\";\nimport { useDevStrictMode } from \"./utils/useDevStrictMode\";\n\nexport namespace useTapRoot {\n export type Unsubscribe = () => void;\n\n export interface Root<R> {\n /**\n * Get the current value of the root.\n */\n getValue(): R;\n\n /**\n * Subscribe to the root.\n */\n subscribe(listener: () => void): Unsubscribe;\n }\n}\n\nconst useHostRoot = <R>(render: () => R): R => render();\n\nexport const useTapRoot = <R>(render: () => R): useTapRoot.Root<R> => {\n const scheduler = useMemo(\n () => new UpdateScheduler(() => handleUpdate()),\n [],\n );\n const queue = useMemo(() => [] as (() => boolean)[], []);\n\n const getDevStrictMode = useDevStrictMode();\n const fiber = useMemo(() => {\n const root = createResourceFiberRoot((callback) => {\n if (!scheduler.isDirty && !callback()) return;\n\n setRootVersion(root, root.committedVersion + root.changelog.length);\n queue.push(callback);\n scheduler.markDirty();\n });\n return createResourceFiber(\n useHostRoot<R>,\n root,\n undefined,\n getDevStrictMode(),\n );\n }, [queue, scheduler, getDevStrictMode]);\n\n const drainedCount = fiber.root.version - fiber.root.committedVersion;\n const render2 = renderResourceFiber(fiber, [render]);\n\n const isMountedRef = useRef(false);\n const committedArgsRef = useRef([render] as const);\n const valueRef = useRef<R>(render2.value);\n const subscribers = useMemo(() => new Set<() => void>(), []);\n\n const publish = (output: R) => {\n if (scheduler.isDirty || valueRef.current === output) return;\n valueRef.current = output;\n subscribers.forEach((listener) => listener());\n };\n\n const handleUpdate = useEffectEvent(() => {\n setRootVersion(fiber.root, fiber.root.committedVersion);\n\n queue.forEach((callback) => {\n if (isDevelopment && fiber.devStrictMode) {\n callback();\n }\n\n callback();\n });\n\n setRootVersion(\n fiber.root,\n fiber.root.committedVersion + fiber.root.changelog.length,\n );\n\n if (isDevelopment && fiber.devStrictMode) {\n void renderResourceFiber(fiber, committedArgsRef.current);\n }\n\n const render = renderResourceFiber(fiber, committedArgsRef.current);\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 publish(render.value);\n });\n\n useEffect(() => {\n isMountedRef.current = true;\n return () => {\n isMountedRef.current = false;\n unmountResourceFiber(fiber);\n };\n }, [fiber]);\n\n useEffect(() => {\n committedArgsRef.current = [render];\n commitRoot(fiber.root);\n queue.splice(0, drainedCount);\n commitResourceFiber(fiber, render2);\n\n publish(render2.value);\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":";;;;;;;AAgCA,MAAM,eAAkB,WAAuB,OAAO;AAEtD,MAAa,cAAiB,WAAwC;CACpE,MAAM,YAAY,cACV,IAAI,sBAAsB,aAAa,CAAC,GAC9C,CAAC,CACH;CACA,MAAM,QAAQ,cAAc,CAAC,GAAwB,CAAC,CAAC;CAEvD,MAAM,mBAAmB,iBAAiB;CAC1C,MAAM,QAAQ,cAAc;EAC1B,MAAM,OAAO,yBAAyB,aAAa;GACjD,IAAI,CAAC,UAAU,WAAW,CAAC,SAAS,GAAG;GAEvC,eAAe,MAAM,KAAK,mBAAmB,KAAK,UAAU,MAAM;GAClE,MAAM,KAAK,QAAQ;GACnB,UAAU,UAAU;EACtB,CAAC;EACD,OAAO,oBACL,aACA,MACA,KAAA,GACA,iBAAiB,CACnB;CACF,GAAG;EAAC;EAAO;EAAW;CAAgB,CAAC;CAEvC,MAAM,eAAe,MAAM,KAAK,UAAU,MAAM,KAAK;CACrD,MAAM,UAAU,oBAAoB,OAAO,CAAC,MAAM,CAAC;CAEnD,MAAM,eAAe,OAAO,KAAK;CACjC,MAAM,mBAAmB,OAAO,CAAC,MAAM,CAAU;CACjD,MAAM,WAAW,OAAU,QAAQ,KAAK;CACxC,MAAM,cAAc,8BAAc,IAAI,IAAgB,GAAG,CAAC,CAAC;CAE3D,MAAM,WAAW,WAAc;EAC7B,IAAI,UAAU,WAAW,SAAS,YAAY,QAAQ;EACtD,SAAS,UAAU;EACnB,YAAY,SAAS,aAAa,SAAS,CAAC;CAC9C;CAEA,MAAM,eAAe,qBAAqB;EACxC,eAAe,MAAM,MAAM,MAAM,KAAK,gBAAgB;EAEtD,MAAM,SAAS,aAAa;GAC1B,IAAI,iBAAiB,MAAM,eACzB,SAAS;GAGX,SAAS;EACX,CAAC;EAED,eACE,MAAM,MACN,MAAM,KAAK,mBAAmB,MAAM,KAAK,UAAU,MACrD;EAEA,IAAI,iBAAiB,MAAM,eACzB,oBAAyB,OAAO,iBAAiB,OAAO;EAG1D,MAAM,SAAS,oBAAoB,OAAO,iBAAiB,OAAO;EAElE,IAAI,UAAU,SACZ,MAAM,IAAI,MAAM,8CAA8C;EAEhE,WAAW,MAAM,IAAI;EACrB,MAAM,SAAS;EAEf,IAAI,aAAa,SACf,oBAAoB,OAAO,MAAM;EAGnC,QAAQ,OAAO,KAAK;CACtB,CAAC;CAED,gBAAgB;EACd,aAAa,UAAU;EACvB,aAAa;GACX,aAAa,UAAU;GACvB,qBAAqB,KAAK;EAC5B;CACF,GAAG,CAAC,KAAK,CAAC;CAEV,gBAAgB;EACd,iBAAiB,UAAU,CAAC,MAAM;EAClC,WAAW,MAAM,IAAI;EACrB,MAAM,OAAO,GAAG,YAAY;EAC5B,oBAAoB,OAAO,OAAO;EAElC,QAAQ,QAAQ,KAAK;CACvB,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 +1 @@
1
- {"version":3,"file":"depsShallowEqual.d.ts","names":[],"sources":["../../../src/hooks/utils/depsShallowEqual.ts"],"mappings":";cAAa,gBAAA,GACX,CAAA,sBACA,CAAqB"}
1
+ {"version":3,"file":"depsShallowEqual.d.ts","names":[],"sources":["../../../src/hooks/utils/depsShallowEqual.ts"],"mappings":";cAEa,gBAAA,GACX,CAAA,sBACA,CAAqB"}
@@ -1,7 +1,10 @@
1
+ import { isDevelopment } from "../../core/helpers/env.js";
1
2
  //#region src/hooks/utils/depsShallowEqual.ts
2
3
  const depsShallowEqual = (a, b) => {
3
- if (a.length !== b.length) return false;
4
- for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;
4
+ if (isDevelopment && a.length !== b.length) console.error(`The final argument passed to a hook changed size between renders. The order and size of this array must remain constant.
5
+
6
+ Previous: [${a.join(", ")}]\nIncoming: [${b.join(", ")}]`);
7
+ for (let i = 0; i < a.length && i < b.length; i++) if (!Object.is(a[i], b[i])) return false;
5
8
  return true;
6
9
  };
7
10
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"depsShallowEqual.js","names":[],"sources":["../../../src/hooks/utils/depsShallowEqual.ts"],"sourcesContent":["export const depsShallowEqual = (\n a: readonly unknown[],\n b: readonly unknown[],\n) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n};\n"],"mappings":";AAAA,MAAa,oBACX,GACA,MACG;CACH,IAAI,EAAE,WAAW,EAAE,QAAQ,OAAO;CAClC,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAC5B,IAAI,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO;CAErC,OAAO;AACT"}
1
+ {"version":3,"file":"depsShallowEqual.js","names":[],"sources":["../../../src/hooks/utils/depsShallowEqual.ts"],"sourcesContent":["import { isDevelopment } from \"../../core/helpers/env\";\n\nexport const depsShallowEqual = (\n a: readonly unknown[],\n b: readonly unknown[],\n) => {\n if (isDevelopment && a.length !== b.length) {\n console.error(\n \"The final argument passed to a hook changed size between renders. \" +\n \"The order and size of this array must remain constant.\\n\\n\" +\n `Previous: [${a.join(\", \")}]\\n` +\n `Incoming: [${b.join(\", \")}]`,\n );\n }\n\n for (let i = 0; i < a.length && i < b.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n};\n"],"mappings":";;AAEA,MAAa,oBACX,GACA,MACG;CACH,IAAI,iBAAiB,EAAE,WAAW,EAAE,QAClC,QAAQ,MACN;;aAEgB,EAAE,KAAK,IAAI,EAAE,gBACb,EAAE,KAAK,IAAI,EAAE,EAC/B;CAGF,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,EAAE,QAAQ,KAC5C,IAAI,CAAC,OAAO,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO;CAErC,OAAO;AACT"}
@@ -1,10 +1,10 @@
1
- import { Cell } from "../../core/types.js";
1
+ import { Cell, EffectTask } from "../../core/types.js";
2
2
 
3
3
  //#region src/hooks/utils/useCell.d.ts
4
4
  declare const useCell: <T extends Cell["type"]>(type: T, init: () => Cell) => Cell & {
5
5
  type: T;
6
6
  };
7
- declare const registerRenderMountTask: (task: () => void) => void;
7
+ declare const registerRenderMountTask: (task: EffectTask) => void;
8
8
  //#endregion
9
9
  export { registerRenderMountTask, useCell };
10
10
  //# sourceMappingURL=useCell.d.ts.map
@@ -1 +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
+ {"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,EAAV,UAAU"}
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"useCell.js","names":[],"sources":["../../../src/hooks/utils/useCell.ts"],"sourcesContent":["import { getCurrentResourceFiber } from \"../../core/helpers/execution-context\";\nimport type { Cell, EffectTask } 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: EffectTask) => {\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"}
@@ -0,0 +1,5 @@
1
+ //#region src/hooks/utils/useDevStrictMode.d.ts
2
+ declare const useDevStrictMode: () => () => "root" | "child" | null;
3
+ //#endregion
4
+ export { useDevStrictMode };
5
+ //# sourceMappingURL=useDevStrictMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDevStrictMode.d.ts","names":[],"sources":["../../../src/hooks/utils/useDevStrictMode.ts"],"mappings":";cA8Ba,gBAAA"}
@@ -0,0 +1,25 @@
1
+ import { getCurrentResourceFiber, peekResourceFiber } from "../../core/helpers/execution-context.js";
2
+ import { isDevelopment } from "../../core/helpers/env.js";
3
+ import { useRef, useState } from "react";
4
+ //#region src/hooks/utils/useDevStrictMode.ts
5
+ const getTapDevMode = () => {
6
+ const currentResourceFiber = getCurrentResourceFiber();
7
+ if (currentResourceFiber.devStrictMode) return currentResourceFiber.isFirstRender ? "child" : "root";
8
+ return null;
9
+ };
10
+ const child = () => "child";
11
+ const notDevMode = () => null;
12
+ const useDevStrictModeReact = () => {
13
+ if (!isDevelopment) return notDevMode;
14
+ const count = useRef(0);
15
+ useState(() => count.current++);
16
+ if (count.current !== 2) return notDevMode;
17
+ return child;
18
+ };
19
+ const useDevStrictMode = () => {
20
+ return peekResourceFiber() ? getTapDevMode : useDevStrictModeReact();
21
+ };
22
+ //#endregion
23
+ export { useDevStrictMode };
24
+
25
+ //# sourceMappingURL=useDevStrictMode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDevStrictMode.js","names":[],"sources":["../../../src/hooks/utils/useDevStrictMode.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\nimport { isDevelopment } from \"../../core/helpers/env\";\nimport {\n getCurrentResourceFiber,\n peekResourceFiber,\n} from \"../../core/helpers/execution-context\";\n\nconst getTapDevMode = () => {\n const currentResourceFiber = getCurrentResourceFiber();\n if (currentResourceFiber.devStrictMode)\n return currentResourceFiber.isFirstRender\n ? (\"child\" as const)\n : (\"root\" as const);\n return null;\n};\n\nconst child = () => \"child\" as const;\nconst notDevMode = () => null;\n\nconst useDevStrictModeReact = () => {\n if (!isDevelopment) return notDevMode;\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 // 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 notDevMode;\n return child;\n};\n\nexport const useDevStrictMode = () => {\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n return peekResourceFiber() ? getTapDevMode : useDevStrictModeReact();\n};\n"],"mappings":";;;;AAOA,MAAM,sBAAsB;CAC1B,MAAM,uBAAuB,wBAAwB;CACrD,IAAI,qBAAqB,eACvB,OAAO,qBAAqB,gBACvB,UACA;CACP,OAAO;AACT;AAEA,MAAM,cAAc;AACpB,MAAM,mBAAmB;AAEzB,MAAM,8BAA8B;CAClC,IAAI,CAAC,eAAe,OAAO;CAG3B,MAAM,QAAQ,OAAO,CAAC;CAEtB,eAAe,MAAM,SAAS;CAC9B,IAAI,MAAM,YAAY,GAAG,OAAO;CAChC,OAAO;AACT;AAEA,MAAa,yBAAyB;CAEpC,OAAO,kBAAkB,IAAI,gBAAgB,sBAAsB;AACrE"}
@@ -0,0 +1,5 @@
1
+ //#region src/hooks/utils/useRenderMemo.d.ts
2
+ declare const useRenderMemo: <T>(callback: () => T, deps: unknown[]) => T;
3
+ //#endregion
4
+ export { useRenderMemo };
5
+ //# sourceMappingURL=useRenderMemo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRenderMemo.d.ts","names":[],"sources":["../../../src/hooks/utils/useRenderMemo.ts"],"mappings":";cAGa,aAAA,MAAoB,QAAA,QAAgB,CAAA,EAAG,IAAA,gBAAe,CAuBlE"}