@assistant-ui/tap 0.0.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 (82) hide show
  1. package/README.md +252 -0
  2. package/dist/__tests__/test-utils.d.ts +79 -0
  3. package/dist/__tests__/test-utils.d.ts.map +1 -0
  4. package/dist/__tests__/test-utils.js +216 -0
  5. package/dist/__tests__/test-utils.js.map +1 -0
  6. package/dist/core/ResourceFiber.d.ts +6 -0
  7. package/dist/core/ResourceFiber.d.ts.map +1 -0
  8. package/dist/core/ResourceFiber.js +41 -0
  9. package/dist/core/ResourceFiber.js.map +1 -0
  10. package/dist/core/ResourceHandle.d.ts +8 -0
  11. package/dist/core/ResourceHandle.d.ts.map +1 -0
  12. package/dist/core/ResourceHandle.js +64 -0
  13. package/dist/core/ResourceHandle.js.map +1 -0
  14. package/dist/core/commit.d.ts +4 -0
  15. package/dist/core/commit.d.ts.map +1 -0
  16. package/dist/core/commit.js +60 -0
  17. package/dist/core/commit.js.map +1 -0
  18. package/dist/core/execution-context.d.ts +4 -0
  19. package/dist/core/execution-context.d.ts.map +1 -0
  20. package/dist/core/execution-context.js +33 -0
  21. package/dist/core/execution-context.js.map +1 -0
  22. package/dist/core/resource.d.ts +3 -0
  23. package/dist/core/resource.d.ts.map +1 -0
  24. package/dist/core/resource.js +14 -0
  25. package/dist/core/resource.js.map +1 -0
  26. package/dist/core/scheduler.d.ts +14 -0
  27. package/dist/core/scheduler.d.ts.map +1 -0
  28. package/dist/core/scheduler.js +66 -0
  29. package/dist/core/scheduler.js.map +1 -0
  30. package/dist/core/types.d.ts +44 -0
  31. package/dist/core/types.d.ts.map +1 -0
  32. package/dist/core/types.js +1 -0
  33. package/dist/core/types.js.map +1 -0
  34. package/dist/hooks/depsShallowEqual.d.ts +2 -0
  35. package/dist/hooks/depsShallowEqual.d.ts.map +1 -0
  36. package/dist/hooks/depsShallowEqual.js +12 -0
  37. package/dist/hooks/depsShallowEqual.js.map +1 -0
  38. package/dist/hooks/tap-callback.d.ts +2 -0
  39. package/dist/hooks/tap-callback.d.ts.map +1 -0
  40. package/dist/hooks/tap-callback.js +9 -0
  41. package/dist/hooks/tap-callback.js.map +1 -0
  42. package/dist/hooks/tap-effect.d.ts +4 -0
  43. package/dist/hooks/tap-effect.d.ts.map +1 -0
  44. package/dist/hooks/tap-effect.js +32 -0
  45. package/dist/hooks/tap-effect.js.map +1 -0
  46. package/dist/hooks/tap-memo.d.ts +2 -0
  47. package/dist/hooks/tap-memo.d.ts.map +1 -0
  48. package/dist/hooks/tap-memo.js +18 -0
  49. package/dist/hooks/tap-memo.js.map +1 -0
  50. package/dist/hooks/tap-ref.d.ts +7 -0
  51. package/dist/hooks/tap-ref.d.ts.map +1 -0
  52. package/dist/hooks/tap-ref.js +12 -0
  53. package/dist/hooks/tap-ref.js.map +1 -0
  54. package/dist/hooks/tap-rerender.d.ts +2 -0
  55. package/dist/hooks/tap-rerender.d.ts.map +1 -0
  56. package/dist/hooks/tap-rerender.js +10 -0
  57. package/dist/hooks/tap-rerender.js.map +1 -0
  58. package/dist/hooks/tap-resource.d.ts +4 -0
  59. package/dist/hooks/tap-resource.d.ts.map +1 -0
  60. package/dist/hooks/tap-resource.js +33 -0
  61. package/dist/hooks/tap-resource.js.map +1 -0
  62. package/dist/hooks/tap-resources.d.ts +5 -0
  63. package/dist/hooks/tap-resources.d.ts.map +1 -0
  64. package/dist/hooks/tap-resources.js +84 -0
  65. package/dist/hooks/tap-resources.js.map +1 -0
  66. package/dist/hooks/tap-state.d.ts +7 -0
  67. package/dist/hooks/tap-state.d.ts.map +1 -0
  68. package/dist/hooks/tap-state.js +43 -0
  69. package/dist/hooks/tap-state.js.map +1 -0
  70. package/dist/index.d.ts +10 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/dist/index.js +20 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/react/index.d.ts +2 -0
  75. package/dist/react/index.d.ts.map +1 -0
  76. package/dist/react/index.js +6 -0
  77. package/dist/react/index.js.map +1 -0
  78. package/dist/react/use-resource.d.ts +3 -0
  79. package/dist/react/use-resource.d.ts.map +1 -0
  80. package/dist/react/use-resource.js +30 -0
  81. package/dist/react/use-resource.js.map +1 -0
  82. package/package.json +46 -0
@@ -0,0 +1,84 @@
1
+ // src/hooks/tap-resources.ts
2
+ import { tapEffect } from "./tap-effect.js";
3
+ import { tapRef } from "./tap-ref.js";
4
+ import {
5
+ createResourceFiber,
6
+ unmountResource,
7
+ renderResource,
8
+ commitResource
9
+ } from "../core/ResourceFiber.js";
10
+ import { tapRerender } from "./tap-rerender.js";
11
+ function tapResources(elements) {
12
+ const seenKeys = /* @__PURE__ */ new Set();
13
+ elements.forEach((element, index) => {
14
+ if (element.key === void 0) {
15
+ throw new Error(
16
+ `tapResources: All resource elements must have a key. Element at index ${index} is missing a key.`
17
+ );
18
+ }
19
+ if (seenKeys.has(element.key)) {
20
+ throw new Error(
21
+ `tapResources: Duplicate key "${element.key}" found. All keys must be unique.`
22
+ );
23
+ }
24
+ seenKeys.add(element.key);
25
+ });
26
+ const entriesRef = tapRef();
27
+ if (!entriesRef.current) {
28
+ entriesRef.current = /* @__PURE__ */ new Map();
29
+ }
30
+ const entries = entriesRef.current;
31
+ const rerender = tapRerender();
32
+ const currentKeys = /* @__PURE__ */ new Set();
33
+ const renderContexts = [];
34
+ elements.forEach((element) => {
35
+ const key = element.key;
36
+ currentKeys.add(key);
37
+ let entry = entries.get(key);
38
+ if (!entry || entry.type !== element.type) {
39
+ if (entry) {
40
+ unmountResource(entry.fiber);
41
+ }
42
+ const fiber = createResourceFiber(element.type, rerender);
43
+ entry = {
44
+ fiber,
45
+ type: element.type,
46
+ props: element.props,
47
+ state: void 0
48
+ };
49
+ entries.set(key, entry);
50
+ }
51
+ entry.props = element.props;
52
+ const result = renderResource(entry.fiber, element.props);
53
+ entry.state = result.state;
54
+ renderContexts.push({ entry, result });
55
+ });
56
+ tapEffect(() => {
57
+ renderContexts.forEach(({ entry, result: ctx }) => {
58
+ commitResource(entry.fiber, ctx);
59
+ });
60
+ });
61
+ tapEffect(() => {
62
+ const keysToRemove = [];
63
+ for (const [key, entry] of entries) {
64
+ if (!currentKeys.has(key)) {
65
+ unmountResource(entry.fiber);
66
+ keysToRemove.push(key);
67
+ }
68
+ }
69
+ keysToRemove.forEach((key) => entries.delete(key));
70
+ });
71
+ tapEffect(() => {
72
+ return () => {
73
+ entries.forEach((entry) => {
74
+ unmountResource(entry.fiber);
75
+ });
76
+ entries.clear();
77
+ };
78
+ }, []);
79
+ return elements.map((element) => entries.get(element.key)?.state);
80
+ }
81
+ export {
82
+ tapResources
83
+ };
84
+ //# sourceMappingURL=tap-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/tap-resources.ts"],"sourcesContent":["import { RenderResult, ResourceElement, ResourceFiber } from \"../core/types\";\nimport { tapEffect } from \"./tap-effect\";\nimport { tapRef } from \"./tap-ref\";\nimport {\n createResourceFiber,\n unmountResource,\n renderResource,\n commitResource,\n} from \"../core/ResourceFiber\";\nimport { tapRerender } from \"./tap-rerender\";\n\ninterface ResourceEntry<R, P> {\n fiber: ResourceFiber;\n type: (props: P) => R;\n props: P;\n state: R;\n}\n\n// TODO make safe for concurrent rendering\nexport function tapResources<\n T extends ReadonlyArray<ResourceElement<any, any>>\n>(\n elements: T\n): { [K in keyof T]: T[K] extends ResourceElement<any, infer R> ? R : never } {\n // Validate that all elements have keys and keys are unique\n const seenKeys = new Set<string | number>();\n elements.forEach((element, index) => {\n if (element.key === undefined) {\n throw new Error(\n `tapResources: All resource elements must have a key. Element at index ${index} is missing a key.`\n );\n }\n if (seenKeys.has(element.key)) {\n throw new Error(\n `tapResources: Duplicate key \"${element.key}\" found. All keys must be unique.`\n );\n }\n seenKeys.add(element.key);\n });\n\n // Use a ref to store resource entries persistently\n const entriesRef = tapRef<Map<string | number, ResourceEntry<any, any>>>();\n if (!entriesRef.current) {\n entriesRef.current = new Map();\n }\n const entries = entriesRef.current;\n\n // State to trigger re-renders when child resources update\n const rerender = tapRerender();\n\n // Process elements and update entries\n const currentKeys = new Set<string | number>();\n const renderContexts: Array<{\n entry: ResourceEntry<any, any>;\n result: RenderResult;\n }> = [];\n\n // First pass: create/update instances and render\n elements.forEach((element) => {\n const key = element.key!;\n currentKeys.add(key);\n\n let entry = entries.get(key);\n\n // Create new fiber if needed or type changed\n if (!entry || entry.type !== element.type) {\n // Clean up old fiber if it exists\n if (entry) {\n unmountResource(entry.fiber);\n }\n\n const fiber = createResourceFiber(element.type, rerender);\n entry = {\n fiber,\n type: element.type,\n props: element.props,\n state: undefined as any,\n };\n entries.set(key, entry);\n }\n\n // Update props if changed\n entry.props = element.props;\n\n // Render with current props\n const result = renderResource(entry.fiber, element.props);\n entry.state = result.state;\n\n renderContexts.push({ entry, result: result });\n });\n\n // No longer need mounting effect since we don't track mount state\n\n // Effect to commit renders\n tapEffect(() => {\n // Commit all renders\n renderContexts.forEach(({ entry, result: ctx }) => {\n commitResource(entry.fiber, ctx);\n });\n });\n\n // Effect to clean up removed resources\n tapEffect(() => {\n // Clean up removed fibers\n const keysToRemove: (string | number)[] = [];\n for (const [key, entry] of entries) {\n if (!currentKeys.has(key)) {\n unmountResource(entry.fiber);\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach((key) => entries.delete(key));\n });\n\n // Effect for final cleanup when this component unmounts\n tapEffect(() => {\n return () => {\n // Unmount all resources when the parent unmounts\n entries.forEach((entry) => {\n unmountResource(entry.fiber);\n });\n entries.clear();\n };\n }, []);\n\n // Return results in the same order as input elements\n return elements.map((element) => entries.get(element.key!)?.state) as any;\n}\n"],"mappings":";AACA,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAUrB,SAAS,aAGd,UAC4E;AAE5E,QAAM,WAAW,oBAAI,IAAqB;AAC1C,WAAS,QAAQ,CAAC,SAAS,UAAU;AACnC,QAAI,QAAQ,QAAQ,QAAW;AAC7B,YAAM,IAAI;AAAA,QACR,yEAAyE,KAAK;AAAA,MAChF;AAAA,IACF;AACA,QAAI,SAAS,IAAI,QAAQ,GAAG,GAAG;AAC7B,YAAM,IAAI;AAAA,QACR,gCAAgC,QAAQ,GAAG;AAAA,MAC7C;AAAA,IACF;AACA,aAAS,IAAI,QAAQ,GAAG;AAAA,EAC1B,CAAC;AAGD,QAAM,aAAa,OAAsD;AACzE,MAAI,CAAC,WAAW,SAAS;AACvB,eAAW,UAAU,oBAAI,IAAI;AAAA,EAC/B;AACA,QAAM,UAAU,WAAW;AAG3B,QAAM,WAAW,YAAY;AAG7B,QAAM,cAAc,oBAAI,IAAqB;AAC7C,QAAM,iBAGD,CAAC;AAGN,WAAS,QAAQ,CAAC,YAAY;AAC5B,UAAM,MAAM,QAAQ;AACpB,gBAAY,IAAI,GAAG;AAEnB,QAAI,QAAQ,QAAQ,IAAI,GAAG;AAG3B,QAAI,CAAC,SAAS,MAAM,SAAS,QAAQ,MAAM;AAEzC,UAAI,OAAO;AACT,wBAAgB,MAAM,KAAK;AAAA,MAC7B;AAEA,YAAM,QAAQ,oBAAoB,QAAQ,MAAM,QAAQ;AACxD,cAAQ;AAAA,QACN;AAAA,QACA,MAAM,QAAQ;AAAA,QACd,OAAO,QAAQ;AAAA,QACf,OAAO;AAAA,MACT;AACA,cAAQ,IAAI,KAAK,KAAK;AAAA,IACxB;AAGA,UAAM,QAAQ,QAAQ;AAGtB,UAAM,SAAS,eAAe,MAAM,OAAO,QAAQ,KAAK;AACxD,UAAM,QAAQ,OAAO;AAErB,mBAAe,KAAK,EAAE,OAAO,OAAe,CAAC;AAAA,EAC/C,CAAC;AAKD,YAAU,MAAM;AAEd,mBAAe,QAAQ,CAAC,EAAE,OAAO,QAAQ,IAAI,MAAM;AACjD,qBAAe,MAAM,OAAO,GAAG;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AAGD,YAAU,MAAM;AAEd,UAAM,eAAoC,CAAC;AAC3C,eAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,UAAI,CAAC,YAAY,IAAI,GAAG,GAAG;AACzB,wBAAgB,MAAM,KAAK;AAC3B,qBAAa,KAAK,GAAG;AAAA,MACvB;AAAA,IACF;AACA,iBAAa,QAAQ,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AAAA,EACnD,CAAC;AAGD,YAAU,MAAM;AACd,WAAO,MAAM;AAEX,cAAQ,QAAQ,CAAC,UAAU;AACzB,wBAAgB,MAAM,KAAK;AAAA,MAC7B,CAAC;AACD,cAAQ,MAAM;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,CAAC;AAGL,SAAO,SAAS,IAAI,CAAC,YAAY,QAAQ,IAAI,QAAQ,GAAI,GAAG,KAAK;AACnE;","names":[]}
@@ -0,0 +1,7 @@
1
+ import { StateUpdater } from "../core/types";
2
+ export declare function tapState<S = undefined>(): [
3
+ S | undefined,
4
+ (updater: StateUpdater<S>) => void
5
+ ];
6
+ export declare function tapState<S>(initial: S | (() => S)): [S, (updater: StateUpdater<S>) => void];
7
+ //# sourceMappingURL=tap-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-state.d.ts","sourceRoot":"","sources":["../../src/hooks/tap-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAQ,MAAM,eAAe,CAAC;AA2DnD,wBAAgB,QAAQ,CAAC,CAAC,GAAG,SAAS,KAAK;IACzC,CAAC,GAAG,SAAS;IACb,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI;CACnC,CAAC;AACF,wBAAgB,QAAQ,CAAC,CAAC,EACxB,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GACrB,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC"}
@@ -0,0 +1,43 @@
1
+ // src/hooks/tap-state.ts
2
+ import { getCurrentResourceFiber } from "../core/execution-context.js";
3
+ function getStateCell(initialValue) {
4
+ const executionContext = getCurrentResourceFiber();
5
+ const index = executionContext.currentIndex++;
6
+ if (!executionContext.isFirstRender && index >= executionContext.cells.length) {
7
+ throw new Error(
8
+ "Rendered more hooks than during the previous render. Hooks must be called in the exact same order in every render."
9
+ );
10
+ }
11
+ if (!executionContext.cells[index]) {
12
+ const value = typeof initialValue === "function" ? initialValue() : initialValue;
13
+ const cell2 = {
14
+ type: "state",
15
+ value,
16
+ set: (updater) => {
17
+ const currentValue = cell2.value;
18
+ const nextValue = typeof updater === "function" ? updater(currentValue) : updater;
19
+ if (!Object.is(currentValue, nextValue)) {
20
+ cell2.value = nextValue;
21
+ if (executionContext.isRendering) {
22
+ throw new Error("Resource updated during render");
23
+ }
24
+ executionContext.scheduleRerender();
25
+ }
26
+ }
27
+ };
28
+ executionContext.cells[index] = cell2;
29
+ }
30
+ const cell = executionContext.cells[index];
31
+ if (cell.type !== "state") {
32
+ throw new Error("Hook order changed between renders");
33
+ }
34
+ return cell;
35
+ }
36
+ function tapState(initial) {
37
+ const cell = getStateCell(initial);
38
+ return [cell.value, cell.set];
39
+ }
40
+ export {
41
+ tapState
42
+ };
43
+ //# sourceMappingURL=tap-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/tap-state.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"],"mappings":";AAAA,SAAS,+BAA+B;AAGxC,SAAS,aACP,cAC0B;AAC1B,QAAM,mBAAmB,wBAAwB;AACjD,QAAM,QAAQ,iBAAiB;AAG/B,MACE,CAAC,iBAAiB,iBAClB,SAAS,iBAAiB,MAAM,QAChC;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,MAAI,CAAC,iBAAiB,MAAM,KAAK,GAAG;AAElC,UAAM,QACJ,OAAO,iBAAiB,aACnB,aAAyB,IAC1B;AAEN,UAAMA,QAAiC;AAAA,MACrC,MAAM;AAAA,MACN;AAAA,MACA,KAAK,CAAC,YAA6B;AACjC,cAAM,eAAeA,MAAK;AAC1B,cAAM,YACJ,OAAO,YAAY,aACd,QAA2B,YAAY,IACxC;AAEN,YAAI,CAAC,OAAO,GAAG,cAAc,SAAS,GAAG;AACvC,UAAAA,MAAK,QAAQ;AAGb,cAAI,iBAAiB,aAAa;AAChC,kBAAM,IAAI,MAAM,gCAAgC;AAAA,UAClD;AACA,2BAAiB,iBAAiB;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAEA,qBAAiB,MAAM,KAAK,IAAIA;AAAA,EAClC;AAEA,QAAM,OAAO,iBAAiB,MAAM,KAAK;AACzC,MAAI,KAAK,SAAS,SAAS;AACzB,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,SAAO;AACT;AASO,SAAS,SACd,SACqD;AACrD,QAAM,OAAO,aAAa,OAAwB;AAElD,SAAO,CAAC,KAAK,OAAO,KAAK,GAAG;AAC9B;","names":["cell"]}
@@ -0,0 +1,10 @@
1
+ export { resource } from "./core/resource";
2
+ export { tapState } from "./hooks/tap-state";
3
+ export { tapEffect } from "./hooks/tap-effect";
4
+ export { tapRef } from "./hooks/tap-ref";
5
+ export { tapMemo } from "./hooks/tap-memo";
6
+ export { tapCallback } from "./hooks/tap-callback";
7
+ export { tapResource } from "./hooks/tap-resource";
8
+ export { createResource, type ResourceHandle } from "./core/ResourceHandle";
9
+ export type { ResourceFn, ResourceElement, ResourceElementConstructor, Unsubscribe, StateUpdater, EffectCallback, Destructor, } from "./core/types";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAInD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5E,YAAY,EACV,UAAU,EACV,eAAe,EACf,0BAA0B,EAC1B,WAAW,EACX,YAAY,EACZ,cAAc,EACd,UAAU,GACX,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ // src/index.ts
2
+ import { resource } from "./core/resource.js";
3
+ import { tapState } from "./hooks/tap-state.js";
4
+ import { tapEffect } from "./hooks/tap-effect.js";
5
+ import { tapRef } from "./hooks/tap-ref.js";
6
+ import { tapMemo } from "./hooks/tap-memo.js";
7
+ import { tapCallback } from "./hooks/tap-callback.js";
8
+ import { tapResource } from "./hooks/tap-resource.js";
9
+ import { createResource } from "./core/ResourceHandle.js";
10
+ export {
11
+ createResource,
12
+ resource,
13
+ tapCallback,
14
+ tapEffect,
15
+ tapMemo,
16
+ tapRef,
17
+ tapResource,
18
+ tapState
19
+ };
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { resource } from \"./core/resource\";\n\n// primitive hooks\nexport { tapState } from \"./hooks/tap-state\";\nexport { tapEffect } from \"./hooks/tap-effect\";\n\n// utility hooks\nexport { tapRef } from \"./hooks/tap-ref\";\nexport { tapMemo } from \"./hooks/tap-memo\";\nexport { tapCallback } from \"./hooks/tap-callback\";\n\n// resources\nexport { tapResource } from \"./hooks/tap-resource\";\n// export { tapResources } from \"./hooks/tap-resources\";\n\n// imperative\nexport { createResource, type ResourceHandle } from \"./core/ResourceHandle\";\n\nexport type {\n ResourceFn,\n ResourceElement,\n ResourceElementConstructor,\n Unsubscribe,\n StateUpdater,\n EffectCallback,\n Destructor,\n} from \"./core/types\";\n"],"mappings":";AAAA,SAAS,gBAAgB;AAGzB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAG1B,SAAS,cAAc;AACvB,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAG5B,SAAS,mBAAmB;AAI5B,SAAS,sBAA2C;","names":[]}
@@ -0,0 +1,2 @@
1
+ export { useResource } from "./use-resource";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ // src/react/index.ts
2
+ import { useResource } from "./use-resource.js";
3
+ export {
4
+ useResource
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/index.ts"],"sourcesContent":["export { useResource } from \"./use-resource\";"],"mappings":";AAAA,SAAS,mBAAmB;","names":[]}
@@ -0,0 +1,3 @@
1
+ import { ResourceElement } from "../core/types";
2
+ export declare function useResource<R, P>(element: ResourceElement<R, P>): R;
3
+ //# sourceMappingURL=use-resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-resource.d.ts","sourceRoot":"","sources":["../../src/react/use-resource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAkBhD,wBAAgB,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAgBnE"}
@@ -0,0 +1,30 @@
1
+ // src/react/use-resource.ts
2
+ import { useEffect, useLayoutEffect, useMemo, useState } from "react";
3
+ import {
4
+ createResourceFiber,
5
+ unmountResource,
6
+ renderResource,
7
+ commitResource
8
+ } from "../core/ResourceFiber.js";
9
+ var shouldUseIsomorphicLayoutEffect = globalThis.__ASSISTANT_UI_USE_ISOMORPHIC_LAYOUT_EFFECT__ === true;
10
+ var isSSR = typeof window === "undefined" || /ServerSideRendering/.test(window.navigator && window.navigator.userAgent);
11
+ var useIsomorphicLayoutEffect = shouldUseIsomorphicLayoutEffect && isSSR ? useEffect : useLayoutEffect;
12
+ function useResource(element) {
13
+ const [, rerender] = useState({});
14
+ const fiber = useMemo(
15
+ () => createResourceFiber(element.type, () => rerender({})),
16
+ [element.type]
17
+ );
18
+ const result = renderResource(fiber, element.props);
19
+ useIsomorphicLayoutEffect(() => {
20
+ return () => unmountResource(fiber);
21
+ }, []);
22
+ useIsomorphicLayoutEffect(() => {
23
+ commitResource(fiber, result);
24
+ });
25
+ return result.state;
26
+ }
27
+ export {
28
+ useResource
29
+ };
30
+ //# sourceMappingURL=use-resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/use-resource.ts"],"sourcesContent":["import { useEffect, useLayoutEffect, useMemo, useState } from \"react\";\nimport { ResourceElement } from \"../core/types\";\nimport {\n createResourceFiber,\n unmountResource,\n renderResource,\n commitResource,\n} from \"../core/ResourceFiber\";\n\nconst shouldUseIsomorphicLayoutEffect =\n (globalThis as any).__ASSISTANT_UI_USE_ISOMORPHIC_LAYOUT_EFFECT__ === true;\n\nconst isSSR =\n typeof window === \"undefined\" ||\n /ServerSideRendering/.test(window.navigator && window.navigator.userAgent);\n\nconst useIsomorphicLayoutEffect =\n shouldUseIsomorphicLayoutEffect && isSSR ? useEffect : useLayoutEffect;\n\nexport function useResource<R, P>(element: ResourceElement<R, P>): R {\n const [, rerender] = useState({});\n const fiber = useMemo(\n () => createResourceFiber(element.type, () => rerender({})),\n [element.type]\n );\n\n const result = renderResource(fiber, element.props);\n useIsomorphicLayoutEffect(() => {\n return () => unmountResource(fiber);\n }, []);\n useIsomorphicLayoutEffect(() => {\n commitResource(fiber, result);\n });\n\n return result.state;\n}\n"],"mappings":";AAAA,SAAS,WAAW,iBAAiB,SAAS,gBAAgB;AAE9D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,IAAM,kCACH,WAAmB,kDAAkD;AAExE,IAAM,QACJ,OAAO,WAAW,eAClB,sBAAsB,KAAK,OAAO,aAAa,OAAO,UAAU,SAAS;AAE3E,IAAM,4BACJ,mCAAmC,QAAQ,YAAY;AAElD,SAAS,YAAkB,SAAmC;AACnE,QAAM,CAAC,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC;AAChC,QAAM,QAAQ;AAAA,IACZ,MAAM,oBAAoB,QAAQ,MAAM,MAAM,SAAS,CAAC,CAAC,CAAC;AAAA,IAC1D,CAAC,QAAQ,IAAI;AAAA,EACf;AAEA,QAAM,SAAS,eAAe,OAAO,QAAQ,KAAK;AAClD,4BAA0B,MAAM;AAC9B,WAAO,MAAM,gBAAgB,KAAK;AAAA,EACpC,GAAG,CAAC,CAAC;AACL,4BAA0B,MAAM;AAC9B,mBAAe,OAAO,MAAM;AAAA,EAC9B,CAAC;AAED,SAAO,OAAO;AAChB;","names":[]}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@assistant-ui/tap",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "description": "Zero-dependency reactive state management inspired by React hooks",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "author": "AgentbaseAI Inc.",
9
+ "license": "MIT",
10
+ "dependencies": {},
11
+ "peerDependencies": {
12
+ "react": "*"
13
+ },
14
+ "peerDependenciesMeta": {
15
+ "react": {
16
+ "optional": true
17
+ }
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^24.2.0",
21
+ "@types/react": "*",
22
+ "@vitest/ui": "^3.2.4",
23
+ "tsx": "^4.20.3",
24
+ "typescript": "^5.9.2",
25
+ "vitest": "^3.2.4",
26
+ "@assistant-ui/x-buildutils": "0.0.1"
27
+ },
28
+ "exports": {
29
+ ".": {
30
+ "import": "./dist/index.js",
31
+ "types": "./dist/index.d.ts"
32
+ },
33
+ "./react": {
34
+ "import": "./dist/react/index.js",
35
+ "types": "./dist/react/index.d.ts"
36
+ }
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "scripts": {
42
+ "build": "tsx build.mts",
43
+ "test": "vitest",
44
+ "test:run": "vitest run"
45
+ }
46
+ }