@assistant-ui/store
Advanced tools
@@ -1,1 +0,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"} | ||
| {"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,OAC9B,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,iBAAA;AAAA,iBAQV,sBAAA,eACA,IAAA,YAAgB,eAAA,qBAChB,IAAA,YAAgB,eAAA,OAC9B,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA;AAAA,iBAgBL,kBAAA,eACA,IAAA,YAAgB,eAAA,OAC9B,QAAA,EAAU,CAAA,GAAI,iBAAA"} |
@@ -1,1 +0,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"} | ||
| {"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;EACd,YAAA;EACA;AAAA;EAEA,YAAA,GAAe,GAAA,EAAK,eAAA,KAAoB,CAAA;EACxC,QAAA,GAAW,OAAA,QAAe,CAAA,KAAM,SAAA;AAAA,IAC9B,SAAA"} |
@@ -1,1 +0,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"} | ||
| {"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 // oxlint-disable-next-line tap-hooks/exhaustive-deps -- memo over decomposed fields so we don't bust on a fresh `el` object each render\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,1 +0,1 @@ | ||
| {"version":3,"file":"tapClientLookup.d.ts","names":[],"sources":["../src/tapClientLookup.ts"],"mappings":";;;;KAUK,gBAAA,aAA6B,QAAQ;EACxC,QAAA;AAAA,IAEE,CAAA;AAAA,iBAgBY,eAAA,kBAAiC,aAAA,CAAA,CAC/C,WAAA,iBAA4B,eAAA,CAAgB,QAAA,KAC5C,eAAA;EAEA,KAAA,EAAO,gBAAA,CAAiB,QAAA;EACxB,GAAA,GAAM,MAAA;IAAU,KAAA;EAAA;IAAoB,GAAA;EAAA,MAAkB,QAAA;AAAA"} | ||
| {"version":3,"file":"tapClientLookup.d.ts","names":[],"sources":["../src/tapClientLookup.ts"],"mappings":";;;;KAUK,gBAAA,aAA6B,QAAQ;EACxC,QAAA;AAAA,IAEE,CAAA;AAAA,iBAgBY,eAAA,kBAAiC,aAAA,EAC/C,WAAA,iBAA4B,eAAA,CAAgB,QAAA,KAC5C,eAAA;EAEA,KAAA,EAAO,gBAAA,CAAiB,QAAA;EACxB,GAAA,GAAM,MAAA;IAAU,KAAA;EAAA;IAAoB,GAAA;EAAA,MAAkB,QAAA;AAAA"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"tapClientLookup.js","names":[],"sources":["../src/tapClientLookup.ts"],"sourcesContent":["import {\n tapMemo,\n tapResource,\n tapResources,\n type ResourceElement,\n} from \"@assistant-ui/tap\";\nimport type { ClientMethods } from \"./types/client\";\nimport { ClientResource } from \"./tapClientResource\";\nimport { wrapperResource } from \"./wrapperResource\";\n\ntype InferClientState<TMethods> = TMethods extends {\n getState: () => infer S;\n}\n ? S\n : unknown;\n\nconst ClientResourceWithKey = wrapperResource(\n <TMethods extends ClientMethods>(el: ResourceElement<TMethods>) => {\n if (el.key === undefined) {\n throw new Error(\"tapClientResource: Element has no key\");\n }\n return tapResource(ClientResource(el)) as {\n methods: TMethods;\n state: InferClientState<TMethods>;\n key: string | number;\n };\n },\n);\n\nexport function tapClientLookup<TMethods extends ClientMethods>(\n getElements: () => readonly ResourceElement<TMethods>[],\n getElementsDeps: readonly unknown[],\n): {\n state: InferClientState<TMethods>[];\n get: (lookup: { index: number } | { key: string }) => TMethods;\n} {\n const resources = tapResources(\n () => getElements().map((el) => ClientResourceWithKey(el)),\n // biome-ignore lint/correctness/useExhaustiveDependencies: getElementsDeps is passed through from caller\n getElementsDeps,\n );\n\n const keys = tapMemo(() => Object.keys(resources), [resources]);\n\n // For arrays, track element key -> index mapping\n const keyToIndex = tapMemo(() => {\n return resources.reduce(\n (acc, resource, index) => {\n acc[resource.key] = index;\n return acc;\n },\n {} as Record<string, number>,\n );\n }, [resources]);\n\n const state = tapMemo(() => {\n return resources.map((r) => r.state);\n }, [resources]);\n\n return {\n state,\n get: (lookup: { index: number } | { key: string }) => {\n if (\"index\" in lookup) {\n if (lookup.index < 0 || lookup.index >= keys.length) {\n throw new Error(\n `tapClientLookup: Index ${lookup.index} out of bounds (length: ${keys.length})`,\n );\n }\n return resources[lookup.index]!.methods;\n }\n\n const index = keyToIndex[lookup.key];\n if (index === undefined) {\n throw new Error(`tapClientLookup: Key \"${lookup.key}\" not found`);\n }\n return resources[index]!.methods;\n },\n };\n}\n"],"mappings":";;;;AAgBA,MAAM,wBAAwB,iBACK,OAAkC;CACjE,IAAI,GAAG,QAAQ,KAAA,GACb,MAAM,IAAI,MAAM,uCAAuC;CAEzD,OAAO,YAAY,eAAe,EAAE,CAAC;AAKvC,CACF;AAEA,SAAgB,gBACd,aACA,iBAIA;CACA,MAAM,YAAY,mBACV,YAAY,EAAE,KAAK,OAAO,sBAAsB,EAAE,CAAC,GAEzD,eACF;CAEA,MAAM,OAAO,cAAc,OAAO,KAAK,SAAS,GAAG,CAAC,SAAS,CAAC;CAG9D,MAAM,aAAa,cAAc;EAC/B,OAAO,UAAU,QACd,KAAK,UAAU,UAAU;GACxB,IAAI,SAAS,OAAO;GACpB,OAAO;EACT,GACA,CAAC,CACH;CACF,GAAG,CAAC,SAAS,CAAC;CAMd,OAAO;EACL,OALY,cAAc;GAC1B,OAAO,UAAU,KAAK,MAAM,EAAE,KAAK;EACrC,GAAG,CAAC,SAAS,CAGP;EACJ,MAAM,WAAgD;GACpD,IAAI,WAAW,QAAQ;IACrB,IAAI,OAAO,QAAQ,KAAK,OAAO,SAAS,KAAK,QAC3C,MAAM,IAAI,MACR,0BAA0B,OAAO,MAAM,0BAA0B,KAAK,OAAO,EAC/E;IAEF,OAAO,UAAU,OAAO,OAAQ;GAClC;GAEA,MAAM,QAAQ,WAAW,OAAO;GAChC,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,yBAAyB,OAAO,IAAI,YAAY;GAElE,OAAO,UAAU,OAAQ;EAC3B;CACF;AACF"} | ||
| {"version":3,"file":"tapClientLookup.js","names":[],"sources":["../src/tapClientLookup.ts"],"sourcesContent":["import {\n tapMemo,\n tapResource,\n tapResources,\n type ResourceElement,\n} from \"@assistant-ui/tap\";\nimport type { ClientMethods } from \"./types/client\";\nimport { ClientResource } from \"./tapClientResource\";\nimport { wrapperResource } from \"./wrapperResource\";\n\ntype InferClientState<TMethods> = TMethods extends {\n getState: () => infer S;\n}\n ? S\n : unknown;\n\nconst ClientResourceWithKey = wrapperResource(\n <TMethods extends ClientMethods>(el: ResourceElement<TMethods>) => {\n if (el.key === undefined) {\n throw new Error(\"tapClientResource: Element has no key\");\n }\n return tapResource(ClientResource(el)) as {\n methods: TMethods;\n state: InferClientState<TMethods>;\n key: string | number;\n };\n },\n);\n\nexport function tapClientLookup<TMethods extends ClientMethods>(\n getElements: () => readonly ResourceElement<TMethods>[],\n getElementsDeps: readonly unknown[],\n): {\n state: InferClientState<TMethods>[];\n get: (lookup: { index: number } | { key: string }) => TMethods;\n} {\n const resources = tapResources(\n () => getElements().map((el) => ClientResourceWithKey(el)),\n // oxlint-disable-next-line tap-hooks/exhaustive-deps -- caller-supplied deps array\n getElementsDeps,\n );\n\n const keys = tapMemo(() => Object.keys(resources), [resources]);\n\n // For arrays, track element key -> index mapping\n const keyToIndex = tapMemo(() => {\n return resources.reduce(\n (acc, resource, index) => {\n acc[resource.key] = index;\n return acc;\n },\n {} as Record<string, number>,\n );\n }, [resources]);\n\n const state = tapMemo(() => {\n return resources.map((r) => r.state);\n }, [resources]);\n\n return {\n state,\n get: (lookup: { index: number } | { key: string }) => {\n if (\"index\" in lookup) {\n if (lookup.index < 0 || lookup.index >= keys.length) {\n throw new Error(\n `tapClientLookup: Index ${lookup.index} out of bounds (length: ${keys.length})`,\n );\n }\n return resources[lookup.index]!.methods;\n }\n\n const index = keyToIndex[lookup.key];\n if (index === undefined) {\n throw new Error(`tapClientLookup: Key \"${lookup.key}\" not found`);\n }\n return resources[index]!.methods;\n },\n };\n}\n"],"mappings":";;;;AAgBA,MAAM,wBAAwB,iBACK,OAAkC;CACjE,IAAI,GAAG,QAAQ,KAAA,GACb,MAAM,IAAI,MAAM,uCAAuC;CAEzD,OAAO,YAAY,eAAe,EAAE,CAAC;AAKvC,CACF;AAEA,SAAgB,gBACd,aACA,iBAIA;CACA,MAAM,YAAY,mBACV,YAAY,EAAE,KAAK,OAAO,sBAAsB,EAAE,CAAC,GAEzD,eACF;CAEA,MAAM,OAAO,cAAc,OAAO,KAAK,SAAS,GAAG,CAAC,SAAS,CAAC;CAG9D,MAAM,aAAa,cAAc;EAC/B,OAAO,UAAU,QACd,KAAK,UAAU,UAAU;GACxB,IAAI,SAAS,OAAO;GACpB,OAAO;EACT,GACA,CAAC,CACH;CACF,GAAG,CAAC,SAAS,CAAC;CAMd,OAAO;EACL,OALY,cAAc;GAC1B,OAAO,UAAU,KAAK,MAAM,EAAE,KAAK;EACrC,GAAG,CAAC,SAAS,CAGP;EACJ,MAAM,WAAgD;GACpD,IAAI,WAAW,QAAQ;IACrB,IAAI,OAAO,QAAQ,KAAK,OAAO,SAAS,KAAK,QAC3C,MAAM,IAAI,MACR,0BAA0B,OAAO,MAAM,0BAA0B,KAAK,OAAO,EAC/E;IAEF,OAAO,UAAU,OAAO,OAAQ;GAClC;GAEA,MAAM,QAAQ,WAAW,OAAO;GAChC,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,yBAAyB,OAAO,IAAI,YAAY;GAElE,OAAO,UAAU,OAAQ;EAC3B;CACF;AACF"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"client.d.ts","names":[],"sources":["../../src/types/client.ts"],"mappings":";;;;;;AAUA;UAAiB,aAAA;EAAA,CACd,GAAA,wBAA2B,IAAI;AAAA;AAAA,KAG7B,cAAA;EAAmB,MAAA,EAAQ,WAAA;EAAa,KAAA,EAAO,MAAM;AAAA;;;;;;;AAAA;KAS9C,YAAA,kBACO,aAAA,GAAgB,aAAA,gBACnB,cAAA,0BACE,MAAA;EAEhB,OAAA,EAAS,QAAA;EACT,IAAA,GAAO,KAAA;EACP,MAAA,GAAS,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;AAAO;AAiClB;;;;AAA8B;AAAG;;UAAhB,aAAA;AAAA,KAEZ,gBAAA,WAA2B,WAAA,IAAe,MAAA,IAC1C,CAAA;AAAA,KAIA,WAAA;EACH,OAAA,EAAS,MAAA,CAAO,CAAA,QAAS,CAAA;EACzB,IAAA;IAAQ,MAAA,EAAQ,WAAA;IAAa,KAAA,EAAO,MAAA,CAAO,CAAA,EAAG,CAAA;EAAA;EAC9C,MAAA,EAAQ,MAAA,IAAU,CAAA,KAAM,CAAA;AAAA;AAAA,KAGrB,cAAA,iBAA+B,aAAA,IAAiB,aAAA,CAAc,CAAA;EACjE,OAAA,EAAS,aAAA;AAAA,yBAEc,aAAA,CAAc,CAAA,IACjC,aAAA,CAAc,CAAA,kBAAmB,cAAA,0BACR,aAAA,CAAc,CAAA,IACnC,aAAA,CAAc,CAAA,oBAAqB,gBAAA,CAAiB,CAAA,IAClD,aAAA,CAAc,CAAA,IACd,WAAA,WAAsB,CAAA,uCACxB,aAAA,CAAc,CAAA,IAChB,WAAA,WAAsB,CAAA,4DACD,aAAA,CAAc,CAAA,IACnC,aAAA,CAAc,CAAA,oBAAqB,gBAAA,CAAiB,CAAA,IAClD,aAAA,CAAc,CAAA,IACd,WAAA,WAAsB,CAAA,uCACxB,aAAA,CAAc,CAAA,IAClB,WAAA,WAAsB,CAAA;AAAA,KAErB,aAAA,SAAsB,aAAA;EAErB,gCAAA,EAAkC,WAAA;AAAA,kBAEtB,aAAA,GAAgB,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;KAgBrC,YAAA,WAAuB,WAAA,IAAe,aAAA,CAAc,CAAA,eAC9D,aAAA;AAAA,KAEU,WAAA,SAAoB,aAAa,mBAAmB,CAAA;AAAA,KAEpD,YAAA,WAAuB,WAAA,2BACV,aAAA,CAAc,CAAA,IACjC,aAAA,CAAc,CAAA,oBAAqB,gBAAA,CAAiB,CAAA,IAClD,aAAA,CAAc,CAAA;AAAA,KAIV,UAAA,WAAqB,WAAA,yBACV,aAAA,CAAc,CAAA,IAC/B,IAAA,CACE,aAAA,CAAc,CAAA,kBAAmB,cAAA,GAC7B,aAAA,CAAc,CAAA;AAAA,KAMd,aAAA,WAAwB,WAAA,IAAe,eAAA,CACjD,YAAA,CAAa,CAAA;;;;KAMH,WAAA;;;AAtEe;KA2Ef,cAAA,WACJ,WAAA,GAAc,aAAA,CAAc,CAAA;EAChC,QAAA;AAAA,IAEE,CAAA;;;;;KAQM,uBAAA,WAAkC,WAAA,WACrC,aAAA,CAAc,CAAA,iBAEf,UAAA,CAAW,CAAA;EACT,MAAA;EAAgB,KAAA,EAAO,MAAA;AAAA;EACvB,MAAA;EAAc,KAAA;AAAA;EACd,IAAA,EAAM,CAAA;AAAA;;;;KAKJ,eAAA,WACJ,WAAA,GAAc,uBAAA,CAAwB,CAAA;EAE5C,SAAA,CAAU,QAAA,eAAuB,WAAA;EACjC,EAAA,gBAAkB,kBAAA,EAChB,QAAA,EAAU,sBAAA,CAAuB,MAAA,GACjC,QAAA,EAAU,sBAAA,CAAuB,MAAA,IAChC,WAAA;AAAA"} | ||
| {"version":3,"file":"client.d.ts","names":[],"sources":["../../src/types/client.ts"],"mappings":";;;;;;AAUA;UAAiB,aAAA;EAAA,CACd,GAAA,wBAA2B,IAAI;AAAA;AAAA,KAG7B,cAAA;EAAmB,MAAA,EAAQ,WAAA;EAAa,KAAA,EAAO,MAAM;AAAA;;;;;;;AAAA;KAS9C,YAAA,kBACO,aAAA,GAAgB,aAAA,gBACnB,cAAA,0BACE,MAAA;EAEhB,OAAA,EAAS,QAAA;EACT,IAAA,GAAO,KAAA;EACP,MAAA,GAAS,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;AAAO;AAgClB;;;;AAA8B;AAAG;;UAAhB,aAAA;AAAA,KAEZ,gBAAA,WAA2B,WAAA,IAAe,MAAA,IAC1C,CAAA;AAAA,KAIA,WAAA;EACH,OAAA,EAAS,MAAA,CAAO,CAAA,QAAS,CAAA;EACzB,IAAA;IAAQ,MAAA,EAAQ,WAAA;IAAa,KAAA,EAAO,MAAA,CAAO,CAAA,EAAG,CAAA;EAAA;EAC9C,MAAA,EAAQ,MAAA,IAAU,CAAA,KAAM,CAAA;AAAA;AAAA,KAGrB,cAAA,iBAA+B,aAAA,IAAiB,aAAA,CAAc,CAAA;EACjE,OAAA,EAAS,aAAA;AAAA,yBAEc,aAAA,CAAc,CAAA,IACjC,aAAA,CAAc,CAAA,kBAAmB,cAAA,0BACR,aAAA,CAAc,CAAA,IACnC,aAAA,CAAc,CAAA,oBAAqB,gBAAA,CAAiB,CAAA,IAClD,aAAA,CAAc,CAAA,IACd,WAAA,WAAsB,CAAA,uCACxB,aAAA,CAAc,CAAA,IAChB,WAAA,WAAsB,CAAA,4DACD,aAAA,CAAc,CAAA,IACnC,aAAA,CAAc,CAAA,oBAAqB,gBAAA,CAAiB,CAAA,IAClD,aAAA,CAAc,CAAA,IACd,WAAA,WAAsB,CAAA,uCACxB,aAAA,CAAc,CAAA,IAClB,WAAA,WAAsB,CAAA;AAAA,KAErB,aAAA,SAAsB,aAAA;EAErB,gCAAA,EAAkC,WAAA;AAAA,kBAEtB,aAAA,GAAgB,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;KAgBrC,YAAA,WAAuB,WAAA,IAAe,aAAA,CAAc,CAAA,eAC9D,aAAA;AAAA,KAEU,WAAA,SAAoB,aAAa,mBAAmB,CAAA;AAAA,KAEpD,YAAA,WAAuB,WAAA,2BACV,aAAA,CAAc,CAAA,IACjC,aAAA,CAAc,CAAA,oBAAqB,gBAAA,CAAiB,CAAA,IAClD,aAAA,CAAc,CAAA;AAAA,KAIV,UAAA,WAAqB,WAAA,yBACV,aAAA,CAAc,CAAA,IAC/B,IAAA,CACE,aAAA,CAAc,CAAA,kBAAmB,cAAA,GAC7B,aAAA,CAAc,CAAA;AAAA,KAMd,aAAA,WAAwB,WAAA,IAAe,eAAA,CACjD,YAAA,CAAa,CAAA;;;;KAMH,WAAA;;;AAtEe;KA2Ef,cAAA,WACJ,WAAA,GAAc,aAAA,CAAc,CAAA;EAChC,QAAA;AAAA,IAEE,CAAA;;;;;KAQM,uBAAA,WAAkC,WAAA,WACrC,aAAA,CAAc,CAAA,iBAEf,UAAA,CAAW,CAAA;EACT,MAAA;EAAgB,KAAA,EAAO,MAAA;AAAA;EACvB,MAAA;EAAc,KAAA;AAAA;EACd,IAAA,EAAM,CAAA;AAAA;;;;KAKJ,eAAA,WACJ,WAAA,GAAc,uBAAA,CAAwB,CAAA;EAE5C,SAAA,CAAU,QAAA,eAAuB,WAAA;EACjC,EAAA,gBAAkB,kBAAA,EAChB,QAAA,EAAU,sBAAA,CAAuB,MAAA,GACjC,QAAA,EAAU,sBAAA,CAAuB,MAAA,IAChC,WAAA;AAAA"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"events.d.ts","names":[],"sources":["../../src/types/events.ts"],"mappings":";;;KAOK,mBAAA,OACH,CAAA,oBACK,CAAA,EAAG,CAAC,6BAEA,CAAA,sBACP,CAAA;AAAA,KAGC,cAAA,GAAiB,mBAAA,SACZ,WAAA,GAAc,YAAA,CAAa,CAAA,IAAK,WAAA;AAAA,KAKrC,eAAA,iBACS,cAAA;EAAmB,KAAA,EAAO,CAAA;EAAG,OAAA,EAAS,cAAA,CAAe,CAAA;AAAA,UAC3D,cAAA;AAAA,KAEI,qBAAA,GAAwB,cAAA;EAAmB,GAAA,EAAK,eAAe;AAAA;AAAA,KAE/D,kBAAA,SAA2B,qBAAqB;AAAA,KAEvD,WAAA,WAAsB,kBAAA,IACzB,CAAC,uCAAuC,MAAA;AAAA,KAIrC,QAAA,WAAmB,WAAA,IACtB,uBAAA,CAAwB,CAAA;EAAa,MAAA;AAAA,IACjC,CAAA,SAAU,WAAA,GACR,CAAA;AAAA,KAIH,WAAA,WACO,WAAA,eACG,WAAA,YACX,CAAA,SAAU,IAAA,WAEV,QAAA,CAAS,CAAA,0BAEP,QAAA,CAAS,CAAA,IAAK,WAAA,CAAY,QAAA,CAAS,CAAA,GAAI,IAAA,GAAO,CAAA;;KAGxC,mBAAA,gBAAmC,kBAAA,UAE3C,WAAA,CAAY,MAAA,KACX,WAAA,CAAY,MAAA,UAAgB,WAAA,GACzB,WAAA,CAAY,WAAA,CAAY,MAAA;AAAA,KAKpB,sBAAA,gBAAsC,kBAAA,IAC9C,MAAA;EACE,KAAA,EAAO,mBAAA,CAAoB,MAAA;EAAS,KAAA,EAAO,MAAA;AAAA;AAAA,cAEpC,sBAAA,kBAAyC,kBAAA,EACpD,QAAA,EAAU,sBAAA,CAAuB,MAAA;;;;KASvB,sBAAA,gBAAsC,kBAAA,KAChD,OAAA,EAAS,qBAAA,CAAsB,MAAA"} | ||
| {"version":3,"file":"events.d.ts","names":[],"sources":["../../src/types/events.ts"],"mappings":";;;KAOK,mBAAA,OACH,CAAA,oBAAqB,CAAA,EAAG,CAAC,6BAChB,CAAA,sBACP,CAAA;AAAA,KAGC,cAAA,GAAiB,mBAAA,SACZ,WAAA,GAAc,YAAA,CAAa,CAAA,IAAK,WAAA;AAAA,KAKrC,eAAA,iBACS,cAAA;EAAmB,KAAA,EAAO,CAAA;EAAG,OAAA,EAAS,cAAA,CAAe,CAAA;AAAA,UAC3D,cAAA;AAAA,KAEI,qBAAA,GAAwB,cAAA;EAAmB,GAAA,EAAK,eAAe;AAAA;AAAA,KAE/D,kBAAA,SAA2B,qBAAqB;AAAA,KAEvD,WAAA,WAAsB,kBAAA,IACzB,CAAC,uCAAuC,MAAA;AAAA,KAIrC,QAAA,WAAmB,WAAA,IACtB,uBAAA,CAAwB,CAAA;EAAa,MAAA;AAAA,IACjC,CAAA,SAAU,WAAA,GACR,CAAA;AAAA,KAIH,WAAA,WACO,WAAA,eACG,WAAA,YACX,CAAA,SAAU,IAAA,WAEV,QAAA,CAAS,CAAA,0BAEP,QAAA,CAAS,CAAA,IAAK,WAAA,CAAY,QAAA,CAAS,CAAA,GAAI,IAAA,GAAO,CAAA;;KAGxC,mBAAA,gBAAmC,kBAAA,UAE3C,WAAA,CAAY,MAAA,KACX,WAAA,CAAY,MAAA,UAAgB,WAAA,GACzB,WAAA,CAAY,WAAA,CAAY,MAAA;AAAA,KAKpB,sBAAA,gBAAsC,kBAAA,IAC9C,MAAA;EACE,KAAA,EAAO,mBAAA,CAAoB,MAAA;EAAS,KAAA,EAAO,MAAA;AAAA;AAAA,cAEpC,sBAAA,kBAAyC,kBAAA,EACpD,QAAA,EAAU,sBAAA,CAAuB,MAAA;;;;KASvB,sBAAA,gBAAsC,kBAAA,KAChD,OAAA,EAAS,qBAAA,CAAsB,MAAA"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"events.js","names":[],"sources":["../../src/types/events.ts"],"sourcesContent":["import type {\n AssistantClientAccessor,\n ClientEvents,\n ClientNames,\n} from \"./client\";\n\n// --- Event Map Construction ---\ntype UnionToIntersection<U> = (\n U extends unknown\n ? (x: U) => void\n : never\n) extends (x: infer I) => void\n ? I\n : never;\n\ntype ClientEventMap = UnionToIntersection<\n { [K in ClientNames]: ClientEvents<K> }[ClientNames]\n>;\n\n// --- Core Types ---\n\ntype WildcardPayload = {\n [K in keyof ClientEventMap]: { event: K; payload: ClientEventMap[K] };\n}[keyof ClientEventMap];\n\nexport type AssistantEventPayload = ClientEventMap & { \"*\": WildcardPayload };\n\nexport type AssistantEventName = keyof AssistantEventPayload;\n\ntype EventSource<T extends AssistantEventName> =\n T extends `${infer Source}.${string}` ? Source : never;\n\n// --- Scoping ---\n\ntype ParentOf<K extends ClientNames> =\n AssistantClientAccessor<K> extends { source: infer S }\n ? S extends ClientNames\n ? S\n : never\n : never;\n\ntype AncestorsOf<\n K extends ClientNames,\n Seen extends ClientNames = never,\n> = K extends Seen\n ? never\n : ParentOf<K> extends never\n ? never\n : ParentOf<K> | AncestorsOf<ParentOf<K>, Seen | K>;\n\n/** Valid scopes: `\"*\"` | event source | ancestors of event source */\nexport type AssistantEventScope<TEvent extends AssistantEventName> =\n | \"*\"\n | EventSource<TEvent>\n | (EventSource<TEvent> extends ClientNames\n ? AncestorsOf<EventSource<TEvent>>\n : never);\n\n// --- Selection & Callbacks ---\n\nexport type AssistantEventSelector<TEvent extends AssistantEventName> =\n | TEvent\n | { scope: AssistantEventScope<TEvent>; event: TEvent };\n\nexport const normalizeEventSelector = <TEvent extends AssistantEventName>(\n selector: AssistantEventSelector<TEvent>,\n) => {\n if (typeof selector === \"string\") {\n const source = selector.split(\".\")[0] as AssistantEventScope<TEvent>;\n return { scope: source, event: selector };\n }\n return { scope: selector.scope, event: selector.event };\n};\n\nexport type AssistantEventCallback<TEvent extends AssistantEventName> = (\n payload: AssistantEventPayload[TEvent],\n) => void;\n"],"mappings":";AAgEA,MAAa,0BACX,aACG;CACH,IAAI,OAAO,aAAa,UAEtB,OAAO;EAAE,OADM,SAAS,MAAM,GAAG,EAAE;EACX,OAAO;CAAS;CAE1C,OAAO;EAAE,OAAO,SAAS;EAAO,OAAO,SAAS;CAAM;AACxD"} | ||
| {"version":3,"file":"events.js","names":[],"sources":["../../src/types/events.ts"],"sourcesContent":["import type {\n AssistantClientAccessor,\n ClientEvents,\n ClientNames,\n} from \"./client\";\n\n// --- Event Map Construction ---\ntype UnionToIntersection<U> = (\n U extends unknown ? (x: U) => void : never\n) extends (x: infer I) => void\n ? I\n : never;\n\ntype ClientEventMap = UnionToIntersection<\n { [K in ClientNames]: ClientEvents<K> }[ClientNames]\n>;\n\n// --- Core Types ---\n\ntype WildcardPayload = {\n [K in keyof ClientEventMap]: { event: K; payload: ClientEventMap[K] };\n}[keyof ClientEventMap];\n\nexport type AssistantEventPayload = ClientEventMap & { \"*\": WildcardPayload };\n\nexport type AssistantEventName = keyof AssistantEventPayload;\n\ntype EventSource<T extends AssistantEventName> =\n T extends `${infer Source}.${string}` ? Source : never;\n\n// --- Scoping ---\n\ntype ParentOf<K extends ClientNames> =\n AssistantClientAccessor<K> extends { source: infer S }\n ? S extends ClientNames\n ? S\n : never\n : never;\n\ntype AncestorsOf<\n K extends ClientNames,\n Seen extends ClientNames = never,\n> = K extends Seen\n ? never\n : ParentOf<K> extends never\n ? never\n : ParentOf<K> | AncestorsOf<ParentOf<K>, Seen | K>;\n\n/** Valid scopes: `\"*\"` | event source | ancestors of event source */\nexport type AssistantEventScope<TEvent extends AssistantEventName> =\n | \"*\"\n | EventSource<TEvent>\n | (EventSource<TEvent> extends ClientNames\n ? AncestorsOf<EventSource<TEvent>>\n : never);\n\n// --- Selection & Callbacks ---\n\nexport type AssistantEventSelector<TEvent extends AssistantEventName> =\n | TEvent\n | { scope: AssistantEventScope<TEvent>; event: TEvent };\n\nexport const normalizeEventSelector = <TEvent extends AssistantEventName>(\n selector: AssistantEventSelector<TEvent>,\n) => {\n if (typeof selector === \"string\") {\n const source = selector.split(\".\")[0] as AssistantEventScope<TEvent>;\n return { scope: source, event: selector };\n }\n return { scope: selector.scope, event: selector.event };\n};\n\nexport type AssistantEventCallback<TEvent extends AssistantEventName> = (\n payload: AssistantEventPayload[TEvent],\n) => void;\n"],"mappings":";AA8DA,MAAa,0BACX,aACG;CACH,IAAI,OAAO,aAAa,UAEtB,OAAO;EAAE,OADM,SAAS,MAAM,GAAG,EAAE;EACX,OAAO;CAAS;CAE1C,OAAO;EAAE,OAAO,SAAS;EAAO,OAAO,SAAS;CAAM;AACxD"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"useAui.d.ts","names":[],"sources":["../src/useAui.ts"],"mappings":";;;;;;AA6SA;cAAa,uBAAA,GAAuB,KAAA;UAKxB,eAAA;WACC,MAAA,CAAO,KAAA;AAAA;UADR,eAAA;WACC,MAAA,CAAO,KAAA;AAAA;AAAA,kBA0DH,MAAA;EAAA,KACH,KAAA,WACJ,WAAA,IAAe,aAAA,CAAc,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA;;;;;;;;;;;;AA5DlC;AA0DzB;;;;;;;;;;;;;;;;;;AAE4D;AAuC5D;;;;iBAAgB,MAAA,CAAA,GAAU,eAAe;AAsBzC;;;;;;;;;AAA8D;AAI9D;;;;;;;;;;;AAJA,iBAAgB,MAAA,CAAO,OAAA,EAAS,MAAA,CAAO,KAAA,GAAQ,eAAe;;;;iBAI9C,MAAA,CACd,OAAA,EAAS,MAAA,CAAO,KAAA,EAChB,MAAA;EAAU,MAAA,SAAe,eAAA;AAAA,IACxB,eAAA"} | ||
| {"version":3,"file":"useAui.d.ts","names":[],"sources":["../src/useAui.ts"],"mappings":";;;;;;AA6SA;cAAa,uBAAA,GAAuB,KAAA;UAKxB,eAAA;WACC,MAAA,CAAO,KAAA;AAAA;UADR,eAAA;WACC,MAAA,CAAO,KAAA;AAAA;AAAA,kBA0DH,MAAA;EAAA,KACH,KAAA,WACJ,WAAA,IAAe,aAAA,CAAc,CAAA,IAAK,cAAA,CAAe,CAAA;AAAA;;;;;;;;;;;;AA5DlC;AA0DzB;;;;;;;;;;;;;;;;;;AAE4D;AAuC5D;;;;iBAAgB,MAAA,IAAU,eAAe;AAsBzC;;;;;;;;;AAA8D;AAI9D;;;;;;;;;;;AAJA,iBAAgB,MAAA,CAAO,OAAA,EAAS,MAAA,CAAO,KAAA,GAAQ,eAAe;;;;iBAI9C,MAAA,CACd,OAAA,EAAS,MAAA,CAAO,KAAA,EAChB,MAAA;EAAU,MAAA,SAAe,eAAA;AAAA,IACxB,eAAA"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"useAui.js","names":[],"sources":["../src/useAui.ts"],"sourcesContent":["\"use client\";\n\nimport { useResource } from \"@assistant-ui/tap/react\";\nimport {\n resource,\n tapMemo,\n tapResources,\n tapEffect,\n tapRef,\n tapResource,\n withKey,\n tapResourceRoot,\n} from \"@assistant-ui/tap\";\nimport type {\n AssistantClient,\n AssistantClientAccessor,\n ClientNames,\n ClientElement,\n ClientMeta,\n} from \"./types/client\";\nimport type { DerivedElement } from \"./Derived\";\nimport {\n useAssistantContextValue,\n DefaultAssistantClient,\n createRootAssistantClient,\n} from \"./utils/react-assistant-context\";\nimport {\n type DerivedClients,\n type RootClients,\n tapSplitClients,\n} from \"./utils/splitClients\";\nimport {\n normalizeEventSelector,\n type AssistantEventName,\n type AssistantEventCallback,\n type AssistantEventSelector,\n} from \"./types/events\";\nimport { NotificationManager } from \"./utils/NotificationManager\";\nimport { withAssistantTapContextProvider } from \"./utils/tap-assistant-context\";\nimport { tapClientResource } from \"./tapClientResource\";\nimport { getClientIndex } from \"./utils/tap-client-stack-context\";\nimport {\n PROXIED_ASSISTANT_STATE_SYMBOL,\n createProxiedAssistantState,\n} from \"./utils/proxied-assistant-state\";\n\nconst tapShallowMemoArray = <T>(array: readonly T[]) => {\n // biome-ignore lint/correctness/useExhaustiveDependencies: shallow memo\n return tapMemo(() => array, array);\n};\n\nconst RootClientResource = resource(\n <K extends ClientNames>({\n element,\n emit,\n clientRef,\n }: {\n element: ClientElement<K>;\n emit: NotificationManager[\"emit\"];\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n }) => {\n const { methods, state } = withAssistantTapContextProvider(\n { clientRef, emit },\n () => tapClientResource(element),\n );\n return tapMemo(() => ({ state, methods }), [methods, state]);\n },\n);\n\nconst RootClientAccessorResource = resource(\n <K extends ClientNames>({\n element,\n notifications,\n clientRef,\n name,\n }: {\n element: ClientElement<K>;\n notifications: NotificationManager;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n name: K;\n }): AssistantClientAccessor<K> => {\n const store = tapResourceRoot(\n RootClientResource({ element, emit: notifications.emit, clientRef }),\n );\n\n tapEffect(() => {\n return store.subscribe(notifications.notifySubscribers);\n }, [store, notifications]);\n\n return tapMemo(() => {\n const clientFunction = () => store.getValue().methods;\n Object.defineProperties(clientFunction, {\n source: {\n value: \"root\" as const,\n writable: false,\n },\n query: {\n value: {} as Record<string, never>,\n writable: false,\n },\n name: {\n value: name,\n configurable: true,\n },\n });\n return clientFunction as AssistantClientAccessor<K>;\n }, [store, name]);\n },\n);\n\nconst NoOpRootClientsAccessorsResource = resource(() => {\n return tapMemo(\n () => ({\n clients: [] as AssistantClientAccessor<ClientNames>[],\n subscribe: undefined,\n on: undefined,\n }),\n [],\n );\n});\n\nconst RootClientsAccessorsResource = resource(\n ({\n clients: inputClients,\n clientRef,\n }: {\n clients: RootClients;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n }) => {\n const notifications = tapResource(NotificationManager());\n\n tapEffect(\n () => clientRef.parent.subscribe(notifications.notifySubscribers),\n [clientRef, notifications],\n );\n\n const results = tapShallowMemoArray(\n tapResources(\n () =>\n Object.keys(inputClients).map((key) =>\n withKey(\n key,\n RootClientAccessorResource({\n element: inputClients[key as keyof typeof inputClients]!,\n notifications,\n clientRef,\n name: key as keyof typeof inputClients,\n }),\n ),\n ),\n [inputClients, notifications, clientRef],\n ),\n );\n\n return tapMemo(() => {\n return {\n clients: results,\n subscribe: notifications.subscribe,\n on: function <TEvent extends AssistantEventName>(\n this: AssistantClient,\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n ) {\n if (!this) {\n throw new Error(\n \"const { on } = useAui() is not supported. Use aui.on() instead.\",\n );\n }\n\n const { scope, event } = normalizeEventSelector(selector);\n\n if (scope !== \"*\") {\n const source = this[scope as ClientNames].source;\n if (source === null) {\n throw new Error(\n `Scope \"${scope}\" is not available. Use { scope: \"*\", event: \"${event}\" } to listen globally.`,\n );\n }\n }\n\n const localUnsub = notifications.on(event, (payload, clientStack) => {\n if (scope === \"*\") {\n callback(payload);\n return;\n }\n\n const scopeClient = this[scope as ClientNames]();\n const index = getClientIndex(scopeClient);\n if (scopeClient === clientStack[index]) {\n callback(payload);\n }\n });\n if (\n scope !== \"*\" &&\n clientRef.parent[scope as ClientNames].source === null\n )\n return localUnsub;\n\n const parentUnsub = clientRef.parent.on(selector, callback);\n\n return () => {\n localUnsub();\n parentUnsub();\n };\n },\n };\n }, [results, notifications, clientRef]);\n },\n);\n\nconst DerivedClientAccessorResource = resource(\n <K extends ClientNames>({\n element,\n clientRef,\n name,\n }: {\n element: DerivedElement<K>;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n name: K;\n }) => {\n // Track the latest props on a ref updated in render. The fiber is\n // keyed on the scope's meta by DerivedClientsAccessorsResource, so\n // source/query are stable for this fiber's lifetime and the only\n // value that can change between renders for the same fiber is the\n // identity of the `get` closure. Routing reads through the ref\n // avoids the one-commit lag that the previous `tapEffectEvent`\n // path imposed.\n const propsRef = tapRef(element.props);\n propsRef.current = element.props;\n\n return tapMemo(() => {\n const clientFunction = () => propsRef.current.get(clientRef.current!);\n Object.defineProperties(clientFunction, {\n source: {\n value: propsRef.current.source,\n },\n query: {\n value: propsRef.current.query,\n },\n name: {\n value: name,\n configurable: true,\n },\n });\n return clientFunction as AssistantClientAccessor<K>;\n }, [clientRef, name]);\n },\n);\n\nconst serializeMeta = <K extends ClientNames>(\n name: K,\n meta: ClientMeta<K>,\n): string => {\n // Sort top-level keys so {a, b} and {b, a} hash to the same fiber\n // identity, and guard JSON.stringify against unusual values (BigInt,\n // circular refs) so render never throws here.\n let queryKey: string;\n try {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(meta.query as object).sort()) {\n sorted[k] = (meta.query as Record<string, unknown>)[k];\n }\n queryKey = JSON.stringify(sorted);\n } catch {\n queryKey = String(meta.query);\n }\n return `${name}::${meta.source}::${queryKey}`;\n};\n\nconst DerivedClientsAccessorsResource = resource(\n ({\n clients,\n clientRef,\n }: {\n clients: DerivedClients;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n }) => {\n return tapShallowMemoArray(\n tapResources(\n () =>\n Object.keys(clients).map((key) => {\n const name = key as keyof typeof clients;\n const element = clients[name]!;\n return withKey(\n serializeMeta(name, element.props),\n DerivedClientAccessorResource({\n element,\n clientRef,\n name,\n }),\n );\n }),\n [clients, clientRef],\n ),\n );\n },\n);\n\n/**\n * Resource that creates an extended AssistantClient.\n */\nexport const AssistantClientResource = resource(\n ({\n parent,\n clients,\n }: {\n parent: AssistantClient;\n clients: useAui.Props;\n }): AssistantClient => {\n const { rootClients, derivedClients } = tapSplitClients(clients, parent);\n\n const clientRef = tapRef({\n parent: parent,\n current: null as AssistantClient | null,\n }).current;\n\n tapEffect(() => {\n // if (clientRef.current && clientRef.current !== client)\n // throw new Error(\"clientRef.current !== client\");\n\n clientRef.current = client;\n });\n\n const rootFields = tapResource(\n Object.keys(rootClients).length > 0\n ? RootClientsAccessorsResource({ clients: rootClients, clientRef })\n : NoOpRootClientsAccessorsResource(),\n );\n\n const derivedFields = tapResource(\n DerivedClientsAccessorsResource({ clients: derivedClients, clientRef }),\n );\n\n const client = tapMemo(() => {\n // Swap DefaultAssistantClient -> createRootAssistantClient at root to change error message\n const proto =\n parent === DefaultAssistantClient\n ? createRootAssistantClient()\n : parent;\n\n const client = Object.create(proto) as AssistantClient;\n Object.assign(client, {\n subscribe: rootFields.subscribe ?? parent.subscribe,\n on: rootFields.on ?? parent.on,\n [PROXIED_ASSISTANT_STATE_SYMBOL]: createProxiedAssistantState(client),\n });\n\n for (const field of rootFields.clients) {\n (client as any)[field.name] = field;\n }\n for (const field of derivedFields) {\n (client as any)[field.name] = field;\n }\n\n return client;\n }, [parent, rootFields, derivedFields]);\n\n if (clientRef.current === null) {\n clientRef.current = client;\n }\n\n return client;\n },\n);\n\nexport namespace useAui {\n export type Props = {\n [K in ClientNames]?: ClientElement<K> | DerivedElement<K>;\n };\n}\n\n/**\n * Returns the current `AssistantClient` from context.\n *\n * Read the client supplied by the nearest {@link AuiProvider} or\n * {@link AssistantRuntimeProvider}, then access a scope on it —\n * `aui.thread()`, `aui.composer()`, `aui.message()`, and so on. Pair\n * with {@link useAuiState} to read reactive state and {@link useAuiEvent}\n * to subscribe to events. The returned client also exposes lower-level\n * methods such as `aui.on(...)` and `aui.subscribe(...)`; prefer\n * `useAuiEvent` for React event subscriptions.\n *\n * Rendered outside a provider, the returned client's scope accessors\n * throw a descriptive error whenever they are called.\n *\n * @example\n * ```tsx\n * const aui = useAui();\n *\n * const onSend = () => aui.composer().send();\n * const onCancel = () => aui.thread().cancelRun();\n * ```\n *\n * @example\n * ```tsx\n * // Combine with useAuiState to drive disabled state.\n * const aui = useAui();\n * const isRunning = useAuiState((s) => s.thread.isRunning);\n *\n * return (\n * <button disabled={isRunning} onClick={() => aui.composer().send()}>\n * Send\n * </button>\n * );\n * ```\n */\nexport function useAui(): AssistantClient;\n/**\n * Extends the parent `AssistantClient` with additional scopes.\n *\n * Advanced overload used when building primitives or providers — for example,\n * when a custom provider needs to register a `message`, `part`, or other scope\n * onto the client visible to its descendants. Application code rarely reaches\n * for this; use {@link useAui} with no arguments to read the existing client.\n *\n * @example\n * ```tsx\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 * const role = useAuiState((s) => s.message.role);\n * ```\n */\nexport function useAui(clients: useAui.Props): AssistantClient;\n/**\n * Extends an explicit parent `AssistantClient` with additional scopes.\n */\nexport function useAui(\n clients: useAui.Props,\n config: { parent: null | AssistantClient },\n): AssistantClient;\n/** @deprecated This API is highly experimental and may be changed in a minor release */\nexport function useAui(\n clients?: useAui.Props,\n { parent }: { parent: null | AssistantClient } = {\n parent: useAssistantContextValue(),\n },\n): AssistantClient {\n if (clients) {\n // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage\n return useResource(\n AssistantClientResource({\n parent: parent ?? DefaultAssistantClient,\n clients,\n }),\n );\n }\n if (parent === null)\n throw new Error(\"received null parent, this usage is not allowed\");\n return parent;\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,MAAM,uBAA0B,UAAwB;CAEtD,OAAO,cAAc,OAAO,KAAK;AACnC;AAEA,MAAM,qBAAqB,UACD,EACtB,SACA,MACA,gBAKI;CACJ,MAAM,EAAE,SAAS,UAAU,gCACzB;EAAE;EAAW;CAAK,SACZ,kBAAkB,OAAO,CACjC;CACA,OAAO,eAAe;EAAE;EAAO;CAAQ,IAAI,CAAC,SAAS,KAAK,CAAC;AAC7D,CACF;AAEA,MAAM,6BAA6B,UACT,EACtB,SACA,eACA,WACA,WAMgC;CAChC,MAAM,QAAQ,gBACZ,mBAAmB;EAAE;EAAS,MAAM,cAAc;EAAM;CAAU,CAAC,CACrE;CAEA,gBAAgB;EACd,OAAO,MAAM,UAAU,cAAc,iBAAiB;CACxD,GAAG,CAAC,OAAO,aAAa,CAAC;CAEzB,OAAO,cAAc;EACnB,MAAM,uBAAuB,MAAM,SAAS,EAAE;EAC9C,OAAO,iBAAiB,gBAAgB;GACtC,QAAQ;IACN,OAAO;IACP,UAAU;GACZ;GACA,OAAO;IACL,OAAO,CAAC;IACR,UAAU;GACZ;GACA,MAAM;IACJ,OAAO;IACP,cAAc;GAChB;EACF,CAAC;EACD,OAAO;CACT,GAAG,CAAC,OAAO,IAAI,CAAC;AAClB,CACF;AAEA,MAAM,mCAAmC,eAAe;CACtD,OAAO,eACE;EACL,SAAS,CAAC;EACV,WAAW,KAAA;EACX,IAAI,KAAA;CACN,IACA,CAAC,CACH;AACF,CAAC;AAED,MAAM,+BAA+B,UAClC,EACC,SAAS,cACT,gBAII;CACJ,MAAM,gBAAgB,YAAY,oBAAoB,CAAC;CAEvD,gBACQ,UAAU,OAAO,UAAU,cAAc,iBAAiB,GAChE,CAAC,WAAW,aAAa,CAC3B;CAEA,MAAM,UAAU,oBACd,mBAEI,OAAO,KAAK,YAAY,EAAE,KAAK,QAC7B,QACE,KACA,2BAA2B;EACzB,SAAS,aAAa;EACtB;EACA;EACA,MAAM;CACR,CAAC,CACH,CACF,GACF;EAAC;EAAc;EAAe;CAAS,CACzC,CACF;CAEA,OAAO,cAAc;EACnB,OAAO;GACL,SAAS;GACT,WAAW,cAAc;GACzB,IAAI,SAEF,UACA,UACA;IACA,IAAI,CAAC,MACH,MAAM,IAAI,MACR,iEACF;IAGF,MAAM,EAAE,OAAO,UAAU,uBAAuB,QAAQ;IAExD,IAAI,UAAU;SACG,KAAK,OAAsB,WAC3B,MACb,MAAM,IAAI,MACR,UAAU,MAAM,gDAAgD,MAAM,wBACxE;IAAA;IAIJ,MAAM,aAAa,cAAc,GAAG,QAAQ,SAAS,gBAAgB;KACnE,IAAI,UAAU,KAAK;MACjB,SAAS,OAAO;MAChB;KACF;KAEA,MAAM,cAAc,KAAK,OAAsB;KAE/C,IAAI,gBAAgB,YADN,eAAe,WACO,IAClC,SAAS,OAAO;IAEpB,CAAC;IACD,IACE,UAAU,OACV,UAAU,OAAO,OAAsB,WAAW,MAElD,OAAO;IAET,MAAM,cAAc,UAAU,OAAO,GAAG,UAAU,QAAQ;IAE1D,aAAa;KACX,WAAW;KACX,YAAY;IACd;GACF;EACF;CACF,GAAG;EAAC;EAAS;EAAe;CAAS,CAAC;AACxC,CACF;AAEA,MAAM,gCAAgC,UACZ,EACtB,SACA,WACA,WAKI;CAQJ,MAAM,WAAW,OAAO,QAAQ,KAAK;CACrC,SAAS,UAAU,QAAQ;CAE3B,OAAO,cAAc;EACnB,MAAM,uBAAuB,SAAS,QAAQ,IAAI,UAAU,OAAQ;EACpE,OAAO,iBAAiB,gBAAgB;GACtC,QAAQ,EACN,OAAO,SAAS,QAAQ,OAC1B;GACA,OAAO,EACL,OAAO,SAAS,QAAQ,MAC1B;GACA,MAAM;IACJ,OAAO;IACP,cAAc;GAChB;EACF,CAAC;EACD,OAAO;CACT,GAAG,CAAC,WAAW,IAAI,CAAC;AACtB,CACF;AAEA,MAAM,iBACJ,MACA,SACW;CAIX,IAAI;CACJ,IAAI;EACF,MAAM,SAAkC,CAAC;EACzC,KAAK,MAAM,KAAK,OAAO,KAAK,KAAK,KAAe,EAAE,KAAK,GACrD,OAAO,KAAM,KAAK,MAAkC;EAEtD,WAAW,KAAK,UAAU,MAAM;CAClC,QAAQ;EACN,WAAW,OAAO,KAAK,KAAK;CAC9B;CACA,OAAO,GAAG,KAAK,IAAI,KAAK,OAAO,IAAI;AACrC;AAEA,MAAM,kCAAkC,UACrC,EACC,SACA,gBAII;CACJ,OAAO,oBACL,mBAEI,OAAO,KAAK,OAAO,EAAE,KAAK,QAAQ;EAChC,MAAM,OAAO;EACb,MAAM,UAAU,QAAQ;EACxB,OAAO,QACL,cAAc,MAAM,QAAQ,KAAK,GACjC,8BAA8B;GAC5B;GACA;GACA;EACF,CAAC,CACH;CACF,CAAC,GACH,CAAC,SAAS,SAAS,CACrB,CACF;AACF,CACF;;;;AAKA,MAAa,0BAA0B,UACpC,EACC,QACA,cAIqB;CACrB,MAAM,EAAE,aAAa,mBAAmB,gBAAgB,SAAS,MAAM;CAEvE,MAAM,YAAY,OAAO;EACf;EACR,SAAS;CACX,CAAC,EAAE;CAEH,gBAAgB;EAId,UAAU,UAAU;CACtB,CAAC;CAED,MAAM,aAAa,YACjB,OAAO,KAAK,WAAW,EAAE,SAAS,IAC9B,6BAA6B;EAAE,SAAS;EAAa;CAAU,CAAC,IAChE,iCAAiC,CACvC;CAEA,MAAM,gBAAgB,YACpB,gCAAgC;EAAE,SAAS;EAAgB;CAAU,CAAC,CACxE;CAEA,MAAM,SAAS,cAAc;EAE3B,MAAM,QACJ,WAAW,yBACP,0BAA0B,IAC1B;EAEN,MAAM,SAAS,OAAO,OAAO,KAAK;EAClC,OAAO,OAAO,QAAQ;GACpB,WAAW,WAAW,aAAa,OAAO;GAC1C,IAAI,WAAW,MAAM,OAAO;IAC3B,iCAAiC,4BAA4B,MAAM;EACtE,CAAC;EAED,KAAK,MAAM,SAAS,WAAW,SAC7B,OAAgB,MAAM,QAAQ;EAEhC,KAAK,MAAM,SAAS,eAClB,OAAgB,MAAM,QAAQ;EAGhC,OAAO;CACT,GAAG;EAAC;EAAQ;EAAY;CAAa,CAAC;CAEtC,IAAI,UAAU,YAAY,MACxB,UAAU,UAAU;CAGtB,OAAO;AACT,CACF;;AA0EA,SAAgB,OACd,SACA,EAAE,WAA+C,EAC/C,QAAQ,yBAAyB,EACnC,GACiB;CACjB,IAAI,SAEF,OAAO,YACL,wBAAwB;EACtB,QAAQ,UAAU;EAClB;CACF,CAAC,CACH;CAEF,IAAI,WAAW,MACb,MAAM,IAAI,MAAM,iDAAiD;CACnE,OAAO;AACT"} | ||
| {"version":3,"file":"useAui.js","names":[],"sources":["../src/useAui.ts"],"sourcesContent":["\"use client\";\n\nimport { useResource } from \"@assistant-ui/tap/react\";\nimport {\n resource,\n tapMemo,\n tapResources,\n tapEffect,\n tapRef,\n tapResource,\n withKey,\n tapResourceRoot,\n} from \"@assistant-ui/tap\";\nimport type {\n AssistantClient,\n AssistantClientAccessor,\n ClientNames,\n ClientElement,\n ClientMeta,\n} from \"./types/client\";\nimport type { DerivedElement } from \"./Derived\";\nimport {\n useAssistantContextValue,\n DefaultAssistantClient,\n createRootAssistantClient,\n} from \"./utils/react-assistant-context\";\nimport {\n type DerivedClients,\n type RootClients,\n tapSplitClients,\n} from \"./utils/splitClients\";\nimport {\n normalizeEventSelector,\n type AssistantEventName,\n type AssistantEventCallback,\n type AssistantEventSelector,\n} from \"./types/events\";\nimport { NotificationManager } from \"./utils/NotificationManager\";\nimport { withAssistantTapContextProvider } from \"./utils/tap-assistant-context\";\nimport { tapClientResource } from \"./tapClientResource\";\nimport { getClientIndex } from \"./utils/tap-client-stack-context\";\nimport {\n PROXIED_ASSISTANT_STATE_SYMBOL,\n createProxiedAssistantState,\n} from \"./utils/proxied-assistant-state\";\n\nconst tapShallowMemoArray = <T>(array: readonly T[]) => {\n // oxlint-disable-next-line tap-hooks/exhaustive-deps -- shallow memo over the array itself\n return tapMemo(() => array, array);\n};\n\nconst RootClientResource = resource(\n <K extends ClientNames>({\n element,\n emit,\n clientRef,\n }: {\n element: ClientElement<K>;\n emit: NotificationManager[\"emit\"];\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n }) => {\n const { methods, state } = withAssistantTapContextProvider(\n { clientRef, emit },\n () => tapClientResource(element),\n );\n return tapMemo(() => ({ state, methods }), [methods, state]);\n },\n);\n\nconst RootClientAccessorResource = resource(\n <K extends ClientNames>({\n element,\n notifications,\n clientRef,\n name,\n }: {\n element: ClientElement<K>;\n notifications: NotificationManager;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n name: K;\n }): AssistantClientAccessor<K> => {\n const store = tapResourceRoot(\n RootClientResource({ element, emit: notifications.emit, clientRef }),\n );\n\n tapEffect(() => {\n return store.subscribe(notifications.notifySubscribers);\n }, [store, notifications]);\n\n return tapMemo(() => {\n const clientFunction = () => store.getValue().methods;\n Object.defineProperties(clientFunction, {\n source: {\n value: \"root\" as const,\n writable: false,\n },\n query: {\n value: {} as Record<string, never>,\n writable: false,\n },\n name: {\n value: name,\n configurable: true,\n },\n });\n return clientFunction as AssistantClientAccessor<K>;\n }, [store, name]);\n },\n);\n\nconst NoOpRootClientsAccessorsResource = resource(() => {\n return tapMemo(\n () => ({\n clients: [] as AssistantClientAccessor<ClientNames>[],\n subscribe: undefined,\n on: undefined,\n }),\n [],\n );\n});\n\nconst RootClientsAccessorsResource = resource(\n ({\n clients: inputClients,\n clientRef,\n }: {\n clients: RootClients;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n }) => {\n const notifications = tapResource(NotificationManager());\n\n tapEffect(\n () => clientRef.parent.subscribe(notifications.notifySubscribers),\n [clientRef, notifications],\n );\n\n const results = tapShallowMemoArray(\n tapResources(\n () =>\n Object.keys(inputClients).map((key) =>\n withKey(\n key,\n RootClientAccessorResource({\n element: inputClients[key as keyof typeof inputClients]!,\n notifications,\n clientRef,\n name: key as keyof typeof inputClients,\n }),\n ),\n ),\n [inputClients, notifications, clientRef],\n ),\n );\n\n return tapMemo(() => {\n return {\n clients: results,\n subscribe: notifications.subscribe,\n on: function <TEvent extends AssistantEventName>(\n this: AssistantClient,\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n ) {\n if (!this) {\n throw new Error(\n \"const { on } = useAui() is not supported. Use aui.on() instead.\",\n );\n }\n\n const { scope, event } = normalizeEventSelector(selector);\n\n if (scope !== \"*\") {\n const source = this[scope as ClientNames].source;\n if (source === null) {\n throw new Error(\n `Scope \"${scope}\" is not available. Use { scope: \"*\", event: \"${event}\" } to listen globally.`,\n );\n }\n }\n\n const localUnsub = notifications.on(event, (payload, clientStack) => {\n if (scope === \"*\") {\n callback(payload);\n return;\n }\n\n const scopeClient = this[scope as ClientNames]();\n const index = getClientIndex(scopeClient);\n if (scopeClient === clientStack[index]) {\n callback(payload);\n }\n });\n if (\n scope !== \"*\" &&\n clientRef.parent[scope as ClientNames].source === null\n )\n return localUnsub;\n\n const parentUnsub = clientRef.parent.on(selector, callback);\n\n return () => {\n localUnsub();\n parentUnsub();\n };\n },\n };\n }, [results, notifications, clientRef]);\n },\n);\n\nconst DerivedClientAccessorResource = resource(\n <K extends ClientNames>({\n element,\n clientRef,\n name,\n }: {\n element: DerivedElement<K>;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n name: K;\n }) => {\n // Track the latest props on a ref updated in render. The fiber is\n // keyed on the scope's meta by DerivedClientsAccessorsResource, so\n // source/query are stable for this fiber's lifetime and the only\n // value that can change between renders for the same fiber is the\n // identity of the `get` closure. Routing reads through the ref\n // avoids the one-commit lag that the previous `tapEffectEvent`\n // path imposed.\n const propsRef = tapRef(element.props);\n propsRef.current = element.props;\n\n return tapMemo(() => {\n const clientFunction = () => propsRef.current.get(clientRef.current!);\n Object.defineProperties(clientFunction, {\n source: {\n value: propsRef.current.source,\n },\n query: {\n value: propsRef.current.query,\n },\n name: {\n value: name,\n configurable: true,\n },\n });\n return clientFunction as AssistantClientAccessor<K>;\n }, [clientRef, name]);\n },\n);\n\nconst serializeMeta = <K extends ClientNames>(\n name: K,\n meta: ClientMeta<K>,\n): string => {\n // Sort top-level keys so {a, b} and {b, a} hash to the same fiber\n // identity, and guard JSON.stringify against unusual values (BigInt,\n // circular refs) so render never throws here.\n let queryKey: string;\n try {\n const sorted: Record<string, unknown> = {};\n for (const k of Object.keys(meta.query as object).sort()) {\n sorted[k] = (meta.query as Record<string, unknown>)[k];\n }\n queryKey = JSON.stringify(sorted);\n } catch {\n queryKey = String(meta.query);\n }\n return `${name}::${meta.source}::${queryKey}`;\n};\n\nconst DerivedClientsAccessorsResource = resource(\n ({\n clients,\n clientRef,\n }: {\n clients: DerivedClients;\n clientRef: { parent: AssistantClient; current: AssistantClient | null };\n }) => {\n return tapShallowMemoArray(\n tapResources(\n () =>\n Object.keys(clients).map((key) => {\n const name = key as keyof typeof clients;\n const element = clients[name]!;\n return withKey(\n serializeMeta(name, element.props),\n DerivedClientAccessorResource({\n element,\n clientRef,\n name,\n }),\n );\n }),\n [clients, clientRef],\n ),\n );\n },\n);\n\n/**\n * Resource that creates an extended AssistantClient.\n */\nexport const AssistantClientResource = resource(\n ({\n parent,\n clients,\n }: {\n parent: AssistantClient;\n clients: useAui.Props;\n }): AssistantClient => {\n const { rootClients, derivedClients } = tapSplitClients(clients, parent);\n\n const clientRef = tapRef({\n parent: parent,\n current: null as AssistantClient | null,\n }).current;\n\n tapEffect(() => {\n // if (clientRef.current && clientRef.current !== client)\n // throw new Error(\"clientRef.current !== client\");\n\n clientRef.current = client;\n });\n\n const rootFields = tapResource(\n Object.keys(rootClients).length > 0\n ? RootClientsAccessorsResource({ clients: rootClients, clientRef })\n : NoOpRootClientsAccessorsResource(),\n );\n\n const derivedFields = tapResource(\n DerivedClientsAccessorsResource({ clients: derivedClients, clientRef }),\n );\n\n const client = tapMemo(() => {\n // Swap DefaultAssistantClient -> createRootAssistantClient at root to change error message\n const proto =\n parent === DefaultAssistantClient\n ? createRootAssistantClient()\n : parent;\n\n const client = Object.create(proto) as AssistantClient;\n Object.assign(client, {\n subscribe: rootFields.subscribe ?? parent.subscribe,\n on: rootFields.on ?? parent.on,\n [PROXIED_ASSISTANT_STATE_SYMBOL]: createProxiedAssistantState(client),\n });\n\n for (const field of rootFields.clients) {\n (client as any)[field.name] = field;\n }\n for (const field of derivedFields) {\n (client as any)[field.name] = field;\n }\n\n return client;\n }, [parent, rootFields, derivedFields]);\n\n if (clientRef.current === null) {\n clientRef.current = client;\n }\n\n return client;\n },\n);\n\nexport namespace useAui {\n export type Props = {\n [K in ClientNames]?: ClientElement<K> | DerivedElement<K>;\n };\n}\n\n/**\n * Returns the current `AssistantClient` from context.\n *\n * Read the client supplied by the nearest {@link AuiProvider} or\n * {@link AssistantRuntimeProvider}, then access a scope on it —\n * `aui.thread()`, `aui.composer()`, `aui.message()`, and so on. Pair\n * with {@link useAuiState} to read reactive state and {@link useAuiEvent}\n * to subscribe to events. The returned client also exposes lower-level\n * methods such as `aui.on(...)` and `aui.subscribe(...)`; prefer\n * `useAuiEvent` for React event subscriptions.\n *\n * Rendered outside a provider, the returned client's scope accessors\n * throw a descriptive error whenever they are called.\n *\n * @example\n * ```tsx\n * const aui = useAui();\n *\n * const onSend = () => aui.composer().send();\n * const onCancel = () => aui.thread().cancelRun();\n * ```\n *\n * @example\n * ```tsx\n * // Combine with useAuiState to drive disabled state.\n * const aui = useAui();\n * const isRunning = useAuiState((s) => s.thread.isRunning);\n *\n * return (\n * <button disabled={isRunning} onClick={() => aui.composer().send()}>\n * Send\n * </button>\n * );\n * ```\n */\nexport function useAui(): AssistantClient;\n/**\n * Extends the parent `AssistantClient` with additional scopes.\n *\n * Advanced overload used when building primitives or providers — for example,\n * when a custom provider needs to register a `message`, `part`, or other scope\n * onto the client visible to its descendants. Application code rarely reaches\n * for this; use {@link useAui} with no arguments to read the existing client.\n *\n * @example\n * ```tsx\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 * const role = useAuiState((s) => s.message.role);\n * ```\n */\nexport function useAui(clients: useAui.Props): AssistantClient;\n/**\n * Extends an explicit parent `AssistantClient` with additional scopes.\n */\nexport function useAui(\n clients: useAui.Props,\n config: { parent: null | AssistantClient },\n): AssistantClient;\n/** @deprecated This API is highly experimental and may be changed in a minor release */\nexport function useAui(\n clients?: useAui.Props,\n { parent }: { parent: null | AssistantClient } = {\n parent: useAssistantContextValue(),\n },\n): AssistantClient {\n if (clients) {\n return useResource(\n AssistantClientResource({\n parent: parent ?? DefaultAssistantClient,\n clients,\n }),\n );\n }\n if (parent === null)\n throw new Error(\"received null parent, this usage is not allowed\");\n return parent;\n}\n"],"mappings":";;;;;;;;;;;;AA8CA,MAAM,uBAA0B,UAAwB;CAEtD,OAAO,cAAc,OAAO,KAAK;AACnC;AAEA,MAAM,qBAAqB,UACD,EACtB,SACA,MACA,gBAKI;CACJ,MAAM,EAAE,SAAS,UAAU,gCACzB;EAAE;EAAW;CAAK,SACZ,kBAAkB,OAAO,CACjC;CACA,OAAO,eAAe;EAAE;EAAO;CAAQ,IAAI,CAAC,SAAS,KAAK,CAAC;AAC7D,CACF;AAEA,MAAM,6BAA6B,UACT,EACtB,SACA,eACA,WACA,WAMgC;CAChC,MAAM,QAAQ,gBACZ,mBAAmB;EAAE;EAAS,MAAM,cAAc;EAAM;CAAU,CAAC,CACrE;CAEA,gBAAgB;EACd,OAAO,MAAM,UAAU,cAAc,iBAAiB;CACxD,GAAG,CAAC,OAAO,aAAa,CAAC;CAEzB,OAAO,cAAc;EACnB,MAAM,uBAAuB,MAAM,SAAS,EAAE;EAC9C,OAAO,iBAAiB,gBAAgB;GACtC,QAAQ;IACN,OAAO;IACP,UAAU;GACZ;GACA,OAAO;IACL,OAAO,CAAC;IACR,UAAU;GACZ;GACA,MAAM;IACJ,OAAO;IACP,cAAc;GAChB;EACF,CAAC;EACD,OAAO;CACT,GAAG,CAAC,OAAO,IAAI,CAAC;AAClB,CACF;AAEA,MAAM,mCAAmC,eAAe;CACtD,OAAO,eACE;EACL,SAAS,CAAC;EACV,WAAW,KAAA;EACX,IAAI,KAAA;CACN,IACA,CAAC,CACH;AACF,CAAC;AAED,MAAM,+BAA+B,UAClC,EACC,SAAS,cACT,gBAII;CACJ,MAAM,gBAAgB,YAAY,oBAAoB,CAAC;CAEvD,gBACQ,UAAU,OAAO,UAAU,cAAc,iBAAiB,GAChE,CAAC,WAAW,aAAa,CAC3B;CAEA,MAAM,UAAU,oBACd,mBAEI,OAAO,KAAK,YAAY,EAAE,KAAK,QAC7B,QACE,KACA,2BAA2B;EACzB,SAAS,aAAa;EACtB;EACA;EACA,MAAM;CACR,CAAC,CACH,CACF,GACF;EAAC;EAAc;EAAe;CAAS,CACzC,CACF;CAEA,OAAO,cAAc;EACnB,OAAO;GACL,SAAS;GACT,WAAW,cAAc;GACzB,IAAI,SAEF,UACA,UACA;IACA,IAAI,CAAC,MACH,MAAM,IAAI,MACR,iEACF;IAGF,MAAM,EAAE,OAAO,UAAU,uBAAuB,QAAQ;IAExD,IAAI,UAAU;SACG,KAAK,OAAsB,WAC3B,MACb,MAAM,IAAI,MACR,UAAU,MAAM,gDAAgD,MAAM,wBACxE;IAAA;IAIJ,MAAM,aAAa,cAAc,GAAG,QAAQ,SAAS,gBAAgB;KACnE,IAAI,UAAU,KAAK;MACjB,SAAS,OAAO;MAChB;KACF;KAEA,MAAM,cAAc,KAAK,OAAsB;KAE/C,IAAI,gBAAgB,YADN,eAAe,WACO,IAClC,SAAS,OAAO;IAEpB,CAAC;IACD,IACE,UAAU,OACV,UAAU,OAAO,OAAsB,WAAW,MAElD,OAAO;IAET,MAAM,cAAc,UAAU,OAAO,GAAG,UAAU,QAAQ;IAE1D,aAAa;KACX,WAAW;KACX,YAAY;IACd;GACF;EACF;CACF,GAAG;EAAC;EAAS;EAAe;CAAS,CAAC;AACxC,CACF;AAEA,MAAM,gCAAgC,UACZ,EACtB,SACA,WACA,WAKI;CAQJ,MAAM,WAAW,OAAO,QAAQ,KAAK;CACrC,SAAS,UAAU,QAAQ;CAE3B,OAAO,cAAc;EACnB,MAAM,uBAAuB,SAAS,QAAQ,IAAI,UAAU,OAAQ;EACpE,OAAO,iBAAiB,gBAAgB;GACtC,QAAQ,EACN,OAAO,SAAS,QAAQ,OAC1B;GACA,OAAO,EACL,OAAO,SAAS,QAAQ,MAC1B;GACA,MAAM;IACJ,OAAO;IACP,cAAc;GAChB;EACF,CAAC;EACD,OAAO;CACT,GAAG,CAAC,WAAW,IAAI,CAAC;AACtB,CACF;AAEA,MAAM,iBACJ,MACA,SACW;CAIX,IAAI;CACJ,IAAI;EACF,MAAM,SAAkC,CAAC;EACzC,KAAK,MAAM,KAAK,OAAO,KAAK,KAAK,KAAe,EAAE,KAAK,GACrD,OAAO,KAAM,KAAK,MAAkC;EAEtD,WAAW,KAAK,UAAU,MAAM;CAClC,QAAQ;EACN,WAAW,OAAO,KAAK,KAAK;CAC9B;CACA,OAAO,GAAG,KAAK,IAAI,KAAK,OAAO,IAAI;AACrC;AAEA,MAAM,kCAAkC,UACrC,EACC,SACA,gBAII;CACJ,OAAO,oBACL,mBAEI,OAAO,KAAK,OAAO,EAAE,KAAK,QAAQ;EAChC,MAAM,OAAO;EACb,MAAM,UAAU,QAAQ;EACxB,OAAO,QACL,cAAc,MAAM,QAAQ,KAAK,GACjC,8BAA8B;GAC5B;GACA;GACA;EACF,CAAC,CACH;CACF,CAAC,GACH,CAAC,SAAS,SAAS,CACrB,CACF;AACF,CACF;;;;AAKA,MAAa,0BAA0B,UACpC,EACC,QACA,cAIqB;CACrB,MAAM,EAAE,aAAa,mBAAmB,gBAAgB,SAAS,MAAM;CAEvE,MAAM,YAAY,OAAO;EACf;EACR,SAAS;CACX,CAAC,EAAE;CAEH,gBAAgB;EAId,UAAU,UAAU;CACtB,CAAC;CAED,MAAM,aAAa,YACjB,OAAO,KAAK,WAAW,EAAE,SAAS,IAC9B,6BAA6B;EAAE,SAAS;EAAa;CAAU,CAAC,IAChE,iCAAiC,CACvC;CAEA,MAAM,gBAAgB,YACpB,gCAAgC;EAAE,SAAS;EAAgB;CAAU,CAAC,CACxE;CAEA,MAAM,SAAS,cAAc;EAE3B,MAAM,QACJ,WAAW,yBACP,0BAA0B,IAC1B;EAEN,MAAM,SAAS,OAAO,OAAO,KAAK;EAClC,OAAO,OAAO,QAAQ;GACpB,WAAW,WAAW,aAAa,OAAO;GAC1C,IAAI,WAAW,MAAM,OAAO;IAC3B,iCAAiC,4BAA4B,MAAM;EACtE,CAAC;EAED,KAAK,MAAM,SAAS,WAAW,SAC7B,OAAgB,MAAM,QAAQ;EAEhC,KAAK,MAAM,SAAS,eAClB,OAAgB,MAAM,QAAQ;EAGhC,OAAO;CACT,GAAG;EAAC;EAAQ;EAAY;CAAa,CAAC;CAEtC,IAAI,UAAU,YAAY,MACxB,UAAU,UAAU;CAGtB,OAAO;AACT,CACF;;AA0EA,SAAgB,OACd,SACA,EAAE,WAA+C,EAC/C,QAAQ,yBAAyB,EACnC,GACiB;CACjB,IAAI,SACF,OAAO,YACL,wBAAwB;EACtB,QAAQ,UAAU;EAClB;CACF,CAAC,CACH;CAEF,IAAI,WAAW,MACb,MAAM,IAAI,MAAM,iDAAiD;CACnE,OAAO;AACT"} |
@@ -57,4 +57,3 @@ import { normalizeEventSelector } from "./types/events.js"; | ||
| scope, | ||
| event, | ||
| callbackRef | ||
| event | ||
| ]); | ||
@@ -61,0 +60,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"useAuiEvent.js","names":[],"sources":["../src/useAuiEvent.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useEffectEvent } from \"use-effect-event\";\nimport { useAui } from \"./useAui\";\nimport type {\n AssistantEventName,\n AssistantEventCallback,\n AssistantEventSelector,\n} from \"./types/events\";\nimport { normalizeEventSelector } from \"./types/events\";\n\n/**\n * Subscribes to an assistant event for the lifetime of the component.\n *\n * The subscription is established on mount and re-established whenever the\n * scope or event name changes. The `callback` is wrapped in an effect-event\n * shim, so the latest closure is invoked on each emission — you do not\n * need to memoize it.\n *\n * @param selector - Either a dotted event name like\n * `\"thread.modelContextUpdate\"` or an object `{ scope, event }`. Use\n * `scope: \"*\"` to subscribe at the root client and receive emissions\n * from any descendant scope, regardless of which one is in React\n * context.\n * @param callback - Invoked with the event payload. The most recent\n * reference is always called. Return values are ignored, async callbacks\n * are not awaited, and the callback cannot be called during render.\n *\n * @example\n * ```tsx\n * // React to transient model-context changes.\n * useAuiEvent(\"thread.modelContextUpdate\", ({ threadId }) => {\n * analytics.track(\"model_context_update\", { threadId });\n * });\n * ```\n *\n * @example\n * ```tsx\n * // React to thread switches.\n * useAuiEvent(\"threadListItem.switchedTo\", () => {\n * resetLocalState();\n * });\n * ```\n *\n * @example\n * ```tsx\n * // Listen from the root client rather than the current React context.\n * useAuiEvent({ scope: \"*\", event: \"thread.modelContextUpdate\" }, (payload) => {\n * analytics.track(\"model_context_update\", payload);\n * });\n * ```\n */\nexport const useAuiEvent = <TEvent extends AssistantEventName>(\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n) => {\n const aui = useAui();\n const callbackRef = useEffectEvent(callback);\n\n const { scope, event } = normalizeEventSelector(selector);\n useEffect(\n () => aui.on({ scope, event }, callbackRef),\n [aui, scope, event, callbackRef],\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,MAAa,eACX,UACA,aACG;CACH,MAAM,MAAM,OAAO;CACnB,MAAM,cAAc,eAAe,QAAQ;CAE3C,MAAM,EAAE,OAAO,UAAU,uBAAuB,QAAQ;CACxD,gBACQ,IAAI,GAAG;EAAE;EAAO;CAAM,GAAG,WAAW,GAC1C;EAAC;EAAK;EAAO;EAAO;CAAW,CACjC;AACF"} | ||
| {"version":3,"file":"useAuiEvent.js","names":[],"sources":["../src/useAuiEvent.ts"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useEffectEvent } from \"use-effect-event\";\nimport { useAui } from \"./useAui\";\nimport type {\n AssistantEventName,\n AssistantEventCallback,\n AssistantEventSelector,\n} from \"./types/events\";\nimport { normalizeEventSelector } from \"./types/events\";\n\n/**\n * Subscribes to an assistant event for the lifetime of the component.\n *\n * The subscription is established on mount and re-established whenever the\n * scope or event name changes. The `callback` is wrapped in an effect-event\n * shim, so the latest closure is invoked on each emission — you do not\n * need to memoize it.\n *\n * @param selector - Either a dotted event name like\n * `\"thread.modelContextUpdate\"` or an object `{ scope, event }`. Use\n * `scope: \"*\"` to subscribe at the root client and receive emissions\n * from any descendant scope, regardless of which one is in React\n * context.\n * @param callback - Invoked with the event payload. The most recent\n * reference is always called. Return values are ignored, async callbacks\n * are not awaited, and the callback cannot be called during render.\n *\n * @example\n * ```tsx\n * // React to transient model-context changes.\n * useAuiEvent(\"thread.modelContextUpdate\", ({ threadId }) => {\n * analytics.track(\"model_context_update\", { threadId });\n * });\n * ```\n *\n * @example\n * ```tsx\n * // React to thread switches.\n * useAuiEvent(\"threadListItem.switchedTo\", () => {\n * resetLocalState();\n * });\n * ```\n *\n * @example\n * ```tsx\n * // Listen from the root client rather than the current React context.\n * useAuiEvent({ scope: \"*\", event: \"thread.modelContextUpdate\" }, (payload) => {\n * analytics.track(\"model_context_update\", payload);\n * });\n * ```\n */\nexport const useAuiEvent = <TEvent extends AssistantEventName>(\n selector: AssistantEventSelector<TEvent>,\n callback: AssistantEventCallback<TEvent>,\n) => {\n const aui = useAui();\n const callbackRef = useEffectEvent(callback);\n\n const { scope, event } = normalizeEventSelector(selector);\n useEffect(() => aui.on({ scope, event }, callbackRef), [aui, scope, event]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,MAAa,eACX,UACA,aACG;CACH,MAAM,MAAM,OAAO;CACnB,MAAM,cAAc,eAAe,QAAQ;CAE3C,MAAM,EAAE,OAAO,UAAU,uBAAuB,QAAQ;CACxD,gBAAgB,IAAI,GAAG;EAAE;EAAO;CAAM,GAAG,WAAW,GAAG;EAAC;EAAK;EAAO;CAAK,CAAC;AAC5E"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"BaseProxyHandler.d.ts","names":[],"sources":["../../src/utils/BaseProxyHandler.ts"],"mappings":";;AAOA;;;;cAAa,uBAAA,GACX,IAAA,mBACA,IAAY;AAAA,uBASQ,gBAAA,YAA4B,YAAY;EAAA,SACnD,GAAA,CAAI,CAAA,WAAY,IAAA,mBAAuB,QAAA;EAAA,SACvC,OAAA,CAAA,GAAW,SAAA;EAAA,SACX,GAAA,CAAI,CAAA,WAAY,IAAA;EAEzB,wBAAA,CAAyB,CAAA,WAAY,IAAA;;;;;;EAWrC,GAAA,CAAA;EAGA,cAAA,CAAA;EAGA,cAAA,CAAA;EAGA,cAAA,CAAA;EAGA,iBAAA,CAAA;AAAA"} | ||
| {"version":3,"file":"BaseProxyHandler.d.ts","names":[],"sources":["../../src/utils/BaseProxyHandler.ts"],"mappings":";;AAOA;;;;cAAa,uBAAA,GACX,IAAA,mBACA,IAAY;AAAA,uBASQ,gBAAA,YAA4B,YAAY;EAAA,SACnD,GAAA,CAAI,CAAA,WAAY,IAAA,mBAAuB,QAAA;EAAA,SACvC,OAAA,IAAW,SAAA;EAAA,SACX,GAAA,CAAI,CAAA,WAAY,IAAA;EAEzB,wBAAA,CAAyB,CAAA,WAAY,IAAA;;;;;;EAWrC,GAAA;EAGA,cAAA;EAGA,cAAA;EAGA,cAAA;EAGA,iBAAA;AAAA"} |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"splitClients.js","names":[],"sources":["../../src/utils/splitClients.ts"],"sourcesContent":["import { Derived, type DerivedElement } from \"../Derived\";\nimport type {\n AssistantClient,\n ClientElement,\n ClientNames,\n} from \"../types/client\";\nimport { getTransformScopes } from \"../attachTransformScopes\";\nimport type { useAui } from \"../useAui\";\nimport { tapMemo, type ResourceElement } from \"@assistant-ui/tap\";\n\nexport type RootClients = Partial<\n Record<ClientNames, ClientElement<ClientNames>>\n>;\nexport type DerivedClients = Partial<\n Record<ClientNames, DerivedElement<ClientNames>>\n>;\n\n/**\n * Splits a clients object into root clients and derived clients,\n * applying transformScopes from root client elements.\n */\nfunction splitClients(clients: useAui.Props, baseClient: AssistantClient) {\n // 1. Collect transforms from root elements and run them iteratively\n const scopes = { ...clients } as Record<\n string,\n ClientElement<ClientNames> | DerivedElement<ClientNames>\n >;\n const visited = new Set<(...args: any[]) => any>();\n\n let changed = true;\n while (changed) {\n changed = false;\n for (const clientElement of Object.values(scopes)) {\n if (clientElement.type === (Derived as unknown)) continue;\n if (visited.has(clientElement.type)) continue;\n visited.add(clientElement.type);\n\n const transform = getTransformScopes(\n clientElement.type as (props: any) => ResourceElement<any>,\n );\n if (transform) {\n transform(scopes, baseClient);\n changed = true;\n break; // restart iteration since scopes may have new root elements\n }\n }\n }\n\n // 2. Split result into root/derived\n const rootClients: RootClients = {};\n const derivedClients: DerivedClients = {};\n\n for (const [key, clientElement] of Object.entries(scopes) as [\n ClientNames,\n ClientElement<ClientNames> | DerivedElement<ClientNames>,\n ][]) {\n if (clientElement.type === (Derived as unknown)) {\n derivedClients[key] = clientElement as DerivedElement<ClientNames>;\n } else {\n rootClients[key] = clientElement as ClientElement<ClientNames>;\n }\n }\n\n return { rootClients, derivedClients };\n}\n\nconst tapShallowMemoObject = <T extends object>(object: T) => {\n // biome-ignore lint/correctness/useExhaustiveDependencies: shallow memo\n return tapMemo(() => object, [...Object.entries(object).flat()]);\n};\n\nexport const tapSplitClients = (\n clients: useAui.Props,\n baseClient: AssistantClient,\n) => {\n const { rootClients, derivedClients } = splitClients(clients, baseClient);\n\n return {\n rootClients: tapShallowMemoObject(rootClients),\n derivedClients: tapShallowMemoObject(derivedClients),\n };\n};\n"],"mappings":";;;;;;;;AAqBA,SAAS,aAAa,SAAuB,YAA6B;CAExE,MAAM,SAAS,EAAE,GAAG,QAAQ;CAI5B,MAAM,0BAAU,IAAI,IAA6B;CAEjD,IAAI,UAAU;CACd,OAAO,SAAS;EACd,UAAU;EACV,KAAK,MAAM,iBAAiB,OAAO,OAAO,MAAM,GAAG;GACjD,IAAI,cAAc,SAAU,SAAqB;GACjD,IAAI,QAAQ,IAAI,cAAc,IAAI,GAAG;GACrC,QAAQ,IAAI,cAAc,IAAI;GAE9B,MAAM,YAAY,mBAChB,cAAc,IAChB;GACA,IAAI,WAAW;IACb,UAAU,QAAQ,UAAU;IAC5B,UAAU;IACV;GACF;EACF;CACF;CAGA,MAAM,cAA2B,CAAC;CAClC,MAAM,iBAAiC,CAAC;CAExC,KAAK,MAAM,CAAC,KAAK,kBAAkB,OAAO,QAAQ,MAAM,GAItD,IAAI,cAAc,SAAU,SAC1B,eAAe,OAAO;MAEtB,YAAY,OAAO;CAIvB,OAAO;EAAE;EAAa;CAAe;AACvC;AAEA,MAAM,wBAA0C,WAAc;CAE5D,OAAO,cAAc,QAAQ,CAAC,GAAG,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC;AACjE;AAEA,MAAa,mBACX,SACA,eACG;CACH,MAAM,EAAE,aAAa,mBAAmB,aAAa,SAAS,UAAU;CAExE,OAAO;EACL,aAAa,qBAAqB,WAAW;EAC7C,gBAAgB,qBAAqB,cAAc;CACrD;AACF"} | ||
| {"version":3,"file":"splitClients.js","names":[],"sources":["../../src/utils/splitClients.ts"],"sourcesContent":["import { Derived, type DerivedElement } from \"../Derived\";\nimport type {\n AssistantClient,\n ClientElement,\n ClientNames,\n} from \"../types/client\";\nimport { getTransformScopes } from \"../attachTransformScopes\";\nimport type { useAui } from \"../useAui\";\nimport { tapMemo, type ResourceElement } from \"@assistant-ui/tap\";\n\nexport type RootClients = Partial<\n Record<ClientNames, ClientElement<ClientNames>>\n>;\nexport type DerivedClients = Partial<\n Record<ClientNames, DerivedElement<ClientNames>>\n>;\n\n/**\n * Splits a clients object into root clients and derived clients,\n * applying transformScopes from root client elements.\n */\nfunction splitClients(clients: useAui.Props, baseClient: AssistantClient) {\n // 1. Collect transforms from root elements and run them iteratively\n const scopes = { ...clients } as Record<\n string,\n ClientElement<ClientNames> | DerivedElement<ClientNames>\n >;\n const visited = new Set<(...args: any[]) => any>();\n\n let changed = true;\n while (changed) {\n changed = false;\n for (const clientElement of Object.values(scopes)) {\n if (clientElement.type === (Derived as unknown)) continue;\n if (visited.has(clientElement.type)) continue;\n visited.add(clientElement.type);\n\n const transform = getTransformScopes(\n clientElement.type as (props: any) => ResourceElement<any>,\n );\n if (transform) {\n transform(scopes, baseClient);\n changed = true;\n break; // restart iteration since scopes may have new root elements\n }\n }\n }\n\n // 2. Split result into root/derived\n const rootClients: RootClients = {};\n const derivedClients: DerivedClients = {};\n\n for (const [key, clientElement] of Object.entries(scopes) as [\n ClientNames,\n ClientElement<ClientNames> | DerivedElement<ClientNames>,\n ][]) {\n if (clientElement.type === (Derived as unknown)) {\n derivedClients[key] = clientElement as DerivedElement<ClientNames>;\n } else {\n rootClients[key] = clientElement as ClientElement<ClientNames>;\n }\n }\n\n return { rootClients, derivedClients };\n}\n\nconst tapShallowMemoObject = <T extends object>(object: T) => {\n // oxlint-disable-next-line tap-hooks/exhaustive-deps -- shallow memo over the object's flattened entries\n return tapMemo(() => object, [...Object.entries(object).flat()]);\n};\n\nexport const tapSplitClients = (\n clients: useAui.Props,\n baseClient: AssistantClient,\n) => {\n const { rootClients, derivedClients } = splitClients(clients, baseClient);\n\n return {\n rootClients: tapShallowMemoObject(rootClients),\n derivedClients: tapShallowMemoObject(derivedClients),\n };\n};\n"],"mappings":";;;;;;;;AAqBA,SAAS,aAAa,SAAuB,YAA6B;CAExE,MAAM,SAAS,EAAE,GAAG,QAAQ;CAI5B,MAAM,0BAAU,IAAI,IAA6B;CAEjD,IAAI,UAAU;CACd,OAAO,SAAS;EACd,UAAU;EACV,KAAK,MAAM,iBAAiB,OAAO,OAAO,MAAM,GAAG;GACjD,IAAI,cAAc,SAAU,SAAqB;GACjD,IAAI,QAAQ,IAAI,cAAc,IAAI,GAAG;GACrC,QAAQ,IAAI,cAAc,IAAI;GAE9B,MAAM,YAAY,mBAChB,cAAc,IAChB;GACA,IAAI,WAAW;IACb,UAAU,QAAQ,UAAU;IAC5B,UAAU;IACV;GACF;EACF;CACF;CAGA,MAAM,cAA2B,CAAC;CAClC,MAAM,iBAAiC,CAAC;CAExC,KAAK,MAAM,CAAC,KAAK,kBAAkB,OAAO,QAAQ,MAAM,GAItD,IAAI,cAAc,SAAU,SAC1B,eAAe,OAAO;MAEtB,YAAY,OAAO;CAIvB,OAAO;EAAE;EAAa;CAAe;AACvC;AAEA,MAAM,wBAA0C,WAAc;CAE5D,OAAO,cAAc,QAAQ,CAAC,GAAG,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC;AACjE;AAEA,MAAa,mBACX,SACA,eACG;CACH,MAAM,EAAE,aAAa,mBAAmB,aAAa,SAAS,UAAU;CAExE,OAAO;EACL,aAAa,qBAAqB,WAAW;EAC7C,gBAAgB,qBAAqB,cAAc;CACrD;AACF"} |
+4
-4
| { | ||
| "name": "@assistant-ui/store", | ||
| "version": "0.2.12", | ||
| "version": "0.2.13", | ||
| "description": "Tap-based state management for @assistant-ui", | ||
@@ -33,3 +33,3 @@ "keywords": [ | ||
| "peerDependencies": { | ||
| "@assistant-ui/tap": "^0.5.12", | ||
| "@assistant-ui/tap": "^0.5.14", | ||
| "@types/react": "*", | ||
@@ -50,4 +50,4 @@ "react": "^18 || ^19" | ||
| "vitest": "^4.1.7", | ||
| "@assistant-ui/tap": "0.5.12", | ||
| "@assistant-ui/x-buildutils": "0.0.9" | ||
| "@assistant-ui/tap": "0.5.14", | ||
| "@assistant-ui/x-buildutils": "0.0.10" | ||
| }, | ||
@@ -54,0 +54,0 @@ "publishConfig": { |
@@ -49,3 +49,2 @@ // @vitest-environment jsdom | ||
| state, | ||
| // biome-ignore lint/suspicious/useIterableCallbackReturn: forEach callback intentionally has no return | ||
| notify: () => listeners.forEach((listener) => listener()), | ||
@@ -52,0 +51,0 @@ emitEvent: (event: string, payload: unknown) => { |
@@ -42,3 +42,2 @@ // @vitest-environment jsdom | ||
| proxiedState.item = itemState; | ||
| // biome-ignore lint/suspicious/useIterableCallbackReturn: forEach callback intentionally has no return | ||
| listeners.forEach((listener) => listener()); | ||
@@ -45,0 +44,0 @@ }, |
@@ -72,5 +72,5 @@ "use client"; | ||
| return ( | ||
| // biome-ignore lint/correctness/useExhaustiveDependencies: optimization | ||
| // oxlint-disable-next-line tap-hooks/exhaustive-deps -- memo over decomposed fields so we don't bust on a fresh `el` object each render | ||
| useMemo(() => el, [resultType, resultKey, resultProps]) ?? node | ||
| ); | ||
| }; |
@@ -39,3 +39,3 @@ import { | ||
| () => getElements().map((el) => ClientResourceWithKey(el)), | ||
| // biome-ignore lint/correctness/useExhaustiveDependencies: getElementsDeps is passed through from caller | ||
| // oxlint-disable-next-line tap-hooks/exhaustive-deps -- caller-supplied deps array | ||
| getElementsDeps, | ||
@@ -42,0 +42,0 @@ ); |
@@ -63,3 +63,2 @@ import type { ResourceElement } from "@assistant-ui/tap"; | ||
| */ | ||
| // biome-ignore lint/suspicious/noEmptyInterface: declaration merging | ||
| export interface ScopeRegistry {} | ||
@@ -66,0 +65,0 @@ |
@@ -9,5 +9,3 @@ import type { | ||
| type UnionToIntersection<U> = ( | ||
| U extends unknown | ||
| ? (x: U) => void | ||
| : never | ||
| U extends unknown ? (x: U) => void : never | ||
| ) extends (x: infer I) => void | ||
@@ -14,0 +12,0 @@ ? I |
+1
-2
@@ -48,3 +48,3 @@ "use client"; | ||
| const tapShallowMemoArray = <T>(array: readonly T[]) => { | ||
| // biome-ignore lint/correctness/useExhaustiveDependencies: shallow memo | ||
| // oxlint-disable-next-line tap-hooks/exhaustive-deps -- shallow memo over the array itself | ||
| return tapMemo(() => array, array); | ||
@@ -446,3 +446,2 @@ }; | ||
| if (clients) { | ||
| // biome-ignore lint/correctness/useHookAtTopLevel: intentional conditional/nested hook usage | ||
| return useResource( | ||
@@ -449,0 +448,0 @@ AssistantClientResource({ |
@@ -60,6 +60,3 @@ import { useEffect } from "react"; | ||
| const { scope, event } = normalizeEventSelector(selector); | ||
| useEffect( | ||
| () => aui.on({ scope, event }, callbackRef), | ||
| [aui, scope, event, callbackRef], | ||
| ); | ||
| useEffect(() => aui.on({ scope, event }, callbackRef), [aui, scope, event]); | ||
| }; |
@@ -68,3 +68,3 @@ import { Derived, type DerivedElement } from "../Derived"; | ||
| const tapShallowMemoObject = <T extends object>(object: T) => { | ||
| // biome-ignore lint/correctness/useExhaustiveDependencies: shallow memo | ||
| // oxlint-disable-next-line tap-hooks/exhaustive-deps -- shallow memo over the object's flattened entries | ||
| return tapMemo(() => object, [...Object.entries(object).flat()]); | ||
@@ -71,0 +71,0 @@ }; |
214450
-0.21%3712
-0.27%