@assistant-ui/tap 0.0.1 → 0.1.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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -2
  3. package/dist/__tests__/test-utils.d.ts +10 -10
  4. package/dist/__tests__/test-utils.d.ts.map +1 -1
  5. package/dist/__tests__/test-utils.js +3 -82
  6. package/dist/__tests__/test-utils.js.map +1 -1
  7. package/dist/core/ResourceFiber.d.ts +4 -4
  8. package/dist/core/ResourceFiber.d.ts.map +1 -1
  9. package/dist/core/ResourceFiber.js +19 -11
  10. package/dist/core/ResourceFiber.js.map +1 -1
  11. package/dist/core/ResourceHandle.d.ts +3 -1
  12. package/dist/core/ResourceHandle.d.ts.map +1 -1
  13. package/dist/core/ResourceHandle.js +23 -10
  14. package/dist/core/ResourceHandle.js.map +1 -1
  15. package/dist/core/commit.d.ts +2 -2
  16. package/dist/core/commit.d.ts.map +1 -1
  17. package/dist/core/commit.js +9 -5
  18. package/dist/core/commit.js.map +1 -1
  19. package/dist/core/execution-context.d.ts +2 -2
  20. package/dist/core/execution-context.d.ts.map +1 -1
  21. package/dist/core/execution-context.js +0 -4
  22. package/dist/core/execution-context.js.map +1 -1
  23. package/dist/core/resource.d.ts +1 -1
  24. package/dist/core/resource.d.ts.map +1 -1
  25. package/dist/core/resource.js.map +1 -1
  26. package/dist/core/scheduler.d.ts.map +1 -1
  27. package/dist/core/scheduler.js.map +1 -1
  28. package/dist/core/types.d.ts +10 -7
  29. package/dist/core/types.d.ts.map +1 -1
  30. package/dist/hooks/depsShallowEqual.js.map +1 -1
  31. package/dist/hooks/tap-callback.js.map +1 -1
  32. package/dist/hooks/tap-effect.d.ts.map +1 -1
  33. package/dist/hooks/tap-effect.js +12 -8
  34. package/dist/hooks/tap-effect.js.map +1 -1
  35. package/dist/hooks/tap-inline-resource.d.ts +3 -0
  36. package/dist/hooks/tap-inline-resource.d.ts.map +1 -0
  37. package/dist/hooks/tap-inline-resource.js +8 -0
  38. package/dist/hooks/tap-inline-resource.js.map +1 -0
  39. package/dist/hooks/tap-ref.d.ts +3 -4
  40. package/dist/hooks/tap-ref.d.ts.map +1 -1
  41. package/dist/hooks/tap-ref.js.map +1 -1
  42. package/dist/hooks/tap-resource.js.map +1 -1
  43. package/dist/hooks/tap-resources.d.ts +1 -1
  44. package/dist/hooks/tap-resources.d.ts.map +1 -1
  45. package/dist/hooks/tap-resources.js +44 -48
  46. package/dist/hooks/tap-resources.js.map +1 -1
  47. package/dist/hooks/tap-state.d.ts +2 -1
  48. package/dist/hooks/tap-state.d.ts.map +1 -1
  49. package/dist/hooks/tap-state.js +19 -10
  50. package/dist/hooks/tap-state.js.map +1 -1
  51. package/dist/index.d.ts +3 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +4 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/react/index.js.map +1 -1
  56. package/dist/react/use-resource.d.ts.map +1 -1
  57. package/dist/react/use-resource.js +2 -3
  58. package/dist/react/use-resource.js.map +1 -1
  59. package/package.json +2 -1
  60. package/dist/hooks/tap-rerender.d.ts +0 -2
  61. package/dist/hooks/tap-rerender.d.ts.map +0 -1
  62. package/dist/hooks/tap-rerender.js +0 -10
  63. package/dist/hooks/tap-rerender.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 AgentbaseAI Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -166,14 +166,13 @@ const MyTodos = resource(() => {
166
166
  ];
167
167
 
168
168
  const todoResources = tapResources(
169
- todos.map((todo) => new TodoItem({ text: todo.text }, { key: todo.id }))
169
+ todos.map((todo) => new TodoItem({ text: todo.text }, { key: todo.id })),
170
170
  );
171
171
 
172
172
  return todoResources;
173
173
  });
174
174
  ```
175
175
 
176
-
177
176
  ## Resource Management
178
177
 
179
178
  ### `createResource`
@@ -4,17 +4,17 @@ import { ResourceFn, ResourceFiber } from "../core/types";
4
4
  * This is a low-level utility that creates a ResourceFiber directly.
5
5
  * Sets up a rerender callback that automatically re-renders when state changes.
6
6
  */
7
- export declare function createTestResource<R, P>(type: ResourceFn<R, P>): ResourceFiber;
7
+ export declare function createTestResource<R, P>(type: ResourceFn<R, P>): ResourceFiber<R, P>;
8
8
  /**
9
9
  * Renders a test resource fiber with the given props and manages its lifecycle.
10
10
  * - Tracks resources for cleanup
11
11
  * - Returns the current state after render
12
12
  */
13
- export declare function renderTest<R, P>(fiber: ResourceFiber, props: P): R;
13
+ export declare function renderTest<R, P>(fiber: ResourceFiber<R, P>, props: P): R;
14
14
  /**
15
15
  * Unmounts a specific resource fiber and removes it from tracking.
16
16
  */
17
- export declare function unmountResource(fiber: ResourceFiber): void;
17
+ export declare function unmountResource<R, P>(fiber: ResourceFiber<R, P>): void;
18
18
  /**
19
19
  * Cleans up all resources. Should be called after each test.
20
20
  */
@@ -23,7 +23,7 @@ export declare function cleanupAllResources(): void;
23
23
  * Gets the current committed state of a resource fiber.
24
24
  * Returns the state from the last render/commit cycle.
25
25
  */
26
- export declare function getCommittedState<R>(fiber: ResourceFiber): R;
26
+ export declare function getCommittedState<R, P>(fiber: ResourceFiber<R, P>): R;
27
27
  /**
28
28
  * Helper to subscribe to resource state changes for testing.
29
29
  * Tracks call count and latest state value.
@@ -32,7 +32,7 @@ export declare class TestSubscriber<T> {
32
32
  callCount: number;
33
33
  lastState: T;
34
34
  private fiber;
35
- constructor(fiber: ResourceFiber);
35
+ constructor(fiber: ResourceFiber<any, any>);
36
36
  cleanup(): void;
37
37
  }
38
38
  /**
@@ -40,9 +40,9 @@ export declare class TestSubscriber<T> {
40
40
  * Useful when you need fine-grained control over mount/unmount timing.
41
41
  */
42
42
  export declare class TestResourceManager<R, P> {
43
- fiber: ResourceFiber;
43
+ fiber: ResourceFiber<R, P>;
44
44
  private isActive;
45
- constructor(fiber: ResourceFiber);
45
+ constructor(fiber: ResourceFiber<R, P>);
46
46
  renderAndMount(props: P): R;
47
47
  cleanup(): void;
48
48
  }
@@ -72,8 +72,8 @@ export declare function createCounterResource(initialValue?: number): (props: {
72
72
  export declare function createStatefulCounterResource(): (props: {
73
73
  initial: number;
74
74
  }) => {
75
- count: any;
76
- increment: () => any;
77
- decrement: () => any;
75
+ count: number;
76
+ increment: () => void;
77
+ decrement: () => void;
78
78
  };
79
79
  //# sourceMappingURL=test-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAM1D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,iBAe9D;AAWD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAclE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,QAKnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,SAGlC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,GAAG,CAAC,CAQ5D;AAMD;;;GAGG;AACH,qBAAa,cAAc,CAAC,CAAC;IACpB,SAAS,SAAK;IACd,SAAS,EAAE,CAAC,CAAC;IACpB,OAAO,CAAC,KAAK,CAAgB;gBAEjB,KAAK,EAAE,aAAa;IAsBhC,OAAO;CAMR;AAED;;;GAGG;AACH,qBAAa,mBAAmB,CAAC,CAAC,EAAE,CAAC;IAGhB,KAAK,EAAE,aAAa;IAFvC,OAAO,CAAC,QAAQ,CAAS;gBAEN,KAAK,EAAE,aAAa;IAEvC,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC;IAc3B,OAAO;CAOR;AAMD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,OAAO,EACxB,OAAO,SAAO,EACd,QAAQ,SAAK,GACZ,OAAO,CAAC,IAAI,CAAC,CAQf;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,SAAI,IAC5C,OAAO;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;;EAIlC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,KAInC,OAAO;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;;;;EAQnC"}
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAO1D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,uBAa9D;AAWD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAcxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,QAK/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,SAGlC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAQrE;AAMD;;;GAGG;AACH,qBAAa,cAAc,CAAC,CAAC;IACpB,SAAS,SAAK;IACd,SAAS,EAAE,CAAC,CAAC;IACpB,OAAO,CAAC,KAAK,CAA0B;gBAE3B,KAAK,EAAE,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC;IAW1C,OAAO;CAMR;AAED;;;GAGG;AACH,qBAAa,mBAAmB,CAAC,CAAC,EAAE,CAAC;IAGhB,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAF7C,OAAO,CAAC,QAAQ,CAAS;gBAEN,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAE7C,cAAc,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC;IAc3B,OAAO;CAOR;AAMD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,OAAO,EACxB,OAAO,SAAO,EACd,QAAQ,SAAK,GACZ,OAAO,CAAC,IAAI,CAAC,CAQf;AAMD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,SAAI,IAC5C,OAAO;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;;EAIlC;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,KACnC,OAAO;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;;;;EAQnC"}
@@ -1,73 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __hasOwnProp = Object.prototype.hasOwnProperty;
5
- var __esm = (fn, res) => function __init() {
6
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
- };
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
-
22
- // src/hooks/tap-state.ts
23
- var tap_state_exports = {};
24
- __export(tap_state_exports, {
25
- tapState: () => tapState
26
- });
27
- import { getCurrentResourceFiber } from "../core/execution-context.js";
28
- function getStateCell(initialValue) {
29
- const executionContext = getCurrentResourceFiber();
30
- const index = executionContext.currentIndex++;
31
- if (!executionContext.isFirstRender && index >= executionContext.cells.length) {
32
- throw new Error(
33
- "Rendered more hooks than during the previous render. Hooks must be called in the exact same order in every render."
34
- );
35
- }
36
- if (!executionContext.cells[index]) {
37
- const value = typeof initialValue === "function" ? initialValue() : initialValue;
38
- const cell2 = {
39
- type: "state",
40
- value,
41
- set: (updater) => {
42
- const currentValue = cell2.value;
43
- const nextValue = typeof updater === "function" ? updater(currentValue) : updater;
44
- if (!Object.is(currentValue, nextValue)) {
45
- cell2.value = nextValue;
46
- if (executionContext.isRendering) {
47
- throw new Error("Resource updated during render");
48
- }
49
- executionContext.scheduleRerender();
50
- }
51
- }
52
- };
53
- executionContext.cells[index] = cell2;
54
- }
55
- const cell = executionContext.cells[index];
56
- if (cell.type !== "state") {
57
- throw new Error("Hook order changed between renders");
58
- }
59
- return cell;
60
- }
61
- function tapState(initial) {
62
- const cell = getStateCell(initial);
63
- return [cell.value, cell.set];
64
- }
65
- var init_tap_state = __esm({
66
- "src/hooks/tap-state.ts"() {
67
- "use strict";
68
- }
69
- });
70
-
71
1
  // src/__tests__/test-utils.ts
72
2
  import {
73
3
  createResourceFiber,
@@ -75,8 +5,8 @@ import {
75
5
  renderResource as renderResourceFiber,
76
6
  commitResource
77
7
  } from "../core/ResourceFiber.js";
8
+ import { tapState } from "../hooks/tap-state.js";
78
9
  function createTestResource(type) {
79
- let fiber;
80
10
  const rerenderCallback = () => {
81
11
  if (activeResources.has(fiber)) {
82
12
  const lastProps = propsMap.get(fiber);
@@ -85,7 +15,7 @@ function createTestResource(type) {
85
15
  lastRenderResultMap.set(fiber, result);
86
16
  }
87
17
  };
88
- fiber = createResourceFiber(type, rerenderCallback);
18
+ const fiber = createResourceFiber(type, rerenderCallback);
89
19
  return fiber;
90
20
  }
91
21
  var activeResources = /* @__PURE__ */ new Set();
@@ -130,14 +60,6 @@ var TestSubscriber = class {
130
60
  this.lastState = initialResult.state;
131
61
  lastRenderResultMap.set(fiber, initialResult);
132
62
  activeResources.add(fiber);
133
- fiber._rerenderCallback = () => {
134
- this.callCount++;
135
- const lastProps2 = propsMap.get(fiber) ?? void 0;
136
- const result = renderResourceFiber(fiber, lastProps2);
137
- commitResource(fiber, result);
138
- this.lastState = result.state;
139
- lastRenderResultMap.set(fiber, result);
140
- };
141
63
  }
142
64
  cleanup() {
143
65
  if (activeResources.has(this.fiber)) {
@@ -190,9 +112,8 @@ function createCounterResource(initialValue = 0) {
190
112
  };
191
113
  }
192
114
  function createStatefulCounterResource() {
193
- const { tapState: tapState2 } = (init_tap_state(), __toCommonJS(tap_state_exports));
194
115
  return (props) => {
195
- const [count, setCount] = tapState2(props.initial);
116
+ const [count, setCount] = tapState(props.initial);
196
117
  return {
197
118
  count,
198
119
  increment: () => setCount((c) => c + 1),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hooks/tap-state.ts","../../src/__tests__/test-utils.ts"],"sourcesContent":["import { getCurrentResourceFiber } from \"../core/execution-context\";\nimport { StateUpdater, Cell } from \"../core/types\";\n\nfunction getStateCell<T>(\n initialValue: T | (() => T)\n): Cell & { type: \"state\" } {\n const executionContext = getCurrentResourceFiber();\n const index = executionContext.currentIndex++;\n\n // Check if we're trying to use more hooks than in previous renders\n if (\n !executionContext.isFirstRender &&\n index >= executionContext.cells.length\n ) {\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 if (!executionContext.cells[index]) {\n // Initialize the value immediately\n const value =\n typeof initialValue === \"function\"\n ? (initialValue as () => T)()\n : initialValue;\n\n const cell: Cell & { type: \"state\" } = {\n type: \"state\",\n value,\n set: (updater: StateUpdater<T>) => {\n const currentValue = cell.value;\n const nextValue =\n typeof updater === \"function\"\n ? (updater as (prev: T) => T)(currentValue)\n : updater;\n\n if (!Object.is(currentValue, nextValue)) {\n cell.value = nextValue;\n\n // Check if called during render (not allowed)\n if (executionContext.isRendering) {\n throw new Error(\"Resource updated during render\");\n }\n executionContext.scheduleRerender();\n }\n },\n };\n\n executionContext.cells[index] = cell;\n }\n\n const cell = executionContext.cells[index];\n if (cell.type !== \"state\") {\n throw new Error(\"Hook order changed between renders\");\n }\n\n return cell as Cell & { type: \"state\" };\n}\n\nexport function tapState<S = undefined>(): [\n S | undefined,\n (updater: StateUpdater<S>) => void\n];\nexport function tapState<S>(\n initial: S | (() => S)\n): [S, (updater: StateUpdater<S>) => void];\nexport function tapState<S>(\n initial?: S | (() => S)\n): [S | undefined, (updater: StateUpdater<S>) => void] {\n const cell = getStateCell(initial as S | (() => S));\n\n return [cell.value, cell.set];\n}\n","import {\n createResourceFiber,\n unmountResource as unmountResourceFiber,\n renderResource as renderResourceFiber,\n commitResource,\n} from \"../core/ResourceFiber\";\nimport { ResourceFn, ResourceFiber } from \"../core/types\";\n\n// ============================================================================\n// Resource Creation\n// ============================================================================\n\n/**\n * Creates a test resource fiber for unit testing.\n * This is a low-level utility that creates a ResourceFiber directly.\n * Sets up a rerender callback that automatically re-renders when state changes.\n */\nexport function createTestResource<R, P>(type: ResourceFn<R, P>) {\n let fiber: ResourceFiber;\n\n const rerenderCallback = () => {\n // Re-render when state changes\n if (activeResources.has(fiber)) {\n const lastProps = propsMap.get(fiber);\n const result = renderResourceFiber(fiber, lastProps);\n commitResource(fiber, result);\n lastRenderResultMap.set(fiber, result);\n }\n };\n\n fiber = createResourceFiber(type, rerenderCallback);\n return fiber;\n}\n\n// ============================================================================\n// Resource Lifecycle Management\n// ============================================================================\n\n// Track resources for cleanup\nconst activeResources = new Set<ResourceFiber>();\nconst propsMap = new WeakMap<ResourceFiber, any>();\nconst lastRenderResultMap = new WeakMap<ResourceFiber, any>();\n\n/**\n * Renders a test resource fiber with the given props and manages its lifecycle.\n * - Tracks resources for cleanup\n * - Returns the current state after render\n */\nexport function renderTest<R, P>(fiber: ResourceFiber, props: P): R {\n propsMap.set(fiber, props);\n\n // Track resource for cleanup\n activeResources.add(fiber);\n\n // Render with new props\n const result = renderResourceFiber(fiber, props);\n commitResource(fiber, result);\n lastRenderResultMap.set(fiber, result);\n\n // Return the committed state from the result\n // This accounts for any re-renders that happened during commit\n return result.state;\n}\n\n/**\n * Unmounts a specific resource fiber and removes it from tracking.\n */\nexport function unmountResource(fiber: ResourceFiber) {\n if (activeResources.has(fiber)) {\n unmountResourceFiber(fiber);\n activeResources.delete(fiber);\n }\n}\n\n/**\n * Cleans up all resources. Should be called after each test.\n */\nexport function cleanupAllResources() {\n activeResources.forEach((fiber) => unmountResourceFiber(fiber));\n activeResources.clear();\n}\n\n/**\n * Gets the current committed state of a resource fiber.\n * Returns the state from the last render/commit cycle.\n */\nexport function getCommittedState<R>(fiber: ResourceFiber): R {\n const lastResult = lastRenderResultMap.get(fiber);\n if (!lastResult) {\n throw new Error(\n \"No render result found for fiber. Make sure to call renderResource first.\"\n );\n }\n return lastResult.state;\n}\n\n// ============================================================================\n// Test Helpers\n// ============================================================================\n\n/**\n * Helper to subscribe to resource state changes for testing.\n * Tracks call count and latest state value.\n */\nexport class TestSubscriber<T> {\n public callCount = 0;\n public lastState: T;\n private fiber: ResourceFiber;\n\n constructor(fiber: ResourceFiber) {\n this.fiber = fiber;\n // Need to render once to get initial state\n const lastProps = propsMap.get(fiber) ?? undefined;\n const initialResult = renderResourceFiber(fiber, lastProps as any);\n commitResource(fiber, initialResult);\n this.lastState = initialResult.state;\n lastRenderResultMap.set(fiber, initialResult);\n activeResources.add(fiber);\n\n // Update the fiber's rerender callback\n (fiber as any)._rerenderCallback = () => {\n this.callCount++;\n // Re-render to get latest state\n const lastProps = propsMap.get(fiber) ?? undefined;\n const result = renderResourceFiber(fiber, lastProps as any);\n commitResource(fiber, result);\n this.lastState = result.state;\n lastRenderResultMap.set(fiber, result);\n };\n }\n\n cleanup() {\n if (activeResources.has(this.fiber)) {\n unmountResourceFiber(this.fiber);\n activeResources.delete(this.fiber);\n }\n }\n}\n\n/**\n * Helper class to manage resource lifecycle in tests with explicit control.\n * Useful when you need fine-grained control over mount/unmount timing.\n */\nexport class TestResourceManager<R, P> {\n private isActive = false;\n\n constructor(public fiber: ResourceFiber) {}\n\n renderAndMount(props: P): R {\n if (this.isActive) {\n throw new Error(\"Resource already active\");\n }\n\n this.isActive = true;\n activeResources.add(this.fiber);\n propsMap.set(this.fiber, props);\n const result = renderResourceFiber(this.fiber, props);\n commitResource(this.fiber, result);\n lastRenderResultMap.set(this.fiber, result);\n return result.state;\n }\n\n cleanup() {\n if (this.isActive && activeResources.has(this.fiber)) {\n unmountResourceFiber(this.fiber);\n activeResources.delete(this.fiber);\n this.isActive = false;\n }\n }\n}\n\n// ============================================================================\n// Async Utilities\n// ============================================================================\n\n/**\n * Waits for the next tick of the event loop.\n * Useful for testing async state updates.\n */\nexport function waitForNextTick(): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, 0));\n}\n\n/**\n * Waits for a condition to be true with timeout.\n * Useful for testing eventual consistency.\n */\nexport async function waitFor(\n condition: () => boolean,\n timeout = 1000,\n interval = 10\n): Promise<void> {\n const start = Date.now();\n while (!condition()) {\n if (Date.now() - start > timeout) {\n throw new Error(\"Timeout waiting for condition\");\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n}\n\n// ============================================================================\n// Test Data Factories\n// ============================================================================\n\n/**\n * Creates a simple counter resource for testing.\n * Commonly used across multiple test files.\n */\nexport function createCounterResource(initialValue = 0) {\n return (props: { value?: number }) => {\n const value = props.value ?? initialValue;\n return { count: value };\n };\n}\n\n/**\n * Creates a stateful counter resource for testing.\n * Includes increment/decrement functions.\n */\nexport function createStatefulCounterResource() {\n // Import at top of file to avoid issues\n const { tapState } = require(\"../hooks/tap-state\");\n\n return (props: { initial: number }) => {\n const [count, setCount] = tapState(props.initial);\n return {\n count,\n increment: () => setCount((c: number) => c + 1),\n decrement: () => setCount((c: number) => c - 1),\n };\n };\n}\n"],"mappings":"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","names":["cell","lastProps","tapState"]}
1
+ {"version":3,"sources":["../../src/__tests__/test-utils.ts"],"sourcesContent":["import {\n createResourceFiber,\n unmountResource as unmountResourceFiber,\n renderResource as renderResourceFiber,\n commitResource,\n} from \"../core/ResourceFiber\";\nimport { ResourceFn, ResourceFiber } from \"../core/types\";\nimport { tapState } from \"../hooks/tap-state\";\n\n// ============================================================================\n// Resource Creation\n// ============================================================================\n\n/**\n * Creates a test resource fiber for unit testing.\n * This is a low-level utility that creates a ResourceFiber directly.\n * Sets up a rerender callback that automatically re-renders when state changes.\n */\nexport function createTestResource<R, P>(type: ResourceFn<R, P>) {\n const rerenderCallback = () => {\n // Re-render when state changes\n if (activeResources.has(fiber)) {\n const lastProps = propsMap.get(fiber);\n const result = renderResourceFiber(fiber, lastProps);\n commitResource(fiber, result);\n lastRenderResultMap.set(fiber, result);\n }\n };\n\n const fiber = createResourceFiber(type, rerenderCallback);\n return fiber;\n}\n\n// ============================================================================\n// Resource Lifecycle Management\n// ============================================================================\n\n// Track resources for cleanup\nconst activeResources = new Set<ResourceFiber<any, any>>();\nconst propsMap = new WeakMap<ResourceFiber<any, any>, any>();\nconst lastRenderResultMap = new WeakMap<ResourceFiber<any, any>, any>();\n\n/**\n * Renders a test resource fiber with the given props and manages its lifecycle.\n * - Tracks resources for cleanup\n * - Returns the current state after render\n */\nexport function renderTest<R, P>(fiber: ResourceFiber<R, P>, props: P): R {\n propsMap.set(fiber, props);\n\n // Track resource for cleanup\n activeResources.add(fiber);\n\n // Render with new props\n const result = renderResourceFiber(fiber, props);\n commitResource(fiber, result);\n lastRenderResultMap.set(fiber, result);\n\n // Return the committed state from the result\n // This accounts for any re-renders that happened during commit\n return result.state;\n}\n\n/**\n * Unmounts a specific resource fiber and removes it from tracking.\n */\nexport function unmountResource<R, P>(fiber: ResourceFiber<R, P>) {\n if (activeResources.has(fiber)) {\n unmountResourceFiber(fiber);\n activeResources.delete(fiber);\n }\n}\n\n/**\n * Cleans up all resources. Should be called after each test.\n */\nexport function cleanupAllResources() {\n activeResources.forEach((fiber) => unmountResourceFiber(fiber));\n activeResources.clear();\n}\n\n/**\n * Gets the current committed state of a resource fiber.\n * Returns the state from the last render/commit cycle.\n */\nexport function getCommittedState<R, P>(fiber: ResourceFiber<R, P>): R {\n const lastResult = lastRenderResultMap.get(fiber);\n if (!lastResult) {\n throw new Error(\n \"No render result found for fiber. Make sure to call renderResource first.\",\n );\n }\n return lastResult.state;\n}\n\n// ============================================================================\n// Test Helpers\n// ============================================================================\n\n/**\n * Helper to subscribe to resource state changes for testing.\n * Tracks call count and latest state value.\n */\nexport class TestSubscriber<T> {\n public callCount = 0;\n public lastState: T;\n private fiber: ResourceFiber<any, any>;\n\n constructor(fiber: ResourceFiber<any, any>) {\n this.fiber = fiber;\n // Need to render once to get initial state\n const lastProps = propsMap.get(fiber) ?? undefined;\n const initialResult = renderResourceFiber(fiber, lastProps as any);\n commitResource(fiber, initialResult);\n this.lastState = initialResult.state;\n lastRenderResultMap.set(fiber, initialResult);\n activeResources.add(fiber);\n }\n\n cleanup() {\n if (activeResources.has(this.fiber)) {\n unmountResourceFiber(this.fiber);\n activeResources.delete(this.fiber);\n }\n }\n}\n\n/**\n * Helper class to manage resource lifecycle in tests with explicit control.\n * Useful when you need fine-grained control over mount/unmount timing.\n */\nexport class TestResourceManager<R, P> {\n private isActive = false;\n\n constructor(public fiber: ResourceFiber<R, P>) {}\n\n renderAndMount(props: P): R {\n if (this.isActive) {\n throw new Error(\"Resource already active\");\n }\n\n this.isActive = true;\n activeResources.add(this.fiber);\n propsMap.set(this.fiber, props);\n const result = renderResourceFiber(this.fiber, props);\n commitResource(this.fiber, result);\n lastRenderResultMap.set(this.fiber, result);\n return result.state;\n }\n\n cleanup() {\n if (this.isActive && activeResources.has(this.fiber)) {\n unmountResourceFiber(this.fiber);\n activeResources.delete(this.fiber);\n this.isActive = false;\n }\n }\n}\n\n// ============================================================================\n// Async Utilities\n// ============================================================================\n\n/**\n * Waits for the next tick of the event loop.\n * Useful for testing async state updates.\n */\nexport function waitForNextTick(): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, 0));\n}\n\n/**\n * Waits for a condition to be true with timeout.\n * Useful for testing eventual consistency.\n */\nexport async function waitFor(\n condition: () => boolean,\n timeout = 1000,\n interval = 10,\n): Promise<void> {\n const start = Date.now();\n while (!condition()) {\n if (Date.now() - start > timeout) {\n throw new Error(\"Timeout waiting for condition\");\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n}\n\n// ============================================================================\n// Test Data Factories\n// ============================================================================\n\n/**\n * Creates a simple counter resource for testing.\n * Commonly used across multiple test files.\n */\nexport function createCounterResource(initialValue = 0) {\n return (props: { value?: number }) => {\n const value = props.value ?? initialValue;\n return { count: value };\n };\n}\n\n/**\n * Creates a stateful counter resource for testing.\n * Includes increment/decrement functions.\n */\nexport function createStatefulCounterResource() {\n return (props: { initial: number }) => {\n const [count, setCount] = tapState(props.initial);\n return {\n count,\n increment: () => setCount((c: number) => c + 1),\n decrement: () => setCount((c: number) => c - 1),\n };\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { ResourceFn, ResourceFiber, RenderResult } from "./types";
2
- export declare function createResourceFiber<R, P>(resourceFn: ResourceFn<R, P>, scheduleRerender: () => void): ResourceFiber;
3
- export declare function unmountResource(fiber: ResourceFiber): void;
4
- export declare function renderResource<R, P>(fiber: ResourceFiber, props: P): RenderResult;
5
- export declare function commitResource(fiber: ResourceFiber, result: RenderResult): void;
2
+ export declare function createResourceFiber<R, P>(resourceFn: ResourceFn<R, P>, scheduleRerender: () => void): ResourceFiber<R, P>;
3
+ export declare function unmountResource<R, P>(fiber: ResourceFiber<R, P>): void;
4
+ export declare function renderResource<R, P>(fiber: ResourceFiber<R, P>, props: P): RenderResult;
5
+ export declare function commitResource<R, P>(fiber: ResourceFiber<R, P>, result: RenderResult): void;
6
6
  //# sourceMappingURL=ResourceFiber.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceFiber.d.ts","sourceRoot":"","sources":["../../src/core/ResourceFiber.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIlE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EACtC,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,gBAAgB,EAAE,MAAM,IAAI,GAC3B,aAAa,CAWf;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAG1D;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EACjC,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,CAAC,GACP,YAAY,CAed;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,YAAY,GACnB,IAAI,CAGN"}
1
+ {"version":3,"file":"ResourceFiber.d.ts","sourceRoot":"","sources":["../../src/core/ResourceFiber.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIlE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EACtC,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAC5B,gBAAgB,EAAE,MAAM,IAAI,GAC3B,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAYrB;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAItE;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EACjC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,GACP,YAAY,CAiBd;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EACjC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,YAAY,GACnB,IAAI,CAMN"}
@@ -6,29 +6,37 @@ function createResourceFiber(resourceFn, scheduleRerender) {
6
6
  resourceFn,
7
7
  scheduleRerender,
8
8
  cells: [],
9
- commitTasks: [],
10
9
  currentIndex: 0,
11
10
  committedProps: void 0,
12
- isRendering: false,
13
- isFirstRender: true
11
+ renderContext: void 0,
12
+ isFirstRender: true,
13
+ isMounted: false,
14
+ isNeverMounted: true
14
15
  };
15
16
  }
16
17
  function unmountResource(fiber) {
18
+ fiber.isMounted = false;
17
19
  cleanupAllEffects(fiber);
18
20
  }
19
21
  function renderResource(fiber, props) {
20
- let state;
21
- withResourceFiber(fiber, () => {
22
- state = fiber.resourceFn(props);
23
- });
24
- fiber.committedProps ??= props;
25
- return {
26
- commitTasks: fiber.commitTasks,
22
+ const result = {
23
+ commitTasks: [],
27
24
  props,
28
- state
25
+ state: void 0
29
26
  };
27
+ withResourceFiber(fiber, () => {
28
+ fiber.renderContext = result;
29
+ try {
30
+ result.state = fiber.resourceFn(props);
31
+ } finally {
32
+ fiber.renderContext = void 0;
33
+ }
34
+ });
35
+ return result;
30
36
  }
31
37
  function commitResource(fiber, result) {
38
+ fiber.isMounted = true;
39
+ fiber.isNeverMounted = false;
32
40
  commitRender(result, fiber);
33
41
  fiber.committedProps = result.props;
34
42
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/ResourceFiber.ts"],"sourcesContent":["import { ResourceFn, ResourceFiber, RenderResult } from \"./types\";\nimport { commitRender, cleanupAllEffects } from \"./commit\";\nimport { withResourceFiber } from \"./execution-context\";\n\nexport function createResourceFiber<R, P>(\n resourceFn: ResourceFn<R, P>,\n scheduleRerender: () => void\n): ResourceFiber {\n return {\n resourceFn,\n scheduleRerender,\n cells: [],\n commitTasks: [],\n currentIndex: 0,\n committedProps: undefined,\n isRendering: false,\n isFirstRender: true,\n };\n}\n\nexport function unmountResource(fiber: ResourceFiber): void {\n // Clean up all effects\n cleanupAllEffects(fiber);\n}\n\nexport function renderResource<R, P>(\n fiber: ResourceFiber,\n props: P\n): RenderResult {\n let state: R | undefined;\n\n withResourceFiber(fiber, () => {\n state = fiber.resourceFn(props);\n });\n\n // on first render, we save the props for setState calls post render before commit\n fiber.committedProps ??= props;\n\n return {\n commitTasks: fiber.commitTasks,\n props,\n state,\n };\n}\n\nexport function commitResource(\n fiber: ResourceFiber,\n result: RenderResult\n): void {\n commitRender(result, fiber);\n fiber.committedProps = result.props;\n}\n"],"mappings":";AACA,SAAS,cAAc,yBAAyB;AAChD,SAAS,yBAAyB;AAE3B,SAAS,oBACd,YACA,kBACe;AACf,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,CAAC;AAAA,IACR,aAAa,CAAC;AAAA,IACd,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,eAAe;AAAA,EACjB;AACF;AAEO,SAAS,gBAAgB,OAA4B;AAE1D,oBAAkB,KAAK;AACzB;AAEO,SAAS,eACd,OACA,OACc;AACd,MAAI;AAEJ,oBAAkB,OAAO,MAAM;AAC7B,YAAQ,MAAM,WAAW,KAAK;AAAA,EAChC,CAAC;AAGD,QAAM,mBAAmB;AAEzB,SAAO;AAAA,IACL,aAAa,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,eACd,OACA,QACM;AACN,eAAa,QAAQ,KAAK;AAC1B,QAAM,iBAAiB,OAAO;AAChC;","names":[]}
1
+ {"version":3,"sources":["../../src/core/ResourceFiber.ts"],"sourcesContent":["import { ResourceFn, ResourceFiber, RenderResult } from \"./types\";\nimport { commitRender, cleanupAllEffects } from \"./commit\";\nimport { withResourceFiber } from \"./execution-context\";\n\nexport function createResourceFiber<R, P>(\n resourceFn: ResourceFn<R, P>,\n scheduleRerender: () => void,\n): ResourceFiber<R, P> {\n return {\n resourceFn,\n scheduleRerender,\n cells: [],\n currentIndex: 0,\n committedProps: undefined,\n renderContext: undefined,\n isFirstRender: true,\n isMounted: false,\n isNeverMounted: true,\n };\n}\n\nexport function unmountResource<R, P>(fiber: ResourceFiber<R, P>): void {\n // Clean up all effects\n fiber.isMounted = false;\n cleanupAllEffects(fiber);\n}\n\nexport function renderResource<R, P>(\n fiber: ResourceFiber<R, P>,\n props: P,\n): RenderResult {\n const result: RenderResult = {\n commitTasks: [],\n props,\n state: undefined,\n };\n\n withResourceFiber(fiber, () => {\n fiber.renderContext = result;\n try {\n result.state = fiber.resourceFn(props);\n } finally {\n fiber.renderContext = undefined;\n }\n });\n\n return result;\n}\n\nexport function commitResource<R, P>(\n fiber: ResourceFiber<R, P>,\n result: RenderResult,\n): void {\n fiber.isMounted = true;\n fiber.isNeverMounted = false;\n\n commitRender(result, fiber);\n fiber.committedProps = result.props;\n}\n"],"mappings":";AACA,SAAS,cAAc,yBAAyB;AAChD,SAAS,yBAAyB;AAE3B,SAAS,oBACd,YACA,kBACqB;AACrB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,CAAC;AAAA,IACR,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,eAAe;AAAA,IACf,WAAW;AAAA,IACX,gBAAgB;AAAA,EAClB;AACF;AAEO,SAAS,gBAAsB,OAAkC;AAEtE,QAAM,YAAY;AAClB,oBAAkB,KAAK;AACzB;AAEO,SAAS,eACd,OACA,OACc;AACd,QAAM,SAAuB;AAAA,IAC3B,aAAa,CAAC;AAAA,IACd;AAAA,IACA,OAAO;AAAA,EACT;AAEA,oBAAkB,OAAO,MAAM;AAC7B,UAAM,gBAAgB;AACtB,QAAI;AACF,aAAO,QAAQ,MAAM,WAAW,KAAK;AAAA,IACvC,UAAE;AACA,YAAM,gBAAgB;AAAA,IACxB;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEO,SAAS,eACd,OACA,QACM;AACN,QAAM,YAAY;AAClB,QAAM,iBAAiB;AAEvB,eAAa,QAAQ,KAAK;AAC1B,QAAM,iBAAiB,OAAO;AAChC;","names":[]}
@@ -3,6 +3,8 @@ export interface ResourceHandle<R, P> {
3
3
  getState(): R;
4
4
  subscribe(callback: () => void): Unsubscribe;
5
5
  updateInput(props: P): void;
6
+ flushSync(): void;
7
+ dispose(): void;
6
8
  }
7
- export declare const createResource: <R, P>(element: ResourceElement<R, P>) => ResourceHandle<R, P>;
9
+ export declare const createResource: <R, P>(element: ResourceElement<R, P>, delayMount?: boolean) => ResourceHandle<R, P>;
8
10
  //# sourceMappingURL=ResourceHandle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceHandle.d.ts","sourceRoot":"","sources":["../../src/core/ResourceHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAcvD,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,CAAC;IAClC,QAAQ,IAAI,CAAC,CAAC;IACd,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;IAC7C,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAC7B;AAuCD,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EACjC,SAAS,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,KAC7B,cAAc,CAAC,CAAC,EAAE,CAAC,CAmBrB,CAAC"}
1
+ {"version":3,"file":"ResourceHandle.d.ts","sourceRoot":"","sources":["../../src/core/ResourceHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAcvD,MAAM,WAAW,cAAc,CAAC,CAAC,EAAE,CAAC;IAClC,QAAQ,IAAI,CAAC,CAAC;IACd,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;IAC7C,WAAW,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAC5B,SAAS,IAAI,IAAI,CAAC;IAClB,OAAO,IAAI,IAAI,CAAC;CACjB;AA6CD,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EACjC,SAAS,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAC9B,oBAAkB,KACjB,cAAc,CAAC,CAAC,EAAE,CAAC,CA2BrB,CAAC"}
@@ -6,17 +6,19 @@ import {
6
6
  commitResource
7
7
  } from "./ResourceFiber.js";
8
8
  import { UpdateScheduler } from "./scheduler.js";
9
- import { tapResource } from "../hooks/tap-resource.js";
10
9
  import { tapRef } from "../hooks/tap-ref.js";
11
- import { tapEffect } from "../hooks/tap-effect.js";
12
10
  import { tapState } from "../hooks/tap-state.js";
13
11
  import { tapMemo } from "../hooks/tap-memo.js";
12
+ import { tapInlineResource } from "../hooks/tap-inline-resource.js";
13
+ import { tapEffect } from "../hooks/tap-effect.js";
14
14
  var HandleWrapperResource = ({
15
15
  element,
16
+ onUpdateInput,
17
+ onFlushSync,
16
18
  onDispose
17
19
  }) => {
18
20
  const [props, setProps] = tapState(element.props);
19
- const value = tapResource({ type: element.type, props });
21
+ const value = tapInlineResource({ type: element.type, props });
20
22
  const subscribers = tapRef(/* @__PURE__ */ new Set()).current;
21
23
  const valueRef = tapRef(value);
22
24
  tapEffect(() => {
@@ -24,7 +26,7 @@ var HandleWrapperResource = ({
24
26
  valueRef.current = value;
25
27
  subscribers.forEach((callback) => callback());
26
28
  }
27
- }, [value]);
29
+ });
28
30
  const handle = tapMemo(
29
31
  () => ({
30
32
  getState: () => valueRef.current,
@@ -33,30 +35,41 @@ var HandleWrapperResource = ({
33
35
  return () => subscribers.delete(callback);
34
36
  },
35
37
  updateInput: (props2) => {
38
+ onUpdateInput();
36
39
  setProps(() => props2);
37
40
  },
41
+ flushSync: onFlushSync,
38
42
  dispose: onDispose
39
43
  }),
40
44
  []
41
45
  );
42
46
  return handle;
43
47
  };
44
- var createResource = (element) => {
48
+ var createResource = (element, delayMount = false) => {
49
+ let isMounted = !delayMount;
45
50
  const props = {
46
51
  element,
52
+ onUpdateInput: () => {
53
+ if (isMounted) return;
54
+ isMounted = true;
55
+ commitResource(fiber, lastRender);
56
+ },
57
+ onFlushSync: () => {
58
+ scheduler.flushSync();
59
+ },
47
60
  onDispose: () => unmountResource(fiber)
48
61
  };
49
62
  const scheduler = new UpdateScheduler(() => {
50
- const result2 = renderResource(fiber, props);
51
- commitResource(fiber, result2);
63
+ lastRender = renderResource(fiber, props);
64
+ if (isMounted) commitResource(fiber, lastRender);
52
65
  });
53
66
  const fiber = createResourceFiber(
54
67
  HandleWrapperResource,
55
68
  () => scheduler.markDirty()
56
69
  );
57
- const result = renderResource(fiber, props);
58
- commitResource(fiber, result);
59
- return result.state;
70
+ let lastRender = renderResource(fiber, props);
71
+ if (isMounted) commitResource(fiber, lastRender);
72
+ return lastRender.state;
60
73
  };
61
74
  export {
62
75
  createResource
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/ResourceHandle.ts"],"sourcesContent":["import { ResourceElement, Unsubscribe } from \"./types\";\nimport {\n createResourceFiber,\n unmountResource,\n renderResource,\n commitResource,\n} from \"./ResourceFiber\";\nimport { UpdateScheduler } from \"./scheduler\";\nimport { tapResource } from \"../hooks/tap-resource\";\nimport { tapRef } from \"../hooks/tap-ref\";\nimport { tapEffect } from \"../hooks/tap-effect\";\nimport { tapState } from \"../hooks/tap-state\";\nimport { tapMemo } from \"../hooks/tap-memo\";\n\nexport interface ResourceHandle<R, P> {\n getState(): R;\n subscribe(callback: () => void): Unsubscribe;\n updateInput(props: P): void;\n}\n\nconst HandleWrapperResource = <R, P>({\n element,\n onDispose,\n}: {\n element: ResourceElement<R, P>;\n onDispose: () => void;\n}): ResourceHandle<R, P> => {\n const [props, setProps] = tapState(element.props);\n const value = tapResource({ type: element.type, props });\n const subscribers = tapRef(new Set<() => void>()).current;\n const valueRef = tapRef(value);\n\n tapEffect(() => {\n if (value !== valueRef.current) {\n valueRef.current = value;\n subscribers.forEach((callback) => callback());\n }\n }, [value]);\n\n const handle = tapMemo(\n () => ({\n getState: () => valueRef.current,\n subscribe: (callback: () => void) => {\n subscribers.add(callback);\n return () => subscribers.delete(callback);\n },\n updateInput: (props: P) => {\n setProps(() => props);\n },\n dispose: onDispose,\n }),\n []\n );\n\n return handle;\n};\n\nexport const createResource = <R, P>(\n element: ResourceElement<R, P>\n): ResourceHandle<R, P> => {\n const props = {\n element,\n onDispose: () => unmountResource(fiber),\n };\n\n const scheduler = new UpdateScheduler(() => {\n const result = renderResource(fiber, props);\n commitResource(fiber, result);\n });\n\n const fiber = createResourceFiber(HandleWrapperResource<R, P>, () =>\n scheduler.markDirty()\n );\n\n const result = renderResource(fiber, props);\n commitResource(fiber, result);\n\n return result.state;\n};\n"],"mappings":";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAQxB,IAAM,wBAAwB,CAAO;AAAA,EACnC;AAAA,EACA;AACF,MAG4B;AAC1B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,QAAQ,KAAK;AAChD,QAAM,QAAQ,YAAY,EAAE,MAAM,QAAQ,MAAM,MAAM,CAAC;AACvD,QAAM,cAAc,OAAO,oBAAI,IAAgB,CAAC,EAAE;AAClD,QAAM,WAAW,OAAO,KAAK;AAE7B,YAAU,MAAM;AACd,QAAI,UAAU,SAAS,SAAS;AAC9B,eAAS,UAAU;AACnB,kBAAY,QAAQ,CAAC,aAAa,SAAS,CAAC;AAAA,IAC9C;AAAA,EACF,GAAG,CAAC,KAAK,CAAC;AAEV,QAAM,SAAS;AAAA,IACb,OAAO;AAAA,MACL,UAAU,MAAM,SAAS;AAAA,MACzB,WAAW,CAAC,aAAyB;AACnC,oBAAY,IAAI,QAAQ;AACxB,eAAO,MAAM,YAAY,OAAO,QAAQ;AAAA,MAC1C;AAAA,MACA,aAAa,CAACA,WAAa;AACzB,iBAAS,MAAMA,MAAK;AAAA,MACtB;AAAA,MACA,SAAS;AAAA,IACX;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,IAAM,iBAAiB,CAC5B,YACyB;AACzB,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,WAAW,MAAM,gBAAgB,KAAK;AAAA,EACxC;AAEA,QAAM,YAAY,IAAI,gBAAgB,MAAM;AAC1C,UAAMC,UAAS,eAAe,OAAO,KAAK;AAC1C,mBAAe,OAAOA,OAAM;AAAA,EAC9B,CAAC;AAED,QAAM,QAAQ;AAAA,IAAoB;AAAA,IAA6B,MAC7D,UAAU,UAAU;AAAA,EACtB;AAEA,QAAM,SAAS,eAAe,OAAO,KAAK;AAC1C,iBAAe,OAAO,MAAM;AAE5B,SAAO,OAAO;AAChB;","names":["props","result"]}
1
+ {"version":3,"sources":["../../src/core/ResourceHandle.ts"],"sourcesContent":["import { ResourceElement, Unsubscribe } from \"./types\";\nimport {\n createResourceFiber,\n unmountResource,\n renderResource,\n commitResource,\n} from \"./ResourceFiber\";\nimport { UpdateScheduler } from \"./scheduler\";\nimport { tapRef } from \"../hooks/tap-ref\";\nimport { tapState } from \"../hooks/tap-state\";\nimport { tapMemo } from \"../hooks/tap-memo\";\nimport { tapInlineResource } from \"../hooks/tap-inline-resource\";\nimport { tapEffect } from \"../hooks/tap-effect\";\n\nexport interface ResourceHandle<R, P> {\n getState(): R;\n subscribe(callback: () => void): Unsubscribe;\n updateInput(props: P): void;\n flushSync(): void;\n dispose(): void;\n}\n\nconst HandleWrapperResource = <R, P>({\n element,\n onUpdateInput,\n onFlushSync,\n onDispose,\n}: {\n element: ResourceElement<R, P>;\n onUpdateInput: () => void;\n onFlushSync: () => void;\n onDispose: () => void;\n}): ResourceHandle<R, P> => {\n const [props, setProps] = tapState(element.props);\n const value = tapInlineResource({ type: element.type, props });\n const subscribers = tapRef(new Set<() => void>()).current;\n const valueRef = tapRef(value);\n\n tapEffect(() => {\n if (value !== valueRef.current) {\n valueRef.current = value;\n subscribers.forEach((callback) => callback());\n }\n });\n\n const handle = tapMemo(\n () => ({\n getState: () => valueRef.current,\n subscribe: (callback: () => void) => {\n subscribers.add(callback);\n return () => subscribers.delete(callback);\n },\n updateInput: (props: P) => {\n onUpdateInput();\n setProps(() => props);\n },\n flushSync: onFlushSync,\n dispose: onDispose,\n }),\n [],\n );\n\n return handle;\n};\n\nexport const createResource = <R, P>(\n element: ResourceElement<R, P>,\n delayMount = false,\n): ResourceHandle<R, P> => {\n let isMounted = !delayMount;\n const props = {\n element,\n onUpdateInput: () => {\n if (isMounted) return;\n isMounted = true;\n commitResource(fiber, lastRender);\n },\n onFlushSync: () => {\n scheduler.flushSync();\n },\n onDispose: () => unmountResource(fiber),\n };\n\n const scheduler = new UpdateScheduler(() => {\n lastRender = renderResource(fiber, props);\n if (isMounted) commitResource(fiber, lastRender);\n });\n\n const fiber = createResourceFiber(HandleWrapperResource<R, P>, () =>\n scheduler.markDirty(),\n );\n\n let lastRender = renderResource(fiber, props);\n if (isMounted) commitResource(fiber, lastRender);\n return lastRender.state;\n};\n"],"mappings":";AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,SAAS,yBAAyB;AAClC,SAAS,iBAAiB;AAU1B,IAAM,wBAAwB,CAAO;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAK4B;AAC1B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,QAAQ,KAAK;AAChD,QAAM,QAAQ,kBAAkB,EAAE,MAAM,QAAQ,MAAM,MAAM,CAAC;AAC7D,QAAM,cAAc,OAAO,oBAAI,IAAgB,CAAC,EAAE;AAClD,QAAM,WAAW,OAAO,KAAK;AAE7B,YAAU,MAAM;AACd,QAAI,UAAU,SAAS,SAAS;AAC9B,eAAS,UAAU;AACnB,kBAAY,QAAQ,CAAC,aAAa,SAAS,CAAC;AAAA,IAC9C;AAAA,EACF,CAAC;AAED,QAAM,SAAS;AAAA,IACb,OAAO;AAAA,MACL,UAAU,MAAM,SAAS;AAAA,MACzB,WAAW,CAAC,aAAyB;AACnC,oBAAY,IAAI,QAAQ;AACxB,eAAO,MAAM,YAAY,OAAO,QAAQ;AAAA,MAC1C;AAAA,MACA,aAAa,CAACA,WAAa;AACzB,sBAAc;AACd,iBAAS,MAAMA,MAAK;AAAA,MACtB;AAAA,MACA,WAAW;AAAA,MACX,SAAS;AAAA,IACX;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,IAAM,iBAAiB,CAC5B,SACA,aAAa,UACY;AACzB,MAAI,YAAY,CAAC;AACjB,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,eAAe,MAAM;AACnB,UAAI,UAAW;AACf,kBAAY;AACZ,qBAAe,OAAO,UAAU;AAAA,IAClC;AAAA,IACA,aAAa,MAAM;AACjB,gBAAU,UAAU;AAAA,IACtB;AAAA,IACA,WAAW,MAAM,gBAAgB,KAAK;AAAA,EACxC;AAEA,QAAM,YAAY,IAAI,gBAAgB,MAAM;AAC1C,iBAAa,eAAe,OAAO,KAAK;AACxC,QAAI,UAAW,gBAAe,OAAO,UAAU;AAAA,EACjD,CAAC;AAED,QAAM,QAAQ;AAAA,IAAoB;AAAA,IAA6B,MAC7D,UAAU,UAAU;AAAA,EACtB;AAEA,MAAI,aAAa,eAAe,OAAO,KAAK;AAC5C,MAAI,UAAW,gBAAe,OAAO,UAAU;AAC/C,SAAO,WAAW;AACpB;","names":["props"]}
@@ -1,4 +1,4 @@
1
1
  import { ResourceFiber, RenderResult } from "./types";
2
- export declare function commitRender(renderContext: RenderResult, executionContext: ResourceFiber): void;
3
- export declare function cleanupAllEffects(executionContext: ResourceFiber): void;
2
+ export declare function commitRender<R, P>(renderResult: RenderResult, fiber: ResourceFiber<R, P>): void;
3
+ export declare function cleanupAllEffects<R, P>(executionContext: ResourceFiber<R, P>): void;
4
4
  //# sourceMappingURL=commit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/core/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEtD,wBAAgB,YAAY,CAC1B,aAAa,EAAE,YAAY,EAC3B,gBAAgB,EAAE,aAAa,GAC9B,IAAI,CAuDN;AAED,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,aAAa,QAYhE"}
1
+ {"version":3,"file":"commit.d.ts","sourceRoot":"","sources":["../../src/core/commit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEtD,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAC/B,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,GACzB,IAAI,CAuDN;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,QAgB5E"}
@@ -1,8 +1,8 @@
1
1
  // src/core/commit.ts
2
- function commitRender(renderContext, executionContext) {
3
- renderContext.commitTasks.forEach((task) => {
2
+ function commitRender(renderResult, fiber) {
3
+ renderResult.commitTasks.forEach((task) => {
4
4
  const cellIndex = task.cellIndex;
5
- const effectCell = executionContext.cells[cellIndex];
5
+ const effectCell = fiber.cells[cellIndex];
6
6
  if (effectCell.type !== "effect") {
7
7
  throw new Error("Cannot find effect cell");
8
8
  }
@@ -18,7 +18,7 @@ function commitRender(renderContext, executionContext) {
18
18
  );
19
19
  }
20
20
  try {
21
- if (effectCell.cleanup) {
21
+ if (effectCell.mounted && effectCell.cleanup) {
22
22
  effectCell.cleanup();
23
23
  }
24
24
  } finally {
@@ -42,16 +42,20 @@ function commitRender(renderContext, executionContext) {
42
42
  });
43
43
  }
44
44
  function cleanupAllEffects(executionContext) {
45
+ let firstError = null;
45
46
  for (let i = executionContext.cells.length - 1; i >= 0; i--) {
46
47
  const cell = executionContext.cells[i];
47
- if (cell?.type === "effect" && cell.cleanup) {
48
+ if (cell?.type === "effect" && cell.mounted && cell.cleanup) {
48
49
  try {
49
50
  cell.cleanup();
51
+ } catch (e) {
52
+ if (firstError == null) firstError = e;
50
53
  } finally {
51
54
  cell.mounted = false;
52
55
  }
53
56
  }
54
57
  }
58
+ if (firstError != null) throw firstError;
55
59
  }
56
60
  export {
57
61
  cleanupAllEffects,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/commit.ts"],"sourcesContent":["import { ResourceFiber, RenderResult } from \"./types\";\n\nexport function commitRender(\n renderContext: RenderResult,\n executionContext: ResourceFiber\n): void {\n // Process all tasks collected during render\n renderContext.commitTasks.forEach((task) => {\n const cellIndex = task.cellIndex;\n const effectCell = executionContext.cells[cellIndex]!;\n if (effectCell.type !== \"effect\") {\n throw new Error(\"Cannot find effect cell\");\n }\n\n // Check if deps changed\n let shouldRunEffect = true;\n\n if (effectCell.deps !== undefined && task.deps !== undefined) {\n shouldRunEffect =\n effectCell.deps.length !== task.deps.length ||\n effectCell.deps.some((dep, j) => !Object.is(dep, task.deps![j]));\n }\n\n // Run cleanup if effect will re-run\n if (shouldRunEffect) {\n if (effectCell.mounted) {\n if (typeof effectCell.deps !== typeof task.deps) {\n throw new Error(\n \"tapEffect called with and without dependencies across re-renders\"\n );\n }\n\n try {\n if (effectCell.cleanup) {\n effectCell.cleanup();\n }\n } finally {\n effectCell.mounted = false;\n }\n }\n\n try {\n const cleanup = task.effect();\n\n if (cleanup !== undefined && typeof cleanup !== \"function\") {\n throw new Error(\n \"An effect function must either return a cleanup function or nothing. \" +\n `Received: ${typeof cleanup}`\n );\n }\n\n effectCell.mounted = true;\n effectCell.cleanup =\n typeof cleanup === \"function\" ? cleanup : undefined;\n effectCell.deps = task.deps;\n } catch (error) {\n throw error;\n }\n }\n });\n}\n\nexport function cleanupAllEffects(executionContext: ResourceFiber) {\n // Run cleanups in reverse order\n for (let i = executionContext.cells.length - 1; i >= 0; i--) {\n const cell = executionContext.cells[i];\n if (cell?.type === \"effect\" && cell.cleanup) {\n try {\n cell.cleanup();\n } finally {\n cell.mounted = false;\n }\n }\n }\n}\n"],"mappings":";AAEO,SAAS,aACd,eACA,kBACM;AAEN,gBAAc,YAAY,QAAQ,CAAC,SAAS;AAC1C,UAAM,YAAY,KAAK;AACvB,UAAM,aAAa,iBAAiB,MAAM,SAAS;AACnD,QAAI,WAAW,SAAS,UAAU;AAChC,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAGA,QAAI,kBAAkB;AAEtB,QAAI,WAAW,SAAS,UAAa,KAAK,SAAS,QAAW;AAC5D,wBACE,WAAW,KAAK,WAAW,KAAK,KAAK,UACrC,WAAW,KAAK,KAAK,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,KAAK,KAAK,KAAM,CAAC,CAAC,CAAC;AAAA,IACnE;AAGA,QAAI,iBAAiB;AACnB,UAAI,WAAW,SAAS;AACtB,YAAI,OAAO,WAAW,SAAS,OAAO,KAAK,MAAM;AAC/C,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,cAAI,WAAW,SAAS;AACtB,uBAAW,QAAQ;AAAA,UACrB;AAAA,QACF,UAAE;AACA,qBAAW,UAAU;AAAA,QACvB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,UAAU,KAAK,OAAO;AAE5B,YAAI,YAAY,UAAa,OAAO,YAAY,YAAY;AAC1D,gBAAM,IAAI;AAAA,YACR,kFACe,OAAO,OAAO;AAAA,UAC/B;AAAA,QACF;AAEA,mBAAW,UAAU;AACrB,mBAAW,UACT,OAAO,YAAY,aAAa,UAAU;AAC5C,mBAAW,OAAO,KAAK;AAAA,MACzB,SAAS,OAAO;AACd,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,kBAAkB,kBAAiC;AAEjE,WAAS,IAAI,iBAAiB,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3D,UAAM,OAAO,iBAAiB,MAAM,CAAC;AACrC,QAAI,MAAM,SAAS,YAAY,KAAK,SAAS;AAC3C,UAAI;AACF,aAAK,QAAQ;AAAA,MACf,UAAE;AACA,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/core/commit.ts"],"sourcesContent":["import { ResourceFiber, RenderResult } from \"./types\";\n\nexport function commitRender<R, P>(\n renderResult: RenderResult,\n fiber: ResourceFiber<R, P>,\n): void {\n // Process all tasks collected during render\n renderResult.commitTasks.forEach((task) => {\n const cellIndex = task.cellIndex;\n const effectCell = fiber.cells[cellIndex]!;\n if (effectCell.type !== \"effect\") {\n throw new Error(\"Cannot find effect cell\");\n }\n\n // Check if deps changed\n let shouldRunEffect = true;\n\n if (effectCell.deps !== undefined && task.deps !== undefined) {\n shouldRunEffect =\n effectCell.deps.length !== task.deps.length ||\n effectCell.deps.some((dep, j) => !Object.is(dep, task.deps![j]));\n }\n\n // Run cleanup if effect will re-run\n if (shouldRunEffect) {\n if (effectCell.mounted) {\n if (typeof effectCell.deps !== typeof task.deps) {\n throw new Error(\n \"tapEffect called with and without dependencies across re-renders\",\n );\n }\n\n try {\n if (effectCell.mounted && effectCell.cleanup) {\n effectCell.cleanup();\n }\n } finally {\n effectCell.mounted = false;\n }\n }\n\n try {\n const cleanup = task.effect();\n\n if (cleanup !== undefined && typeof cleanup !== \"function\") {\n throw new Error(\n \"An effect function must either return a cleanup function or nothing. \" +\n `Received: ${typeof cleanup}`,\n );\n }\n\n effectCell.mounted = true;\n effectCell.cleanup =\n typeof cleanup === \"function\" ? cleanup : undefined;\n effectCell.deps = task.deps;\n } catch (error) {\n throw error;\n }\n }\n });\n}\n\nexport function cleanupAllEffects<R, P>(executionContext: ResourceFiber<R, P>) {\n let firstError: unknown | null = null;\n // Run cleanups in reverse order\n for (let i = executionContext.cells.length - 1; i >= 0; i--) {\n const cell = executionContext.cells[i];\n if (cell?.type === \"effect\" && cell.mounted && cell.cleanup) {\n try {\n cell.cleanup();\n } catch (e) {\n if (firstError == null) firstError = e;\n } finally {\n cell.mounted = false;\n }\n }\n }\n if (firstError != null) throw firstError;\n}\n"],"mappings":";AAEO,SAAS,aACd,cACA,OACM;AAEN,eAAa,YAAY,QAAQ,CAAC,SAAS;AACzC,UAAM,YAAY,KAAK;AACvB,UAAM,aAAa,MAAM,MAAM,SAAS;AACxC,QAAI,WAAW,SAAS,UAAU;AAChC,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAGA,QAAI,kBAAkB;AAEtB,QAAI,WAAW,SAAS,UAAa,KAAK,SAAS,QAAW;AAC5D,wBACE,WAAW,KAAK,WAAW,KAAK,KAAK,UACrC,WAAW,KAAK,KAAK,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,KAAK,KAAK,KAAM,CAAC,CAAC,CAAC;AAAA,IACnE;AAGA,QAAI,iBAAiB;AACnB,UAAI,WAAW,SAAS;AACtB,YAAI,OAAO,WAAW,SAAS,OAAO,KAAK,MAAM;AAC/C,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAEA,YAAI;AACF,cAAI,WAAW,WAAW,WAAW,SAAS;AAC5C,uBAAW,QAAQ;AAAA,UACrB;AAAA,QACF,UAAE;AACA,qBAAW,UAAU;AAAA,QACvB;AAAA,MACF;AAEA,UAAI;AACF,cAAM,UAAU,KAAK,OAAO;AAE5B,YAAI,YAAY,UAAa,OAAO,YAAY,YAAY;AAC1D,gBAAM,IAAI;AAAA,YACR,kFACe,OAAO,OAAO;AAAA,UAC/B;AAAA,QACF;AAEA,mBAAW,UAAU;AACrB,mBAAW,UACT,OAAO,YAAY,aAAa,UAAU;AAC5C,mBAAW,OAAO,KAAK;AAAA,MACzB,SAAS,OAAO;AACd,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,kBAAwB,kBAAuC;AAC7E,MAAI,aAA6B;AAEjC,WAAS,IAAI,iBAAiB,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3D,UAAM,OAAO,iBAAiB,MAAM,CAAC;AACrC,QAAI,MAAM,SAAS,YAAY,KAAK,WAAW,KAAK,SAAS;AAC3D,UAAI;AACF,aAAK,QAAQ;AAAA,MACf,SAAS,GAAG;AACV,YAAI,cAAc,KAAM,cAAa;AAAA,MACvC,UAAE;AACA,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACA,MAAI,cAAc,KAAM,OAAM;AAChC;","names":[]}
@@ -1,4 +1,4 @@
1
1
  import { ResourceFiber } from "./types";
2
- export declare function withResourceFiber(fiber: ResourceFiber, fn: () => void): void;
3
- export declare function getCurrentResourceFiber(): ResourceFiber;
2
+ export declare function withResourceFiber<R, P>(fiber: ResourceFiber<R, P>, fn: () => void): void;
3
+ export declare function getCurrentResourceFiber(): ResourceFiber<unknown, unknown>;
4
4
  //# sourceMappingURL=execution-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../src/core/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIxC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAwB5E;AACD,wBAAgB,uBAAuB,IAAI,aAAa,CAKvD"}
1
+ {"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../../src/core/execution-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIxC,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EACpC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,EAAE,EAAE,MAAM,IAAI,GACb,IAAI,CAoBN;AACD,wBAAgB,uBAAuB,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAKzE"}
@@ -1,9 +1,6 @@
1
1
  // src/core/execution-context.ts
2
2
  var currentResourceFiber = null;
3
3
  function withResourceFiber(fiber, fn) {
4
- if (fiber.isRendering) throw new Error("Execution context is locked");
5
- fiber.isRendering = true;
6
- fiber.commitTasks = [];
7
4
  fiber.currentIndex = 0;
8
5
  const previousContext = currentResourceFiber;
9
6
  currentResourceFiber = fiber;
@@ -17,7 +14,6 @@ function withResourceFiber(fiber, fn) {
17
14
  }
18
15
  } finally {
19
16
  currentResourceFiber = previousContext;
20
- fiber.isRendering = false;
21
17
  }
22
18
  }
23
19
  function getCurrentResourceFiber() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/execution-context.ts"],"sourcesContent":["import { ResourceFiber } from \"./types\";\n\nlet currentResourceFiber: ResourceFiber | null = null;\n\nexport function withResourceFiber(fiber: ResourceFiber, fn: () => void): void {\n if (fiber.isRendering) throw new Error(\"Execution context is locked\");\n fiber.isRendering = true;\n fiber.commitTasks = [];\n fiber.currentIndex = 0;\n\n const previousContext = currentResourceFiber;\n currentResourceFiber = fiber;\n try {\n fn();\n\n fiber.isFirstRender = false;\n\n // ensure hook count matches\n if (fiber.cells.length !== fiber.currentIndex) {\n throw new Error(\n `Rendered ${fiber.currentIndex} hooks but expected ${fiber.cells.length}. ` +\n \"Hooks must be called in the exact same order in every render.\"\n );\n }\n } finally {\n currentResourceFiber = previousContext;\n fiber.isRendering = false;\n }\n}\nexport function getCurrentResourceFiber(): ResourceFiber {\n if (!currentResourceFiber) {\n throw new Error(\"No resource fiber available\");\n }\n return currentResourceFiber;\n}\n"],"mappings":";AAEA,IAAI,uBAA6C;AAE1C,SAAS,kBAAkB,OAAsB,IAAsB;AAC5E,MAAI,MAAM,YAAa,OAAM,IAAI,MAAM,6BAA6B;AACpE,QAAM,cAAc;AACpB,QAAM,cAAc,CAAC;AACrB,QAAM,eAAe;AAErB,QAAM,kBAAkB;AACxB,yBAAuB;AACvB,MAAI;AACF,OAAG;AAEH,UAAM,gBAAgB;AAGtB,QAAI,MAAM,MAAM,WAAW,MAAM,cAAc;AAC7C,YAAM,IAAI;AAAA,QACR,YAAY,MAAM,YAAY,uBAAuB,MAAM,MAAM,MAAM;AAAA,MAEzE;AAAA,IACF;AAAA,EACF,UAAE;AACA,2BAAuB;AACvB,UAAM,cAAc;AAAA,EACtB;AACF;AACO,SAAS,0BAAyC;AACvD,MAAI,CAAC,sBAAsB;AACzB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACA,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/core/execution-context.ts"],"sourcesContent":["import { ResourceFiber } from \"./types\";\n\nlet currentResourceFiber: ResourceFiber<any, any> | null = null;\n\nexport function withResourceFiber<R, P>(\n fiber: ResourceFiber<R, P>,\n fn: () => void,\n): void {\n fiber.currentIndex = 0;\n\n const previousContext = currentResourceFiber;\n currentResourceFiber = fiber;\n try {\n fn();\n\n fiber.isFirstRender = false;\n\n // ensure hook count matches\n if (fiber.cells.length !== fiber.currentIndex) {\n throw new Error(\n `Rendered ${fiber.currentIndex} hooks but expected ${fiber.cells.length}. ` +\n \"Hooks must be called in the exact same order in every render.\",\n );\n }\n } finally {\n currentResourceFiber = previousContext;\n }\n}\nexport function getCurrentResourceFiber(): ResourceFiber<unknown, unknown> {\n if (!currentResourceFiber) {\n throw new Error(\"No resource fiber available\");\n }\n return currentResourceFiber;\n}\n"],"mappings":";AAEA,IAAI,uBAAuD;AAEpD,SAAS,kBACd,OACA,IACM;AACN,QAAM,eAAe;AAErB,QAAM,kBAAkB;AACxB,yBAAuB;AACvB,MAAI;AACF,OAAG;AAEH,UAAM,gBAAgB;AAGtB,QAAI,MAAM,MAAM,WAAW,MAAM,cAAc;AAC7C,YAAM,IAAI;AAAA,QACR,YAAY,MAAM,YAAY,uBAAuB,MAAM,MAAM,MAAM;AAAA,MAEzE;AAAA,IACF;AAAA,EACF,UAAE;AACA,2BAAuB;AAAA,EACzB;AACF;AACO,SAAS,0BAA2D;AACzE,MAAI,CAAC,sBAAsB;AACzB,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACA,SAAO;AACT;","names":[]}
@@ -1,3 +1,3 @@
1
1
  import { ResourceFn, ResourceElementConstructor } from "./types";
2
- export declare function resource<R, P>(type: ResourceFn<R, P>): ResourceElementConstructor<R, P>;
2
+ export declare function resource<R, P = undefined>(type: ResourceFn<R, P>): ResourceElementConstructor<R, P>;
3
3
  //# sourceMappingURL=resource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/core/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAEjB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAC3B,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACrB,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAQlC"}
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/core/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAEjB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EACvC,IAAI,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACrB,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAQlC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/resource.ts"],"sourcesContent":["import {\n ResourceFn,\n ResourceElement,\n ResourceElementConstructor,\n} from \"./types\";\n\nexport function resource<R, P>(\n type: ResourceFn<R, P>\n): ResourceElementConstructor<R, P> {\n return (props: P, options?: { key?: string | number }) => {\n return {\n type,\n props,\n ...(options?.key !== undefined && { key: options.key }),\n } as ResourceElement<R, P>;\n };\n}\n"],"mappings":";AAMO,SAAS,SACd,MACkC;AAClC,SAAO,CAAC,OAAU,YAAwC;AACxD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAI,SAAS,QAAQ,UAAa,EAAE,KAAK,QAAQ,IAAI;AAAA,IACvD;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/core/resource.ts"],"sourcesContent":["import {\n ResourceFn,\n ResourceElement,\n ResourceElementConstructor,\n} from \"./types\";\n\nexport function resource<R, P = undefined>(\n type: ResourceFn<R, P>,\n): ResourceElementConstructor<R, P> {\n return (props?: P, options?: { key?: string | number }) => {\n return {\n type,\n props,\n ...(options?.key !== undefined && { key: options.key }),\n } as ResourceElement<R, P>;\n };\n}\n"],"mappings":";AAMO,SAAS,SACd,MACkC;AAClC,SAAO,CAAC,OAAW,YAAwC;AACzD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,GAAI,SAAS,QAAQ,UAAa,EAAE,KAAK,QAAQ,IAAI;AAAA,IACvD;AAAA,EACF;AACF;","names":[]}