@assistant-ui/store 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/dist/AssistantContext.d.ts +22 -0
- package/dist/AssistantContext.d.ts.map +1 -0
- package/dist/AssistantContext.js +44 -0
- package/dist/AssistantContext.js.map +1 -0
- package/dist/DerivedScope.d.ts +18 -0
- package/dist/DerivedScope.d.ts.map +1 -0
- package/dist/DerivedScope.js +11 -0
- package/dist/DerivedScope.js.map +1 -0
- package/dist/ScopeRegistry.d.ts +41 -0
- package/dist/ScopeRegistry.d.ts.map +1 -0
- package/dist/ScopeRegistry.js +17 -0
- package/dist/ScopeRegistry.js.map +1 -0
- package/dist/asStore.d.ts +20 -0
- package/dist/asStore.d.ts.map +1 -0
- package/dist/asStore.js +23 -0
- package/dist/asStore.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/tapApi.d.ts +36 -0
- package/dist/tapApi.d.ts.map +1 -0
- package/dist/tapApi.js +52 -0
- package/dist/tapApi.js.map +1 -0
- package/dist/tapLookupResources.d.ts +44 -0
- package/dist/tapLookupResources.d.ts.map +1 -0
- package/dist/tapLookupResources.js +21 -0
- package/dist/tapLookupResources.js.map +1 -0
- package/dist/tapStoreList.d.ts +76 -0
- package/dist/tapStoreList.d.ts.map +1 -0
- package/dist/tapStoreList.js +46 -0
- package/dist/tapStoreList.js.map +1 -0
- package/dist/types.d.ts +86 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/useAssistantClient.d.ts +42 -0
- package/dist/useAssistantClient.d.ts.map +1 -0
- package/dist/useAssistantClient.js +153 -0
- package/dist/useAssistantClient.js.map +1 -0
- package/dist/useAssistantState.d.ts +18 -0
- package/dist/useAssistantState.d.ts.map +1 -0
- package/dist/useAssistantState.js +53 -0
- package/dist/useAssistantState.js.map +1 -0
- package/dist/utils/splitScopes.d.ts +24 -0
- package/dist/utils/splitScopes.d.ts.map +1 -0
- package/dist/utils/splitScopes.js +18 -0
- package/dist/utils/splitScopes.js.map +1 -0
- package/package.json +50 -0
- package/src/AssistantContext.tsx +64 -0
- package/src/DerivedScope.ts +21 -0
- package/src/ScopeRegistry.ts +58 -0
- package/src/asStore.ts +40 -0
- package/src/index.ts +13 -0
- package/src/tapApi.ts +91 -0
- package/src/tapLookupResources.ts +62 -0
- package/src/tapStoreList.ts +133 -0
- package/src/types.ts +120 -0
- package/src/useAssistantClient.tsx +250 -0
- package/src/useAssistantState.tsx +80 -0
- package/src/utils/splitScopes.ts +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AgentbaseAI Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# @assistant-ui/store
|
|
2
|
+
|
|
3
|
+
Tap-based state management for assistant-ui with React Context integration.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The store package provides a bridge between tap Resources and React Components via React Context. It implements a scope-based system where you can define custom scopes using TypeScript module augmentation.
|
|
8
|
+
|
|
9
|
+
## Key Concepts
|
|
10
|
+
|
|
11
|
+
### Scopes
|
|
12
|
+
|
|
13
|
+
A **scope** defines a piece of state in your application. Each scope has:
|
|
14
|
+
|
|
15
|
+
- **value**: The state type (e.g., `{ bar: string }`)
|
|
16
|
+
- **source**: Where this scope comes from (`"root"` for top-level, or name of parent scope)
|
|
17
|
+
- **query**: Parameters needed to access this scope (e.g., `{ type: "index", index: number }`)
|
|
18
|
+
|
|
19
|
+
### Module Augmentation
|
|
20
|
+
|
|
21
|
+
Define custom scopes by extending the `AssistantScopes` interface:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import type { ScopeDefinition } from "@assistant-ui/store";
|
|
25
|
+
|
|
26
|
+
declare module "@assistant-ui/store" {
|
|
27
|
+
interface AssistantScopes {
|
|
28
|
+
foo: ScopeDefinition<{ bar: string }, "root", {}>;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### 1. Define a Scope
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// foo-scope.ts
|
|
39
|
+
import { resource, tapState } from "@assistant-ui/tap";
|
|
40
|
+
import { tapApi } from "@assistant-ui/store";
|
|
41
|
+
|
|
42
|
+
// Define the scope type via module augmentation
|
|
43
|
+
// Implement the scope definition raw (no need to import ScopeDefinition)
|
|
44
|
+
declare module "@assistant-ui/store" {
|
|
45
|
+
interface AssistantScopes {
|
|
46
|
+
foo: {
|
|
47
|
+
value: {
|
|
48
|
+
getState: () => { bar: string };
|
|
49
|
+
updateBar: (newBar: string) => void;
|
|
50
|
+
};
|
|
51
|
+
source: "root";
|
|
52
|
+
query: Record<string, never>;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Create the resource
|
|
58
|
+
export const FooResource = resource(() => {
|
|
59
|
+
const [state, setState] = tapState<{ bar: string }>({ bar: "Hello, World!" });
|
|
60
|
+
|
|
61
|
+
const updateBar = (newBar: string) => {
|
|
62
|
+
setState({ bar: newBar });
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Use tapApi to wrap the API for stability and reactivity
|
|
66
|
+
return tapApi({
|
|
67
|
+
getState: () => state,
|
|
68
|
+
updateBar,
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. Use in React Component
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { useAssistantClient } from "@assistant-ui/store";
|
|
77
|
+
import { FooResource } from "./foo-scope";
|
|
78
|
+
|
|
79
|
+
function MyComponent() {
|
|
80
|
+
// Create a client with the foo scope
|
|
81
|
+
const client = useAssistantClient({
|
|
82
|
+
foo: FooResource(),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Access the state
|
|
86
|
+
const fooState = client.foo.getState();
|
|
87
|
+
console.log(fooState.bar); // "Hello, World!"
|
|
88
|
+
|
|
89
|
+
// Call actions
|
|
90
|
+
const handleClick = () => {
|
|
91
|
+
client.foo.updateBar("New value!");
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
return <div onClick={handleClick}>{fooState.bar}</div>;
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Use with Provider (Optional)
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { AssistantProvider, useAssistantClient } from "@assistant-ui/store";
|
|
102
|
+
import { FooResource } from "./foo-scope";
|
|
103
|
+
|
|
104
|
+
function App() {
|
|
105
|
+
const client = useAssistantClient({
|
|
106
|
+
foo: FooResource,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<AssistantProvider client={client}>
|
|
111
|
+
<MyComponent />
|
|
112
|
+
</AssistantProvider>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function MyComponent() {
|
|
117
|
+
// Access client from context
|
|
118
|
+
const client = useAssistantClient();
|
|
119
|
+
const fooState = client.foo.getState();
|
|
120
|
+
|
|
121
|
+
return <div>{fooState.bar}</div>;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 4. Derived Scopes
|
|
126
|
+
|
|
127
|
+
Create scopes that depend on other scopes:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { DerivedScope } from "@assistant-ui/store";
|
|
131
|
+
|
|
132
|
+
function MyComponent() {
|
|
133
|
+
const client = useAssistantClient({
|
|
134
|
+
foo: FooResource,
|
|
135
|
+
message: DerivedScope({
|
|
136
|
+
source: "thread",
|
|
137
|
+
query: { type: "index", index: 0 },
|
|
138
|
+
get: () => messageApi,
|
|
139
|
+
}),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return <div>{client.message.getState().content}</div>;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## API
|
|
147
|
+
|
|
148
|
+
### `useAssistantClient()`
|
|
149
|
+
|
|
150
|
+
Returns the AssistantClient from context.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const client = useAssistantClient();
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### `useAssistantClient(scopes)`
|
|
157
|
+
|
|
158
|
+
Creates a new AssistantClient with the provided scopes, merging with any client from context.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const client = useAssistantClient({
|
|
162
|
+
foo: FooResource,
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### `AssistantProvider`
|
|
167
|
+
|
|
168
|
+
Provides an AssistantClient via React Context.
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
<AssistantProvider client={client}>
|
|
172
|
+
{children}
|
|
173
|
+
</AssistantProvider>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### `DerivedScope(config)`
|
|
177
|
+
|
|
178
|
+
Creates a derived scope field that memoizes based on source and query.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
DerivedScope({
|
|
182
|
+
source: "thread",
|
|
183
|
+
query: { type: "index", index: 0 },
|
|
184
|
+
get: () => messageApi,
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Advanced: List Management with tapLookupResources
|
|
189
|
+
|
|
190
|
+
For managing lists of items, use `tapLookupResources`:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import { tapLookupResources, tapApi } from "@assistant-ui/store";
|
|
194
|
+
|
|
195
|
+
// Define item resource
|
|
196
|
+
const FooItemResource = resource(
|
|
197
|
+
({ id, initialBar }: { id: string; initialBar: string }) => {
|
|
198
|
+
const [state, setState] = tapState({ id, bar: initialBar });
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
key: id,
|
|
202
|
+
state,
|
|
203
|
+
api: tapApi({
|
|
204
|
+
getState: () => state,
|
|
205
|
+
updateBar: (newBar: string) => setState({ ...state, bar: newBar }),
|
|
206
|
+
}),
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// Define list resource
|
|
212
|
+
const FooListResource = resource(() => {
|
|
213
|
+
const items = [
|
|
214
|
+
{ id: "foo-1", initialBar: "First" },
|
|
215
|
+
{ id: "foo-2", initialBar: "Second" },
|
|
216
|
+
];
|
|
217
|
+
|
|
218
|
+
const foos = tapLookupResources(
|
|
219
|
+
items.map((item) => FooItemResource(item, { key: item.id })),
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
return tapApi({
|
|
223
|
+
getState: () => ({ foos: foos.state }),
|
|
224
|
+
// Wrap to rename "key" field to "id"
|
|
225
|
+
foo: (lookup: { index: number } | { id: string }) => {
|
|
226
|
+
return "id" in lookup
|
|
227
|
+
? foos.api({ key: lookup.id })
|
|
228
|
+
: foos.api({ index: lookup.index });
|
|
229
|
+
},
|
|
230
|
+
}).api;
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Provider Pattern
|
|
235
|
+
|
|
236
|
+
Create providers to scope access to specific list items:
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const FooProvider = ({ index, children }) => {
|
|
240
|
+
const parentAui = useAssistantClient();
|
|
241
|
+
|
|
242
|
+
const aui = useAssistantClient({
|
|
243
|
+
foo: DerivedScope({
|
|
244
|
+
source: "fooList",
|
|
245
|
+
query: { index },
|
|
246
|
+
get: () => parentAui.fooList().foo({ index }),
|
|
247
|
+
}),
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
return <AssistantProvider client={aui}>{children}</AssistantProvider>;
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// Render list
|
|
254
|
+
const FooList = ({ components }) => {
|
|
255
|
+
const aui = useAssistantClient();
|
|
256
|
+
const { foos } = aui.fooList().getState();
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<div>
|
|
260
|
+
{foos.map((_, index) => (
|
|
261
|
+
<FooProvider key={index} index={index}>
|
|
262
|
+
<components.Foo />
|
|
263
|
+
</FooProvider>
|
|
264
|
+
))}
|
|
265
|
+
</div>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Examples
|
|
271
|
+
|
|
272
|
+
See the [store-example](../store-example) Next.js app for a complete working example including:
|
|
273
|
+
|
|
274
|
+
- Basic scope definition with `tapApi`
|
|
275
|
+
- List management with `tapLookupResources`
|
|
276
|
+
- Provider pattern for scoped access
|
|
277
|
+
- Component composition
|
|
278
|
+
- Tailwind CSS styling
|
|
279
|
+
|
|
280
|
+
## How It Works
|
|
281
|
+
|
|
282
|
+
The store is implemented using tap resources:
|
|
283
|
+
|
|
284
|
+
1. Each scope is a tap resource that manages its own state
|
|
285
|
+
2. `useAssistantClient` creates a resource that composes all provided scopes
|
|
286
|
+
3. The React Context provides the client to child components
|
|
287
|
+
4. Scopes can be extended/overridden by calling `useAssistantClient` with new scope definitions
|
|
288
|
+
|
|
289
|
+
This design allows for:
|
|
290
|
+
|
|
291
|
+
- ✅ Type-safe scope definitions via module augmentation
|
|
292
|
+
- ✅ Automatic cleanup of resources when components unmount
|
|
293
|
+
- ✅ Composable scope hierarchy (root → derived scopes)
|
|
294
|
+
- ✅ Full TypeScript inference for state and APIs
|
|
295
|
+
- ✅ Zero runtime overhead for scopes that aren't used
|
|
@@ -0,0 +1,22 @@
|
|
|
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>;
|
|
7
|
+
export declare const useAssistantContextValue: () => AssistantClient;
|
|
8
|
+
/**
|
|
9
|
+
* Provider component for AssistantClient
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* <AssistantProvider client={client}>
|
|
14
|
+
* <YourApp />
|
|
15
|
+
* </AssistantProvider>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const AssistantProvider: ({ client, children, }: {
|
|
19
|
+
client: AssistantClient;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
}) => React.ReactElement;
|
|
22
|
+
//# sourceMappingURL=AssistantContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantContext.d.ts","sourceRoot":"","sources":["../src/AssistantContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAA+B,MAAM,SAAS,CAAC;AAgB5E;;GAEG;AACH,eAAO,MAAM,gBAAgB,gCAe5B,CAAC;AAEF,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,44 @@
|
|
|
1
|
+
// src/AssistantContext.tsx
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { hasRegisteredScope } from "./ScopeRegistry.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
var NO_OP_SUBSCRIBE = () => () => {
|
|
6
|
+
};
|
|
7
|
+
var NO_OP_FLUSH_SYNC = () => {
|
|
8
|
+
};
|
|
9
|
+
var NO_OP_SCOPE_FIELD = (() => {
|
|
10
|
+
const fn = (() => {
|
|
11
|
+
throw new Error(
|
|
12
|
+
"You need to wrap this component/hook in <AssistantProvider>"
|
|
13
|
+
);
|
|
14
|
+
});
|
|
15
|
+
fn.source = null;
|
|
16
|
+
fn.query = null;
|
|
17
|
+
return fn;
|
|
18
|
+
})();
|
|
19
|
+
var AssistantContext = createContext(
|
|
20
|
+
new Proxy({}, {
|
|
21
|
+
get(_, prop) {
|
|
22
|
+
if (prop === "subscribe") return NO_OP_SUBSCRIBE;
|
|
23
|
+
if (prop === "flushSync") return NO_OP_FLUSH_SYNC;
|
|
24
|
+
if (hasRegisteredScope(prop))
|
|
25
|
+
return NO_OP_SCOPE_FIELD;
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
);
|
|
30
|
+
var useAssistantContextValue = () => {
|
|
31
|
+
return useContext(AssistantContext);
|
|
32
|
+
};
|
|
33
|
+
var AssistantProvider = ({
|
|
34
|
+
client,
|
|
35
|
+
children
|
|
36
|
+
}) => {
|
|
37
|
+
return /* @__PURE__ */ jsx(AssistantContext.Provider, { value: client, children });
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
AssistantContext,
|
|
41
|
+
AssistantProvider,
|
|
42
|
+
useAssistantContextValue
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=AssistantContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/AssistantContext.tsx"],"sourcesContent":["import React, { createContext, useContext } from \"react\";\nimport type { AssistantClient, AssistantScopes, ScopeField } from \"./types\";\nimport { hasRegisteredScope } from \"./ScopeRegistry\";\n\nconst NO_OP_SUBSCRIBE = () => () => {};\nconst NO_OP_FLUSH_SYNC = () => {};\nconst NO_OP_SCOPE_FIELD = (() => {\n const fn = (() => {\n throw new Error(\n \"You need to wrap this component/hook in <AssistantProvider>\",\n );\n }) as ScopeField<never>;\n fn.source = null;\n fn.query = null;\n return fn;\n})();\n\n/**\n * React Context for the AssistantClient\n */\nexport const AssistantContext = createContext<AssistantClient>(\n new Proxy({} as AssistantClient, {\n get(_, prop: string) {\n // Allow access to subscribe and flushSync without error\n if (prop === \"subscribe\") return NO_OP_SUBSCRIBE;\n\n if (prop === \"flushSync\") return NO_OP_FLUSH_SYNC;\n\n // If this is a registered scope, return a function that errors when called or accessed\n if (hasRegisteredScope(prop as keyof AssistantScopes))\n return NO_OP_SCOPE_FIELD;\n\n return null;\n },\n }),\n);\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,SAAS,0BAA0B;AAyD/B;AAvDJ,IAAM,kBAAkB,MAAM,MAAM;AAAC;AACrC,IAAM,mBAAmB,MAAM;AAAC;AAChC,IAAM,qBAAqB,MAAM;AAC/B,QAAM,MAAM,MAAM;AAChB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,KAAG,SAAS;AACZ,KAAG,QAAQ;AACX,SAAO;AACT,GAAG;AAKI,IAAM,mBAAmB;AAAA,EAC9B,IAAI,MAAM,CAAC,GAAsB;AAAA,IAC/B,IAAI,GAAG,MAAc;AAEnB,UAAI,SAAS,YAAa,QAAO;AAEjC,UAAI,SAAS,YAAa,QAAO;AAGjC,UAAI,mBAAmB,IAA6B;AAClD,eAAO;AAET,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEO,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,18 @@
|
|
|
1
|
+
import type { ScopeDefinition, ScopeValue, DerivedScopeProps } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a derived scope field that memoizes based on source and query.
|
|
4
|
+
* The get callback always calls the most recent version (useEffectEvent pattern).
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const MessageScope = DerivedScope<MessageScopeDefinition>({
|
|
9
|
+
* source: "thread",
|
|
10
|
+
* query: { type: "index", index: 0 },
|
|
11
|
+
* get: () => messageApi,
|
|
12
|
+
* });
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export declare const DerivedScope: <T extends ScopeDefinition>(props: DerivedScopeProps<T>, options?: {
|
|
16
|
+
key?: string | number;
|
|
17
|
+
} | undefined) => import("@assistant-ui/tap").ResourceElement<ScopeValue<T>, DerivedScopeProps<T>>;
|
|
18
|
+
//# sourceMappingURL=DerivedScope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DerivedScope.d.ts","sourceRoot":"","sources":["../src/DerivedScope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE9E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GACtB,CAAC,SAAS,eAAe;;kGAG3B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/DerivedScope.ts"],"sourcesContent":["import { resource } from \"@assistant-ui/tap\";\nimport type { ScopeDefinition, ScopeValue, DerivedScopeProps } from \"./types\";\n\n/**\n * Creates a derived scope field that memoizes based on source and query.\n * The get callback always calls the most recent version (useEffectEvent pattern).\n *\n * @example\n * ```typescript\n * const MessageScope = DerivedScope<MessageScopeDefinition>({\n * source: \"thread\",\n * query: { type: \"index\", index: 0 },\n * get: () => messageApi,\n * });\n * ```\n */\nexport const DerivedScope = resource(\n <T extends ScopeDefinition>(config: DerivedScopeProps<T>): ScopeValue<T> => {\n return config;\n },\n);\n"],"mappings":";AAAA,SAAS,gBAAgB;AAgBlB,IAAM,eAAe;AAAA,EAC1B,CAA4B,WAAgD;AAC1E,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AssistantScopes } from "./types";
|
|
2
|
+
import type { ResourceElement } from "@assistant-ui/tap";
|
|
3
|
+
type ScopeRegistryEntry<K extends keyof AssistantScopes> = {
|
|
4
|
+
name: K;
|
|
5
|
+
defaultInitialize: ResourceElement<AssistantScopes[K]["value"]> | {
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Register a default scope implementation.
|
|
11
|
+
* This allows scopes to have default values when not explicitly provided.
|
|
12
|
+
*
|
|
13
|
+
* @example With a resource:
|
|
14
|
+
* ```typescript
|
|
15
|
+
* registerAssistantScope({
|
|
16
|
+
* name: "myScope",
|
|
17
|
+
* defaultInitialize: MyResource(),
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @example With an error:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* registerAssistantScope({
|
|
24
|
+
* name: "myScope",
|
|
25
|
+
* defaultInitialize: { error: "MyScope is not configured" },
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function registerAssistantScope<K extends keyof AssistantScopes>(config: ScopeRegistryEntry<K>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Get the default initializer for a scope, if registered.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getDefaultScopeInitializer<K extends keyof AssistantScopes>(name: K): (ResourceElement<AssistantScopes[K]["value"]> | {
|
|
34
|
+
error: string;
|
|
35
|
+
}) | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Get all registered scope names.
|
|
38
|
+
*/
|
|
39
|
+
export declare function hasRegisteredScope(name: keyof AssistantScopes): boolean;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=ScopeRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScopeRegistry.d.ts","sourceRoot":"","sources":["../src/ScopeRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,KAAK,kBAAkB,CAAC,CAAC,SAAS,MAAM,eAAe,IAAI;IACzD,IAAI,EAAE,CAAC,CAAC;IACR,iBAAiB,EACb,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAC5C;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACvB,CAAC;AAOF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,eAAe,EACpE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC5B,IAAI,CAEN;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,SAAS,MAAM,eAAe,EACxE,IAAI,EAAE,CAAC,GAEL,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAClE,SAAS,CAEZ;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,eAAe,GAAG,OAAO,CAEvE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/ScopeRegistry.ts
|
|
2
|
+
var scopeRegistry = /* @__PURE__ */ new Map();
|
|
3
|
+
function registerAssistantScope(config) {
|
|
4
|
+
scopeRegistry.set(config.name, config.defaultInitialize);
|
|
5
|
+
}
|
|
6
|
+
function getDefaultScopeInitializer(name) {
|
|
7
|
+
return scopeRegistry.get(name);
|
|
8
|
+
}
|
|
9
|
+
function hasRegisteredScope(name) {
|
|
10
|
+
return scopeRegistry.has(name);
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
getDefaultScopeInitializer,
|
|
14
|
+
hasRegisteredScope,
|
|
15
|
+
registerAssistantScope
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=ScopeRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ScopeRegistry.ts"],"sourcesContent":["import type { AssistantScopes } from \"./types\";\nimport type { ResourceElement } from \"@assistant-ui/tap\";\n\ntype ScopeRegistryEntry<K extends keyof AssistantScopes> = {\n name: K;\n defaultInitialize:\n | ResourceElement<AssistantScopes[K][\"value\"]>\n | { error: string };\n};\n\nconst scopeRegistry = new Map<\n keyof AssistantScopes,\n ResourceElement<any> | { error: string }\n>();\n\n/**\n * Register a default scope implementation.\n * This allows scopes to have default values when not explicitly provided.\n *\n * @example With a resource:\n * ```typescript\n * registerAssistantScope({\n * name: \"myScope\",\n * defaultInitialize: MyResource(),\n * });\n * ```\n *\n * @example With an error:\n * ```typescript\n * registerAssistantScope({\n * name: \"myScope\",\n * defaultInitialize: { error: \"MyScope is not configured\" },\n * });\n * ```\n */\nexport function registerAssistantScope<K extends keyof AssistantScopes>(\n config: ScopeRegistryEntry<K>,\n): void {\n scopeRegistry.set(config.name, config.defaultInitialize);\n}\n\n/**\n * Get the default initializer for a scope, if registered.\n */\nexport function getDefaultScopeInitializer<K extends keyof AssistantScopes>(\n name: K,\n):\n | (ResourceElement<AssistantScopes[K][\"value\"]> | { error: string })\n | undefined {\n return scopeRegistry.get(name);\n}\n\n/**\n * Get all registered scope names.\n */\nexport function hasRegisteredScope(name: keyof AssistantScopes): boolean {\n return scopeRegistry.has(name);\n}\n"],"mappings":";AAUA,IAAM,gBAAgB,oBAAI,IAGxB;AAsBK,SAAS,uBACd,QACM;AACN,gBAAc,IAAI,OAAO,MAAM,OAAO,iBAAiB;AACzD;AAKO,SAAS,2BACd,MAGY;AACZ,SAAO,cAAc,IAAI,IAAI;AAC/B;AAKO,SAAS,mBAAmB,MAAsC;AACvE,SAAO,cAAc,IAAI,IAAI;AAC/B;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ResourceElement } from "@assistant-ui/tap";
|
|
2
|
+
import { Unsubscribe } from "./types";
|
|
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
|
+
* Synchronously flush all the updates to the store.
|
|
14
|
+
*/
|
|
15
|
+
flushSync(): void;
|
|
16
|
+
}
|
|
17
|
+
export declare const asStore: <TState, TProps>(props: ResourceElement<TState, TProps>, options?: {
|
|
18
|
+
key?: string | number;
|
|
19
|
+
} | undefined) => ResourceElement<Store<TState>, ResourceElement<TState, TProps>>;
|
|
20
|
+
//# sourceMappingURL=asStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asStore.d.ts","sourceRoot":"","sources":["../src/asStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EAGhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,WAAW,KAAK,CAAC,MAAM;IAC3B;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,WAAW,CAAC;IAE7C;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,OAAO,GACjB,MAAM,EAAE,MAAM;;iFAYhB,CAAC"}
|
package/dist/asStore.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/asStore.ts
|
|
2
|
+
import {
|
|
3
|
+
tapMemo,
|
|
4
|
+
tapEffect,
|
|
5
|
+
resource,
|
|
6
|
+
createResource
|
|
7
|
+
} from "@assistant-ui/tap";
|
|
8
|
+
var asStore = resource(
|
|
9
|
+
(element) => {
|
|
10
|
+
const resource2 = tapMemo(
|
|
11
|
+
() => createResource(element, true),
|
|
12
|
+
[element.type]
|
|
13
|
+
);
|
|
14
|
+
tapEffect(() => {
|
|
15
|
+
resource2.updateInput(element.props);
|
|
16
|
+
});
|
|
17
|
+
return resource2;
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
export {
|
|
21
|
+
asStore
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=asStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/asStore.ts"],"sourcesContent":["import {\n tapMemo,\n tapEffect,\n ResourceElement,\n resource,\n createResource,\n} from \"@assistant-ui/tap\";\nimport { Unsubscribe } from \"./types\";\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 /**\n * Synchronously flush all the updates to the store.\n */\n flushSync(): void;\n}\n\nexport const asStore = resource(\n <TState, TProps>(element: ResourceElement<TState, TProps>): Store<TState> => {\n const resource = tapMemo(\n () => createResource(element, true),\n [element.type],\n );\n\n tapEffect(() => {\n resource.updateInput(element.props);\n });\n\n return resource;\n },\n);\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AAoBA,IAAM,UAAU;AAAA,EACrB,CAAiB,YAA4D;AAC3E,UAAMA,YAAW;AAAA,MACf,MAAM,eAAe,SAAS,IAAI;AAAA,MAClC,CAAC,QAAQ,IAAI;AAAA,IACf;AAEA,cAAU,MAAM;AACd,MAAAA,UAAS,YAAY,QAAQ,KAAK;AAAA,IACpC,CAAC;AAED,WAAOA;AAAA,EACT;AACF;","names":["resource"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { useAssistantClient } from "./useAssistantClient";
|
|
2
|
+
export { useAssistantState } from "./useAssistantState";
|
|
3
|
+
export { AssistantProvider } from "./AssistantContext";
|
|
4
|
+
export type { AssistantScopes, AssistantClient, AssistantState } from "./types";
|
|
5
|
+
export { DerivedScope } from "./DerivedScope";
|
|
6
|
+
export type { ApiObject } from "./tapApi";
|
|
7
|
+
export { tapApi } from "./tapApi";
|
|
8
|
+
export { tapLookupResources } from "./tapLookupResources";
|
|
9
|
+
export { tapStoreList } from "./tapStoreList";
|
|
10
|
+
export type { TapStoreListConfig } from "./tapStoreList";
|
|
11
|
+
export { registerAssistantScope } from "./ScopeRegistry";
|
|
12
|
+
export type { AssistantScopeRegistry } from "./types";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { useAssistantClient } from "./useAssistantClient.js";
|
|
3
|
+
import { useAssistantState } from "./useAssistantState.js";
|
|
4
|
+
import { AssistantProvider } from "./AssistantContext.js";
|
|
5
|
+
import { DerivedScope } from "./DerivedScope.js";
|
|
6
|
+
import { tapApi } from "./tapApi.js";
|
|
7
|
+
import { tapLookupResources } from "./tapLookupResources.js";
|
|
8
|
+
import { tapStoreList } from "./tapStoreList.js";
|
|
9
|
+
import { registerAssistantScope } from "./ScopeRegistry.js";
|
|
10
|
+
export {
|
|
11
|
+
AssistantProvider,
|
|
12
|
+
DerivedScope,
|
|
13
|
+
registerAssistantScope,
|
|
14
|
+
tapApi,
|
|
15
|
+
tapLookupResources,
|
|
16
|
+
tapStoreList,
|
|
17
|
+
useAssistantClient,
|
|
18
|
+
useAssistantState
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { useAssistantClient } from \"./useAssistantClient\";\nexport { useAssistantState } from \"./useAssistantState\";\nexport { AssistantProvider } from \"./AssistantContext\";\nexport type { AssistantScopes, AssistantClient, AssistantState } from \"./types\";\nexport { DerivedScope } from \"./DerivedScope\";\nexport type { ApiObject } from \"./tapApi\";\nexport { tapApi } from \"./tapApi\";\nexport { tapLookupResources } from \"./tapLookupResources\";\nexport { tapStoreList } from \"./tapStoreList\";\nexport type { TapStoreListConfig } from \"./tapStoreList\";\nexport { registerAssistantScope } from \"./ScopeRegistry\";\n\nexport type { AssistantScopeRegistry } from \"./types\";\n"],"mappings":";AAAA,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,yBAAyB;AAElC,SAAS,oBAAoB;AAE7B,SAAS,cAAc;AACvB,SAAS,0BAA0B;AACnC,SAAS,oBAAoB;AAE7B,SAAS,8BAA8B;","names":[]}
|
package/dist/tapApi.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API object type
|
|
3
|
+
*/
|
|
4
|
+
export interface ApiObject {
|
|
5
|
+
[key: string]: ((...args: any[]) => any) | ApiObject;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Wraps an API object to make it stable across renders while keeping getState reactive.
|
|
9
|
+
* This is the recommended pattern for scope resources.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* export const FooResource = resource(() => {
|
|
14
|
+
* const [state, setState] = tapState({ bar: "Hello" });
|
|
15
|
+
*
|
|
16
|
+
* const updateBar = (newBar: string) => {
|
|
17
|
+
* setState({ bar: newBar });
|
|
18
|
+
* };
|
|
19
|
+
*
|
|
20
|
+
* return tapApi({
|
|
21
|
+
* getState: () => state,
|
|
22
|
+
* updateBar,
|
|
23
|
+
* });
|
|
24
|
+
* });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare const tapApi: <TApi extends ApiObject & {
|
|
28
|
+
getState: () => any;
|
|
29
|
+
}>(api: TApi, options?: {
|
|
30
|
+
key?: string | undefined;
|
|
31
|
+
}) => {
|
|
32
|
+
key: string | undefined;
|
|
33
|
+
state: any;
|
|
34
|
+
api: TApi;
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=tapApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tapApi.d.ts","sourceRoot":"","sources":["../src/tapApi.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;CACtD;AAmCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,MAAM,GAAI,IAAI,SAAS,SAAS,GAAG;IAAE,QAAQ,EAAE,MAAM,GAAG,CAAA;CAAE,EACrE,KAAK,IAAI,EACT,UAAU;IACR,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;;;;CAwBF,CAAC"}
|