@assistant-ui/tap 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/ResourceFiber.d.ts +1 -1
- package/dist/core/ResourceFiber.d.ts.map +1 -1
- package/dist/core/ResourceFiber.js +35 -40
- package/dist/core/ResourceFiber.js.map +1 -1
- package/dist/core/callResourceFn.js +15 -12
- package/dist/core/callResourceFn.js.map +1 -1
- package/dist/core/commit.d.ts +1 -1
- package/dist/core/commit.d.ts.map +1 -1
- package/dist/core/commit.js +57 -54
- package/dist/core/commit.js.map +1 -1
- package/dist/core/context.js +16 -21
- package/dist/core/context.js.map +1 -1
- package/dist/core/createResource.d.ts +1 -1
- package/dist/core/createResource.d.ts.map +1 -1
- package/dist/core/createResource.js +54 -67
- package/dist/core/createResource.js.map +1 -1
- package/dist/core/execution-context.d.ts +1 -1
- package/dist/core/execution-context.d.ts.map +1 -1
- package/dist/core/execution-context.js +21 -25
- package/dist/core/execution-context.js.map +1 -1
- package/dist/core/resource.d.ts +1 -1
- package/dist/core/resource.d.ts.map +1 -1
- package/dist/core/resource.js +8 -12
- package/dist/core/resource.js.map +1 -1
- package/dist/core/scheduler.js +73 -72
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +1 -0
- package/dist/core/types.js.map +1 -1
- package/dist/hooks/depsShallowEqual.js +8 -10
- package/dist/hooks/depsShallowEqual.js.map +1 -1
- package/dist/hooks/tap-callback.js +2 -6
- package/dist/hooks/tap-callback.js.map +1 -1
- package/dist/hooks/tap-effect-event.js +21 -10
- package/dist/hooks/tap-effect-event.js.map +1 -1
- package/dist/hooks/tap-effect.js +30 -31
- package/dist/hooks/tap-effect.js.map +1 -1
- package/dist/hooks/tap-inline-resource.d.ts +1 -1
- package/dist/hooks/tap-inline-resource.d.ts.map +1 -1
- package/dist/hooks/tap-inline-resource.js +2 -6
- package/dist/hooks/tap-inline-resource.js.map +1 -1
- package/dist/hooks/tap-memo.js +10 -14
- package/dist/hooks/tap-memo.js.map +1 -1
- package/dist/hooks/tap-ref.js +5 -9
- package/dist/hooks/tap-ref.js.map +1 -1
- package/dist/hooks/tap-resource.d.ts +1 -1
- package/dist/hooks/tap-resource.d.ts.map +1 -1
- package/dist/hooks/tap-resource.js +13 -28
- package/dist/hooks/tap-resource.js.map +1 -1
- package/dist/hooks/tap-resources.d.ts +1 -1
- package/dist/hooks/tap-resources.d.ts.map +1 -1
- package/dist/hooks/tap-resources.js +63 -64
- package/dist/hooks/tap-resources.js.map +1 -1
- package/dist/hooks/tap-state.js +47 -44
- package/dist/hooks/tap-state.js.map +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -31
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -5
- package/dist/react/index.js.map +1 -1
- package/dist/react/use-resource.d.ts +1 -1
- package/dist/react/use-resource.d.ts.map +1 -1
- package/dist/react/use-resource.js +16 -26
- package/dist/react/use-resource.js.map +1 -1
- package/package.json +44 -30
- package/react/package.json +5 -0
- package/src/__tests__/basic/resourceHandle.test.ts +56 -0
- package/src/__tests__/basic/tapEffect.basic.test.ts +247 -0
- package/src/__tests__/basic/tapResources.basic.test.ts +222 -0
- package/src/__tests__/basic/tapState.basic.test.ts +240 -0
- package/src/__tests__/errors/errors.effect-errors.test.ts +222 -0
- package/src/__tests__/errors/errors.render-errors.test.ts +190 -0
- package/src/__tests__/lifecycle/lifecycle.dependencies.test.ts +241 -0
- package/src/__tests__/lifecycle/lifecycle.mount-unmount.test.ts +211 -0
- package/src/__tests__/rules/rules.hook-count.test.ts +200 -0
- package/src/__tests__/rules/rules.hook-order.test.ts +192 -0
- package/src/__tests__/test-utils.ts +219 -0
- package/src/core/ResourceFiber.ts +58 -0
- package/src/core/callResourceFn.ts +21 -0
- package/src/core/commit.ts +73 -0
- package/src/core/context.ts +28 -0
- package/src/core/createResource.ts +116 -0
- package/src/core/execution-context.ts +34 -0
- package/src/core/resource.ts +16 -0
- package/src/core/scheduler.ts +95 -0
- package/src/core/types.ts +59 -0
- package/src/hooks/depsShallowEqual.ts +10 -0
- package/src/hooks/tap-callback.ts +8 -0
- package/src/hooks/tap-effect-event.ts +29 -0
- package/src/hooks/tap-effect.ts +59 -0
- package/src/hooks/tap-inline-resource.ts +8 -0
- package/src/hooks/tap-memo.ts +16 -0
- package/src/hooks/tap-ref.ts +16 -0
- package/src/hooks/tap-resource.ts +44 -0
- package/src/hooks/tap-resources.ts +112 -0
- package/src/hooks/tap-state.ts +83 -0
- package/src/index.ts +31 -0
- package/src/react/index.ts +1 -0
- package/src/react/use-resource.ts +35 -0
- package/dist/__tests__/test-utils.d.ts +0 -79
- package/dist/__tests__/test-utils.d.ts.map +0 -1
- package/dist/__tests__/test-utils.js +0 -138
- package/dist/__tests__/test-utils.js.map +0 -1
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { ResourceFiber } from "../core/types";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a test resource fiber for unit testing.
|
|
4
|
-
* This is a low-level utility that creates a ResourceFiber directly.
|
|
5
|
-
* Sets up a rerender callback that automatically re-renders when state changes.
|
|
6
|
-
*/
|
|
7
|
-
export declare function createTestResource<R, P>(fn: (props: P) => R): ResourceFiber<R, P>;
|
|
8
|
-
/**
|
|
9
|
-
* Renders a test resource fiber with the given props and manages its lifecycle.
|
|
10
|
-
* - Tracks resources for cleanup
|
|
11
|
-
* - Returns the current state after render
|
|
12
|
-
*/
|
|
13
|
-
export declare function renderTest<R, P>(fiber: ResourceFiber<R, P>, props: P): R;
|
|
14
|
-
/**
|
|
15
|
-
* Unmounts a specific resource fiber and removes it from tracking.
|
|
16
|
-
*/
|
|
17
|
-
export declare function unmountResource<R, P>(fiber: ResourceFiber<R, P>): void;
|
|
18
|
-
/**
|
|
19
|
-
* Cleans up all resources. Should be called after each test.
|
|
20
|
-
*/
|
|
21
|
-
export declare function cleanupAllResources(): void;
|
|
22
|
-
/**
|
|
23
|
-
* Gets the current committed state of a resource fiber.
|
|
24
|
-
* Returns the state from the last render/commit cycle.
|
|
25
|
-
*/
|
|
26
|
-
export declare function getCommittedState<R, P>(fiber: ResourceFiber<R, P>): R;
|
|
27
|
-
/**
|
|
28
|
-
* Helper to subscribe to resource state changes for testing.
|
|
29
|
-
* Tracks call count and latest state value.
|
|
30
|
-
*/
|
|
31
|
-
export declare class TestSubscriber<T> {
|
|
32
|
-
callCount: number;
|
|
33
|
-
lastState: T;
|
|
34
|
-
private fiber;
|
|
35
|
-
constructor(fiber: ResourceFiber<any, any>);
|
|
36
|
-
cleanup(): void;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Helper class to manage resource lifecycle in tests with explicit control.
|
|
40
|
-
* Useful when you need fine-grained control over mount/unmount timing.
|
|
41
|
-
*/
|
|
42
|
-
export declare class TestResourceManager<R, P> {
|
|
43
|
-
fiber: ResourceFiber<R, P>;
|
|
44
|
-
private isActive;
|
|
45
|
-
constructor(fiber: ResourceFiber<R, P>);
|
|
46
|
-
renderAndMount(props: P): R;
|
|
47
|
-
cleanup(): void;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Waits for the next tick of the event loop.
|
|
51
|
-
* Useful for testing async state updates.
|
|
52
|
-
*/
|
|
53
|
-
export declare function waitForNextTick(): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* Waits for a condition to be true with timeout.
|
|
56
|
-
* Useful for testing eventual consistency.
|
|
57
|
-
*/
|
|
58
|
-
export declare function waitFor(condition: () => boolean, timeout?: number, interval?: number): Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
* Creates a simple counter resource for testing.
|
|
61
|
-
* Commonly used across multiple test files.
|
|
62
|
-
*/
|
|
63
|
-
export declare function createCounterResource(initialValue?: number): (props: {
|
|
64
|
-
value?: number;
|
|
65
|
-
}) => {
|
|
66
|
-
count: number;
|
|
67
|
-
};
|
|
68
|
-
/**
|
|
69
|
-
* Creates a stateful counter resource for testing.
|
|
70
|
-
* Includes increment/decrement functions.
|
|
71
|
-
*/
|
|
72
|
-
export declare function createStatefulCounterResource(): (props: {
|
|
73
|
-
initial: number;
|
|
74
|
-
}) => {
|
|
75
|
-
count: number;
|
|
76
|
-
increment: () => void;
|
|
77
|
-
decrement: () => void;
|
|
78
|
-
};
|
|
79
|
-
//# sourceMappingURL=test-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAO9C;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,uBAa3D;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,138 +0,0 @@
|
|
|
1
|
-
// src/__tests__/test-utils.ts
|
|
2
|
-
import { resource } from "../core/resource.js";
|
|
3
|
-
import {
|
|
4
|
-
createResourceFiber,
|
|
5
|
-
unmountResourceFiber,
|
|
6
|
-
renderResourceFiber,
|
|
7
|
-
commitResourceFiber
|
|
8
|
-
} from "../core/ResourceFiber.js";
|
|
9
|
-
import { tapState } from "../hooks/tap-state.js";
|
|
10
|
-
function createTestResource(fn) {
|
|
11
|
-
const rerenderCallback = () => {
|
|
12
|
-
if (activeResources.has(fiber)) {
|
|
13
|
-
const lastProps = propsMap.get(fiber);
|
|
14
|
-
const result = renderResourceFiber(fiber, lastProps);
|
|
15
|
-
commitResourceFiber(fiber, result);
|
|
16
|
-
lastRenderResultMap.set(fiber, result);
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const fiber = createResourceFiber(resource(fn), rerenderCallback);
|
|
20
|
-
return fiber;
|
|
21
|
-
}
|
|
22
|
-
var activeResources = /* @__PURE__ */ new Set();
|
|
23
|
-
var propsMap = /* @__PURE__ */ new WeakMap();
|
|
24
|
-
var lastRenderResultMap = /* @__PURE__ */ new WeakMap();
|
|
25
|
-
function renderTest(fiber, props) {
|
|
26
|
-
propsMap.set(fiber, props);
|
|
27
|
-
activeResources.add(fiber);
|
|
28
|
-
const result = renderResourceFiber(fiber, props);
|
|
29
|
-
commitResourceFiber(fiber, result);
|
|
30
|
-
lastRenderResultMap.set(fiber, result);
|
|
31
|
-
return result.state;
|
|
32
|
-
}
|
|
33
|
-
function unmountResource(fiber) {
|
|
34
|
-
if (activeResources.has(fiber)) {
|
|
35
|
-
unmountResourceFiber(fiber);
|
|
36
|
-
activeResources.delete(fiber);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
function cleanupAllResources() {
|
|
40
|
-
activeResources.forEach((fiber) => unmountResourceFiber(fiber));
|
|
41
|
-
activeResources.clear();
|
|
42
|
-
}
|
|
43
|
-
function getCommittedState(fiber) {
|
|
44
|
-
const lastResult = lastRenderResultMap.get(fiber);
|
|
45
|
-
if (!lastResult) {
|
|
46
|
-
throw new Error(
|
|
47
|
-
"No render result found for fiber. Make sure to call renderResource first."
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
return lastResult.state;
|
|
51
|
-
}
|
|
52
|
-
var TestSubscriber = class {
|
|
53
|
-
callCount = 0;
|
|
54
|
-
lastState;
|
|
55
|
-
fiber;
|
|
56
|
-
constructor(fiber) {
|
|
57
|
-
this.fiber = fiber;
|
|
58
|
-
const lastProps = propsMap.get(fiber) ?? void 0;
|
|
59
|
-
const initialResult = renderResourceFiber(fiber, lastProps);
|
|
60
|
-
commitResourceFiber(fiber, initialResult);
|
|
61
|
-
this.lastState = initialResult.state;
|
|
62
|
-
lastRenderResultMap.set(fiber, initialResult);
|
|
63
|
-
activeResources.add(fiber);
|
|
64
|
-
}
|
|
65
|
-
cleanup() {
|
|
66
|
-
if (activeResources.has(this.fiber)) {
|
|
67
|
-
unmountResourceFiber(this.fiber);
|
|
68
|
-
activeResources.delete(this.fiber);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
var TestResourceManager = class {
|
|
73
|
-
constructor(fiber) {
|
|
74
|
-
this.fiber = fiber;
|
|
75
|
-
}
|
|
76
|
-
isActive = false;
|
|
77
|
-
renderAndMount(props) {
|
|
78
|
-
if (this.isActive) {
|
|
79
|
-
throw new Error("Resource already active");
|
|
80
|
-
}
|
|
81
|
-
this.isActive = true;
|
|
82
|
-
activeResources.add(this.fiber);
|
|
83
|
-
propsMap.set(this.fiber, props);
|
|
84
|
-
const result = renderResourceFiber(this.fiber, props);
|
|
85
|
-
commitResourceFiber(this.fiber, result);
|
|
86
|
-
lastRenderResultMap.set(this.fiber, result);
|
|
87
|
-
return result.state;
|
|
88
|
-
}
|
|
89
|
-
cleanup() {
|
|
90
|
-
if (this.isActive && activeResources.has(this.fiber)) {
|
|
91
|
-
unmountResourceFiber(this.fiber);
|
|
92
|
-
activeResources.delete(this.fiber);
|
|
93
|
-
this.isActive = false;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
function waitForNextTick() {
|
|
98
|
-
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
99
|
-
}
|
|
100
|
-
async function waitFor(condition, timeout = 1e3, interval = 10) {
|
|
101
|
-
const start = Date.now();
|
|
102
|
-
while (!condition()) {
|
|
103
|
-
if (Date.now() - start > timeout) {
|
|
104
|
-
throw new Error("Timeout waiting for condition");
|
|
105
|
-
}
|
|
106
|
-
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function createCounterResource(initialValue = 0) {
|
|
110
|
-
return (props) => {
|
|
111
|
-
const value = props.value ?? initialValue;
|
|
112
|
-
return { count: value };
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
function createStatefulCounterResource() {
|
|
116
|
-
return (props) => {
|
|
117
|
-
const [count, setCount] = tapState(props.initial);
|
|
118
|
-
return {
|
|
119
|
-
count,
|
|
120
|
-
increment: () => setCount((c) => c + 1),
|
|
121
|
-
decrement: () => setCount((c) => c - 1)
|
|
122
|
-
};
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
export {
|
|
126
|
-
TestResourceManager,
|
|
127
|
-
TestSubscriber,
|
|
128
|
-
cleanupAllResources,
|
|
129
|
-
createCounterResource,
|
|
130
|
-
createStatefulCounterResource,
|
|
131
|
-
createTestResource,
|
|
132
|
-
getCommittedState,
|
|
133
|
-
renderTest,
|
|
134
|
-
unmountResource,
|
|
135
|
-
waitFor,
|
|
136
|
-
waitForNextTick
|
|
137
|
-
};
|
|
138
|
-
//# sourceMappingURL=test-utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/__tests__/test-utils.ts"],"sourcesContent":["import { resource } from \"../core/resource\";\nimport {\n createResourceFiber,\n unmountResourceFiber,\n renderResourceFiber,\n commitResourceFiber,\n} from \"../core/ResourceFiber\";\nimport { 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>(fn: (props: P) => R) {\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 commitResourceFiber(fiber, result);\n lastRenderResultMap.set(fiber, result);\n }\n };\n\n const fiber = createResourceFiber(resource(fn), 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 commitResourceFiber(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 commitResourceFiber(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 commitResourceFiber(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":";AAAA,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,gBAAgB;AAWlB,SAAS,mBAAyB,IAAqB;AAC5D,QAAM,mBAAmB,MAAM;AAE7B,QAAI,gBAAgB,IAAI,KAAK,GAAG;AAC9B,YAAM,YAAY,SAAS,IAAI,KAAK;AACpC,YAAM,SAAS,oBAAoB,OAAO,SAAS;AACnD,0BAAoB,OAAO,MAAM;AACjC,0BAAoB,IAAI,OAAO,MAAM;AAAA,IACvC;AAAA,EACF;AAEA,QAAM,QAAQ,oBAAoB,SAAS,EAAE,GAAG,gBAAgB;AAChE,SAAO;AACT;AAOA,IAAM,kBAAkB,oBAAI,IAA6B;AACzD,IAAM,WAAW,oBAAI,QAAsC;AAC3D,IAAM,sBAAsB,oBAAI,QAAsC;AAO/D,SAAS,WAAiB,OAA4B,OAAa;AACxE,WAAS,IAAI,OAAO,KAAK;AAGzB,kBAAgB,IAAI,KAAK;AAGzB,QAAM,SAAS,oBAAoB,OAAO,KAAK;AAC/C,sBAAoB,OAAO,MAAM;AACjC,sBAAoB,IAAI,OAAO,MAAM;AAIrC,SAAO,OAAO;AAChB;AAKO,SAAS,gBAAsB,OAA4B;AAChE,MAAI,gBAAgB,IAAI,KAAK,GAAG;AAC9B,yBAAqB,KAAK;AAC1B,oBAAgB,OAAO,KAAK;AAAA,EAC9B;AACF;AAKO,SAAS,sBAAsB;AACpC,kBAAgB,QAAQ,CAAC,UAAU,qBAAqB,KAAK,CAAC;AAC9D,kBAAgB,MAAM;AACxB;AAMO,SAAS,kBAAwB,OAA+B;AACrE,QAAM,aAAa,oBAAoB,IAAI,KAAK;AAChD,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,WAAW;AACpB;AAUO,IAAM,iBAAN,MAAwB;AAAA,EACtB,YAAY;AAAA,EACZ;AAAA,EACC;AAAA,EAER,YAAY,OAAgC;AAC1C,SAAK,QAAQ;AAEb,UAAM,YAAY,SAAS,IAAI,KAAK,KAAK;AACzC,UAAM,gBAAgB,oBAAoB,OAAO,SAAgB;AACjE,wBAAoB,OAAO,aAAa;AACxC,SAAK,YAAY,cAAc;AAC/B,wBAAoB,IAAI,OAAO,aAAa;AAC5C,oBAAgB,IAAI,KAAK;AAAA,EAC3B;AAAA,EAEA,UAAU;AACR,QAAI,gBAAgB,IAAI,KAAK,KAAK,GAAG;AACnC,2BAAqB,KAAK,KAAK;AAC/B,sBAAgB,OAAO,KAAK,KAAK;AAAA,IACnC;AAAA,EACF;AACF;AAMO,IAAM,sBAAN,MAAgC;AAAA,EAGrC,YAAmB,OAA4B;AAA5B;AAAA,EAA6B;AAAA,EAFxC,WAAW;AAAA,EAInB,eAAe,OAAa;AAC1B,QAAI,KAAK,UAAU;AACjB,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAEA,SAAK,WAAW;AAChB,oBAAgB,IAAI,KAAK,KAAK;AAC9B,aAAS,IAAI,KAAK,OAAO,KAAK;AAC9B,UAAM,SAAS,oBAAoB,KAAK,OAAO,KAAK;AACpD,wBAAoB,KAAK,OAAO,MAAM;AACtC,wBAAoB,IAAI,KAAK,OAAO,MAAM;AAC1C,WAAO,OAAO;AAAA,EAChB;AAAA,EAEA,UAAU;AACR,QAAI,KAAK,YAAY,gBAAgB,IAAI,KAAK,KAAK,GAAG;AACpD,2BAAqB,KAAK,KAAK;AAC/B,sBAAgB,OAAO,KAAK,KAAK;AACjC,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AACF;AAUO,SAAS,kBAAiC;AAC/C,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,CAAC,CAAC;AACxD;AAMA,eAAsB,QACpB,WACA,UAAU,KACV,WAAW,IACI;AACf,QAAM,QAAQ,KAAK,IAAI;AACvB,SAAO,CAAC,UAAU,GAAG;AACnB,QAAI,KAAK,IAAI,IAAI,QAAQ,SAAS;AAChC,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,QAAQ,CAAC;AAAA,EAC9D;AACF;AAUO,SAAS,sBAAsB,eAAe,GAAG;AACtD,SAAO,CAAC,UAA8B;AACpC,UAAM,QAAQ,MAAM,SAAS;AAC7B,WAAO,EAAE,OAAO,MAAM;AAAA,EACxB;AACF;AAMO,SAAS,gCAAgC;AAC9C,SAAO,CAAC,UAA+B;AACrC,UAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,MAAM,OAAO;AAChD,WAAO;AAAA,MACL;AAAA,MACA,WAAW,MAAM,SAAS,CAAC,MAAc,IAAI,CAAC;AAAA,MAC9C,WAAW,MAAM,SAAS,CAAC,MAAc,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AACF;","names":[]}
|