@assistant-ui/react 0.11.35 → 0.11.36

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 (199) hide show
  1. package/dist/client/AssistantClient.d.ts +13 -57
  2. package/dist/client/AssistantClient.d.ts.map +1 -1
  3. package/dist/client/AssistantClient.js +49 -26
  4. package/dist/client/AssistantClient.js.map +1 -1
  5. package/dist/client/ModelContext.d.ts +8 -0
  6. package/dist/client/ModelContext.d.ts.map +1 -0
  7. package/dist/client/ModelContext.js +21 -0
  8. package/dist/client/ModelContext.js.map +1 -0
  9. package/dist/client/ModelContextClient.d.ts +7 -0
  10. package/dist/client/ModelContextClient.d.ts.map +1 -0
  11. package/dist/client/ModelContextClient.js +18 -0
  12. package/dist/client/ModelContextClient.js.map +1 -0
  13. package/dist/client/ToolUIClient.d.ts.map +1 -1
  14. package/dist/client/ToolUIClient.js +45 -3
  15. package/dist/client/ToolUIClient.js.map +1 -1
  16. package/dist/client/ToolUIContext.d.ts +4 -0
  17. package/dist/client/ToolUIContext.d.ts.map +1 -0
  18. package/dist/client/ToolUIContext.js +20 -0
  19. package/dist/client/ToolUIContext.js.map +1 -0
  20. package/dist/client/Tools.d.ts +10 -0
  21. package/dist/client/Tools.d.ts.map +1 -0
  22. package/dist/client/Tools.js +55 -0
  23. package/dist/client/Tools.js.map +1 -0
  24. package/dist/client/types/ModelContext.d.ts +12 -0
  25. package/dist/client/types/ModelContext.d.ts.map +1 -0
  26. package/dist/client/types/ModelContext.js +1 -0
  27. package/dist/client/types/ModelContext.js.map +1 -0
  28. package/dist/client/types/ThreadList.d.ts.map +1 -1
  29. package/dist/client/types/ToolUI.d.ts +12 -1
  30. package/dist/client/types/ToolUI.d.ts.map +1 -1
  31. package/dist/client/types/Tools.d.ts +9 -0
  32. package/dist/client/types/Tools.d.ts.map +1 -0
  33. package/dist/client/types/Tools.js +1 -0
  34. package/dist/client/types/Tools.js.map +1 -0
  35. package/dist/context/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  36. package/dist/context/providers/AttachmentByIndexProvider.js +20 -24
  37. package/dist/context/providers/AttachmentByIndexProvider.js.map +1 -1
  38. package/dist/context/providers/MessageByIndexProvider.d.ts.map +1 -1
  39. package/dist/context/providers/MessageByIndexProvider.js +27 -29
  40. package/dist/context/providers/MessageByIndexProvider.js.map +1 -1
  41. package/dist/context/providers/MessageProvider.d.ts.map +1 -1
  42. package/dist/context/providers/MessageProvider.js +11 -13
  43. package/dist/context/providers/MessageProvider.js.map +1 -1
  44. package/dist/context/providers/PartByIndexProvider.d.ts.map +1 -1
  45. package/dist/context/providers/PartByIndexProvider.js +11 -13
  46. package/dist/context/providers/PartByIndexProvider.js.map +1 -1
  47. package/dist/context/providers/TextMessagePartProvider.d.ts.map +1 -1
  48. package/dist/context/providers/TextMessagePartProvider.js +11 -13
  49. package/dist/context/providers/TextMessagePartProvider.js.map +1 -1
  50. package/dist/context/providers/ThreadListItemProvider.d.ts.map +1 -1
  51. package/dist/context/providers/ThreadListItemProvider.js +41 -45
  52. package/dist/context/providers/ThreadListItemProvider.js.map +1 -1
  53. package/dist/context/react/AssistantApiContext.d.ts +33 -4
  54. package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
  55. package/dist/context/react/AssistantApiContext.js +35 -17
  56. package/dist/context/react/AssistantApiContext.js.map +1 -1
  57. package/dist/context/react/index.d.ts +1 -1
  58. package/dist/context/react/index.d.ts.map +1 -1
  59. package/dist/context/react/index.js +5 -1
  60. package/dist/context/react/index.js.map +1 -1
  61. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
  62. package/dist/legacy-runtime/AssistantRuntimeProvider.js +7 -9
  63. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  64. package/dist/legacy-runtime/RuntimeAdapter.d.ts +7 -0
  65. package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +1 -0
  66. package/dist/legacy-runtime/RuntimeAdapter.js +20 -0
  67. package/dist/legacy-runtime/RuntimeAdapter.js.map +1 -0
  68. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts +2 -0
  69. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts.map +1 -1
  70. package/dist/legacy-runtime/client/ThreadListRuntimeClient.js +6 -2
  71. package/dist/legacy-runtime/client/ThreadListRuntimeClient.js.map +1 -1
  72. package/dist/legacy-runtime/hooks/AssistantContext.d.ts +14 -1
  73. package/dist/legacy-runtime/hooks/AssistantContext.d.ts.map +1 -1
  74. package/dist/legacy-runtime/hooks/AssistantContext.js +1 -1
  75. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  76. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +6 -0
  77. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts.map +1 -1
  78. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  79. package/dist/legacy-runtime/hooks/ComposerContext.d.ts +41 -2
  80. package/dist/legacy-runtime/hooks/ComposerContext.d.ts.map +1 -1
  81. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  82. package/dist/legacy-runtime/hooks/MessageContext.d.ts +36 -2
  83. package/dist/legacy-runtime/hooks/MessageContext.d.ts.map +1 -1
  84. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  85. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +6 -0
  86. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts.map +1 -1
  87. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  88. package/dist/legacy-runtime/hooks/ThreadContext.d.ts +26 -1
  89. package/dist/legacy-runtime/hooks/ThreadContext.d.ts.map +1 -1
  90. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  91. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +6 -0
  92. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts.map +1 -1
  93. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  94. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +1 -0
  95. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +1 -1
  96. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +1 -0
  97. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +1 -1
  98. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +3 -0
  99. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js.map +1 -1
  100. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +4 -1
  101. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +1 -1
  102. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +2 -2
  103. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js.map +1 -1
  104. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
  105. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +7 -1
  106. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
  107. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +2 -12
  108. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +1 -1
  109. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +45 -15
  110. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
  111. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +2 -0
  112. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
  113. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +4 -2
  114. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
  115. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +4 -1
  116. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +1 -1
  117. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +2 -2
  118. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js.map +1 -1
  119. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +1 -1
  120. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
  121. package/dist/model-context/index.d.ts +2 -0
  122. package/dist/model-context/index.d.ts.map +1 -1
  123. package/dist/model-context/index.js +6 -0
  124. package/dist/model-context/index.js.map +1 -1
  125. package/dist/model-context/makeAssistantVisible.js +1 -1
  126. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  127. package/dist/model-context/toolbox.d.ts +28 -0
  128. package/dist/model-context/toolbox.d.ts.map +1 -0
  129. package/dist/model-context/toolbox.js +15 -0
  130. package/dist/model-context/toolbox.js.map +1 -0
  131. package/dist/model-context/useAssistantInstructions.js +1 -1
  132. package/dist/model-context/useAssistantInstructions.js.map +1 -1
  133. package/dist/model-context/useAssistantTool.js +1 -1
  134. package/dist/model-context/useAssistantTool.js.map +1 -1
  135. package/dist/primitives/message/MessageParts.d.ts.map +1 -1
  136. package/dist/primitives/message/MessageParts.js +2 -2
  137. package/dist/primitives/message/MessageParts.js.map +1 -1
  138. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  139. package/dist/primitives/message/MessagePartsGrouped.js +2 -2
  140. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  141. package/dist/tests/setup.js +7 -7
  142. package/dist/tests/setup.js.map +1 -1
  143. package/dist/utils/tap-store/derived-scopes.d.ts +81 -0
  144. package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -0
  145. package/dist/utils/tap-store/derived-scopes.js +67 -0
  146. package/dist/utils/tap-store/derived-scopes.js.map +1 -0
  147. package/dist/utils/tap-store/index.d.ts +1 -0
  148. package/dist/utils/tap-store/index.d.ts.map +1 -1
  149. package/dist/utils/tap-store/index.js +4 -0
  150. package/dist/utils/tap-store/index.js.map +1 -1
  151. package/dist/utils/tap-store/tap-api.js +1 -1
  152. package/dist/utils/tap-store/tap-api.js.map +1 -1
  153. package/package.json +9 -9
  154. package/src/client/AssistantClient.ts +64 -38
  155. package/src/client/ModelContext.ts +28 -0
  156. package/src/client/ModelContextClient.ts +16 -0
  157. package/src/client/ToolUIClient.ts +50 -3
  158. package/src/client/ToolUIContext.ts +22 -0
  159. package/src/client/Tools.ts +68 -0
  160. package/src/client/types/ModelContext.ts +15 -0
  161. package/src/client/types/ThreadList.ts +4 -0
  162. package/src/client/types/ToolUI.ts +10 -1
  163. package/src/client/types/Tools.ts +11 -0
  164. package/src/context/providers/AttachmentByIndexProvider.tsx +21 -25
  165. package/src/context/providers/MessageByIndexProvider.tsx +31 -33
  166. package/src/context/providers/MessageProvider.tsx +12 -14
  167. package/src/context/providers/PartByIndexProvider.tsx +12 -14
  168. package/src/context/providers/TextMessagePartProvider.tsx +12 -14
  169. package/src/context/providers/ThreadListItemProvider.tsx +42 -46
  170. package/src/context/react/AssistantApiContext.tsx +69 -29
  171. package/src/context/react/index.ts +5 -1
  172. package/src/legacy-runtime/AssistantRuntimeProvider.tsx +7 -9
  173. package/src/legacy-runtime/RuntimeAdapter.ts +19 -0
  174. package/src/legacy-runtime/client/ThreadListRuntimeClient.ts +10 -1
  175. package/src/legacy-runtime/hooks/AssistantContext.ts +16 -2
  176. package/src/legacy-runtime/hooks/AttachmentContext.ts +6 -0
  177. package/src/legacy-runtime/hooks/ComposerContext.ts +41 -2
  178. package/src/legacy-runtime/hooks/MessageContext.ts +37 -2
  179. package/src/legacy-runtime/hooks/MessagePartContext.ts +6 -0
  180. package/src/legacy-runtime/hooks/ThreadContext.ts +27 -1
  181. package/src/legacy-runtime/hooks/ThreadListItemContext.ts +6 -0
  182. package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.tsx +1 -0
  183. package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.tsx +4 -0
  184. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.tsx +4 -2
  185. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.tsx +7 -1
  186. package/src/legacy-runtime/runtime-cores/external-store/auto-status.tsx +49 -16
  187. package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.tsx +4 -0
  188. package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.tsx +4 -2
  189. package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +1 -1
  190. package/src/model-context/index.ts +9 -0
  191. package/src/model-context/makeAssistantVisible.tsx +1 -1
  192. package/src/model-context/toolbox.tsx +37 -0
  193. package/src/model-context/useAssistantInstructions.tsx +1 -1
  194. package/src/model-context/useAssistantTool.tsx +1 -1
  195. package/src/primitives/message/MessageParts.tsx +3 -2
  196. package/src/primitives/message/MessagePartsGrouped.tsx +3 -2
  197. package/src/utils/tap-store/derived-scopes.ts +185 -0
  198. package/src/utils/tap-store/index.ts +9 -0
  199. package/src/utils/tap-store/tap-api.ts +1 -1
@@ -0,0 +1,37 @@
1
+ "use client";
2
+
3
+ import type { ComponentType, ReactNode } from "react";
4
+ import type { Tool } from "assistant-stream";
5
+ import type { ToolCallMessagePartComponent } from "../types/MessagePartComponentTypes";
6
+
7
+ export type ToolDefinition<
8
+ TArgs extends Record<string, unknown>,
9
+ TResult,
10
+ > = Tool<TArgs, TResult> & {
11
+ render?: ToolCallMessagePartComponent<TArgs, TResult> | undefined;
12
+ };
13
+
14
+ export const FallbackSymbol = Symbol("Toolkit.Fallback");
15
+ export const LayoutSymbol = Symbol("Toolkit.Layout");
16
+
17
+ export type ToolkitFallback = {
18
+ render: ToolCallMessagePartComponent<unknown, unknown>;
19
+ };
20
+
21
+ export type ToolkitLayout = {
22
+ render: ComponentType<{ children: ReactNode }>;
23
+ };
24
+
25
+ export type Toolkit = Record<string, ToolDefinition<any, any>> & {
26
+ [FallbackSymbol]?: ToolkitFallback;
27
+ [LayoutSymbol]?: ToolkitLayout;
28
+ };
29
+
30
+ export const Toolkit = {
31
+ Fallback: FallbackSymbol,
32
+ Layout: LayoutSymbol,
33
+ } as const;
34
+
35
+ export type ToolsConfig = {
36
+ toolkit: Toolkit;
37
+ };
@@ -27,7 +27,7 @@ export const useAssistantInstructions = (
27
27
  const config = {
28
28
  system: instruction,
29
29
  };
30
- return api.registerModelContextProvider({
30
+ return api.modelContext().register({
31
31
  getModelContext: () => config,
32
32
  });
33
33
  }, [api, instruction, disabled]);
@@ -33,7 +33,7 @@ export const useAssistantTool = <
33
33
  [toolName]: rest,
34
34
  },
35
35
  };
36
- return api.registerModelContextProvider({
36
+ return api.modelContext().register({
37
37
  getModelContext: () => context,
38
38
  });
39
39
  }, [api, tool]);
@@ -196,8 +196,9 @@ const ToolUIDisplay = ({
196
196
  Fallback: ToolCallMessagePartComponent | undefined;
197
197
  } & ToolCallMessagePartProps) => {
198
198
  const Render = useAssistantState(({ toolUIs }) => {
199
- const Render = toolUIs[props.toolName] ?? Fallback;
200
- if (Array.isArray(Render)) return Render[0];
199
+ const Render =
200
+ toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? Fallback;
201
+ if (Array.isArray(Render)) return Render[0] ?? Fallback;
201
202
  return Render;
202
203
  });
203
204
  if (!Render) return null;
@@ -221,8 +221,9 @@ const ToolUIDisplay = ({
221
221
  Fallback: ToolCallMessagePartComponent | undefined;
222
222
  } & ToolCallMessagePartProps) => {
223
223
  const Render = useAssistantState(({ toolUIs }) => {
224
- const Render = toolUIs[props.toolName] ?? Fallback;
225
- if (Array.isArray(Render)) return Render[0];
224
+ const Render =
225
+ toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? Fallback;
226
+ if (Array.isArray(Render)) return Render[0] ?? Fallback;
226
227
  return Render;
227
228
  });
228
229
  if (!Render) return null;
@@ -0,0 +1,185 @@
1
+ import { resource, tapEffect } from "@assistant-ui/tap";
2
+ import { tapMemo, tapRef, tapResource, tapResources } from "@assistant-ui/tap";
3
+ import { createAssistantApiField } from "../../context/react/AssistantApiContext";
4
+ import type {
5
+ AssistantApi,
6
+ AssistantApiField,
7
+ } from "../../context/react/AssistantApiContext";
8
+ import type {
9
+ AssistantEvent,
10
+ AssistantEventCallback,
11
+ AssistantEventSelector,
12
+ } from "../../types/EventTypes";
13
+ import type { ResourceElement, Unsubscribe } from "@assistant-ui/tap";
14
+
15
+ /**
16
+ * Extract the API return type from an AssistantApiField
17
+ */
18
+ type ExtractApiType<T> =
19
+ T extends AssistantApiField<infer TApi, any> ? TApi : never;
20
+
21
+ /**
22
+ * Extract the metadata type from an AssistantApiField
23
+ *
24
+ * Used in DerivedScopesInput to validate that each field's source/query types match
25
+ * the expected types from AssistantApi.
26
+ */
27
+ type ExtractMeta<T> =
28
+ T extends AssistantApiField<any, infer TMeta> ? TMeta : never;
29
+
30
+ /**
31
+ * Get only the field names from AssistantApi (exclude method names)
32
+ */
33
+ type AssistantApiFieldNames = {
34
+ [K in keyof AssistantApi]: AssistantApi[K] extends { source: any; query: any }
35
+ ? K
36
+ : never;
37
+ }[keyof AssistantApi];
38
+
39
+ /**
40
+ * Configuration for a derived scope field - infers types from the actual values provided
41
+ */
42
+ export type DerivedScopeConfig<TSource extends string | null, TQuery, TApi> = {
43
+ source: TSource;
44
+ query: TQuery;
45
+ get: () => TApi;
46
+ };
47
+
48
+ /**
49
+ * Type for the special `on` callback function
50
+ */
51
+ export type OnCallbackFn = <TEvent extends AssistantEvent>(
52
+ selector: AssistantEventSelector<TEvent>,
53
+ callback: AssistantEventCallback<TEvent>,
54
+ ) => Unsubscribe;
55
+
56
+ /**
57
+ * Type for the special `subscribe` callback function
58
+ */
59
+ export type SubscribeCallbackFn = (listener: () => void) => Unsubscribe;
60
+
61
+ /**
62
+ * Type for the special `flushSync` callback function
63
+ */
64
+ export type FlushSyncCallbackFn = () => void;
65
+
66
+ /**
67
+ * Type for special non-field functions in AssistantApi
68
+ */
69
+ export type SpecialCallbacks = {
70
+ on?: OnCallbackFn;
71
+ subscribe?: SubscribeCallbackFn;
72
+ flushSync?: FlushSyncCallbackFn;
73
+ };
74
+
75
+ /**
76
+ * Type for the scopes parameter - allows both DerivedScope elements and special callbacks.
77
+ * Field names are restricted to valid AssistantApi field names.
78
+ * TypeScript validates that the source/query/get types match the expected field type.
79
+ */
80
+ export type DerivedScopesInput = {
81
+ [K in AssistantApiFieldNames]?: ResourceElement<
82
+ AssistantApiField<
83
+ ExtractApiType<AssistantApi[K]>,
84
+ {
85
+ source: ExtractMeta<AssistantApi[K]>["source"];
86
+ query: ExtractMeta<AssistantApi[K]>["query"];
87
+ }
88
+ >
89
+ >;
90
+ } & SpecialCallbacks;
91
+
92
+ /**
93
+ * DerivedScope resource - memoizes an AssistantApiField based on source and query.
94
+ * The get callback always calls the most recent version (useEffectEvent pattern).
95
+ * TypeScript infers TSource, TQuery, and TApi from the config object.
96
+ * Validation happens at the DerivedScopesInput level.
97
+ */
98
+ export const DerivedScope = resource(
99
+ <TSource extends string | null, TQuery, TApi>(
100
+ config: DerivedScopeConfig<TSource, TQuery, TApi>,
101
+ ): AssistantApiField<
102
+ TApi,
103
+ {
104
+ source: TSource;
105
+ query: TQuery;
106
+ }
107
+ > => {
108
+ const getRef = tapRef(config.get);
109
+ tapEffect(() => {
110
+ getRef.current = config.get;
111
+ });
112
+
113
+ return tapMemo(() => {
114
+ return createAssistantApiField({
115
+ source: config.source,
116
+ query: config.query,
117
+ get: () => getRef.current(),
118
+ });
119
+ }, [config.source, JSON.stringify(config.query)]);
120
+ },
121
+ );
122
+
123
+ /**
124
+ * Helper resource to wrap each scope field - stable resource identity for proper memoization.
125
+ * Creating this outside the map ensures tapResources can properly track and memoize each field.
126
+ */
127
+ const ScopeFieldWithNameResource = resource(
128
+ (config: {
129
+ fieldName: string;
130
+ scopeElement: ReturnType<typeof DerivedScope>;
131
+ }) => {
132
+ const field = tapResource(config.scopeElement);
133
+ return tapMemo(
134
+ () => [config.fieldName, field] as const,
135
+ [config.fieldName, field],
136
+ );
137
+ },
138
+ );
139
+
140
+ /**
141
+ * DerivedScopes resource - takes an object of DerivedScope resource elements and special callbacks,
142
+ * and returns a Partial<AssistantApi> with all the derived fields.
143
+ */
144
+ export const DerivedScopes = resource(
145
+ (scopes: DerivedScopesInput): Partial<AssistantApi> => {
146
+ const { on, subscribe, flushSync, ...scopeFields } = scopes;
147
+ const callbacksRef = tapRef({ on, subscribe, flushSync });
148
+ tapEffect(() => {
149
+ callbacksRef.current = { on, subscribe, flushSync };
150
+ });
151
+
152
+ const results = tapResources(
153
+ Object.entries(scopeFields).map(([fieldName, scopeElement]) =>
154
+ ScopeFieldWithNameResource(
155
+ {
156
+ fieldName,
157
+ scopeElement: scopeElement as ReturnType<typeof DerivedScope>,
158
+ },
159
+ { key: fieldName },
160
+ ),
161
+ ),
162
+ );
163
+
164
+ return tapMemo(() => {
165
+ const result = Object.fromEntries(results) as Partial<AssistantApi>;
166
+
167
+ const {
168
+ on: onCb,
169
+ subscribe: subCb,
170
+ flushSync: flushCb,
171
+ } = callbacksRef.current;
172
+
173
+ if (onCb) {
174
+ result.on = <TEvent extends AssistantEvent>(
175
+ selector: AssistantEventSelector<TEvent>,
176
+ callback: AssistantEventCallback<TEvent>,
177
+ ) => onCb(selector, callback);
178
+ }
179
+ if (subCb) result.subscribe = (listener) => subCb(listener);
180
+ if (flushCb) result.flushSync = () => flushCb();
181
+
182
+ return result;
183
+ }, [...results]);
184
+ },
185
+ );
@@ -1,2 +1,11 @@
1
1
  export { type Store, asStore } from "./store";
2
2
  export { tapApi, type ApiObject } from "./tap-api";
3
+ export {
4
+ DerivedScope,
5
+ type DerivedScopeConfig,
6
+ type OnCallbackFn,
7
+ type SubscribeCallbackFn,
8
+ type FlushSyncCallbackFn,
9
+ type SpecialCallbacks,
10
+ type DerivedScopesInput,
11
+ } from "./derived-scopes";
@@ -40,7 +40,7 @@ export const tapApi = <TApi extends ApiObject & { getState: () => any }>(
40
40
  key?: string | undefined;
41
41
  },
42
42
  ) => {
43
- const ref = tapRef(() => api);
43
+ const ref = tapRef(api);
44
44
  tapEffect(() => {
45
45
  ref.current = api;
46
46
  });