@assistant-ui/store 0.2.10 → 0.2.12
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/README.md +36 -65
- package/dist/AuiIf.d.ts +43 -8
- package/dist/AuiIf.d.ts.map +1 -1
- package/dist/AuiIf.js +28 -3
- package/dist/AuiIf.js.map +1 -1
- package/dist/Derived.d.ts +15 -13
- package/dist/Derived.d.ts.map +1 -1
- package/dist/Derived.js +24 -20
- package/dist/Derived.js.map +1 -1
- package/dist/RenderChildrenWithAccessor.d.ts +13 -6
- package/dist/RenderChildrenWithAccessor.d.ts.map +1 -1
- package/dist/RenderChildrenWithAccessor.js +42 -48
- package/dist/RenderChildrenWithAccessor.js.map +1 -1
- package/dist/attachTransformScopes.d.ts +11 -10
- package/dist/attachTransformScopes.d.ts.map +1 -1
- package/dist/attachTransformScopes.js +20 -23
- package/dist/attachTransformScopes.js.map +1 -1
- package/dist/index.d.ts +15 -16
- package/dist/index.js +14 -18
- package/dist/tapClientList.d.ts +26 -23
- package/dist/tapClientList.d.ts.map +1 -1
- package/dist/tapClientList.js +66 -63
- package/dist/tapClientList.js.map +1 -1
- package/dist/tapClientLookup.d.ts +14 -11
- package/dist/tapClientLookup.d.ts.map +1 -1
- package/dist/tapClientLookup.js +31 -37
- package/dist/tapClientLookup.js.map +1 -1
- package/dist/tapClientResource.d.ts +12 -9
- package/dist/tapClientResource.d.ts.map +1 -1
- package/dist/tapClientResource.js +92 -104
- package/dist/tapClientResource.js.map +1 -1
- package/dist/types/client.d.ts +50 -42
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/client.js +0 -2
- package/dist/types/events.d.ts +23 -24
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/events.js +13 -6
- package/dist/types/events.js.map +1 -1
- package/dist/useAui.d.ts +76 -15
- package/dist/useAui.d.ts.map +1 -1
- package/dist/useAui.js +178 -175
- package/dist/useAui.js.map +1 -1
- package/dist/useAuiEvent.d.ts +47 -2
- package/dist/useAuiEvent.d.ts.map +1 -1
- package/dist/useAuiEvent.js +60 -7
- package/dist/useAuiEvent.js.map +1 -1
- package/dist/useAuiState.d.ts +31 -10
- package/dist/useAuiState.d.ts.map +1 -1
- package/dist/useAuiState.js +44 -25
- package/dist/useAuiState.js.map +1 -1
- package/dist/utils/BaseProxyHandler.d.ts +19 -16
- package/dist/utils/BaseProxyHandler.d.ts.map +1 -1
- package/dist/utils/BaseProxyHandler.js +46 -43
- package/dist/utils/BaseProxyHandler.js.map +1 -1
- package/dist/utils/NotificationManager.d.ts +13 -9
- package/dist/utils/NotificationManager.d.ts.map +1 -1
- package/dist/utils/NotificationManager.js +69 -82
- package/dist/utils/NotificationManager.js.map +1 -1
- package/dist/utils/proxied-assistant-state.d.ts +8 -4
- package/dist/utils/proxied-assistant-state.d.ts.map +1 -1
- package/dist/utils/proxied-assistant-state.js +28 -26
- package/dist/utils/proxied-assistant-state.js.map +1 -1
- package/dist/utils/react-assistant-context.d.ts +31 -13
- package/dist/utils/react-assistant-context.d.ts.map +1 -1
- package/dist/utils/react-assistant-context.js +69 -56
- package/dist/utils/react-assistant-context.js.map +1 -1
- package/dist/utils/splitClients.d.ts +12 -8
- package/dist/utils/splitClients.d.ts.map +1 -1
- package/dist/utils/splitClients.js +39 -43
- package/dist/utils/splitClients.js.map +1 -1
- package/dist/utils/tap-assistant-context.d.ts +17 -14
- package/dist/utils/tap-assistant-context.d.ts.map +1 -1
- package/dist/utils/tap-assistant-context.js +18 -15
- package/dist/utils/tap-assistant-context.js.map +1 -1
- package/dist/utils/tap-client-stack-context.d.ts +10 -6
- package/dist/utils/tap-client-stack-context.d.ts.map +1 -1
- package/dist/utils/tap-client-stack-context.js +22 -19
- package/dist/utils/tap-client-stack-context.js.map +1 -1
- package/dist/wrapperResource.d.ts +6 -2
- package/dist/wrapperResource.d.ts.map +1 -1
- package/dist/wrapperResource.js +12 -9
- package/dist/wrapperResource.js.map +1 -1
- package/package.json +7 -7
- package/src/AuiIf.ts +35 -1
- package/src/Derived.ts +1 -1
- package/src/types/client.ts +1 -2
- package/src/useAui.ts +101 -32
- package/src/useAuiEvent.ts +41 -0
- package/src/useAuiState.ts +25 -8
- package/src/utils/react-assistant-context.tsx +18 -5
- package/src/utils/splitClients.ts +4 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/client.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,30 +1,55 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@assistant-ui/store`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@assistant-ui/store)
|
|
4
|
+
[](https://github.com/assistant-ui/assistant-ui)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
Tap-based state container with React Context integration. Bridges `@assistant-ui/tap` resources into React via `useAui`, `useAuiState`, and `<AuiProvider>`.
|
|
7
|
+
|
|
8
|
+
`store` powers the runtime layer of assistant-ui. Most users do not install it directly; reach for `@assistant-ui/react` instead.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @assistant-ui/store @assistant-ui/tap
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
6
17
|
|
|
7
18
|
```typescript
|
|
8
19
|
import { resource, tapState } from "@assistant-ui/tap";
|
|
9
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
useAui,
|
|
22
|
+
useAuiState,
|
|
23
|
+
AuiProvider,
|
|
24
|
+
type ClientOutput,
|
|
25
|
+
} from "@assistant-ui/store";
|
|
10
26
|
|
|
11
|
-
// 1. Define client type
|
|
12
27
|
declare module "@assistant-ui/store" {
|
|
13
28
|
interface ScopeRegistry {
|
|
14
|
-
counter: {
|
|
29
|
+
counter: {
|
|
30
|
+
methods: {
|
|
31
|
+
getState: () => { count: number };
|
|
32
|
+
increment: () => void;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
15
35
|
}
|
|
16
36
|
}
|
|
17
37
|
|
|
18
|
-
// 2. Create resource
|
|
19
38
|
const CounterClient = resource((): ClientOutput<"counter"> => {
|
|
20
39
|
const [state, setState] = tapState({ count: 0 });
|
|
21
|
-
return {
|
|
40
|
+
return {
|
|
41
|
+
getState: () => state,
|
|
42
|
+
increment: () => setState({ count: state.count + 1 }),
|
|
43
|
+
};
|
|
22
44
|
});
|
|
23
45
|
|
|
24
|
-
// 3. Use in React
|
|
25
46
|
function App() {
|
|
26
47
|
const aui = useAui({ counter: CounterClient() });
|
|
27
|
-
return
|
|
48
|
+
return (
|
|
49
|
+
<AuiProvider value={aui}>
|
|
50
|
+
<Counter />
|
|
51
|
+
</AuiProvider>
|
|
52
|
+
);
|
|
28
53
|
}
|
|
29
54
|
|
|
30
55
|
function Counter() {
|
|
@@ -34,58 +59,4 @@ function Counter() {
|
|
|
34
59
|
}
|
|
35
60
|
```
|
|
36
61
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
**Clients**: Named state containers registered via module augmentation.
|
|
40
|
-
```typescript
|
|
41
|
-
declare module "@assistant-ui/store" {
|
|
42
|
-
interface ScopeRegistry {
|
|
43
|
-
myClient: {
|
|
44
|
-
methods: MyMethods; // must include getState(): MyState
|
|
45
|
-
meta?: { source: "parent"; query: { id: string } };
|
|
46
|
-
events?: { "myClient.updated": { id: string } };
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
**Derived Clients**: Access nested clients from parents.
|
|
53
|
-
```typescript
|
|
54
|
-
useAui({
|
|
55
|
-
item: Derived({ source: "list", query: { index: 0 }, get: (aui) => aui.list().item({ index: 0 }) }),
|
|
56
|
-
});
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
**Events**:
|
|
60
|
-
```typescript
|
|
61
|
-
const emit = tapAssistantEmit();
|
|
62
|
-
emit("myClient.updated", { id: "123" });
|
|
63
|
-
|
|
64
|
-
useAuiEvent("myClient.updated", (p) => console.log(p.id));
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## API
|
|
68
|
-
|
|
69
|
-
| Hook/Component | Description |
|
|
70
|
-
|----------------|-------------|
|
|
71
|
-
| `useAui()` | Get client from context |
|
|
72
|
-
| `useAui(clients)` | Create/extend client |
|
|
73
|
-
| `useAuiState(selector)` | Subscribe to state |
|
|
74
|
-
| `useAuiEvent(event, cb)` | Subscribe to events |
|
|
75
|
-
| `AuiProvider` | Provide client to tree |
|
|
76
|
-
| `AuiIf` | Conditional rendering |
|
|
77
|
-
|
|
78
|
-
| Tap Utility | Description |
|
|
79
|
-
|-------------|-------------|
|
|
80
|
-
| `tapAssistantClientRef()` | Access client ref in resources |
|
|
81
|
-
| `tapAssistantEmit()` | Emit events from resources |
|
|
82
|
-
| `tapClientResource(element)` | Wrap resource for event scoping (1:1 mappings) |
|
|
83
|
-
| `tapClientLookup(map, fn, deps)` | Lookup by `{index}` or `{key}` |
|
|
84
|
-
| `tapClientList(config)` | Dynamic list with add/remove |
|
|
85
|
-
| `attachTransformScopes(resource, fn)` | Attach scope transform |
|
|
86
|
-
|
|
87
|
-
| Type | Description |
|
|
88
|
-
|------|-------------|
|
|
89
|
-
| `ClientOutput<K>` | Resource return type (methods object) |
|
|
90
|
-
| `ScopeRegistry` | Module augmentation interface |
|
|
91
|
-
| `AssistantClient` | Full client type |
|
|
62
|
+
Full API reference (clients, derived clients, events, `tapClientLookup`, `tapClientList`) at [assistant-ui.com/tap/docs/store/quickstart](https://www.assistant-ui.com/tap/docs/store/quickstart).
|
package/dist/AuiIf.d.ts
CHANGED
|
@@ -1,10 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { AssistantState } from "./types/client.js";
|
|
2
|
+
import { FC, PropsWithChildren } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/AuiIf.d.ts
|
|
5
|
+
declare namespace AuiIf {
|
|
6
|
+
/** Props for `AuiIf`. */
|
|
7
|
+
type Props = PropsWithChildren<{
|
|
8
|
+
/**
|
|
9
|
+
* Selector that decides whether to render `children`. Children render
|
|
10
|
+
* when this returns `true` and unmount when it returns `false`.
|
|
11
|
+
*/
|
|
12
|
+
condition: AuiIf.Condition;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Selector passed to `AuiIf`. Receives the assistant state and must
|
|
16
|
+
* return a boolean.
|
|
17
|
+
*/
|
|
18
|
+
type Condition = (state: AssistantState) => boolean;
|
|
8
19
|
}
|
|
9
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Conditionally renders children based on a slice of assistant state.
|
|
22
|
+
*
|
|
23
|
+
* A thin wrapper around {@link useAuiState} that renders its children
|
|
24
|
+
* when `condition` returns `true` and unmounts them when it returns
|
|
25
|
+
* `false`. Keeps render logic declarative without mounting unused
|
|
26
|
+
* subtrees.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <AuiIf condition={(s) => s.thread.isRunning}>
|
|
31
|
+
* <CancelButton />
|
|
32
|
+
* </AuiIf>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <AuiIf condition={(s) => s.thread.messages.length === 0}>
|
|
38
|
+
* <EmptyState />
|
|
39
|
+
* </AuiIf>
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
declare const AuiIf: FC<AuiIf.Props>;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { AuiIf };
|
|
10
45
|
//# sourceMappingURL=AuiIf.d.ts.map
|
package/dist/AuiIf.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuiIf.d.ts","
|
|
1
|
+
{"version":3,"file":"AuiIf.d.ts","names":[],"sources":["../src/AuiIf.ts"],"mappings":";;;;kBAMiB,KAAA;;OAEH,KAAA,GAAQ,iBAAA;IAFA;;;;IAOlB,SAAA,EAAW,KAAA,CAAM,SAAA;EAAA;EAO2B;;;;EAAA,KAAlC,SAAA,IAAa,KAAA,EAAO,cAAA;AAAA;;;;;AAAc;AAyBhD;;;;;;;;AAAkC;;;;;;;;;cAArB,KAAA,EAAO,EAAE,CAAC,KAAA,CAAM,KAAA"}
|
package/dist/AuiIf.js
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useAuiState } from "./useAuiState.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
//#region src/AuiIf.ts
|
|
4
|
+
/**
|
|
5
|
+
* Conditionally renders children based on a slice of assistant state.
|
|
6
|
+
*
|
|
7
|
+
* A thin wrapper around {@link useAuiState} that renders its children
|
|
8
|
+
* when `condition` returns `true` and unmounts them when it returns
|
|
9
|
+
* `false`. Keeps render logic declarative without mounting unused
|
|
10
|
+
* subtrees.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* <AuiIf condition={(s) => s.thread.isRunning}>
|
|
15
|
+
* <CancelButton />
|
|
16
|
+
* </AuiIf>
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <AuiIf condition={(s) => s.thread.messages.length === 0}>
|
|
22
|
+
* <EmptyState />
|
|
23
|
+
* </AuiIf>
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
const AuiIf = ({ children, condition }) => {
|
|
27
|
+
return useAuiState(condition) ? children : null;
|
|
6
28
|
};
|
|
7
29
|
AuiIf.displayName = "AuiIf";
|
|
30
|
+
//#endregion
|
|
31
|
+
export { AuiIf };
|
|
32
|
+
|
|
8
33
|
//# sourceMappingURL=AuiIf.js.map
|
package/dist/AuiIf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuiIf.js","
|
|
1
|
+
{"version":3,"file":"AuiIf.js","names":[],"sources":["../src/AuiIf.ts"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAuiState } from \"./useAuiState\";\nimport type { AssistantState } from \"./types/client\";\n\nexport namespace AuiIf {\n /** Props for `AuiIf`. */\n export type Props = PropsWithChildren<{\n /**\n * Selector that decides whether to render `children`. Children render\n * when this returns `true` and unmount when it returns `false`.\n */\n condition: AuiIf.Condition;\n }>;\n\n /**\n * Selector passed to `AuiIf`. Receives the assistant state and must\n * return a boolean.\n */\n export type Condition = (state: AssistantState) => boolean;\n}\n\n/**\n * Conditionally renders children based on a slice of assistant state.\n *\n * A thin wrapper around {@link useAuiState} that renders its children\n * when `condition` returns `true` and unmounts them when it returns\n * `false`. Keeps render logic declarative without mounting unused\n * subtrees.\n *\n * @example\n * ```tsx\n * <AuiIf condition={(s) => s.thread.isRunning}>\n * <CancelButton />\n * </AuiIf>\n * ```\n *\n * @example\n * ```tsx\n * <AuiIf condition={(s) => s.thread.messages.length === 0}>\n * <EmptyState />\n * </AuiIf>\n * ```\n */\nexport const AuiIf: FC<AuiIf.Props> = ({ children, condition }) => {\n const result = useAuiState(condition);\n return result ? children : null;\n};\n\nAuiIf.displayName = \"AuiIf\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAa,SAA0B,EAAE,UAAU,gBAAgB;CAEjE,OADe,YAAY,SACf,IAAI,WAAW;AAC7B;AAEA,MAAM,cAAc"}
|
package/dist/Derived.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { AssistantClient, AssistantClientAccessor, ClientMeta, ClientNames } from "./types/client.js";
|
|
2
|
+
import { ResourceElement } from "@assistant-ui/tap";
|
|
3
|
+
|
|
4
|
+
//#region src/Derived.d.ts
|
|
3
5
|
/**
|
|
4
6
|
* Creates a derived client field that references a client from a parent scope.
|
|
5
7
|
* The get callback always calls the most recent version (useEffectEvent pattern).
|
|
@@ -19,16 +21,16 @@ import type { AssistantClient, ClientNames, AssistantClientAccessor, ClientMeta
|
|
|
19
21
|
* });
|
|
20
22
|
* ```
|
|
21
23
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
getMeta: (client: AssistantClient) => ClientMeta<K>;
|
|
32
|
-
});
|
|
24
|
+
declare const Derived: <K extends ClientNames>(props: Derived.Props<K>) => ResourceElement<null, Derived.Props<K>>;
|
|
25
|
+
type DerivedElement<K extends ClientNames> = ResourceElement<null, Derived.Props<K>>;
|
|
26
|
+
declare namespace Derived {
|
|
27
|
+
/**
|
|
28
|
+
* Props passed to a derived client resource element.
|
|
29
|
+
*/
|
|
30
|
+
type Props<K extends ClientNames> = {
|
|
31
|
+
get: (client: AssistantClient) => ReturnType<AssistantClientAccessor<K>>;
|
|
32
|
+
} & ClientMeta<K>;
|
|
33
33
|
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Derived, DerivedElement };
|
|
34
36
|
//# sourceMappingURL=Derived.d.ts.map
|
package/dist/Derived.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Derived.d.ts","
|
|
1
|
+
{"version":3,"file":"Derived.d.ts","names":[],"sources":["../src/Derived.ts"],"mappings":";;;;;;AA2BA;;;;;;;;;;;;;;;;;cAAa,OAAA,aACA,WAAA,EAAW,KAAA,EAAA,OAAA,CAAA,KAAA,CAAA,CAAA,MAAA,eAAA,OAAA,OAAA,CAAA,KAAA,CAAA,CAAA;AAAA,KAKZ,cAAA,WAAyB,WAAA,IAAe,eAAA,OAElD,OAAA,CAAQ,KAAA,CAAM,CAAA;AAAA,kBAGC,OAAA;EAVO;;AAAA;EAAA,KAcV,KAAA,WAAgB,WAAA;IAC1B,GAAA,GAAM,MAAA,EAAQ,eAAA,KAAoB,UAAA,CAAW,uBAAA,CAAwB,CAAA;EAAA,IACnE,UAAA,CAAW,CAAA;AAAA"}
|
package/dist/Derived.js
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
import { resource } from "@assistant-ui/tap";
|
|
2
|
+
//#region src/Derived.ts
|
|
2
3
|
/**
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
* Creates a derived client field that references a client from a parent scope.
|
|
5
|
+
* The get callback always calls the most recent version (useEffectEvent pattern).
|
|
6
|
+
*
|
|
7
|
+
* IMPORTANT: The `get` callback must return a client that was created via
|
|
8
|
+
* `tapClientResource` (or `tapClientLookup`/`tapClientList` which use it internally).
|
|
9
|
+
* This is required for event scoping to work correctly.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const aui = useAui({
|
|
14
|
+
* message: Derived({
|
|
15
|
+
* source: "thread",
|
|
16
|
+
* query: { index: 0 },
|
|
17
|
+
* get: (aui) => aui.thread().message({ index: 0 }),
|
|
18
|
+
* }),
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
const Derived = resource((_config) => {
|
|
23
|
+
return null;
|
|
23
24
|
});
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Derived };
|
|
27
|
+
|
|
24
28
|
//# sourceMappingURL=Derived.js.map
|
package/dist/Derived.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Derived.js","
|
|
1
|
+
{"version":3,"file":"Derived.js","names":[],"sources":["../src/Derived.ts"],"sourcesContent":["import { resource, type ResourceElement } from \"@assistant-ui/tap\";\nimport type {\n AssistantClient,\n ClientNames,\n AssistantClientAccessor,\n ClientMeta,\n} from \"./types/client\";\n\n/**\n * Creates a derived client field that references a client from a parent scope.\n * The get callback always calls the most recent version (useEffectEvent pattern).\n *\n * IMPORTANT: The `get` callback must return a client that was created via\n * `tapClientResource` (or `tapClientLookup`/`tapClientList` which use it internally).\n * This is required for event scoping to work correctly.\n *\n * @example\n * ```typescript\n * const aui = useAui({\n * message: Derived({\n * source: \"thread\",\n * query: { index: 0 },\n * get: (aui) => aui.thread().message({ index: 0 }),\n * }),\n * });\n * ```\n */\nexport const Derived = resource(\n <K extends ClientNames>(_config: Derived.Props<K>): null => {\n return null;\n },\n);\n\nexport type DerivedElement<K extends ClientNames> = ResourceElement<\n null,\n Derived.Props<K>\n>;\n\nexport namespace Derived {\n /**\n * Props passed to a derived client resource element.\n */\n export type Props<K extends ClientNames> = {\n get: (client: AssistantClient) => ReturnType<AssistantClientAccessor<K>>;\n } & ClientMeta<K>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA2BA,MAAa,UAAU,UACG,YAAoC;CAC1D,OAAO;AACT,CACF"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { AssistantClient } from "./types/client.js";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/RenderChildrenWithAccessor.d.ts
|
|
5
|
+
declare const useGetItemAccessor: <T>(getItemState: (aui: AssistantClient) => T) => () => T;
|
|
4
6
|
/**
|
|
5
7
|
* Component that sets up a lazy item accessor and memoizes propless children.
|
|
6
8
|
*
|
|
@@ -16,8 +18,13 @@ export declare const useGetItemAccessor: <T>(getItemState: (aui: AssistantClient
|
|
|
16
18
|
* </RenderChildrenWithAccessor>
|
|
17
19
|
* ```
|
|
18
20
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
declare function RenderChildrenWithAccessor<T>({
|
|
22
|
+
getItemState,
|
|
23
|
+
children
|
|
24
|
+
}: {
|
|
25
|
+
getItemState: (aui: AssistantClient) => T;
|
|
26
|
+
children: (getItem: () => T) => ReactNode;
|
|
22
27
|
}): ReactNode;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { RenderChildrenWithAccessor, useGetItemAccessor };
|
|
23
30
|
//# sourceMappingURL=RenderChildrenWithAccessor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderChildrenWithAccessor.d.ts","
|
|
1
|
+
{"version":3,"file":"RenderChildrenWithAccessor.d.ts","names":[],"sources":["../src/RenderChildrenWithAccessor.tsx"],"mappings":";;;;cAOa,kBAAA,MACX,YAAA,GAAe,GAAA,EAAK,eAAA,KAAoB,CAAA,WAAC,CAAA;;AAD3C;;;;;;;;;;;;;;iBAwCgB,0BAAA,GAAA,CAAA;EACd,YAAA;EACA;AAAA;EAEA,YAAA,GAAe,GAAA,EAAK,eAAA,KAAoB,CAAA;EACxC,QAAA,GAAW,OAAA,QAAe,CAAA,KAAM,SAAA;AAAA,IAC9B,SAAA"}
|
|
@@ -1,57 +1,51 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useMemo, useRef } from "react";
|
|
3
|
-
import { useAuiState } from "./useAuiState.js";
|
|
4
2
|
import { useAui } from "./useAui.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
accessedRef.current = true;
|
|
21
|
-
return getItemState(aui);
|
|
22
|
-
};
|
|
3
|
+
import { useAuiState } from "./useAuiState.js";
|
|
4
|
+
import { useMemo, useRef } from "react";
|
|
5
|
+
//#region src/RenderChildrenWithAccessor.tsx
|
|
6
|
+
const useGetItemAccessor = (getItemState) => {
|
|
7
|
+
const aui = useAui();
|
|
8
|
+
const accessedRef = useRef(false);
|
|
9
|
+
const currentValue = accessedRef.current ? null : getItemState(aui);
|
|
10
|
+
useAuiState(() => {
|
|
11
|
+
if (!accessedRef.current) return currentValue;
|
|
12
|
+
return getItemState(aui);
|
|
13
|
+
});
|
|
14
|
+
return () => {
|
|
15
|
+
accessedRef.current = true;
|
|
16
|
+
return getItemState(aui);
|
|
17
|
+
};
|
|
23
18
|
};
|
|
24
19
|
const EMPTY_OBJECT = Object.freeze({});
|
|
25
20
|
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return useMemoizedProplessComponent(children(getItem));
|
|
21
|
+
* Component that sets up a lazy item accessor and memoizes propless children.
|
|
22
|
+
*
|
|
23
|
+
* For the common pattern where children returns a component without props
|
|
24
|
+
* (e.g. `<Foo />`), the output is memoized and not re-created on parent re-renders.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```tsx
|
|
28
|
+
* <RenderChildrenWithAccessor
|
|
29
|
+
* getItemState={(aui) => aui.fooList().foo({ index }).getState()}
|
|
30
|
+
* >
|
|
31
|
+
* {() => <Foo />}
|
|
32
|
+
* </RenderChildrenWithAccessor>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function RenderChildrenWithAccessor({ getItemState, children }) {
|
|
36
|
+
return useMemoizedProplessComponent(children(useGetItemAccessor(getItemState)));
|
|
43
37
|
}
|
|
44
38
|
const useMemoizedProplessComponent = (node) => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
// biome-ignore lint/correctness/useExhaustiveDependencies: optimization
|
|
55
|
-
useMemo(() => el, [resultType, resultKey, resultProps]) ?? node);
|
|
39
|
+
const el = typeof node === "object" && node != null && "type" in node ? node : null;
|
|
40
|
+
const resultType = el?.type;
|
|
41
|
+
const resultKey = el?.key;
|
|
42
|
+
return useMemo(() => el, [
|
|
43
|
+
resultType,
|
|
44
|
+
resultKey,
|
|
45
|
+
typeof el?.props === "object" && el.props != null && Object.entries(el.props).length === 0 ? EMPTY_OBJECT : el?.props
|
|
46
|
+
]) ?? node;
|
|
56
47
|
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { RenderChildrenWithAccessor, useGetItemAccessor };
|
|
50
|
+
|
|
57
51
|
//# sourceMappingURL=RenderChildrenWithAccessor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RenderChildrenWithAccessor.js","
|
|
1
|
+
{"version":3,"file":"RenderChildrenWithAccessor.js","names":[],"sources":["../src/RenderChildrenWithAccessor.tsx"],"sourcesContent":["\"use client\";\n\nimport { type ReactNode, useMemo, useRef } from \"react\";\nimport type { AssistantClient } from \"./types/client\";\nimport { useAuiState } from \"./useAuiState\";\nimport { useAui } from \"./useAui\";\n\nexport const useGetItemAccessor = <T,>(\n getItemState: (aui: AssistantClient) => T,\n) => {\n const aui = useAui();\n\n // Track access with a dedicated flag:\n // useSyncExternalStore may call getSnapshot() after commit (tearing checks),\n // which would re-cache the current state and mask later real updates.\n // Use the current state as the pre-access snapshot so the post-commit check\n // matches getItemState(aui) and doesn't schedule an unnecessary re-render.\n const accessedRef = useRef(false);\n const currentValue = accessedRef.current ? null : getItemState(aui);\n useAuiState(() => {\n if (!accessedRef.current) return currentValue;\n return getItemState(aui);\n });\n\n return () => {\n accessedRef.current = true;\n return getItemState(aui);\n };\n};\n\nconst EMPTY_OBJECT = Object.freeze({});\n\n/**\n * Component that sets up a lazy item accessor and memoizes propless children.\n *\n * For the common pattern where children returns a component without props\n * (e.g. `<Foo />`), the output is memoized and not re-created on parent re-renders.\n *\n * @example\n * ```tsx\n * <RenderChildrenWithAccessor\n * getItemState={(aui) => aui.fooList().foo({ index }).getState()}\n * >\n * {() => <Foo />}\n * </RenderChildrenWithAccessor>\n * ```\n */\nexport function RenderChildrenWithAccessor<T>({\n getItemState,\n children,\n}: {\n getItemState: (aui: AssistantClient) => T;\n children: (getItem: () => T) => ReactNode;\n}): ReactNode {\n const getItem = useGetItemAccessor(getItemState);\n return useMemoizedProplessComponent(children(getItem));\n}\n\nconst useMemoizedProplessComponent = (node: ReactNode) => {\n const el =\n typeof node === \"object\" && node != null && \"type\" in node ? node : null;\n const resultType = el?.type;\n const resultKey = el?.key;\n const resultProps =\n typeof el?.props === \"object\" &&\n el.props != null &&\n Object.entries(el.props).length === 0\n ? EMPTY_OBJECT\n : el?.props;\n\n return (\n // biome-ignore lint/correctness/useExhaustiveDependencies: optimization\n useMemo(() => el, [resultType, resultKey, resultProps]) ?? node\n );\n};\n"],"mappings":";;;;;AAOA,MAAa,sBACX,iBACG;CACH,MAAM,MAAM,OAAO;CAOnB,MAAM,cAAc,OAAO,KAAK;CAChC,MAAM,eAAe,YAAY,UAAU,OAAO,aAAa,GAAG;CAClE,kBAAkB;EAChB,IAAI,CAAC,YAAY,SAAS,OAAO;EACjC,OAAO,aAAa,GAAG;CACzB,CAAC;CAED,aAAa;EACX,YAAY,UAAU;EACtB,OAAO,aAAa,GAAG;CACzB;AACF;AAEA,MAAM,eAAe,OAAO,OAAO,CAAC,CAAC;;;;;;;;;;;;;;;;AAiBrC,SAAgB,2BAA8B,EAC5C,cACA,YAIY;CAEZ,OAAO,6BAA6B,SADpB,mBAAmB,YACgB,CAAC,CAAC;AACvD;AAEA,MAAM,gCAAgC,SAAoB;CACxD,MAAM,KACJ,OAAO,SAAS,YAAY,QAAQ,QAAQ,UAAU,OAAO,OAAO;CACtE,MAAM,aAAa,IAAI;CACvB,MAAM,YAAY,IAAI;CAQtB,OAEE,cAAc,IAAI;EAAC;EAAY;EAR/B,OAAO,IAAI,UAAU,YACrB,GAAG,SAAS,QACZ,OAAO,QAAQ,GAAG,KAAK,EAAE,WAAW,IAChC,eACA,IAAI;CAI6C,CAAC,KAAK;AAE/D"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
1
|
+
import { AssistantClient, ClientElement, ClientNames } from "./types/client.js";
|
|
2
|
+
import { DerivedElement } from "./Derived.js";
|
|
3
|
+
import { ResourceElement } from "@assistant-ui/tap";
|
|
4
|
+
|
|
5
|
+
//#region src/attachTransformScopes.d.ts
|
|
6
|
+
type ScopesConfig = { [K in ClientNames]?: ClientElement<K> | DerivedElement<K> };
|
|
7
7
|
type TransformScopesFn = (scopes: ScopesConfig, parent: AssistantClient) => void;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
declare function attachTransformScopes<T extends (...args: any[]) => ResourceElement<any>>(resource: T, transform: TransformScopesFn): void;
|
|
9
|
+
declare function forwardTransformScopes<T extends (...args: any[]) => ResourceElement<any>, S extends (...args: any[]) => ResourceElement<any>>(target: T, source: S): void;
|
|
10
|
+
declare function getTransformScopes<T extends (...args: any[]) => ResourceElement<any>>(resource: T): TransformScopesFn | undefined;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { ScopesConfig, attachTransformScopes, forwardTransformScopes, getTransformScopes };
|
|
12
13
|
//# sourceMappingURL=attachTransformScopes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachTransformScopes.d.ts","
|
|
1
|
+
{"version":3,"file":"attachTransformScopes.d.ts","names":[],"sources":["../src/attachTransformScopes.ts"],"mappings":";;;;;KAUY,YAAA,WACJ,WAAA,IAAe,aAAA,CAAc,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA,KAGpD,iBAAA,IACH,MAAA,EAAQ,YAAA,EACR,MAAA,EAAQ,eAAe;AAAA,iBAOT,qBAAA,eACA,IAAA,YAAgB,eAAA,MAAA,CAC9B,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,iBAAA;AAAA,iBAQV,sBAAA,eACA,IAAA,YAAgB,eAAA,qBAChB,IAAA,YAAgB,eAAA,MAAA,CAC9B,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAA,iBAgBL,kBAAA,eACA,IAAA,YAAgB,eAAA,MAAA,CAC9B,QAAA,EAAU,CAAA,GAAI,iBAAA"}
|
|
@@ -1,28 +1,25 @@
|
|
|
1
|
+
//#region src/attachTransformScopes.ts
|
|
1
2
|
const TRANSFORM_SCOPES = Symbol("assistant-ui.transform-scopes");
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
r[TRANSFORM_SCOPES] = transform;
|
|
3
|
+
function attachTransformScopes(resource, transform) {
|
|
4
|
+
const r = resource;
|
|
5
|
+
if (r[TRANSFORM_SCOPES]) throw new Error("transformScopes is already attached to this resource");
|
|
6
|
+
r[TRANSFORM_SCOPES] = transform;
|
|
8
7
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
r[TRANSFORM_SCOPES] = sourceTransform;
|
|
23
|
-
}
|
|
8
|
+
function forwardTransformScopes(target, source) {
|
|
9
|
+
const sourceTransform = getTransformScopes(source);
|
|
10
|
+
if (!sourceTransform) return;
|
|
11
|
+
const r = target;
|
|
12
|
+
const existingTransform = r[TRANSFORM_SCOPES];
|
|
13
|
+
if (existingTransform) r[TRANSFORM_SCOPES] = (scopes, parent) => {
|
|
14
|
+
sourceTransform(scopes, parent);
|
|
15
|
+
existingTransform(scopes, parent);
|
|
16
|
+
};
|
|
17
|
+
else r[TRANSFORM_SCOPES] = sourceTransform;
|
|
24
18
|
}
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
function getTransformScopes(resource) {
|
|
20
|
+
return resource[TRANSFORM_SCOPES];
|
|
27
21
|
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { attachTransformScopes, forwardTransformScopes, getTransformScopes };
|
|
24
|
+
|
|
28
25
|
//# sourceMappingURL=attachTransformScopes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachTransformScopes.js","
|
|
1
|
+
{"version":3,"file":"attachTransformScopes.js","names":[],"sources":["../src/attachTransformScopes.ts"],"sourcesContent":["import type { ResourceElement } from \"@assistant-ui/tap\";\nimport type {\n AssistantClient,\n ClientElement,\n ClientNames,\n} from \"./types/client\";\nimport type { DerivedElement } from \"./Derived\";\n\nconst TRANSFORM_SCOPES = Symbol(\"assistant-ui.transform-scopes\");\n\nexport type ScopesConfig = {\n [K in ClientNames]?: ClientElement<K> | DerivedElement<K>;\n};\n\ntype TransformScopesFn = (\n scopes: ScopesConfig,\n parent: AssistantClient,\n) => void;\n\ntype ResourceWithTransformScopes = {\n [TRANSFORM_SCOPES]?: TransformScopesFn;\n};\n\nexport function attachTransformScopes<\n T extends (...args: any[]) => ResourceElement<any>,\n>(resource: T, transform: TransformScopesFn): void {\n const r = resource as T & ResourceWithTransformScopes;\n if (r[TRANSFORM_SCOPES]) {\n throw new Error(\"transformScopes is already attached to this resource\");\n }\n r[TRANSFORM_SCOPES] = transform;\n}\n\nexport function forwardTransformScopes<\n T extends (...args: any[]) => ResourceElement<any>,\n S extends (...args: any[]) => ResourceElement<any>,\n>(target: T, source: S): void {\n const sourceTransform = getTransformScopes(source);\n if (!sourceTransform) return;\n\n const r = target as T & ResourceWithTransformScopes;\n const existingTransform = r[TRANSFORM_SCOPES];\n if (existingTransform) {\n r[TRANSFORM_SCOPES] = (scopes, parent) => {\n sourceTransform(scopes, parent);\n existingTransform(scopes, parent);\n };\n } else {\n r[TRANSFORM_SCOPES] = sourceTransform;\n }\n}\n\nexport function getTransformScopes<\n T extends (...args: any[]) => ResourceElement<any>,\n>(resource: T): TransformScopesFn | undefined {\n return (resource as T & ResourceWithTransformScopes)[TRANSFORM_SCOPES];\n}\n"],"mappings":";AAQA,MAAM,mBAAmB,OAAO,+BAA+B;AAe/D,SAAgB,sBAEd,UAAa,WAAoC;CACjD,MAAM,IAAI;CACV,IAAI,EAAE,mBACJ,MAAM,IAAI,MAAM,sDAAsD;CAExE,EAAE,oBAAoB;AACxB;AAEA,SAAgB,uBAGd,QAAW,QAAiB;CAC5B,MAAM,kBAAkB,mBAAmB,MAAM;CACjD,IAAI,CAAC,iBAAiB;CAEtB,MAAM,IAAI;CACV,MAAM,oBAAoB,EAAE;CAC5B,IAAI,mBACF,EAAE,qBAAqB,QAAQ,WAAW;EACxC,gBAAgB,QAAQ,MAAM;EAC9B,kBAAkB,QAAQ,MAAM;CAClC;MAEA,EAAE,oBAAoB;AAE1B;AAEA,SAAgB,mBAEd,UAA4C;CAC5C,OAAQ,SAA6C;AACvD"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export {
|
|
16
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
import { AssistantEventCallback, AssistantEventName, AssistantEventPayload, AssistantEventScope, AssistantEventSelector, normalizeEventSelector } from "./types/events.js";
|
|
2
|
+
import { AssistantClient, AssistantClientAccessor, AssistantState, ClientElement, ClientEvents, ClientMeta, ClientMethods, ClientNames, ClientOutput, ClientSchema, ScopeRegistry, Unsubscribe } from "./types/client.js";
|
|
3
|
+
import { AuiIf } from "./AuiIf.js";
|
|
4
|
+
import { Derived } from "./Derived.js";
|
|
5
|
+
import { RenderChildrenWithAccessor } from "./RenderChildrenWithAccessor.js";
|
|
6
|
+
import { ScopesConfig, attachTransformScopes, forwardTransformScopes } from "./attachTransformScopes.js";
|
|
7
|
+
import { useAui } from "./useAui.js";
|
|
8
|
+
import { useAuiState } from "./useAuiState.js";
|
|
9
|
+
import { useAuiEvent } from "./useAuiEvent.js";
|
|
10
|
+
import { AuiProvider } from "./utils/react-assistant-context.js";
|
|
11
|
+
import { tapAssistantClientRef, tapAssistantEmit } from "./utils/tap-assistant-context.js";
|
|
12
|
+
import { tapClientResource } from "./tapClientResource.js";
|
|
13
|
+
import { tapClientLookup } from "./tapClientLookup.js";
|
|
14
|
+
import { tapClientList } from "./tapClientList.js";
|
|
15
|
+
export { type AssistantClient, type AssistantClientAccessor, type AssistantEventCallback, type AssistantEventName, type AssistantEventPayload, type AssistantEventScope, type AssistantEventSelector, type AssistantState, AuiIf, AuiProvider, type ClientElement, type ClientEvents, type ClientMeta, type ClientMethods, type ClientNames, type ClientOutput, type ClientSchema, Derived, RenderChildrenWithAccessor, type ScopeRegistry, type ScopesConfig, type Unsubscribe, attachTransformScopes, forwardTransformScopes, normalizeEventSelector, tapAssistantClientRef, tapAssistantEmit, tapClientList, tapClientLookup, tapClientResource, useAui, useAuiEvent, useAuiState };
|