@assistant-ui/store 0.0.1 → 0.0.3

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 (155) hide show
  1. package/README.md +59 -262
  2. package/dist/AssistantIf.d.ts +10 -0
  3. package/dist/AssistantIf.d.ts.map +1 -0
  4. package/dist/AssistantIf.js +13 -0
  5. package/dist/AssistantIf.js.map +1 -0
  6. package/dist/Derived.d.ts +34 -0
  7. package/dist/Derived.d.ts.map +1 -0
  8. package/dist/Derived.js +11 -0
  9. package/dist/Derived.js.map +1 -0
  10. package/dist/attachDefaultPeers.d.ts +56 -0
  11. package/dist/attachDefaultPeers.d.ts.map +1 -0
  12. package/dist/attachDefaultPeers.js +22 -0
  13. package/dist/attachDefaultPeers.js.map +1 -0
  14. package/dist/index.d.ts +11 -14
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +19 -16
  17. package/dist/index.js.map +1 -1
  18. package/dist/tapClientList.d.ts +24 -0
  19. package/dist/tapClientList.d.ts.map +1 -0
  20. package/dist/tapClientList.js +72 -0
  21. package/dist/tapClientList.js.map +1 -0
  22. package/dist/tapClientLookup.d.ts +11 -0
  23. package/dist/tapClientLookup.d.ts.map +1 -0
  24. package/dist/tapClientLookup.js +42 -0
  25. package/dist/tapClientLookup.js.map +1 -0
  26. package/dist/tapClientResource.d.ts +24 -0
  27. package/dist/tapClientResource.d.ts.map +1 -0
  28. package/dist/tapClientResource.js +100 -0
  29. package/dist/tapClientResource.js.map +1 -0
  30. package/dist/types/client.d.ts +117 -0
  31. package/dist/types/client.d.ts.map +1 -0
  32. package/dist/types/client.js +1 -0
  33. package/dist/types/events.d.ts +33 -0
  34. package/dist/types/events.d.ts.map +1 -0
  35. package/dist/types/events.js +12 -0
  36. package/dist/types/events.js.map +1 -0
  37. package/dist/useAssistantClient.d.ts +13 -41
  38. package/dist/useAssistantClient.d.ts.map +1 -1
  39. package/dist/useAssistantClient.js +185 -130
  40. package/dist/useAssistantClient.js.map +1 -1
  41. package/dist/useAssistantEvent.d.ts +2 -2
  42. package/dist/useAssistantEvent.d.ts.map +1 -1
  43. package/dist/useAssistantEvent.js +3 -6
  44. package/dist/useAssistantEvent.js.map +1 -1
  45. package/dist/useAssistantState.d.ts +2 -2
  46. package/dist/useAssistantState.d.ts.map +1 -1
  47. package/dist/useAssistantState.js +7 -36
  48. package/dist/useAssistantState.js.map +1 -1
  49. package/dist/utils/BaseProxyHandler.d.ts +23 -0
  50. package/dist/utils/BaseProxyHandler.d.ts.map +1 -0
  51. package/dist/utils/BaseProxyHandler.js +41 -0
  52. package/dist/utils/BaseProxyHandler.js.map +1 -0
  53. package/dist/utils/NotificationManager.d.ts +11 -0
  54. package/dist/utils/NotificationManager.d.ts.map +1 -0
  55. package/dist/utils/NotificationManager.js +81 -0
  56. package/dist/utils/NotificationManager.js.map +1 -0
  57. package/dist/utils/StoreResource.d.ts +14 -0
  58. package/dist/utils/StoreResource.d.ts.map +1 -0
  59. package/dist/utils/StoreResource.js +23 -0
  60. package/dist/utils/StoreResource.js.map +1 -0
  61. package/dist/utils/proxied-assistant-state.d.ts +8 -0
  62. package/dist/utils/proxied-assistant-state.d.ts.map +1 -0
  63. package/dist/utils/proxied-assistant-state.js +41 -0
  64. package/dist/utils/proxied-assistant-state.js.map +1 -0
  65. package/dist/{AssistantContext.d.ts → utils/react-assistant-context.d.ts} +6 -6
  66. package/dist/utils/react-assistant-context.d.ts.map +1 -0
  67. package/dist/utils/react-assistant-context.js +73 -0
  68. package/dist/utils/react-assistant-context.js.map +1 -0
  69. package/dist/utils/splitClients.d.ts +28 -0
  70. package/dist/utils/splitClients.d.ts.map +1 -0
  71. package/dist/utils/splitClients.js +37 -0
  72. package/dist/utils/splitClients.js.map +1 -0
  73. package/dist/utils/tap-assistant-context.d.ts +19 -0
  74. package/dist/utils/tap-assistant-context.d.ts.map +1 -0
  75. package/dist/utils/tap-assistant-context.js +37 -0
  76. package/dist/utils/tap-assistant-context.js.map +1 -0
  77. package/dist/utils/tap-client-stack-context.d.ts +23 -0
  78. package/dist/utils/tap-client-stack-context.d.ts.map +1 -0
  79. package/dist/utils/tap-client-stack-context.js +30 -0
  80. package/dist/utils/tap-client-stack-context.js.map +1 -0
  81. package/package.json +5 -6
  82. package/src/AssistantIf.tsx +17 -0
  83. package/src/Derived.ts +46 -0
  84. package/src/attachDefaultPeers.ts +78 -0
  85. package/src/index.ts +31 -25
  86. package/src/tapClientList.ts +105 -0
  87. package/src/tapClientLookup.ts +56 -0
  88. package/src/tapClientResource.ts +152 -0
  89. package/src/types/client.ts +186 -0
  90. package/src/types/events.ts +77 -0
  91. package/src/useAssistantClient.tsx +259 -217
  92. package/src/useAssistantEvent.ts +6 -9
  93. package/src/useAssistantState.tsx +10 -48
  94. package/src/utils/BaseProxyHandler.ts +50 -0
  95. package/src/utils/NotificationManager.ts +110 -0
  96. package/src/utils/StoreResource.ts +36 -0
  97. package/src/utils/proxied-assistant-state.tsx +53 -0
  98. package/src/utils/react-assistant-context.tsx +107 -0
  99. package/src/utils/splitClients.ts +85 -0
  100. package/src/utils/tap-assistant-context.ts +59 -0
  101. package/src/utils/tap-client-stack-context.ts +51 -0
  102. package/dist/AssistantContext.d.ts.map +0 -1
  103. package/dist/AssistantContext.js +0 -45
  104. package/dist/AssistantContext.js.map +0 -1
  105. package/dist/DerivedScope.d.ts +0 -18
  106. package/dist/DerivedScope.d.ts.map +0 -1
  107. package/dist/DerivedScope.js +0 -11
  108. package/dist/DerivedScope.js.map +0 -1
  109. package/dist/EventContext.d.ts +0 -65
  110. package/dist/EventContext.d.ts.map +0 -1
  111. package/dist/EventContext.js +0 -62
  112. package/dist/EventContext.js.map +0 -1
  113. package/dist/ScopeRegistry.d.ts +0 -41
  114. package/dist/ScopeRegistry.d.ts.map +0 -1
  115. package/dist/ScopeRegistry.js +0 -17
  116. package/dist/ScopeRegistry.js.map +0 -1
  117. package/dist/StoreContext.d.ts +0 -9
  118. package/dist/StoreContext.d.ts.map +0 -1
  119. package/dist/StoreContext.js +0 -20
  120. package/dist/StoreContext.js.map +0 -1
  121. package/dist/asStore.d.ts +0 -20
  122. package/dist/asStore.d.ts.map +0 -1
  123. package/dist/asStore.js +0 -23
  124. package/dist/asStore.js.map +0 -1
  125. package/dist/tapApi.d.ts +0 -36
  126. package/dist/tapApi.d.ts.map +0 -1
  127. package/dist/tapApi.js +0 -52
  128. package/dist/tapApi.js.map +0 -1
  129. package/dist/tapLookupResources.d.ts +0 -44
  130. package/dist/tapLookupResources.d.ts.map +0 -1
  131. package/dist/tapLookupResources.js +0 -21
  132. package/dist/tapLookupResources.js.map +0 -1
  133. package/dist/tapStoreList.d.ts +0 -76
  134. package/dist/tapStoreList.d.ts.map +0 -1
  135. package/dist/tapStoreList.js +0 -46
  136. package/dist/tapStoreList.js.map +0 -1
  137. package/dist/types.d.ts +0 -88
  138. package/dist/types.d.ts.map +0 -1
  139. package/dist/types.js +0 -1
  140. package/dist/utils/splitScopes.d.ts +0 -24
  141. package/dist/utils/splitScopes.d.ts.map +0 -1
  142. package/dist/utils/splitScopes.js +0 -18
  143. package/dist/utils/splitScopes.js.map +0 -1
  144. package/src/AssistantContext.tsx +0 -64
  145. package/src/DerivedScope.ts +0 -21
  146. package/src/EventContext.ts +0 -184
  147. package/src/ScopeRegistry.ts +0 -58
  148. package/src/StoreContext.ts +0 -28
  149. package/src/asStore.ts +0 -40
  150. package/src/tapApi.ts +0 -91
  151. package/src/tapLookupResources.ts +0 -62
  152. package/src/tapStoreList.ts +0 -133
  153. package/src/types.ts +0 -129
  154. package/src/utils/splitScopes.ts +0 -38
  155. /package/dist/{types.js.map → types/client.js.map} +0 -0
@@ -0,0 +1,81 @@
1
+ // src/utils/NotificationManager.ts
2
+ import { resource, tapMemo } from "@assistant-ui/tap";
3
+ var NotificationManager = resource(() => {
4
+ return tapMemo(() => {
5
+ const listeners = /* @__PURE__ */ new Map();
6
+ const wildcardListeners = /* @__PURE__ */ new Set();
7
+ const subscribers = /* @__PURE__ */ new Set();
8
+ return {
9
+ on(event, callback) {
10
+ const cb = callback;
11
+ if (event === "*") {
12
+ wildcardListeners.add(cb);
13
+ return () => wildcardListeners.delete(cb);
14
+ }
15
+ let set = listeners.get(event);
16
+ if (!set) {
17
+ set = /* @__PURE__ */ new Set();
18
+ listeners.set(event, set);
19
+ }
20
+ set.add(cb);
21
+ return () => {
22
+ set.delete(cb);
23
+ if (set.size === 0) listeners.delete(event);
24
+ };
25
+ },
26
+ emit(event, payload, clientStack) {
27
+ const eventListeners = listeners.get(event);
28
+ if (!eventListeners && wildcardListeners.size === 0) return;
29
+ queueMicrotask(() => {
30
+ const errors = [];
31
+ if (eventListeners) {
32
+ for (const cb of eventListeners) {
33
+ try {
34
+ cb(payload, clientStack);
35
+ } catch (e) {
36
+ errors.push(e);
37
+ }
38
+ }
39
+ }
40
+ if (wildcardListeners.size > 0) {
41
+ const wrapped = { event, payload };
42
+ for (const cb of wildcardListeners) {
43
+ try {
44
+ cb(wrapped, clientStack);
45
+ } catch (e) {
46
+ errors.push(e);
47
+ }
48
+ }
49
+ }
50
+ if (errors.length > 0) {
51
+ if (errors.length === 1) {
52
+ throw errors[0];
53
+ } else {
54
+ throw new AggregateError(
55
+ errors,
56
+ "Errors occurred during event emission"
57
+ );
58
+ }
59
+ }
60
+ });
61
+ },
62
+ subscribe(callback) {
63
+ subscribers.add(callback);
64
+ return () => subscribers.delete(callback);
65
+ },
66
+ notifySubscribers() {
67
+ for (const cb of subscribers) {
68
+ try {
69
+ cb();
70
+ } catch (e) {
71
+ console.error("NotificationManager: subscriber callback error", e);
72
+ }
73
+ }
74
+ }
75
+ };
76
+ }, []);
77
+ });
78
+ export {
79
+ NotificationManager
80
+ };
81
+ //# sourceMappingURL=NotificationManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/NotificationManager.ts"],"sourcesContent":["import { resource, tapMemo } from \"@assistant-ui/tap\";\nimport type { ClientStack } from \"./tap-client-stack-context\";\nimport type {\n AssistantEventName,\n AssistantEventPayload,\n} from \"../types/events\";\nimport { Unsubscribe } from \"../types/client\";\n\ntype InternalCallback = (payload: unknown, clientStack: ClientStack) => void;\n\nexport type NotificationManager = {\n on<TEvent extends AssistantEventName>(\n event: TEvent,\n callback: (\n payload: AssistantEventPayload[TEvent],\n clientStack: ClientStack,\n ) => void,\n ): Unsubscribe;\n emit<TEvent extends Exclude<AssistantEventName, \"*\">>(\n event: TEvent,\n payload: AssistantEventPayload[TEvent],\n clientStack: ClientStack,\n ): void;\n subscribe(callback: () => void): Unsubscribe;\n notifySubscribers(): void;\n};\n\nexport const NotificationManager = resource((): NotificationManager => {\n return tapMemo(() => {\n const listeners = new Map<string, Set<InternalCallback>>();\n const wildcardListeners = new Set<InternalCallback>();\n const subscribers = new Set<() => void>();\n\n return {\n on(event, callback) {\n const cb = callback as InternalCallback;\n if (event === \"*\") {\n wildcardListeners.add(cb);\n return () => wildcardListeners.delete(cb);\n }\n\n let set = listeners.get(event);\n if (!set) {\n set = new Set();\n listeners.set(event, set);\n }\n set.add(cb);\n\n return () => {\n set!.delete(cb);\n if (set!.size === 0) listeners.delete(event);\n };\n },\n\n emit(event, payload, clientStack) {\n const eventListeners = listeners.get(event);\n if (!eventListeners && wildcardListeners.size === 0) return;\n\n queueMicrotask(() => {\n const errors = [];\n if (eventListeners) {\n for (const cb of eventListeners) {\n try {\n cb(payload, clientStack);\n } catch (e) {\n errors.push(e);\n }\n }\n }\n if (wildcardListeners.size > 0) {\n const wrapped = { event, payload };\n for (const cb of wildcardListeners) {\n try {\n cb(wrapped, clientStack);\n } catch (e) {\n errors.push(e);\n }\n }\n }\n\n if (errors.length > 0) {\n if (errors.length === 1) {\n throw errors[0];\n } else {\n throw new AggregateError(\n errors,\n \"Errors occurred during event emission\",\n );\n }\n }\n });\n },\n\n subscribe(callback) {\n subscribers.add(callback);\n return () => subscribers.delete(callback);\n },\n\n notifySubscribers() {\n for (const cb of subscribers) {\n try {\n cb();\n } catch (e) {\n console.error(\"NotificationManager: subscriber callback error\", e);\n }\n }\n },\n };\n }, []);\n});\n"],"mappings":";AAAA,SAAS,UAAU,eAAe;AA2B3B,IAAM,sBAAsB,SAAS,MAA2B;AACrE,SAAO,QAAQ,MAAM;AACnB,UAAM,YAAY,oBAAI,IAAmC;AACzD,UAAM,oBAAoB,oBAAI,IAAsB;AACpD,UAAM,cAAc,oBAAI,IAAgB;AAExC,WAAO;AAAA,MACL,GAAG,OAAO,UAAU;AAClB,cAAM,KAAK;AACX,YAAI,UAAU,KAAK;AACjB,4BAAkB,IAAI,EAAE;AACxB,iBAAO,MAAM,kBAAkB,OAAO,EAAE;AAAA,QAC1C;AAEA,YAAI,MAAM,UAAU,IAAI,KAAK;AAC7B,YAAI,CAAC,KAAK;AACR,gBAAM,oBAAI,IAAI;AACd,oBAAU,IAAI,OAAO,GAAG;AAAA,QAC1B;AACA,YAAI,IAAI,EAAE;AAEV,eAAO,MAAM;AACX,cAAK,OAAO,EAAE;AACd,cAAI,IAAK,SAAS,EAAG,WAAU,OAAO,KAAK;AAAA,QAC7C;AAAA,MACF;AAAA,MAEA,KAAK,OAAO,SAAS,aAAa;AAChC,cAAM,iBAAiB,UAAU,IAAI,KAAK;AAC1C,YAAI,CAAC,kBAAkB,kBAAkB,SAAS,EAAG;AAErD,uBAAe,MAAM;AACnB,gBAAM,SAAS,CAAC;AAChB,cAAI,gBAAgB;AAClB,uBAAW,MAAM,gBAAgB;AAC/B,kBAAI;AACF,mBAAG,SAAS,WAAW;AAAA,cACzB,SAAS,GAAG;AACV,uBAAO,KAAK,CAAC;AAAA,cACf;AAAA,YACF;AAAA,UACF;AACA,cAAI,kBAAkB,OAAO,GAAG;AAC9B,kBAAM,UAAU,EAAE,OAAO,QAAQ;AACjC,uBAAW,MAAM,mBAAmB;AAClC,kBAAI;AACF,mBAAG,SAAS,WAAW;AAAA,cACzB,SAAS,GAAG;AACV,uBAAO,KAAK,CAAC;AAAA,cACf;AAAA,YACF;AAAA,UACF;AAEA,cAAI,OAAO,SAAS,GAAG;AACrB,gBAAI,OAAO,WAAW,GAAG;AACvB,oBAAM,OAAO,CAAC;AAAA,YAChB,OAAO;AACL,oBAAM,IAAI;AAAA,gBACR;AAAA,gBACA;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AAAA,MAEA,UAAU,UAAU;AAClB,oBAAY,IAAI,QAAQ;AACxB,eAAO,MAAM,YAAY,OAAO,QAAQ;AAAA,MAC1C;AAAA,MAEA,oBAAoB;AAClB,mBAAW,MAAM,aAAa;AAC5B,cAAI;AACF,eAAG;AAAA,UACL,SAAS,GAAG;AACV,oBAAQ,MAAM,kDAAkD,CAAC;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AACP,CAAC;","names":[]}
@@ -0,0 +1,14 @@
1
+ import { ResourceElement } from "@assistant-ui/tap";
2
+ import { Unsubscribe } from "../types/client";
3
+ export interface Store<TState> {
4
+ /**
5
+ * Get the current state of the store.
6
+ */
7
+ getState(): TState;
8
+ /**
9
+ * Subscribe to the store.
10
+ */
11
+ subscribe(listener: () => void): Unsubscribe;
12
+ }
13
+ export declare const StoreResource: <TState>(props: ResourceElement<TState>) => ResourceElement<Store<TState>, ResourceElement<TState>>;
14
+ //# sourceMappingURL=StoreResource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StoreResource.d.ts","sourceRoot":"","sources":["../../src/utils/StoreResource.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EAIhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,WAAW,KAAK,CAAC,MAAM;IAC3B;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;CAC9C;AAED,eAAO,MAAM,aAAa,GACvB,MAAM,4FAaR,CAAC"}
@@ -0,0 +1,23 @@
1
+ // src/utils/StoreResource.ts
2
+ import {
3
+ tapEffect,
4
+ resource,
5
+ createResource,
6
+ tapState
7
+ } from "@assistant-ui/tap";
8
+ var StoreResource = resource(
9
+ (element) => {
10
+ const [handle] = tapState(() => createResource(element, { mount: false }));
11
+ tapEffect(() => {
12
+ return handle.unmount;
13
+ }, [handle]);
14
+ tapEffect(() => {
15
+ handle.render(element);
16
+ }, [handle, element]);
17
+ return handle;
18
+ }
19
+ );
20
+ export {
21
+ StoreResource
22
+ };
23
+ //# sourceMappingURL=StoreResource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/StoreResource.ts"],"sourcesContent":["import {\n tapEffect,\n ResourceElement,\n resource,\n createResource,\n tapState,\n} from \"@assistant-ui/tap\";\nimport { Unsubscribe } from \"../types/client\";\n\nexport interface Store<TState> {\n /**\n * Get the current state of the store.\n */\n getState(): TState;\n\n /**\n * Subscribe to the store.\n */\n subscribe(listener: () => void): Unsubscribe;\n}\n\nexport const StoreResource = resource(\n <TState>(element: ResourceElement<TState>): Store<TState> => {\n const [handle] = tapState(() => createResource(element, { mount: false }));\n\n tapEffect(() => {\n return handle.unmount;\n }, [handle]);\n\n tapEffect(() => {\n handle.render(element);\n }, [handle, element]);\n\n return handle;\n },\n);\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeA,IAAM,gBAAgB;AAAA,EAC3B,CAAS,YAAoD;AAC3D,UAAM,CAAC,MAAM,IAAI,SAAS,MAAM,eAAe,SAAS,EAAE,OAAO,MAAM,CAAC,CAAC;AAEzE,cAAU,MAAM;AACd,aAAO,OAAO;AAAA,IAChB,GAAG,CAAC,MAAM,CAAC;AAEX,cAAU,MAAM;AACd,aAAO,OAAO,OAAO;AAAA,IACvB,GAAG,CAAC,QAAQ,OAAO,CAAC;AAEpB,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,8 @@
1
+ import type { AssistantClient, AssistantState } from "../types/client";
2
+ export declare const PROXIED_ASSISTANT_STATE_SYMBOL: unique symbol;
3
+ /**
4
+ * Proxied state that lazily accesses scope states
5
+ */
6
+ export declare const createProxiedAssistantState: (client: AssistantClient) => AssistantState;
7
+ export declare const getProxiedAssistantState: (client: AssistantClient) => AssistantState;
8
+ //# sourceMappingURL=proxied-assistant-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxied-assistant-state.d.ts","sourceRoot":"","sources":["../../src/utils/proxied-assistant-state.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGvE,eAAO,MAAM,8BAA8B,eAE1C,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,QAAQ,eAAe,KACtB,cA0BF,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,eAAe,KACtB,cAIF,CAAC"}
@@ -0,0 +1,41 @@
1
+ "use client";
2
+
3
+ // src/utils/proxied-assistant-state.tsx
4
+ import { getClientState } from "../tapClientResource.js";
5
+ import { BaseProxyHandler, handleIntrospectionProp } from "./BaseProxyHandler.js";
6
+ var PROXIED_ASSISTANT_STATE_SYMBOL = /* @__PURE__ */ Symbol(
7
+ "assistant-ui.store.proxiedAssistantState"
8
+ );
9
+ var isIgnoredKey = (key) => {
10
+ return key === "on" || key === "subscribe" || typeof key === "symbol";
11
+ };
12
+ var createProxiedAssistantState = (client) => {
13
+ class ProxiedAssistantStateProxyHandler extends BaseProxyHandler {
14
+ get(_, prop) {
15
+ const introspection = handleIntrospectionProp(prop, "AssistantState");
16
+ if (introspection !== false) return introspection;
17
+ const scope = prop;
18
+ if (isIgnoredKey(scope)) return void 0;
19
+ return getClientState(client[scope]());
20
+ }
21
+ ownKeys() {
22
+ return Object.keys(client).filter((key) => !isIgnoredKey(key));
23
+ }
24
+ has(_, prop) {
25
+ return !isIgnoredKey(prop) && prop in client;
26
+ }
27
+ }
28
+ return new Proxy(
29
+ {},
30
+ new ProxiedAssistantStateProxyHandler()
31
+ );
32
+ };
33
+ var getProxiedAssistantState = (client) => {
34
+ return client[PROXIED_ASSISTANT_STATE_SYMBOL];
35
+ };
36
+ export {
37
+ PROXIED_ASSISTANT_STATE_SYMBOL,
38
+ createProxiedAssistantState,
39
+ getProxiedAssistantState
40
+ };
41
+ //# sourceMappingURL=proxied-assistant-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/proxied-assistant-state.tsx"],"sourcesContent":["\"use client\";\nimport { getClientState } from \"../tapClientResource\";\nimport type { AssistantClient, AssistantState } from \"../types/client\";\nimport { BaseProxyHandler, handleIntrospectionProp } from \"./BaseProxyHandler\";\n\nexport const PROXIED_ASSISTANT_STATE_SYMBOL = Symbol(\n \"assistant-ui.store.proxiedAssistantState\",\n);\n\nconst isIgnoredKey = (key: string | symbol): key is \"on\" | \"subscribe\" => {\n return key === \"on\" || key === \"subscribe\" || typeof key === \"symbol\";\n};\n\n/**\n * Proxied state that lazily accesses scope states\n */\nexport const createProxiedAssistantState = (\n client: AssistantClient,\n): AssistantState => {\n class ProxiedAssistantStateProxyHandler\n extends BaseProxyHandler\n implements ProxyHandler<AssistantState>\n {\n get(_: unknown, prop: string | symbol) {\n const introspection = handleIntrospectionProp(prop, \"AssistantState\");\n if (introspection !== false) return introspection;\n const scope = prop as keyof AssistantClient;\n if (isIgnoredKey(scope)) return undefined;\n return getClientState(client[scope]());\n }\n\n ownKeys(): ArrayLike<string | symbol> {\n return Object.keys(client).filter((key) => !isIgnoredKey(key));\n }\n\n has(_: unknown, prop: string | symbol): boolean {\n return !isIgnoredKey(prop) && prop in client;\n }\n }\n\n return new Proxy<AssistantState>(\n {} as AssistantState,\n new ProxiedAssistantStateProxyHandler(),\n );\n};\n\nexport const getProxiedAssistantState = (\n client: AssistantClient,\n): AssistantState => {\n return (\n client as unknown as { [PROXIED_ASSISTANT_STATE_SYMBOL]: AssistantState }\n )[PROXIED_ASSISTANT_STATE_SYMBOL];\n};\n"],"mappings":";;;AACA,SAAS,sBAAsB;AAE/B,SAAS,kBAAkB,+BAA+B;AAEnD,IAAM,iCAAiC;AAAA,EAC5C;AACF;AAEA,IAAM,eAAe,CAAC,QAAoD;AACxE,SAAO,QAAQ,QAAQ,QAAQ,eAAe,OAAO,QAAQ;AAC/D;AAKO,IAAM,8BAA8B,CACzC,WACmB;AAAA,EACnB,MAAM,0CACI,iBAEV;AAAA,IACE,IAAI,GAAY,MAAuB;AACrC,YAAM,gBAAgB,wBAAwB,MAAM,gBAAgB;AACpE,UAAI,kBAAkB,MAAO,QAAO;AACpC,YAAM,QAAQ;AACd,UAAI,aAAa,KAAK,EAAG,QAAO;AAChC,aAAO,eAAe,OAAO,KAAK,EAAE,CAAC;AAAA,IACvC;AAAA,IAEA,UAAsC;AACpC,aAAO,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,aAAa,GAAG,CAAC;AAAA,IAC/D;AAAA,IAEA,IAAI,GAAY,MAAgC;AAC9C,aAAO,CAAC,aAAa,IAAI,KAAK,QAAQ;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,IAAI;AAAA,IACT,CAAC;AAAA,IACD,IAAI,kCAAkC;AAAA,EACxC;AACF;AAEO,IAAM,2BAA2B,CACtC,WACmB;AACnB,SACE,OACA,8BAA8B;AAClC;","names":[]}
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import type { AssistantClient } from "./types";
3
- /**
4
- * React Context for the AssistantClient
5
- */
6
- export declare const AssistantContext: React.Context<AssistantClient>;
2
+ import type { AssistantClient } from "../types/client";
3
+ /** Default context value - throws "wrap in AssistantProvider" error */
4
+ export declare const DefaultAssistantClient: AssistantClient;
5
+ /** Root prototype for created clients - throws "scope not defined" error */
6
+ export declare const createRootAssistantClient: () => AssistantClient;
7
7
  export declare const useAssistantContextValue: () => AssistantClient;
8
8
  /**
9
9
  * Provider component for AssistantClient
@@ -19,4 +19,4 @@ export declare const AssistantProvider: ({ client, children, }: {
19
19
  client: AssistantClient;
20
20
  children: React.ReactNode;
21
21
  }) => React.ReactElement;
22
- //# sourceMappingURL=AssistantContext.d.ts.map
22
+ //# sourceMappingURL=react-assistant-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-assistant-context.d.ts","sourceRoot":"","sources":["../../src/utils/react-assistant-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAA2B,MAAM,iBAAiB,CAAC;AAmDhF,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,EAAE,eAIlC,CAAC;AAMJ,4EAA4E;AAC5E,eAAO,MAAM,yBAAyB,QAAO,eASzC,CAAC;AAOL,eAAO,MAAM,wBAAwB,QAAO,eAE3C,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,uBAG/B;IACD,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,KAAG,KAAK,CAAC,YAMT,CAAC"}
@@ -0,0 +1,73 @@
1
+ // src/utils/react-assistant-context.tsx
2
+ import { createContext, useContext } from "react";
3
+ import {
4
+ createProxiedAssistantState,
5
+ PROXIED_ASSISTANT_STATE_SYMBOL
6
+ } from "./proxied-assistant-state.js";
7
+ import { BaseProxyHandler, handleIntrospectionProp } from "./BaseProxyHandler.js";
8
+ import { jsx } from "react/jsx-runtime";
9
+ var NO_OP_SUBSCRIBE = () => () => {
10
+ };
11
+ var createErrorClientField = (message) => {
12
+ const fn = (() => {
13
+ throw new Error(message);
14
+ });
15
+ fn.source = null;
16
+ fn.query = null;
17
+ return fn;
18
+ };
19
+ var DefaultAssistantClientProxyHandler = class extends BaseProxyHandler {
20
+ get(_, prop) {
21
+ if (prop === "subscribe") return NO_OP_SUBSCRIBE;
22
+ if (prop === "on") return NO_OP_SUBSCRIBE;
23
+ if (prop === PROXIED_ASSISTANT_STATE_SYMBOL)
24
+ return DefaultAssistantClientProxiedAssistantState;
25
+ const introspection = handleIntrospectionProp(
26
+ prop,
27
+ "DefaultAssistantClient"
28
+ );
29
+ if (introspection !== false) return introspection;
30
+ return createErrorClientField(
31
+ `The current scope does not have a "${String(prop)}" property.`
32
+ );
33
+ }
34
+ ownKeys() {
35
+ return ["subscribe", "on", PROXIED_ASSISTANT_STATE_SYMBOL];
36
+ }
37
+ has(_, prop) {
38
+ return prop === "subscribe" || prop === "on" || prop === PROXIED_ASSISTANT_STATE_SYMBOL;
39
+ }
40
+ };
41
+ var DefaultAssistantClient = new Proxy(
42
+ {},
43
+ new DefaultAssistantClientProxyHandler()
44
+ );
45
+ var DefaultAssistantClientProxiedAssistantState = createProxiedAssistantState(
46
+ DefaultAssistantClient
47
+ );
48
+ var createRootAssistantClient = () => new Proxy({}, {
49
+ get(_, prop) {
50
+ const introspection = handleIntrospectionProp(prop, "AssistantClient");
51
+ if (introspection !== false) return introspection;
52
+ return createErrorClientField(
53
+ `The current scope does not have a "${String(prop)}" property.`
54
+ );
55
+ }
56
+ });
57
+ var AssistantContext = createContext(DefaultAssistantClient);
58
+ var useAssistantContextValue = () => {
59
+ return useContext(AssistantContext);
60
+ };
61
+ var AssistantProvider = ({
62
+ client,
63
+ children
64
+ }) => {
65
+ return /* @__PURE__ */ jsx(AssistantContext.Provider, { value: client, children });
66
+ };
67
+ export {
68
+ AssistantProvider,
69
+ DefaultAssistantClient,
70
+ createRootAssistantClient,
71
+ useAssistantContextValue
72
+ };
73
+ //# sourceMappingURL=react-assistant-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/react-assistant-context.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport type { AssistantClient, AssistantClientAccessor } from \"../types/client\";\nimport {\n createProxiedAssistantState,\n PROXIED_ASSISTANT_STATE_SYMBOL,\n} from \"./proxied-assistant-state\";\nimport { BaseProxyHandler, handleIntrospectionProp } from \"./BaseProxyHandler\";\n\nconst NO_OP_SUBSCRIBE = () => () => {};\n\nconst createErrorClientField = (\n message: string,\n): AssistantClientAccessor<never> => {\n const fn = (() => {\n throw new Error(message);\n }) as AssistantClientAccessor<never>;\n fn.source = null;\n fn.query = null;\n return fn;\n};\n\nclass DefaultAssistantClientProxyHandler\n extends BaseProxyHandler\n implements ProxyHandler<AssistantClient>\n{\n get(_: unknown, prop: string | symbol) {\n if (prop === \"subscribe\") return NO_OP_SUBSCRIBE;\n if (prop === \"on\") return NO_OP_SUBSCRIBE;\n if (prop === PROXIED_ASSISTANT_STATE_SYMBOL)\n return DefaultAssistantClientProxiedAssistantState;\n const introspection = handleIntrospectionProp(\n prop,\n \"DefaultAssistantClient\",\n );\n if (introspection !== false) return introspection;\n return createErrorClientField(\n `The current scope does not have a \"${String(prop)}\" property.`,\n );\n }\n\n ownKeys(): ArrayLike<string | symbol> {\n return [\"subscribe\", \"on\", PROXIED_ASSISTANT_STATE_SYMBOL];\n }\n\n has(_: unknown, prop: string | symbol): boolean {\n return (\n prop === \"subscribe\" ||\n prop === \"on\" ||\n prop === PROXIED_ASSISTANT_STATE_SYMBOL\n );\n }\n}\n/** Default context value - throws \"wrap in AssistantProvider\" error */\nexport const DefaultAssistantClient: AssistantClient =\n new Proxy<AssistantClient>(\n {} as AssistantClient,\n new DefaultAssistantClientProxyHandler(),\n );\n\nconst DefaultAssistantClientProxiedAssistantState = createProxiedAssistantState(\n DefaultAssistantClient,\n);\n\n/** Root prototype for created clients - throws \"scope not defined\" error */\nexport const createRootAssistantClient = (): AssistantClient =>\n new Proxy<AssistantClient>({} as AssistantClient, {\n get(_: AssistantClient, prop: string | symbol) {\n const introspection = handleIntrospectionProp(prop, \"AssistantClient\");\n if (introspection !== false) return introspection;\n return createErrorClientField(\n `The current scope does not have a \"${String(prop)}\" property.`,\n );\n },\n });\n\n/**\n * React Context for the AssistantClient\n */\nconst AssistantContext = createContext<AssistantClient>(DefaultAssistantClient);\n\nexport const useAssistantContextValue = (): AssistantClient => {\n return useContext(AssistantContext);\n};\n\n/**\n * Provider component for AssistantClient\n *\n * @example\n * ```typescript\n * <AssistantProvider client={client}>\n * <YourApp />\n * </AssistantProvider>\n * ```\n */\nexport const AssistantProvider = ({\n client,\n children,\n}: {\n client: AssistantClient;\n children: React.ReactNode;\n}): React.ReactElement => {\n return (\n <AssistantContext.Provider value={client}>\n {children}\n </AssistantContext.Provider>\n );\n};\n"],"mappings":";AAAA,SAAgB,eAAe,kBAAkB;AAEjD;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB,+BAA+B;AAgGtD;AA9FJ,IAAM,kBAAkB,MAAM,MAAM;AAAC;AAErC,IAAM,yBAAyB,CAC7B,YACmC;AACnC,QAAM,MAAM,MAAM;AAChB,UAAM,IAAI,MAAM,OAAO;AAAA,EACzB;AACA,KAAG,SAAS;AACZ,KAAG,QAAQ;AACX,SAAO;AACT;AAEA,IAAM,qCAAN,cACU,iBAEV;AAAA,EACE,IAAI,GAAY,MAAuB;AACrC,QAAI,SAAS,YAAa,QAAO;AACjC,QAAI,SAAS,KAAM,QAAO;AAC1B,QAAI,SAAS;AACX,aAAO;AACT,UAAM,gBAAgB;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AACA,QAAI,kBAAkB,MAAO,QAAO;AACpC,WAAO;AAAA,MACL,sCAAsC,OAAO,IAAI,CAAC;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,UAAsC;AACpC,WAAO,CAAC,aAAa,MAAM,8BAA8B;AAAA,EAC3D;AAAA,EAEA,IAAI,GAAY,MAAgC;AAC9C,WACE,SAAS,eACT,SAAS,QACT,SAAS;AAAA,EAEb;AACF;AAEO,IAAM,yBACX,IAAI;AAAA,EACF,CAAC;AAAA,EACD,IAAI,mCAAmC;AACzC;AAEF,IAAM,8CAA8C;AAAA,EAClD;AACF;AAGO,IAAM,4BAA4B,MACvC,IAAI,MAAuB,CAAC,GAAsB;AAAA,EAChD,IAAI,GAAoB,MAAuB;AAC7C,UAAM,gBAAgB,wBAAwB,MAAM,iBAAiB;AACrE,QAAI,kBAAkB,MAAO,QAAO;AACpC,WAAO;AAAA,MACL,sCAAsC,OAAO,IAAI,CAAC;AAAA,IACpD;AAAA,EACF;AACF,CAAC;AAKH,IAAM,mBAAmB,cAA+B,sBAAsB;AAEvE,IAAM,2BAA2B,MAAuB;AAC7D,SAAO,WAAW,gBAAgB;AACpC;AAYO,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA;AACF,MAG0B;AACxB,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,QAC/B,UACH;AAEJ;","names":[]}
@@ -0,0 +1,28 @@
1
+ import { DerivedElement } from "../Derived";
2
+ import type { AssistantClient, ClientElement, ClientNames } from "../types/client";
3
+ import type { useAssistantClient } from "../useAssistantClient";
4
+ export type RootClients = Partial<Record<ClientNames, ClientElement<ClientNames>>>;
5
+ export type DerivedClients = Partial<Record<ClientNames, DerivedElement<ClientNames>>>;
6
+ /**
7
+ * Splits a clients object into root clients and derived clients.
8
+ *
9
+ * @param clients - The clients input object to split
10
+ * @returns An object with { rootClients, derivedClients }
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const clients = {
15
+ * foo: RootClient({ ... }),
16
+ * bar: Derived({ ... }),
17
+ * };
18
+ *
19
+ * const { rootClients, derivedClients } = splitClients(clients);
20
+ * // rootClients = { foo: ... }
21
+ * // derivedClients = { bar: ... }
22
+ * ```
23
+ */
24
+ export declare function splitClients(clients: useAssistantClient.Props, baseClient: AssistantClient): {
25
+ rootClients: Partial<Record<"ERROR: No clients were defined", ClientElement<"ERROR: No clients were defined">>>;
26
+ derivedClients: Partial<Record<"ERROR: No clients were defined", DerivedElement<"ERROR: No clients were defined">>>;
27
+ };
28
+ //# sourceMappingURL=splitClients.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splitClients.d.ts","sourceRoot":"","sources":["../../src/utils/splitClients.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,cAAc,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG,OAAO,CAC/B,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,CAChD,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,OAAO,CAClC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC,CACjD,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,kBAAkB,CAAC,KAAK,EACjC,UAAU,EAAE,eAAe;;;EAgD5B"}
@@ -0,0 +1,37 @@
1
+ // src/utils/splitClients.ts
2
+ import { Derived } from "../Derived.js";
3
+ import { getDefaultPeers } from "../attachDefaultPeers.js";
4
+ function splitClients(clients, baseClient) {
5
+ const rootClients = {};
6
+ const derivedClients = {};
7
+ for (const [key, clientElement] of Object.entries(clients)) {
8
+ if (clientElement.type === Derived) {
9
+ derivedClients[key] = clientElement;
10
+ } else {
11
+ rootClients[key] = clientElement;
12
+ }
13
+ }
14
+ for (const [clientKey, clientElement] of Object.entries(rootClients)) {
15
+ const defaultPeers = getDefaultPeers(clientElement.type);
16
+ if (!defaultPeers) continue;
17
+ for (const [key, peerElement] of Object.entries(defaultPeers)) {
18
+ if (key in rootClients || key in derivedClients || baseClient[key].source !== null)
19
+ continue;
20
+ if (peerElement.type === Derived) {
21
+ derivedClients[key] = peerElement;
22
+ } else {
23
+ rootClients[key] = peerElement;
24
+ const subDefaultPeers = getDefaultPeers(peerElement.type);
25
+ if (subDefaultPeers)
26
+ throw new Error(
27
+ `Nested default peers are not supported. Client "${clientKey}" has default peers, but its peer "${key}" also has default peers.`
28
+ );
29
+ }
30
+ }
31
+ }
32
+ return { rootClients, derivedClients };
33
+ }
34
+ export {
35
+ splitClients
36
+ };
37
+ //# sourceMappingURL=splitClients.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/splitClients.ts"],"sourcesContent":["import { Derived, DerivedElement } from \"../Derived\";\nimport type {\n AssistantClient,\n ClientElement,\n ClientNames,\n} from \"../types/client\";\nimport { getDefaultPeers } from \"../attachDefaultPeers\";\nimport type { useAssistantClient } from \"../useAssistantClient\";\n\nexport type RootClients = Partial<\n Record<ClientNames, ClientElement<ClientNames>>\n>;\nexport type DerivedClients = Partial<\n Record<ClientNames, DerivedElement<ClientNames>>\n>;\n\n/**\n * Splits a clients object into root clients and derived clients.\n *\n * @param clients - The clients input object to split\n * @returns An object with { rootClients, derivedClients }\n *\n * @example\n * ```typescript\n * const clients = {\n * foo: RootClient({ ... }),\n * bar: Derived({ ... }),\n * };\n *\n * const { rootClients, derivedClients } = splitClients(clients);\n * // rootClients = { foo: ... }\n * // derivedClients = { bar: ... }\n * ```\n */\nexport function splitClients(\n clients: useAssistantClient.Props,\n baseClient: AssistantClient,\n) {\n const rootClients: RootClients = {};\n const derivedClients: DerivedClients = {};\n\n for (const [key, clientElement] of Object.entries(clients) as [\n keyof useAssistantClient.Props,\n NonNullable<useAssistantClient.Props[keyof useAssistantClient.Props]>,\n ][]) {\n if (clientElement.type === Derived) {\n derivedClients[key] = clientElement as DerivedElement<ClientNames>;\n } else {\n rootClients[key] = clientElement as ClientElement<ClientNames>;\n }\n }\n\n for (const [clientKey, clientElement] of Object.entries(rootClients) as [\n ClientNames,\n ClientElement<ClientNames>,\n ][]) {\n const defaultPeers = getDefaultPeers(clientElement.type);\n if (!defaultPeers) continue;\n\n for (const [key, peerElement] of Object.entries(defaultPeers) as [\n ClientNames,\n ClientElement<ClientNames> | DerivedElement<ClientNames>,\n ][]) {\n if (\n key in rootClients ||\n key in derivedClients ||\n baseClient[key].source !== null\n )\n continue;\n\n if (peerElement.type === Derived<ClientNames>) {\n derivedClients[key] = peerElement as DerivedElement<ClientNames>;\n } else {\n rootClients[key] = peerElement as ClientElement<ClientNames>;\n const subDefaultPeers = getDefaultPeers(peerElement.type);\n if (subDefaultPeers)\n throw new Error(\n `Nested default peers are not supported. Client \"${clientKey}\" has default peers, but its peer \"${key}\" also has default peers.`,\n );\n }\n }\n }\n\n return { rootClients, derivedClients };\n}\n"],"mappings":";AAAA,SAAS,eAA+B;AAMxC,SAAS,uBAAuB;AA4BzB,SAAS,aACd,SACA,YACA;AACA,QAAM,cAA2B,CAAC;AAClC,QAAM,iBAAiC,CAAC;AAExC,aAAW,CAAC,KAAK,aAAa,KAAK,OAAO,QAAQ,OAAO,GAGpD;AACH,QAAI,cAAc,SAAS,SAAS;AAClC,qBAAe,GAAG,IAAI;AAAA,IACxB,OAAO;AACL,kBAAY,GAAG,IAAI;AAAA,IACrB;AAAA,EACF;AAEA,aAAW,CAAC,WAAW,aAAa,KAAK,OAAO,QAAQ,WAAW,GAG9D;AACH,UAAM,eAAe,gBAAgB,cAAc,IAAI;AACvD,QAAI,CAAC,aAAc;AAEnB,eAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,YAAY,GAGvD;AACH,UACE,OAAO,eACP,OAAO,kBACP,WAAW,GAAG,EAAE,WAAW;AAE3B;AAEF,UAAI,YAAY,SAAS,SAAsB;AAC7C,uBAAe,GAAG,IAAI;AAAA,MACxB,OAAO;AACL,oBAAY,GAAG,IAAI;AACnB,cAAM,kBAAkB,gBAAgB,YAAY,IAAI;AACxD,YAAI;AACF,gBAAM,IAAI;AAAA,YACR,mDAAmD,SAAS,sCAAsC,GAAG;AAAA,UACvG;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,eAAe;AACvC;","names":[]}
@@ -0,0 +1,19 @@
1
+ import type { AssistantEventName, AssistantEventPayload } from "../types/events";
2
+ import type { AssistantClient } from "../types/client";
3
+ import { type ClientStack } from "./tap-client-stack-context";
4
+ type EmitFn = <TEvent extends Exclude<AssistantEventName, "*">>(event: TEvent, payload: AssistantEventPayload[TEvent], clientStack: ClientStack) => void;
5
+ export type AssistantTapContextValue = {
6
+ clientRef: {
7
+ parent: AssistantClient;
8
+ current: AssistantClient | null;
9
+ };
10
+ emit: EmitFn;
11
+ };
12
+ export declare const withAssistantTapContextProvider: <TResult>(value: AssistantTapContextValue, fn: () => TResult) => TResult;
13
+ export declare const tapAssistantClientRef: () => {
14
+ parent: AssistantClient;
15
+ current: AssistantClient | null;
16
+ };
17
+ export declare const tapAssistantEmit: () => <TEvent extends Exclude<AssistantEventName, "*">>(event: TEvent, payload: AssistantEventPayload[TEvent]) => void;
18
+ export {};
19
+ //# sourceMappingURL=tap-assistant-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-assistant-context.d.ts","sourceRoot":"","sources":["../../src/utils/tap-assistant-context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9E,KAAK,MAAM,GAAG,CAAC,MAAM,SAAS,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,EAC5D,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,qBAAqB,CAAC,MAAM,CAAC,EACtC,WAAW,EAAE,WAAW,KACrB,IAAI,CAAC;AAEV,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE;QAAE,MAAM,EAAE,eAAe,CAAC;QAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAAA;KAAE,CAAC;IACxE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAMF,eAAO,MAAM,+BAA+B,GAAI,OAAO,EACrD,OAAO,wBAAwB,EAC/B,IAAI,MAAM,OAAO,YAGlB,CAAC;AASF,eAAO,MAAM,qBAAqB;YAtBX,eAAe;aAAW,eAAe,GAAG,IAAI;CAwBtE,CAAC;AAEF,eAAO,MAAM,gBAAgB,SAKxB,MAAM,SAAS,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,SACvC,MAAM,WACJ,qBAAqB,CAAC,MAAM,CAAC,SAK3C,CAAC"}
@@ -0,0 +1,37 @@
1
+ // src/utils/tap-assistant-context.ts
2
+ import {
3
+ createContext,
4
+ tapContext,
5
+ withContextProvider,
6
+ tapEffectEvent
7
+ } from "@assistant-ui/tap";
8
+ import { tapClientStack } from "./tap-client-stack-context.js";
9
+ var AssistantTapContext = createContext(
10
+ null
11
+ );
12
+ var withAssistantTapContextProvider = (value, fn) => {
13
+ return withContextProvider(AssistantTapContext, value, fn);
14
+ };
15
+ var tapAssistantTapContext = () => {
16
+ const ctx = tapContext(AssistantTapContext);
17
+ if (!ctx) throw new Error("AssistantTapContext is not available");
18
+ return ctx;
19
+ };
20
+ var tapAssistantClientRef = () => {
21
+ return tapAssistantTapContext().clientRef;
22
+ };
23
+ var tapAssistantEmit = () => {
24
+ const { emit } = tapAssistantTapContext();
25
+ const clientStack = tapClientStack();
26
+ return tapEffectEvent(
27
+ (event, payload) => {
28
+ emit(event, payload, clientStack);
29
+ }
30
+ );
31
+ };
32
+ export {
33
+ tapAssistantClientRef,
34
+ tapAssistantEmit,
35
+ withAssistantTapContextProvider
36
+ };
37
+ //# sourceMappingURL=tap-assistant-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/tap-assistant-context.ts"],"sourcesContent":["import {\n createContext,\n tapContext,\n withContextProvider,\n tapEffectEvent,\n} from \"@assistant-ui/tap\";\nimport type {\n AssistantEventName,\n AssistantEventPayload,\n} from \"../types/events\";\nimport type { AssistantClient } from \"../types/client\";\nimport { tapClientStack, type ClientStack } from \"./tap-client-stack-context\";\n\ntype EmitFn = <TEvent extends Exclude<AssistantEventName, \"*\">>(\n event: TEvent,\n payload: AssistantEventPayload[TEvent],\n clientStack: ClientStack,\n) => void;\n\nexport type AssistantTapContextValue = {\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n emit: EmitFn;\n};\n\nconst AssistantTapContext = createContext<AssistantTapContextValue | null>(\n null,\n);\n\nexport const withAssistantTapContextProvider = <TResult>(\n value: AssistantTapContextValue,\n fn: () => TResult,\n) => {\n return withContextProvider(AssistantTapContext, value, fn);\n};\n\nconst tapAssistantTapContext = () => {\n const ctx = tapContext(AssistantTapContext);\n if (!ctx) throw new Error(\"AssistantTapContext is not available\");\n\n return ctx;\n};\n\nexport const tapAssistantClientRef = () => {\n return tapAssistantTapContext().clientRef;\n};\n\nexport const tapAssistantEmit = () => {\n const { emit } = tapAssistantTapContext();\n const clientStack = tapClientStack();\n\n return tapEffectEvent(\n <TEvent extends Exclude<AssistantEventName, \"*\">>(\n event: TEvent,\n payload: AssistantEventPayload[TEvent],\n ) => {\n emit(event, payload, clientStack);\n },\n );\n};\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP,SAAS,sBAAwC;AAajD,IAAM,sBAAsB;AAAA,EAC1B;AACF;AAEO,IAAM,kCAAkC,CAC7C,OACA,OACG;AACH,SAAO,oBAAoB,qBAAqB,OAAO,EAAE;AAC3D;AAEA,IAAM,yBAAyB,MAAM;AACnC,QAAM,MAAM,WAAW,mBAAmB;AAC1C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sCAAsC;AAEhE,SAAO;AACT;AAEO,IAAM,wBAAwB,MAAM;AACzC,SAAO,uBAAuB,EAAE;AAClC;AAEO,IAAM,mBAAmB,MAAM;AACpC,QAAM,EAAE,KAAK,IAAI,uBAAuB;AACxC,QAAM,cAAc,eAAe;AAEnC,SAAO;AAAA,IACL,CACE,OACA,YACG;AACH,WAAK,OAAO,SAAS,WAAW;AAAA,IAClC;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,23 @@
1
+ import type { ClientMethods } from "../types/client";
2
+ /**
3
+ * Symbol used to get the client index from a ClientProxy.
4
+ */
5
+ export declare const SYMBOL_CLIENT_INDEX: unique symbol;
6
+ /**
7
+ * Get the index of a client (its position in the client stack when created).
8
+ */
9
+ export declare const getClientIndex: (client: ClientMethods) => number;
10
+ /**
11
+ * The client stack - an array of clients representing the current hierarchy.
12
+ */
13
+ export type ClientStack = readonly ClientMethods[];
14
+ /**
15
+ * Get the current client stack inside a tap resource.
16
+ */
17
+ export declare const tapClientStack: () => ClientStack;
18
+ /**
19
+ * Execute a callback with a client pushed onto the stack.
20
+ * The stack is duplicated, not mutated.
21
+ */
22
+ export declare const tapWithClientStack: <T>(client: ClientMethods, callback: () => T) => T;
23
+ //# sourceMappingURL=tap-client-stack-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-client-stack-context.d.ts","sourceRoot":"","sources":["../../src/utils/tap-client-stack-context.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAA2C,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,aAAa,KAAG,MAItD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,aAAa,EAAE,CAAC;AAInD;;GAEG;AACH,eAAO,MAAM,cAAc,QAAO,WAEjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAClC,QAAQ,aAAa,EACrB,UAAU,MAAM,CAAC,KAChB,CAOF,CAAC"}
@@ -0,0 +1,30 @@
1
+ // src/utils/tap-client-stack-context.ts
2
+ import {
3
+ createContext,
4
+ tapContext,
5
+ withContextProvider,
6
+ tapMemo
7
+ } from "@assistant-ui/tap";
8
+ var SYMBOL_CLIENT_INDEX = /* @__PURE__ */ Symbol("assistant-ui.store.clientIndex");
9
+ var getClientIndex = (client) => {
10
+ return client[SYMBOL_CLIENT_INDEX];
11
+ };
12
+ var ClientStackContext = createContext([]);
13
+ var tapClientStack = () => {
14
+ return tapContext(ClientStackContext);
15
+ };
16
+ var tapWithClientStack = (client, callback) => {
17
+ const currentStack = tapClientStack();
18
+ const newStack = tapMemo(
19
+ () => [...currentStack, client],
20
+ [currentStack, client]
21
+ );
22
+ return withContextProvider(ClientStackContext, newStack, callback);
23
+ };
24
+ export {
25
+ SYMBOL_CLIENT_INDEX,
26
+ getClientIndex,
27
+ tapClientStack,
28
+ tapWithClientStack
29
+ };
30
+ //# sourceMappingURL=tap-client-stack-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/tap-client-stack-context.ts"],"sourcesContent":["import {\n createContext,\n tapContext,\n withContextProvider,\n tapMemo,\n} from \"@assistant-ui/tap\";\nimport type { ClientMethods } from \"../types/client\";\n\n/**\n * Symbol used to get the client index from a ClientProxy.\n */\nexport const SYMBOL_CLIENT_INDEX = Symbol(\"assistant-ui.store.clientIndex\");\n\n/**\n * Get the index of a client (its position in the client stack when created).\n */\nexport const getClientIndex = (client: ClientMethods): number => {\n return (client as unknown as { [SYMBOL_CLIENT_INDEX]: number })[\n SYMBOL_CLIENT_INDEX\n ];\n};\n\n/**\n * The client stack - an array of clients representing the current hierarchy.\n */\nexport type ClientStack = readonly ClientMethods[];\n\nconst ClientStackContext = createContext<ClientStack>([]);\n\n/**\n * Get the current client stack inside a tap resource.\n */\nexport const tapClientStack = (): ClientStack => {\n return tapContext(ClientStackContext);\n};\n\n/**\n * Execute a callback with a client pushed onto the stack.\n * The stack is duplicated, not mutated.\n */\nexport const tapWithClientStack = <T>(\n client: ClientMethods,\n callback: () => T,\n): T => {\n const currentStack = tapClientStack();\n const newStack = tapMemo(\n () => [...currentStack, client],\n [currentStack, client],\n );\n return withContextProvider(ClientStackContext, newStack, callback);\n};\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMA,IAAM,sBAAsB,uBAAO,gCAAgC;AAKnE,IAAM,iBAAiB,CAAC,WAAkC;AAC/D,SAAQ,OACN,mBACF;AACF;AAOA,IAAM,qBAAqB,cAA2B,CAAC,CAAC;AAKjD,IAAM,iBAAiB,MAAmB;AAC/C,SAAO,WAAW,kBAAkB;AACtC;AAMO,IAAM,qBAAqB,CAChC,QACA,aACM;AACN,QAAM,eAAe,eAAe;AACpC,QAAM,WAAW;AAAA,IACf,MAAM,CAAC,GAAG,cAAc,MAAM;AAAA,IAC9B,CAAC,cAAc,MAAM;AAAA,EACvB;AACA,SAAO,oBAAoB,oBAAoB,UAAU,QAAQ;AACnE;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@assistant-ui/store",
3
3
  "description": "Tap-based state management for @assistant-ui",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "exports": {
@@ -20,15 +20,15 @@
20
20
  ],
21
21
  "sideEffects": false,
22
22
  "dependencies": {
23
- "@assistant-ui/tap": "0.3.1"
23
+ "@assistant-ui/tap": "0.3.3"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "react": "^18.0.0 || ^19.0.0"
27
27
  },
28
28
  "devDependencies": {
29
- "@types/node": "^24.10.1",
29
+ "@types/node": "^25.0.0",
30
30
  "@types/react": "19.2.7",
31
- "tsx": "^4.20.6",
31
+ "tsx": "^4.21.0",
32
32
  "@assistant-ui/x-buildutils": "0.0.1"
33
33
  },
34
34
  "publishConfig": {
@@ -44,7 +44,6 @@
44
44
  "url": "https://github.com/assistant-ui/assistant-ui/issues"
45
45
  },
46
46
  "scripts": {
47
- "build": "tsx scripts/build.mts",
48
- "lint": "eslint ."
47
+ "build": "tsx scripts/build.mts"
49
48
  }
50
49
  }
@@ -0,0 +1,17 @@
1
+ "use client";
2
+
3
+ import type { FC, PropsWithChildren } from "react";
4
+ import { useAssistantState } from "./useAssistantState";
5
+ import type { AssistantState } from "./types/client";
6
+
7
+ export namespace AssistantIf {
8
+ export type Props = PropsWithChildren<{ condition: AssistantIf.Condition }>;
9
+ export type Condition = (state: AssistantState) => boolean;
10
+ }
11
+
12
+ export const AssistantIf: FC<AssistantIf.Props> = ({ children, condition }) => {
13
+ const result = useAssistantState(condition);
14
+ return result ? children : null;
15
+ };
16
+
17
+ AssistantIf.displayName = "AssistantIf";
package/src/Derived.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { resource, ResourceElement } from "@assistant-ui/tap";
2
+ import type {
3
+ AssistantClient,
4
+ ClientNames,
5
+ AssistantClientAccessor,
6
+ ClientMeta,
7
+ } from "./types/client";
8
+
9
+ /**
10
+ * Creates a derived client field that references a client from a parent scope.
11
+ * The get callback always calls the most recent version (useEffectEvent pattern).
12
+ *
13
+ * IMPORTANT: The `get` callback must return a client that was created via
14
+ * `tapClientResource` (or `tapClientLookup`/`tapClientList` which use it internally).
15
+ * This is required for event scoping to work correctly.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const aui = useAssistantClient({
20
+ * message: Derived({
21
+ * source: "thread",
22
+ * query: { index: 0 },
23
+ * get: (aui) => aui.thread().message({ index: 0 }),
24
+ * }),
25
+ * });
26
+ * ```
27
+ */
28
+ export const Derived = resource(
29
+ <K extends ClientNames>(_config: Derived.Props<K>): null => {
30
+ return null;
31
+ },
32
+ );
33
+
34
+ export type DerivedElement<K extends ClientNames> = ResourceElement<
35
+ null,
36
+ Derived.Props<K>
37
+ >;
38
+
39
+ export namespace Derived {
40
+ /**
41
+ * Props passed to a derived client resource element.
42
+ */
43
+ export type Props<K extends ClientNames> = {
44
+ get: (client: AssistantClient) => ReturnType<AssistantClientAccessor<K>>;
45
+ } & (ClientMeta<K> | { getMeta: (client: AssistantClient) => ClientMeta<K> });
46
+ }