@assistant-ui/store 0.0.2 → 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 +4 -6
  3. package/dist/AssistantIf.d.ts.map +1 -1
  4. package/dist/AssistantIf.js +1 -4
  5. package/dist/AssistantIf.js.map +1 -1
  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 +10 -9
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +17 -13
  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 -46
  38. package/dist/useAssistantClient.d.ts.map +1 -1
  39. package/dist/useAssistantClient.js +177 -137
  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 +3 -3
  82. package/src/AssistantIf.tsx +3 -11
  83. package/src/Derived.ts +46 -0
  84. package/src/attachDefaultPeers.ts +78 -0
  85. package/src/index.ts +19 -22
  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 +252 -234
  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 -20
  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 -61
  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 -84
  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 -23
  146. package/src/EventContext.ts +0 -187
  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 -119
  154. package/src/utils/splitScopes.ts +0 -38
  155. /package/dist/{types.js.map → types/client.js.map} +0 -0
@@ -1,46 +0,0 @@
1
- // src/tapStoreList.ts
2
- import { tapState } from "@assistant-ui/tap";
3
- import { tapLookupResources } from "./tapLookupResources.js";
4
- var tapStoreList = (config) => {
5
- const { initialValues, resource: Resource, idGenerator } = config;
6
- const [items, setItems] = tapState(initialValues);
7
- const lookup = tapLookupResources(
8
- items.map(
9
- (item) => Resource(
10
- {
11
- initialValue: item,
12
- remove: () => {
13
- setItems(items.filter((i) => i !== item));
14
- }
15
- },
16
- {
17
- key: item.id
18
- }
19
- )
20
- )
21
- );
22
- const add = (id) => {
23
- const newId = id ?? idGenerator?.();
24
- if (!newId) {
25
- throw new Error(
26
- "tapStoreList: Either provide an id to add() or configure an idGenerator"
27
- );
28
- }
29
- const newItem = { id: newId };
30
- setItems([...items, newItem]);
31
- };
32
- return {
33
- state: lookup.state,
34
- api: (query) => {
35
- if ("index" in query) {
36
- return lookup.api({ index: query.index });
37
- }
38
- return lookup.api({ key: query.id });
39
- },
40
- add
41
- };
42
- };
43
- export {
44
- tapStoreList
45
- };
46
- //# sourceMappingURL=tapStoreList.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tapStoreList.ts"],"sourcesContent":["import { tapState } from \"@assistant-ui/tap\";\nimport type { ContravariantResource } from \"@assistant-ui/tap\";\nimport { tapLookupResources } from \"./tapLookupResources\";\nimport { ApiObject } from \"./tapApi\";\n\n/**\n * Resource props that will be passed to each item resource\n */\nexport type TapStoreListResourceProps<TProps> = {\n initialValue: TProps;\n remove: () => void;\n};\n\n/**\n * Configuration for tapStoreList hook\n */\nexport type TapStoreListConfig<TProps, TState, TApi extends ApiObject> = {\n /**\n * Initial values for the list items\n */\n initialValues: TProps[];\n\n // TODO we can't use Resource type here because of contravariance\n // I think we need a special type in tap that correctly handles the contravariance\n // or change the behavior of the Resource type\n\n /**\n * Resource function that creates an element for each item\n * Should return a ResourceElement with { key, state, api }\n *\n * The resource will receive { initialValue, remove } as props.\n */\n resource: ContravariantResource<\n {\n key: string | undefined;\n state: TState;\n api: TApi;\n },\n TapStoreListResourceProps<TProps>\n >;\n /**\n * Optional ID generator function for new items\n * If not provided, items must include an ID when added\n */\n idGenerator?: () => string;\n};\n\n/**\n * Creates a stateful list with add functionality, rendering each item via the provided resource.\n * Returns state array, api lookup function, and add method.\n *\n * @param config - Configuration object with initialValues, resource, and optional idGenerator\n * @returns Object with { state: TState[], api: (lookup) => TApi, add: (id?) => void }\n *\n * @example\n * ```typescript\n * const todoList = tapStoreList({\n * initialValues: [\n * { id: \"1\", text: \"First todo\" },\n * { id: \"2\", text: \"Second todo\" }\n * ],\n * resource: (props) => TodoItemResource(props, { key: props.id }),\n * idGenerator: () => `todo-${Date.now()}`\n * });\n *\n * // Access state array\n * const allTodos = todoList.state;\n *\n * // Lookup specific item\n * const firstTodo = todoList.api({ index: 0 });\n * const specificTodo = todoList.api({ key: \"1\" });\n *\n * // Add new item\n * todoList.add(); // Uses idGenerator\n * todoList.add(\"custom-id\"); // Uses provided id\n * ```\n */\nexport const tapStoreList = <\n TProps extends { id: string },\n TState,\n TApi extends ApiObject,\n>(\n config: TapStoreListConfig<TProps, TState, TApi>,\n): {\n state: TState[];\n api: (lookup: { index: number } | { id: string }) => TApi;\n add: (id?: string) => void;\n} => {\n const { initialValues, resource: Resource, idGenerator } = config;\n\n const [items, setItems] = tapState<TProps[]>(initialValues);\n\n const lookup = tapLookupResources(\n items.map((item) =>\n Resource(\n {\n initialValue: item,\n remove: () => {\n setItems(items.filter((i) => i !== item));\n },\n },\n {\n key: item.id,\n },\n ),\n ),\n );\n\n const add = (id?: string) => {\n const newId = id ?? idGenerator?.();\n if (!newId) {\n throw new Error(\n \"tapStoreList: Either provide an id to add() or configure an idGenerator\",\n );\n }\n\n // Create a new item with the generated/provided id\n // This assumes TProps has an 'id' field - users will need to ensure their props type supports this\n const newItem = { id: newId } as TProps;\n setItems([...items, newItem]);\n };\n\n return {\n state: lookup.state,\n api: (query: { index: number } | { id: string }) => {\n if (\"index\" in query) {\n return lookup.api({ index: query.index });\n }\n return lookup.api({ key: query.id });\n },\n add,\n };\n};\n"],"mappings":";AAAA,SAAS,gBAAgB;AAEzB,SAAS,0BAA0B;AA2E5B,IAAM,eAAe,CAK1B,WAKG;AACH,QAAM,EAAE,eAAe,UAAU,UAAU,YAAY,IAAI;AAE3D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmB,aAAa;AAE1D,QAAM,SAAS;AAAA,IACb,MAAM;AAAA,MAAI,CAAC,SACT;AAAA,QACE;AAAA,UACE,cAAc;AAAA,UACd,QAAQ,MAAM;AACZ,qBAAS,MAAM,OAAO,CAAC,MAAM,MAAM,IAAI,CAAC;AAAA,UAC1C;AAAA,QACF;AAAA,QACA;AAAA,UACE,KAAK,KAAK;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,CAAC,OAAgB;AAC3B,UAAM,QAAQ,MAAM,cAAc;AAClC,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAIA,UAAM,UAAU,EAAE,IAAI,MAAM;AAC5B,aAAS,CAAC,GAAG,OAAO,OAAO,CAAC;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,KAAK,CAAC,UAA8C;AAClD,UAAI,WAAW,OAAO;AACpB,eAAO,OAAO,IAAI,EAAE,OAAO,MAAM,MAAM,CAAC;AAAA,MAC1C;AACA,aAAO,OAAO,IAAI,EAAE,KAAK,MAAM,GAAG,CAAC;AAAA,IACrC;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
package/dist/types.d.ts DELETED
@@ -1,84 +0,0 @@
1
- import type { ResourceElement } from "@assistant-ui/tap";
2
- import type { AssistantEvent, AssistantEventCallback, AssistantEventSelector } from "./EventContext";
3
- /**
4
- * Module augmentation interface for assistant-ui store type extensions.
5
- *
6
- * @example
7
- * ```typescript
8
- * declare module "@assistant-ui/store" {
9
- * interface AssistantScopeRegistry {
10
- * foo: {
11
- * value: { getState: () => { bar: string }; updateBar: (bar: string) => void };
12
- * meta: { source: "root"; query: Record<string, never> };
13
- * events: {
14
- * "foo.updated": { id: string; newValue: string };
15
- * "foo.deleted": { id: string };
16
- * };
17
- * };
18
- * // Example with multiple sources (discriminated union):
19
- * bar: {
20
- * value: { getState: () => { id: string } };
21
- * meta:
22
- * | { source: "fooList"; query: { index: number } }
23
- * | { source: "barList"; query: { id: string } };
24
- * events: Record<string, never>;
25
- * };
26
- * }
27
- * }
28
- * ```
29
- */
30
- export interface AssistantScopeRegistry {
31
- }
32
- export type AssistantScopes = keyof AssistantScopeRegistry extends never ? Record<"ERROR: No scopes were defined", ScopeDefinition> : {
33
- [K in keyof AssistantScopeRegistry]: AssistantScopeRegistry[K];
34
- };
35
- /**
36
- * Type for a scope field - a function that returns the current API value,
37
- * with source/query metadata attached (derived from meta)
38
- */
39
- export type ScopeField<T extends ScopeDefinition> = (() => T["value"]) & (T["meta"] | {
40
- source: null;
41
- query: null;
42
- });
43
- /**
44
- * Props passed to a derived scope resource element
45
- */
46
- export type DerivedScopeProps<T extends ScopeDefinition> = {
47
- get: (parent: AssistantClient) => T["value"];
48
- source: T["meta"]["source"];
49
- query: T["meta"]["query"];
50
- };
51
- /**
52
- * Input type for scope definitions - ResourceElement that returns the API value
53
- * Can optionally include source/query metadata via DerivedScope
54
- */
55
- export type ScopeInput<T extends ScopeDefinition> = ResourceElement<{
56
- api: T["value"];
57
- }>;
58
- /**
59
- * Map of scope names to their input definitions
60
- */
61
- export type ScopesInput = {
62
- [K in keyof AssistantScopes]?: ScopeInput<AssistantScopes[K]>;
63
- };
64
- /**
65
- * Unsubscribe function type
66
- */
67
- export type Unsubscribe = () => void;
68
- /**
69
- * State type extracted from all scopes
70
- */
71
- export type AssistantState = {
72
- [K in keyof AssistantScopes]: ReturnType<AssistantScopes[K]["value"]["getState"]>;
73
- };
74
- /**
75
- * The assistant client type with all registered scopes
76
- */
77
- export type AssistantClient = {
78
- [K in keyof AssistantScopes]: ScopeField<AssistantScopes[K]>;
79
- } & {
80
- subscribe(listener: () => void): Unsubscribe;
81
- flushSync(): void;
82
- on<TEvent extends AssistantEvent>(selector: AssistantEventSelector<TEvent>, callback: AssistantEventCallback<TEvent>): Unsubscribe;
83
- };
84
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAwBxB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,sBAAsB;CAAG;AAE1C,MAAM,MAAM,eAAe,GAAG,MAAM,sBAAsB,SAAS,KAAK,GACpE,MAAM,CAAC,+BAA+B,EAAE,eAAe,CAAC,GACxD;KAAG,CAAC,IAAI,MAAM,sBAAsB,GAAG,sBAAsB,CAAC,CAAC,CAAC;CAAE,CAAC;AACvE;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,eAAe,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GACpE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AAE9C;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,eAAe,IAAI;IACzD,GAAG,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC;CAC3B,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,eAAe,IAAI,eAAe,CAAC;IAClE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;CACjB,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;KACvB,CAAC,IAAI,MAAM,eAAe,CAAC,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;KAC1B,CAAC,IAAI,MAAM,eAAe,GAAG,UAAU,CACtC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CACxC;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;KAC3B,CAAC,IAAI,MAAM,eAAe,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;CAC7D,GAAG;IACF,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;IAC7C,SAAS,IAAI,IAAI,CAAC;IAClB,EAAE,CAAC,MAAM,SAAS,cAAc,EAC9B,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC,EACxC,QAAQ,EAAE,sBAAsB,CAAC,MAAM,CAAC,GACvC,WAAW,CAAC;CAChB,CAAC"}
package/dist/types.js DELETED
@@ -1 +0,0 @@
1
- //# sourceMappingURL=types.js.map
@@ -1,24 +0,0 @@
1
- import type { ScopesInput } from "../types";
2
- /**
3
- * Splits a scopes object into root scopes and derived scopes.
4
- *
5
- * @param scopes - The scopes input object to split
6
- * @returns An object with { rootScopes, derivedScopes }
7
- *
8
- * @example
9
- * ```typescript
10
- * const scopes = {
11
- * foo: RootScope({ ... }),
12
- * bar: DerivedScope({ ... }),
13
- * };
14
- *
15
- * const { rootScopes, derivedScopes } = splitScopes(scopes);
16
- * // rootScopes = { foo: ... }
17
- * // derivedScopes = { bar: ... }
18
- * ```
19
- */
20
- export declare function splitScopes(scopes: ScopesInput): {
21
- rootScopes: ScopesInput;
22
- derivedScopes: ScopesInput;
23
- };
24
- //# sourceMappingURL=splitScopes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"splitScopes.d.ts","sourceRoot":"","sources":["../../src/utils/splitScopes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW;;;EAgB9C"}
@@ -1,18 +0,0 @@
1
- // src/utils/splitScopes.ts
2
- import { DerivedScope } from "../DerivedScope.js";
3
- function splitScopes(scopes) {
4
- const rootScopes = {};
5
- const derivedScopes = {};
6
- for (const [key, scopeElement] of Object.entries(scopes)) {
7
- if (scopeElement.type === DerivedScope) {
8
- derivedScopes[key] = scopeElement;
9
- } else {
10
- rootScopes[key] = scopeElement;
11
- }
12
- }
13
- return { rootScopes, derivedScopes };
14
- }
15
- export {
16
- splitScopes
17
- };
18
- //# sourceMappingURL=splitScopes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utils/splitScopes.ts"],"sourcesContent":["import { DerivedScope } from \"../DerivedScope\";\nimport type { AssistantScopes, ScopeInput, ScopesInput } from \"../types\";\n\n/**\n * Splits a scopes object into root scopes and derived scopes.\n *\n * @param scopes - The scopes input object to split\n * @returns An object with { rootScopes, derivedScopes }\n *\n * @example\n * ```typescript\n * const scopes = {\n * foo: RootScope({ ... }),\n * bar: DerivedScope({ ... }),\n * };\n *\n * const { rootScopes, derivedScopes } = splitScopes(scopes);\n * // rootScopes = { foo: ... }\n * // derivedScopes = { bar: ... }\n * ```\n */\nexport function splitScopes(scopes: ScopesInput) {\n const rootScopes: ScopesInput = {};\n const derivedScopes: ScopesInput = {};\n\n for (const [key, scopeElement] of Object.entries(scopes) as [\n keyof ScopesInput,\n ScopeInput<AssistantScopes[keyof ScopesInput]>,\n ][]) {\n if (scopeElement.type === DerivedScope) {\n derivedScopes[key] = scopeElement;\n } else {\n rootScopes[key] = scopeElement;\n }\n }\n\n return { rootScopes, derivedScopes };\n}\n"],"mappings":";AAAA,SAAS,oBAAoB;AAqBtB,SAAS,YAAY,QAAqB;AAC/C,QAAM,aAA0B,CAAC;AACjC,QAAM,gBAA6B,CAAC;AAEpC,aAAW,CAAC,KAAK,YAAY,KAAK,OAAO,QAAQ,MAAM,GAGlD;AACH,QAAI,aAAa,SAAS,cAAc;AACtC,oBAAc,GAAG,IAAI;AAAA,IACvB,OAAO;AACL,iBAAW,GAAG,IAAI;AAAA,IACpB;AAAA,EACF;AAEA,SAAO,EAAE,YAAY,cAAc;AACrC;","names":[]}
@@ -1,64 +0,0 @@
1
- import React, { createContext, useContext } from "react";
2
- import type { AssistantClient, AssistantScopes, ScopeField } from "./types";
3
- import { hasRegisteredScope } from "./ScopeRegistry";
4
-
5
- const NO_OP_SUBSCRIBE = () => () => {};
6
- const NO_OP_FLUSH_SYNC = () => {};
7
- const NO_OP_SCOPE_FIELD = (() => {
8
- const fn = (() => {
9
- throw new Error(
10
- "You need to wrap this component/hook in <AssistantProvider>",
11
- );
12
- }) as ScopeField<never>;
13
- fn.source = null;
14
- fn.query = null;
15
- return fn;
16
- })();
17
-
18
- /**
19
- * React Context for the AssistantClient
20
- */
21
- export const AssistantContext = createContext<AssistantClient>(
22
- new Proxy({} as AssistantClient, {
23
- get(_, prop: string) {
24
- // Allow access to subscribe and flushSync without error
25
- if (prop === "subscribe") return NO_OP_SUBSCRIBE;
26
- if (prop === "on") return NO_OP_SUBSCRIBE;
27
- if (prop === "flushSync") return NO_OP_FLUSH_SYNC;
28
-
29
- // If this is a registered scope, return a function that errors when called or accessed
30
- if (hasRegisteredScope(prop as keyof AssistantScopes))
31
- return NO_OP_SCOPE_FIELD;
32
-
33
- return null;
34
- },
35
- }),
36
- );
37
-
38
- export const useAssistantContextValue = (): AssistantClient => {
39
- return useContext(AssistantContext);
40
- };
41
-
42
- /**
43
- * Provider component for AssistantClient
44
- *
45
- * @example
46
- * ```typescript
47
- * <AssistantProvider client={client}>
48
- * <YourApp />
49
- * </AssistantProvider>
50
- * ```
51
- */
52
- export const AssistantProvider = ({
53
- client,
54
- children,
55
- }: {
56
- client: AssistantClient;
57
- children: React.ReactNode;
58
- }): React.ReactElement => {
59
- return (
60
- <AssistantContext.Provider value={client}>
61
- {children}
62
- </AssistantContext.Provider>
63
- );
64
- };
@@ -1,23 +0,0 @@
1
- import { resource } from "@assistant-ui/tap";
2
- import type { ScopeDefinition, DerivedScopeProps } from "./types";
3
-
4
- /**
5
- * Creates a derived scope field that memoizes based on source and query.
6
- * The get callback always calls the most recent version (useEffectEvent pattern).
7
- *
8
- * @example
9
- * ```typescript
10
- * const client = useAssistantClient({
11
- * message: DerivedScope({
12
- * source: "thread",
13
- * query: { index: 0 },
14
- * get: (client) => client.thread().message({ index: 0 }),
15
- * }),
16
- * });
17
- * ```
18
- */
19
- export const DerivedScope = resource(
20
- <T extends ScopeDefinition>(_config: DerivedScopeProps<T>): null => {
21
- return null;
22
- },
23
- );
@@ -1,187 +0,0 @@
1
- import { resource, tapMemo } from "@assistant-ui/tap";
2
- import type { AssistantScopes, Unsubscribe } from "./types";
3
-
4
- /**
5
- * Module augmentation interface for event scope configuration.
6
- * Maps event sources to their parent scopes.
7
- *
8
- * @example
9
- * ```typescript
10
- * declare module "@assistant-ui/store" {
11
- * interface AssistantEventScopeConfig {
12
- * composer: "thread" | "message";
13
- * thread: never;
14
- * }
15
- * }
16
- * ```
17
- */
18
- export interface AssistantEventScopeConfig {}
19
-
20
- type UnionToIntersection<U> = (
21
- U extends unknown
22
- ? (x: U) => void
23
- : never
24
- ) extends (x: infer I) => void
25
- ? I
26
- : never;
27
-
28
- /**
29
- * Event map derived from scope event definitions
30
- */
31
- export type ScopeEventMap = UnionToIntersection<
32
- {
33
- [K in keyof AssistantScopes]: AssistantScopes[K] extends {
34
- events: infer E;
35
- }
36
- ? E extends Record<string, unknown>
37
- ? E
38
- : never
39
- : never;
40
- }[keyof AssistantScopes]
41
- >;
42
-
43
- type WildcardPayload = {
44
- [K in keyof ScopeEventMap]: {
45
- event: K;
46
- payload: ScopeEventMap[K];
47
- };
48
- }[keyof ScopeEventMap];
49
-
50
- export type AssistantEventMap = ScopeEventMap & {
51
- // Catch-all
52
- "*": WildcardPayload;
53
- };
54
-
55
- export type AssistantEvent = keyof AssistantEventMap;
56
-
57
- export type EventSource<T extends AssistantEvent = AssistantEvent> =
58
- T extends `${infer Source}.${string}` ? Source : never;
59
-
60
- export type SourceByScope<TScope extends AssistantEventScope<AssistantEvent>> =
61
- | (TScope extends "*" ? EventSource : never)
62
- | (TScope extends keyof AssistantEventScopeConfig ? TScope : never)
63
- | {
64
- [K in keyof AssistantEventScopeConfig]: TScope extends AssistantEventScopeConfig[K]
65
- ? K
66
- : never;
67
- }[keyof AssistantEventScopeConfig];
68
-
69
- export type AssistantEventScope<TEvent extends AssistantEvent> =
70
- | "*"
71
- | EventSource<TEvent>
72
- | (EventSource<TEvent> extends keyof AssistantEventScopeConfig
73
- ? AssistantEventScopeConfig[EventSource<TEvent>]
74
- : never);
75
-
76
- export type AssistantEventSelector<TEvent extends AssistantEvent> =
77
- | TEvent
78
- | {
79
- scope: AssistantEventScope<TEvent>;
80
- event: TEvent;
81
- };
82
-
83
- export const normalizeEventSelector = <TEvent extends AssistantEvent>(
84
- selector: AssistantEventSelector<TEvent>,
85
- ) => {
86
- if (typeof selector === "string") {
87
- const source = selector.split(".")[0] as AssistantEventScope<TEvent>;
88
- return {
89
- scope: source,
90
- event: selector,
91
- };
92
- }
93
-
94
- return {
95
- scope: selector.scope,
96
- event: selector.event,
97
- };
98
- };
99
-
100
- export const checkEventScope = <
101
- TEvent extends AssistantEvent,
102
- TExpectedScope extends AssistantEventScope<AssistantEvent>,
103
- >(
104
- expectedScope: TExpectedScope,
105
- scope: AssistantEventScope<TEvent>,
106
- _event: TEvent,
107
- ): _event is Extract<TEvent, `${SourceByScope<TExpectedScope>}.${string}`> => {
108
- return scope === expectedScope;
109
- };
110
-
111
- export type AssistantEventCallback<TEvent extends AssistantEvent> = (
112
- payload: AssistantEventMap[TEvent],
113
- ) => void;
114
-
115
- export type EventManager = {
116
- on<TEvent extends AssistantEvent>(
117
- event: TEvent,
118
- callback: AssistantEventCallback<TEvent>,
119
- ): Unsubscribe;
120
- emit<TEvent extends Exclude<AssistantEvent, "*">>(
121
- event: TEvent,
122
- payload: AssistantEventMap[TEvent],
123
- ): void;
124
- };
125
-
126
- type ListenerMap = Omit<
127
- Map<AssistantEvent, Set<AssistantEventCallback<AssistantEvent>>>,
128
- "get" | "set"
129
- > & {
130
- get<TEvent extends AssistantEvent>(
131
- event: TEvent,
132
- ): Set<AssistantEventCallback<TEvent>> | undefined;
133
- set<TEvent extends AssistantEvent>(
134
- event: TEvent,
135
- value: Set<AssistantEventCallback<TEvent>>,
136
- ): void;
137
- };
138
-
139
- export const EventManager = resource(() => {
140
- const events = tapMemo(() => {
141
- const listeners: ListenerMap = new Map();
142
-
143
- return {
144
- on: (event, callback) => {
145
- if (!listeners.has(event)) {
146
- listeners.set(event, new Set());
147
- }
148
-
149
- const eventListeners = listeners.get(event)!;
150
- eventListeners.add(callback);
151
-
152
- return () => {
153
- eventListeners.delete(callback);
154
- if (eventListeners.size === 0) {
155
- listeners.delete(event);
156
- }
157
- };
158
- },
159
-
160
- emit: (event, payload) => {
161
- const eventListeners = listeners.get(event);
162
- const wildcardListeners = listeners.get("*");
163
-
164
- if (!eventListeners && !wildcardListeners) return;
165
-
166
- // make sure state updates flush
167
- queueMicrotask(() => {
168
- // Emit to specific event listeners
169
- if (eventListeners) {
170
- for (const callback of eventListeners) {
171
- callback(payload);
172
- }
173
- }
174
-
175
- // Emit to wildcard listeners
176
- if (wildcardListeners) {
177
- for (const callback of wildcardListeners) {
178
- callback({ event, payload } as any);
179
- }
180
- }
181
- });
182
- },
183
- } satisfies EventManager;
184
- }, []);
185
-
186
- return events;
187
- });
@@ -1,58 +0,0 @@
1
- import type { AssistantScopes } from "./types";
2
- import type { ResourceElement } from "@assistant-ui/tap";
3
-
4
- type ScopeRegistryEntry<K extends keyof AssistantScopes> = {
5
- name: K;
6
- defaultInitialize:
7
- | ResourceElement<AssistantScopes[K]["value"]>
8
- | { error: string };
9
- };
10
-
11
- const scopeRegistry = new Map<
12
- keyof AssistantScopes,
13
- ResourceElement<any> | { error: string }
14
- >();
15
-
16
- /**
17
- * Register a default scope implementation.
18
- * This allows scopes to have default values when not explicitly provided.
19
- *
20
- * @example With a resource:
21
- * ```typescript
22
- * registerAssistantScope({
23
- * name: "myScope",
24
- * defaultInitialize: MyResource(),
25
- * });
26
- * ```
27
- *
28
- * @example With an error:
29
- * ```typescript
30
- * registerAssistantScope({
31
- * name: "myScope",
32
- * defaultInitialize: { error: "MyScope is not configured" },
33
- * });
34
- * ```
35
- */
36
- export function registerAssistantScope<K extends keyof AssistantScopes>(
37
- config: ScopeRegistryEntry<K>,
38
- ): void {
39
- scopeRegistry.set(config.name, config.defaultInitialize);
40
- }
41
-
42
- /**
43
- * Get the default initializer for a scope, if registered.
44
- */
45
- export function getDefaultScopeInitializer<K extends keyof AssistantScopes>(
46
- name: K,
47
- ):
48
- | (ResourceElement<AssistantScopes[K]["value"]> | { error: string })
49
- | undefined {
50
- return scopeRegistry.get(name);
51
- }
52
-
53
- /**
54
- * Get all registered scope names.
55
- */
56
- export function hasRegisteredScope(name: keyof AssistantScopes): boolean {
57
- return scopeRegistry.has(name);
58
- }
@@ -1,28 +0,0 @@
1
- import {
2
- createContext,
3
- tapContext,
4
- withContextProvider,
5
- } from "@assistant-ui/tap";
6
- import type { EventManager } from "./EventContext";
7
- import type { AssistantClient } from "./types";
8
-
9
- export type StoreContextValue = {
10
- events: EventManager;
11
- parent: AssistantClient;
12
- };
13
-
14
- const StoreContext = createContext<StoreContextValue | null>(null);
15
-
16
- export const withStoreContextProvider = <TResult>(
17
- value: StoreContextValue,
18
- fn: () => TResult,
19
- ) => {
20
- return withContextProvider(StoreContext, value, fn);
21
- };
22
-
23
- export const tapStoreContext = () => {
24
- const ctx = tapContext(StoreContext);
25
- if (!ctx) throw new Error("Store context is not available");
26
-
27
- return ctx;
28
- };
package/src/asStore.ts DELETED
@@ -1,40 +0,0 @@
1
- import {
2
- tapMemo,
3
- tapEffect,
4
- ResourceElement,
5
- resource,
6
- createResource,
7
- } from "@assistant-ui/tap";
8
- import { Unsubscribe } from "./types";
9
-
10
- export interface Store<TState> {
11
- /**
12
- * Get the current state of the store.
13
- */
14
- getState(): TState;
15
-
16
- /**
17
- * Subscribe to the store.
18
- */
19
- subscribe(listener: () => void): Unsubscribe;
20
-
21
- /**
22
- * Synchronously flush all the updates to the store.
23
- */
24
- flushSync(): void;
25
- }
26
-
27
- export const asStore = resource(
28
- <TState, TProps>(element: ResourceElement<TState, TProps>): Store<TState> => {
29
- const resource = tapMemo(
30
- () => createResource(element, true),
31
- [element.type],
32
- );
33
-
34
- tapEffect(() => {
35
- resource.updateInput(element.props);
36
- });
37
-
38
- return resource;
39
- },
40
- );