@assistant-ui/store 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ import { type ReactNode } from "react";
2
+ import type { AssistantClient } from "./types/client.js";
3
+ export declare const useGetItemAccessor: <T>(getItemState: (aui: AssistantClient) => T) => () => T;
4
+ /**
5
+ * Component that sets up a lazy item accessor and memoizes propless children.
6
+ *
7
+ * For the common pattern where children returns a component without props
8
+ * (e.g. `<Foo />`), the output is memoized and not re-created on parent re-renders.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <RenderChildrenWithAccessor
13
+ * getItemState={(aui) => aui.fooList().foo({ index }).getState()}
14
+ * >
15
+ * {() => <Foo />}
16
+ * </RenderChildrenWithAccessor>
17
+ * ```
18
+ */
19
+ export declare function RenderChildrenWithAccessor<T>({ getItemState, children, }: {
20
+ getItemState: (aui: AssistantClient) => T;
21
+ children: (getItem: () => T) => ReactNode;
22
+ }): ReactNode;
23
+ //# sourceMappingURL=RenderChildrenWithAccessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderChildrenWithAccessor.d.ts","sourceRoot":"","sources":["../src/RenderChildrenWithAccessor.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,OAAO,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,0BAAuB;AAItD,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAClC,cAAc,CAAC,GAAG,EAAE,eAAe,KAAK,CAAC,YAkB1C,CAAC;AAIF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,EAC5C,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,CAAC,CAAC;IAC1C,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,SAAS,CAAC;CAC3C,GAAG,SAAS,CAGZ"}
@@ -0,0 +1,53 @@
1
+ "use client";
2
+ import { useMemo, useRef } from "react";
3
+ import { useAuiState } from "./useAuiState.js";
4
+ import { useAui } from "./useAui.js";
5
+ export const useGetItemAccessor = (getItemState) => {
6
+ const aui = useAui();
7
+ // if the consumer never accesses the item, do not trigger rerenders
8
+ const cacheRef = useRef(undefined);
9
+ useAuiState(() => {
10
+ if (cacheRef.current === undefined) {
11
+ cacheRef.current = getItemState(aui);
12
+ }
13
+ return cacheRef.current;
14
+ });
15
+ return () => {
16
+ cacheRef.current = undefined; // clear the cache (rerender on next state change)
17
+ return getItemState(aui);
18
+ };
19
+ };
20
+ const EMPTY_OBJECT = Object.freeze({});
21
+ /**
22
+ * Component that sets up a lazy item accessor and memoizes propless children.
23
+ *
24
+ * For the common pattern where children returns a component without props
25
+ * (e.g. `<Foo />`), the output is memoized and not re-created on parent re-renders.
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <RenderChildrenWithAccessor
30
+ * getItemState={(aui) => aui.fooList().foo({ index }).getState()}
31
+ * >
32
+ * {() => <Foo />}
33
+ * </RenderChildrenWithAccessor>
34
+ * ```
35
+ */
36
+ export function RenderChildrenWithAccessor({ getItemState, children, }) {
37
+ const getItem = useGetItemAccessor(getItemState);
38
+ return useMemoizedProplessComponent(children(getItem));
39
+ }
40
+ const useMemoizedProplessComponent = (node) => {
41
+ const el = typeof node === "object" && node != null && "type" in node ? node : null;
42
+ const resultType = el?.type;
43
+ const resultKey = el?.key;
44
+ const resultProps = typeof el?.props === "object" &&
45
+ el.props != null &&
46
+ Object.entries(el.props).length === 0
47
+ ? EMPTY_OBJECT
48
+ : el?.props;
49
+ return (
50
+ // biome-ignore lint/correctness/useExhaustiveDependencies: optimization
51
+ useMemo(() => el, [resultType, resultKey, resultProps]) ?? node);
52
+ };
53
+ //# sourceMappingURL=RenderChildrenWithAccessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RenderChildrenWithAccessor.js","sourceRoot":"","sources":["../src/RenderChildrenWithAccessor.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAkB,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAExD,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,MAAM,EAAE,oBAAiB;AAElC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,YAAyC,EACzC,EAAE;IACF,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;IAErB,oEAAoE;IACpE,MAAM,QAAQ,GAAG,MAAM,CAAgB,SAAS,CAAC,CAAC;IAClD,WAAW,CAAC,GAAG,EAAE;QACf,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,QAAQ,CAAC,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE;QACV,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,kDAAkD;QAEhF,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0BAA0B,CAAI,EAC5C,YAAY,EACZ,QAAQ,GAIT;IACC,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IACjD,OAAO,4BAA4B,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,4BAA4B,GAAG,CAAC,IAAe,EAAE,EAAE;IACvD,MAAM,EAAE,GACN,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3E,MAAM,UAAU,GAAG,EAAE,EAAE,IAAI,CAAC;IAC5B,MAAM,SAAS,GAAG,EAAE,EAAE,GAAG,CAAC;IAC1B,MAAM,WAAW,GACf,OAAO,EAAE,EAAE,KAAK,KAAK,QAAQ;QAC7B,EAAE,CAAC,KAAK,IAAI,IAAI;QAChB,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;QACnC,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC;IAEhB,OAAO;IACL,wEAAwE;IACxE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,IAAI,IAAI,CAChE,CAAC;AACJ,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { useAui } from "./useAui.js";
2
2
  export { useAuiState } from "./useAuiState.js";
3
3
  export { useAuiEvent } from "./useAuiEvent.js";
4
+ export { RenderChildrenWithAccessor } from "./RenderChildrenWithAccessor.js";
4
5
  export { AuiIf } from "./AuiIf.js";
5
6
  export { AuiProvider } from "./utils/react-assistant-context.js";
6
7
  export { Derived } from "./Derived.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,oBAAiB;AAClC,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAG5C,OAAO,EAAE,KAAK,EAAE,mBAAgB;AAChC,OAAO,EAAE,WAAW,EAAE,2CAAwC;AAG9D,OAAO,EAAE,OAAO,EAAE,qBAAkB;AACpC,OAAO,EAAE,qBAAqB,EAAE,mCAAgC;AAChE,YAAY,EAAE,YAAY,EAAE,mCAAgC;AAG5D,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GACjB,yCAAsC;AACvC,OAAO,EAAE,iBAAiB,EAAE,+BAA4B;AACxD,OAAO,EAAE,eAAe,EAAE,6BAA0B;AACpD,OAAO,EAAE,aAAa,EAAE,2BAAwB;AAGhD,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,eAAe,EACf,cAAc,GACf,0BAAuB;AACxB,OAAO,EACL,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,0BAAuB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,oBAAiB;AAClC,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,0BAA0B,EAAE,wCAAqC;AAG1E,OAAO,EAAE,KAAK,EAAE,mBAAgB;AAChC,OAAO,EAAE,WAAW,EAAE,2CAAwC;AAG9D,OAAO,EAAE,OAAO,EAAE,qBAAkB;AACpC,OAAO,EAAE,qBAAqB,EAAE,mCAAgC;AAChE,YAAY,EAAE,YAAY,EAAE,mCAAgC;AAG5D,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GACjB,yCAAsC;AACvC,OAAO,EAAE,iBAAiB,EAAE,+BAA4B;AACxD,OAAO,EAAE,eAAe,EAAE,6BAA0B;AACpD,OAAO,EAAE,aAAa,EAAE,2BAAwB;AAGhD,YAAY,EACV,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,UAAU,EACV,aAAa,EACb,WAAW,EACX,uBAAuB,EACvB,eAAe,EACf,cAAc,GACf,0BAAuB;AACxB,OAAO,EACL,sBAAsB,EACtB,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,0BAAuB"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  export { useAui } from "./useAui.js";
3
3
  export { useAuiState } from "./useAuiState.js";
4
4
  export { useAuiEvent } from "./useAuiEvent.js";
5
+ export { RenderChildrenWithAccessor } from "./RenderChildrenWithAccessor.js";
5
6
  // components
6
7
  export { AuiIf } from "./AuiIf.js";
7
8
  export { AuiProvider } from "./utils/react-assistant-context.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,MAAM,EAAE,oBAAiB;AAClC,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAE5C,aAAa;AACb,OAAO,EAAE,KAAK,EAAE,mBAAgB;AAChC,OAAO,EAAE,WAAW,EAAE,2CAAwC;AAE9D,YAAY;AACZ,OAAO,EAAE,OAAO,EAAE,qBAAkB;AACpC,OAAO,EAAE,qBAAqB,EAAE,mCAAgC;AAGhE,YAAY;AACZ,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GACjB,yCAAsC;AACvC,OAAO,EAAE,iBAAiB,EAAE,+BAA4B;AACxD,OAAO,EAAE,eAAe,EAAE,6BAA0B;AACpD,OAAO,EAAE,aAAa,EAAE,2BAAwB;AAiBhD,OAAO,EACL,sBAAsB,GAMvB,0BAAuB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,MAAM,EAAE,oBAAiB;AAClC,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,WAAW,EAAE,yBAAsB;AAC5C,OAAO,EAAE,0BAA0B,EAAE,wCAAqC;AAE1E,aAAa;AACb,OAAO,EAAE,KAAK,EAAE,mBAAgB;AAChC,OAAO,EAAE,WAAW,EAAE,2CAAwC;AAE9D,YAAY;AACZ,OAAO,EAAE,OAAO,EAAE,qBAAkB;AACpC,OAAO,EAAE,qBAAqB,EAAE,mCAAgC;AAGhE,YAAY;AACZ,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GACjB,yCAAsC;AACvC,OAAO,EAAE,iBAAiB,EAAE,+BAA4B;AACxD,OAAO,EAAE,eAAe,EAAE,6BAA0B;AACpD,OAAO,EAAE,aAAa,EAAE,2BAAwB;AAiBhD,OAAO,EACL,sBAAsB,GAMvB,0BAAuB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/store",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Tap-based state management for @assistant-ui",
5
5
  "keywords": [
6
6
  "state-management",
@@ -31,7 +31,7 @@
31
31
  "use-effect-event": "^2.0.3"
32
32
  },
33
33
  "peerDependencies": {
34
- "@assistant-ui/tap": "^0.5.2",
34
+ "@assistant-ui/tap": "^0.5.3",
35
35
  "@types/react": "*",
36
36
  "react": "^18 || ^19"
37
37
  },
@@ -46,9 +46,9 @@
46
46
  "@types/react-dom": "^19.2.3",
47
47
  "jsdom": "^28.1.0",
48
48
  "react": "^19.2.4",
49
- "vitest": "^4.0.18",
50
- "@assistant-ui/tap": "0.5.2",
51
- "@assistant-ui/x-buildutils": "0.0.1"
49
+ "vitest": "^4.1.0",
50
+ "@assistant-ui/tap": "0.5.3",
51
+ "@assistant-ui/x-buildutils": "0.0.3"
52
52
  },
53
53
  "publishConfig": {
54
54
  "access": "public",
@@ -0,0 +1,73 @@
1
+ "use client";
2
+
3
+ import { type ReactNode, useMemo, useRef } from "react";
4
+ import type { AssistantClient } from "./types/client";
5
+ import { useAuiState } from "./useAuiState";
6
+ import { useAui } from "./useAui";
7
+
8
+ export const useGetItemAccessor = <T,>(
9
+ getItemState: (aui: AssistantClient) => T,
10
+ ) => {
11
+ const aui = useAui();
12
+
13
+ // if the consumer never accesses the item, do not trigger rerenders
14
+ const cacheRef = useRef<T | undefined>(undefined);
15
+ useAuiState(() => {
16
+ if (cacheRef.current === undefined) {
17
+ cacheRef.current = getItemState(aui);
18
+ }
19
+ return cacheRef.current;
20
+ });
21
+
22
+ return () => {
23
+ cacheRef.current = undefined; // clear the cache (rerender on next state change)
24
+
25
+ return getItemState(aui);
26
+ };
27
+ };
28
+
29
+ const EMPTY_OBJECT = Object.freeze({});
30
+
31
+ /**
32
+ * Component that sets up a lazy item accessor and memoizes propless children.
33
+ *
34
+ * For the common pattern where children returns a component without props
35
+ * (e.g. `<Foo />`), the output is memoized and not re-created on parent re-renders.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * <RenderChildrenWithAccessor
40
+ * getItemState={(aui) => aui.fooList().foo({ index }).getState()}
41
+ * >
42
+ * {() => <Foo />}
43
+ * </RenderChildrenWithAccessor>
44
+ * ```
45
+ */
46
+ export function RenderChildrenWithAccessor<T>({
47
+ getItemState,
48
+ children,
49
+ }: {
50
+ getItemState: (aui: AssistantClient) => T;
51
+ children: (getItem: () => T) => ReactNode;
52
+ }): ReactNode {
53
+ const getItem = useGetItemAccessor(getItemState);
54
+ return useMemoizedProplessComponent(children(getItem));
55
+ }
56
+
57
+ const useMemoizedProplessComponent = (node: ReactNode) => {
58
+ const el =
59
+ typeof node === "object" && node != null && "type" in node ? node : null;
60
+ const resultType = el?.type;
61
+ const resultKey = el?.key;
62
+ const resultProps =
63
+ typeof el?.props === "object" &&
64
+ el.props != null &&
65
+ Object.entries(el.props).length === 0
66
+ ? EMPTY_OBJECT
67
+ : el?.props;
68
+
69
+ return (
70
+ // biome-ignore lint/correctness/useExhaustiveDependencies: optimization
71
+ useMemo(() => el, [resultType, resultKey, resultProps]) ?? node
72
+ );
73
+ };
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  export { useAui } from "./useAui";
3
3
  export { useAuiState } from "./useAuiState";
4
4
  export { useAuiEvent } from "./useAuiEvent";
5
+ export { RenderChildrenWithAccessor } from "./RenderChildrenWithAccessor";
5
6
 
6
7
  // components
7
8
  export { AuiIf } from "./AuiIf";