@assistant-ui/react-devtools 1.0.6 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +11 -47
  2. package/dist/DevToolsFrame.d.ts +9 -6
  3. package/dist/DevToolsFrame.d.ts.map +1 -1
  4. package/dist/DevToolsFrame.js +33 -24
  5. package/dist/DevToolsFrame.js.map +1 -1
  6. package/dist/DevToolsHost.d.ts +31 -29
  7. package/dist/DevToolsHost.d.ts.map +1 -1
  8. package/dist/DevToolsHost.js +81 -99
  9. package/dist/DevToolsHost.js.map +1 -1
  10. package/dist/DevToolsModal.d.ts +4 -1
  11. package/dist/DevToolsModal.d.ts.map +1 -1
  12. package/dist/DevToolsModal.js +132 -77
  13. package/dist/DevToolsModal.js.map +1 -1
  14. package/dist/ExtensionHost.d.ts +8 -5
  15. package/dist/ExtensionHost.d.ts.map +1 -1
  16. package/dist/ExtensionHost.js +40 -44
  17. package/dist/ExtensionHost.js.map +1 -1
  18. package/dist/FrameClient.d.ts +29 -27
  19. package/dist/FrameClient.d.ts.map +1 -1
  20. package/dist/FrameClient.js +52 -55
  21. package/dist/FrameClient.js.map +1 -1
  22. package/dist/FrameHost.d.ts +9 -6
  23. package/dist/FrameHost.d.ts.map +1 -1
  24. package/dist/FrameHost.js +24 -25
  25. package/dist/FrameHost.js.map +1 -1
  26. package/dist/constants.d.ts +5 -2
  27. package/dist/constants.d.ts.map +1 -1
  28. package/dist/constants.js +6 -2
  29. package/dist/constants.js.map +1 -1
  30. package/dist/index.d.ts +11 -11
  31. package/dist/index.js +10 -10
  32. package/dist/styles/DevToolsModal.styles.d.ts +16 -12
  33. package/dist/styles/DevToolsModal.styles.d.ts.map +1 -1
  34. package/dist/styles/DevToolsModal.styles.js +101 -103
  35. package/dist/styles/DevToolsModal.styles.js.map +1 -1
  36. package/dist/types.d.ts +12 -8
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/types.js +0 -2
  39. package/dist/utils/serialization.d.ts +7 -3
  40. package/dist/utils/serialization.d.ts.map +1 -1
  41. package/dist/utils/serialization.js +48 -76
  42. package/dist/utils/serialization.js.map +1 -1
  43. package/dist/utils/toolNormalization.d.ts +10 -7
  44. package/dist/utils/toolNormalization.d.ts.map +1 -1
  45. package/dist/utils/toolNormalization.js +38 -48
  46. package/dist/utils/toolNormalization.js.map +1 -1
  47. package/package.json +11 -11
  48. package/src/DevToolsModal.tsx +7 -1
  49. package/src/FrameClient.ts +2 -0
  50. package/src/utils/serialization.ts +7 -7
  51. package/src/utils/toolNormalization.ts +10 -10
  52. package/dist/index.d.ts.map +0 -1
  53. package/dist/index.js.map +0 -1
  54. package/dist/types.js.map +0 -1
package/README.md CHANGED
@@ -1,65 +1,29 @@
1
- # @assistant-ui/react-devtools
1
+ # `@assistant-ui/react-devtools`
2
2
 
3
- React-first development tools for assistant-ui components. This package ships the reusable React helpers, runtime adapters, and UI necessary to embed the DevTools experience in any host application.
4
-
5
- ## Features
6
-
7
- - **Component Library**: React components for debugging assistant-ui experiences
8
- - **Event Logging**: Track and inspect assistant-ui events and state changes
9
- - **Context Viewer**: View Assistant API context and state in real-time
10
- - **Embeddable Host**: Frame bridges that power custom hosts, including the Chrome extension
3
+ React DevTools UI for `@assistant-ui/react`. Embed an event log, context viewer, and runtime inspector in any host application.
11
4
 
12
5
  ## Installation
13
6
 
14
- ### As React Component Library
15
-
16
7
  ```bash
17
8
  npm install @assistant-ui/react-devtools
18
9
  ```
19
10
 
20
- ### As Chrome Extension
21
-
22
- See `apps/devtools-extension` for the standalone Chrome extension source and build scripts (`pnpm --filter @assistant-ui/devtools-extension run build`).
23
-
24
11
  ## Usage
25
12
 
26
- ### React Components
27
-
28
13
  ```tsx
29
- import { DevToolsUI, DevToolsModal } from '@assistant-ui/react-devtools';
30
-
31
- // Use the full DevTools UI
32
- <DevToolsUI />
14
+ import { DevToolsModal, DevToolsFrame } from "@assistant-ui/react-devtools";
33
15
 
34
- // Or use as a modal overlay
35
- <DevToolsModal />
36
- ```
37
-
38
- ### Chrome Extension
39
-
40
- The Chrome extension now lives under `apps/devtools-extension` as a separate workspace app. It consumes this package at build time to reuse the shared runtime and UI.
41
-
42
- ## Build Scripts
16
+ // render as a modal overlay
17
+ <DevToolsModal />;
43
18
 
44
- - `npm run build` - Build the React component library
45
- - `npm run build:lib` - Alias for `build`
46
- - `npm run dev` - Development build with watch mode
47
-
48
- ## Package Structure
49
-
50
- ```
51
- packages/react-devtools/
52
- ├── src/ # React component library source
53
- │ ├── DevToolsHooks.ts # Core devtools functionality
54
- │ ├── DevToolsModal.tsx # Modal wrapper component (iframe host)
55
- │ └── index.ts # Main exports
56
- └── scripts/ # Build scripts
19
+ // or embed inline as a frame
20
+ <DevToolsFrame />;
57
21
  ```
58
22
 
59
- ## Development
23
+ ## Chrome extension
60
24
 
61
- The devtools package builds with `@assistant-ui/x-buildutils` to transpile the TypeScript sources that power the React helpers and adapters consumed across the workspace.
25
+ A standalone Chrome extension consuming this package lives at [`apps/devtools-extension`](https://github.com/assistant-ui/assistant-ui/tree/main/apps/devtools-extension).
62
26
 
63
- ## License
27
+ ## Documentation
64
28
 
65
- MIT
29
+ Full reference at [assistant-ui.com/docs/devtools](https://www.assistant-ui.com/docs/devtools).
@@ -1,8 +1,11 @@
1
- export interface DevToolsFrameProps {
2
- frameUrl?: string;
3
- className?: string;
4
- style?: React.CSSProperties;
5
- title?: string;
1
+ //#region src/DevToolsFrame.d.ts
2
+ interface DevToolsFrameProps {
3
+ frameUrl?: string;
4
+ className?: string;
5
+ style?: React.CSSProperties;
6
+ title?: string;
6
7
  }
7
- export declare const DevToolsFrame: React.FC<DevToolsFrameProps>;
8
+ declare const DevToolsFrame: React.FC<DevToolsFrameProps>;
9
+ //#endregion
10
+ export { DevToolsFrame, DevToolsFrameProps };
8
11
  //# sourceMappingURL=DevToolsFrame.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsFrame.d.ts","sourceRoot":"","sources":["../src/DevToolsFrame.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyCtD,CAAC"}
1
+ {"version":3,"file":"DevToolsFrame.d.ts","names":[],"sources":["../src/DevToolsFrame.tsx"],"mappings":";UAMiB,kBAAA;EACf,QAAA;EACA,SAAA;EACA,KAAA,GAAQ,KAAA,CAAM,aAAa;EAC3B,KAAA;AAAA;AAAA,cAGW,aAAA,EAAe,KAAA,CAAM,EAAE,CAAC,kBAAA"}
@@ -1,29 +1,38 @@
1
1
  "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useMemo, useRef } from "react";
4
2
  import { FrameHost } from "./FrameHost.js";
5
3
  import { DEFAULT_FRAME_URL } from "./constants.js";
6
- export const DevToolsFrame = ({ frameUrl = DEFAULT_FRAME_URL, className, style, title = "assistant-ui DevTools", }) => {
7
- const iframeRef = useRef(null);
8
- const frameHostRef = useRef(null);
9
- const resolvedFrameUrl = useMemo(() => frameUrl, [frameUrl]);
10
- const handleFrameLoad = useCallback(() => {
11
- if (frameHostRef.current) {
12
- frameHostRef.current.destroy();
13
- frameHostRef.current = null;
14
- }
15
- if (iframeRef.current) {
16
- frameHostRef.current = new FrameHost(iframeRef.current);
17
- }
18
- }, []);
19
- useEffect(() => {
20
- return () => {
21
- if (frameHostRef.current) {
22
- frameHostRef.current.destroy();
23
- frameHostRef.current = null;
24
- }
25
- };
26
- }, []);
27
- return (_jsx("iframe", { ref: iframeRef, src: resolvedFrameUrl, onLoad: handleFrameLoad, className: className, style: style, title: title }));
4
+ import { useCallback, useEffect, useMemo, useRef } from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ //#region src/DevToolsFrame.tsx
7
+ const DevToolsFrame = ({ frameUrl = DEFAULT_FRAME_URL, className, style, title = "assistant-ui DevTools" }) => {
8
+ const iframeRef = useRef(null);
9
+ const frameHostRef = useRef(null);
10
+ const resolvedFrameUrl = useMemo(() => frameUrl, [frameUrl]);
11
+ const handleFrameLoad = useCallback(() => {
12
+ if (frameHostRef.current) {
13
+ frameHostRef.current.destroy();
14
+ frameHostRef.current = null;
15
+ }
16
+ if (iframeRef.current) frameHostRef.current = new FrameHost(iframeRef.current);
17
+ }, []);
18
+ useEffect(() => {
19
+ return () => {
20
+ if (frameHostRef.current) {
21
+ frameHostRef.current.destroy();
22
+ frameHostRef.current = null;
23
+ }
24
+ };
25
+ }, []);
26
+ return /* @__PURE__ */ jsx("iframe", {
27
+ ref: iframeRef,
28
+ src: resolvedFrameUrl,
29
+ onLoad: handleFrameLoad,
30
+ className,
31
+ style,
32
+ title
33
+ });
28
34
  };
35
+ //#endregion
36
+ export { DevToolsFrame };
37
+
29
38
  //# sourceMappingURL=DevToolsFrame.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsFrame.js","sourceRoot":"","sources":["../src/DevToolsFrame.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,uBAAoB;AACxC,OAAO,EAAE,iBAAiB,EAAE,uBAAoB;AAShD,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAC1D,QAAQ,GAAG,iBAAiB,EAC5B,SAAS,EACT,KAAK,EACL,KAAK,GAAG,uBAAuB,GAChC,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,MAAM,CAA2B,IAAI,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEpD,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE7D,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;QACvC,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;YACzB,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC/B,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;QAC9B,CAAC;QAED,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,YAAY,CAAC,OAAO,GAAG,IAAI,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,GAAG,EAAE;YACV,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;gBACzB,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAC/B,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,iBACE,GAAG,EAAE,SAAS,EACd,GAAG,EAAE,gBAAgB,EACrB,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,GACZ,CACH,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"DevToolsFrame.js","names":[],"sources":["../src/DevToolsFrame.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { FrameHost } from \"./FrameHost\";\nimport { DEFAULT_FRAME_URL } from \"./constants\";\n\nexport interface DevToolsFrameProps {\n frameUrl?: string;\n className?: string;\n style?: React.CSSProperties;\n title?: string;\n}\n\nexport const DevToolsFrame: React.FC<DevToolsFrameProps> = ({\n frameUrl = DEFAULT_FRAME_URL,\n className,\n style,\n title = \"assistant-ui DevTools\",\n}) => {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const frameHostRef = useRef<FrameHost | null>(null);\n\n const resolvedFrameUrl = useMemo(() => frameUrl, [frameUrl]);\n\n const handleFrameLoad = useCallback(() => {\n if (frameHostRef.current) {\n frameHostRef.current.destroy();\n frameHostRef.current = null;\n }\n\n if (iframeRef.current) {\n frameHostRef.current = new FrameHost(iframeRef.current);\n }\n }, []);\n\n useEffect(() => {\n return () => {\n if (frameHostRef.current) {\n frameHostRef.current.destroy();\n frameHostRef.current = null;\n }\n };\n }, []);\n\n return (\n <iframe\n ref={iframeRef}\n src={resolvedFrameUrl}\n onLoad={handleFrameLoad}\n className={className}\n style={style}\n title={title}\n />\n );\n};\n"],"mappings":";;;;;;AAaA,MAAa,iBAA+C,EAC1D,WAAW,mBACX,WACA,OACA,QAAQ,8BACJ;CACJ,MAAM,YAAY,OAAiC,IAAI;CACvD,MAAM,eAAe,OAAyB,IAAI;CAElD,MAAM,mBAAmB,cAAc,UAAU,CAAC,QAAQ,CAAC;CAE3D,MAAM,kBAAkB,kBAAkB;EACxC,IAAI,aAAa,SAAS;GACxB,aAAa,QAAQ,QAAQ;GAC7B,aAAa,UAAU;EACzB;EAEA,IAAI,UAAU,SACZ,aAAa,UAAU,IAAI,UAAU,UAAU,OAAO;CAE1D,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,aAAa;GACX,IAAI,aAAa,SAAS;IACxB,aAAa,QAAQ,QAAQ;IAC7B,aAAa,UAAU;GACzB;EACF;CACF,GAAG,CAAC,CAAC;CAEL,OACE,oBAAC,UAAD;EACE,KAAK;EACL,KAAK;EACL,QAAQ;EACG;EACJ;EACA;CACR,CAAA;AAEL"}
@@ -1,35 +1,37 @@
1
+ //#region src/DevToolsHost.d.ts
1
2
  interface FrameToHostMessage {
2
- type: "subscription" | "clearEvents";
3
- data: {
4
- apiList?: boolean;
5
- apis?: number[];
6
- apiId?: number;
7
- };
3
+ type: "subscription" | "clearEvents";
4
+ data: {
5
+ apiList?: boolean;
6
+ apis?: number[];
7
+ apiId?: number;
8
+ };
8
9
  }
9
10
  interface HostToFrameMessage {
10
- type: "update";
11
- data: {
12
- apiList?: Array<{
13
- apiId: number;
14
- }>;
15
- apis?: Array<{
16
- apiId: number;
17
- state: any;
18
- events: any[];
19
- modelContext?: any;
20
- }>;
21
- };
11
+ type: "update";
12
+ data: {
13
+ apiList?: Array<{
14
+ apiId: number;
15
+ }>;
16
+ apis?: Array<{
17
+ apiId: number;
18
+ state: any;
19
+ events: any[];
20
+ modelContext?: any;
21
+ }>;
22
+ };
22
23
  }
23
- export declare class DevToolsHost {
24
- private subscription;
25
- private unsubscribe?;
26
- private onSendMessage;
27
- constructor(onSendMessage: (message: HostToFrameMessage) => void);
28
- onReceiveMessage(message: FrameToHostMessage): void;
29
- private handleSubscription;
30
- private subscribeToDevTools;
31
- private sendUpdate;
32
- destroy(): void;
24
+ declare class DevToolsHost {
25
+ private subscription;
26
+ private unsubscribe?;
27
+ private onSendMessage;
28
+ constructor(onSendMessage: (message: HostToFrameMessage) => void);
29
+ onReceiveMessage(message: FrameToHostMessage): void;
30
+ private handleSubscription;
31
+ private subscribeToDevTools;
32
+ private sendUpdate;
33
+ destroy(): void;
33
34
  }
34
- export {};
35
+ //#endregion
36
+ export { DevToolsHost };
35
37
  //# sourceMappingURL=DevToolsHost.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsHost.d.ts","sourceRoot":"","sources":["../src/DevToolsHost.ts"],"names":[],"mappings":"AAMA,UAAU,kBAAkB;IAC1B,IAAI,EAAE,cAAc,GAAG,aAAa,CAAC;IACrC,IAAI,EAAE;QACJ,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,UAAU,kBAAkB;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,IAAI,EAAE;QACJ,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACnC,IAAI,CAAC,EAAE,KAAK,CAAC;YACX,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,GAAG,CAAC;YACX,MAAM,EAAE,GAAG,EAAE,CAAC;YACd,YAAY,CAAC,EAAE,GAAG,CAAC;SACpB,CAAC,CAAC;KACJ,CAAC;CACH;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAMlB;IACF,OAAO,CAAC,WAAW,CAAC,CAAa;IACjC,OAAO,CAAC,aAAa,CAAwC;gBAEjD,aAAa,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI;IAKhE,gBAAgB,CAAC,OAAO,EAAE,kBAAkB;IAc5C,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,mBAAmB;IAM3B,OAAO,CAAC,UAAU;IA+DlB,OAAO;CAKR"}
1
+ {"version":3,"file":"DevToolsHost.d.ts","names":[],"sources":["../src/DevToolsHost.ts"],"mappings":";UAMU,kBAAA;EACR,IAAA;EACA,IAAA;IACE,OAAA;IACA,IAAA;IACA,KAAA;EAAA;AAAA;AAAA,UAIM,kBAAA;EACR,IAAA;EACA,IAAA;IACE,OAAA,GAAU,KAAA;MAAQ,KAAA;IAAA;IAClB,IAAA,GAAO,KAAK;MACV,KAAA;MACA,KAAA;MACA,MAAA;MACA,YAAA;IAAA;EAAA;AAAA;AAAA,cAKO,YAAA;EAAA,QACH,YAAA;EAAA,QAOA,WAAA;EAAA,QACA,aAAA;cAEI,aAAA,GAAgB,OAAA,EAAS,kBAAA;EAKrC,gBAAA,CAAiB,OAAA,EAAS,kBAAkB;EAAA,QAcpC,kBAAA;EAAA,QAiBA,mBAAA;EAAA,QAMA,UAAA;EA+DR,OAAA,CAAA;AAAA"}
@@ -1,101 +1,83 @@
1
+ import { sanitizeForMessage, serializeModelContext } from "./utils/serialization.js";
1
2
  import { DevToolsHooks } from "@assistant-ui/react";
2
- import { sanitizeForMessage, serializeModelContext, } from "./utils/serialization.js";
3
- export class DevToolsHost {
4
- subscription = {
5
- apiList: false,
6
- apis: new Set(),
7
- };
8
- unsubscribe;
9
- onSendMessage;
10
- constructor(onSendMessage) {
11
- this.onSendMessage = onSendMessage;
12
- this.subscribeToDevTools();
13
- }
14
- onReceiveMessage(message) {
15
- switch (message.type) {
16
- case "subscription":
17
- this.handleSubscription(message.data);
18
- break;
19
- case "clearEvents":
20
- if (typeof message.data.apiId === "number") {
21
- DevToolsHooks.clearEventLogs(message.data.apiId);
22
- // The subscription will automatically trigger an update
23
- }
24
- break;
25
- }
26
- }
27
- handleSubscription(data) {
28
- const prevApiList = this.subscription.apiList;
29
- const prevApis = new Set(this.subscription.apis);
30
- this.subscription.apiList = data.apiList || false;
31
- this.subscription.apis = new Set(data.apis);
32
- // Only send update if subscription actually changed
33
- const apisChanged = prevApis.size !== this.subscription.apis.size ||
34
- [...this.subscription.apis].some((id) => !prevApis.has(id));
35
- if (prevApiList !== this.subscription.apiList || apisChanged) {
36
- this.sendUpdate();
37
- }
38
- }
39
- subscribeToDevTools() {
40
- this.unsubscribe = DevToolsHooks.subscribe(() => {
41
- this.sendUpdate();
42
- });
43
- }
44
- sendUpdate() {
45
- const update = {
46
- type: "update",
47
- data: {},
48
- };
49
- const allApis = DevToolsHooks.getApis();
50
- for (const subscriptionApiId of this.subscription.apis) {
51
- if (!allApis.has(subscriptionApiId)) {
52
- this.subscription.apis.delete(subscriptionApiId);
53
- }
54
- }
55
- if (this.subscription.apiList) {
56
- update.data.apiList = [...allApis.keys()].map((apiId) => ({ apiId }));
57
- if (this.subscription.apis.size === 0 && allApis.size > 0) {
58
- this.subscription.apis = new Set([allApis.keys().next().value]);
59
- }
60
- }
61
- if (this.subscription.apis.size > 0) {
62
- update.data.apis = [];
63
- for (const apiId of this.subscription.apis) {
64
- const apiEntry = allApis.get(apiId);
65
- if (apiEntry) {
66
- // Collect state from api scopes (only root source)
67
- const state = {};
68
- if (apiEntry.api) {
69
- for (const [name, scope] of Object.entries(apiEntry.api)) {
70
- if (typeof scope === "function" && "source" in scope) {
71
- // Only forward scopes with source === "root"
72
- if (scope.source === "root") {
73
- const scopeValue = scope();
74
- state[name] = scopeValue?.getState?.() ?? scopeValue;
75
- }
76
- }
77
- }
78
- }
79
- // Extract model context from thread runtime
80
- const modelContext = serializeModelContext(apiEntry.api?.thread?.().getModelContext());
81
- update.data.apis.push({
82
- apiId,
83
- state: sanitizeForMessage(state),
84
- events: sanitizeForMessage(apiEntry.logs),
85
- modelContext: modelContext,
86
- });
87
- }
88
- }
89
- }
90
- if (Object.keys(update.data).length === 0) {
91
- return;
92
- }
93
- this.onSendMessage(update);
94
- }
95
- destroy() {
96
- if (this.unsubscribe) {
97
- this.unsubscribe();
98
- }
99
- }
100
- }
3
+ //#region src/DevToolsHost.ts
4
+ var DevToolsHost = class {
5
+ subscription = {
6
+ apiList: false,
7
+ apis: /* @__PURE__ */ new Set()
8
+ };
9
+ unsubscribe;
10
+ onSendMessage;
11
+ constructor(onSendMessage) {
12
+ this.onSendMessage = onSendMessage;
13
+ this.subscribeToDevTools();
14
+ }
15
+ onReceiveMessage(message) {
16
+ switch (message.type) {
17
+ case "subscription":
18
+ this.handleSubscription(message.data);
19
+ break;
20
+ case "clearEvents":
21
+ if (typeof message.data.apiId === "number") DevToolsHooks.clearEventLogs(message.data.apiId);
22
+ break;
23
+ }
24
+ }
25
+ handleSubscription(data) {
26
+ const prevApiList = this.subscription.apiList;
27
+ const prevApis = new Set(this.subscription.apis);
28
+ this.subscription.apiList = data.apiList || false;
29
+ this.subscription.apis = new Set(data.apis);
30
+ const apisChanged = prevApis.size !== this.subscription.apis.size || [...this.subscription.apis].some((id) => !prevApis.has(id));
31
+ if (prevApiList !== this.subscription.apiList || apisChanged) this.sendUpdate();
32
+ }
33
+ subscribeToDevTools() {
34
+ this.unsubscribe = DevToolsHooks.subscribe(() => {
35
+ this.sendUpdate();
36
+ });
37
+ }
38
+ sendUpdate() {
39
+ const update = {
40
+ type: "update",
41
+ data: {}
42
+ };
43
+ const allApis = DevToolsHooks.getApis();
44
+ for (const subscriptionApiId of this.subscription.apis) if (!allApis.has(subscriptionApiId)) this.subscription.apis.delete(subscriptionApiId);
45
+ if (this.subscription.apiList) {
46
+ update.data.apiList = [...allApis.keys()].map((apiId) => ({ apiId }));
47
+ if (this.subscription.apis.size === 0 && allApis.size > 0) this.subscription.apis = new Set([allApis.keys().next().value]);
48
+ }
49
+ if (this.subscription.apis.size > 0) {
50
+ update.data.apis = [];
51
+ for (const apiId of this.subscription.apis) {
52
+ const apiEntry = allApis.get(apiId);
53
+ if (apiEntry) {
54
+ const state = {};
55
+ if (apiEntry.api) {
56
+ for (const [name, scope] of Object.entries(apiEntry.api)) if (typeof scope === "function" && "source" in scope) {
57
+ if (scope.source === "root") {
58
+ const scopeValue = scope();
59
+ state[name] = scopeValue?.getState?.() ?? scopeValue;
60
+ }
61
+ }
62
+ }
63
+ const modelContext = serializeModelContext(apiEntry.api?.thread?.().getModelContext());
64
+ update.data.apis.push({
65
+ apiId,
66
+ state: sanitizeForMessage(state),
67
+ events: sanitizeForMessage(apiEntry.logs),
68
+ modelContext
69
+ });
70
+ }
71
+ }
72
+ }
73
+ if (Object.keys(update.data).length === 0) return;
74
+ this.onSendMessage(update);
75
+ }
76
+ destroy() {
77
+ if (this.unsubscribe) this.unsubscribe();
78
+ }
79
+ };
80
+ //#endregion
81
+ export { DevToolsHost };
82
+
101
83
  //# sourceMappingURL=DevToolsHost.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsHost.js","sourceRoot":"","sources":["../src/DevToolsHost.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DevToolsHost.js","names":[],"sources":["../src/DevToolsHost.ts"],"sourcesContent":["import { DevToolsHooks } from \"@assistant-ui/react\";\nimport {\n sanitizeForMessage,\n serializeModelContext,\n} from \"./utils/serialization\";\n\ninterface FrameToHostMessage {\n type: \"subscription\" | \"clearEvents\";\n data: {\n apiList?: boolean;\n apis?: number[];\n apiId?: number;\n };\n}\n\ninterface HostToFrameMessage {\n type: \"update\";\n data: {\n apiList?: Array<{ apiId: number }>;\n apis?: Array<{\n apiId: number;\n state: any;\n events: any[];\n modelContext?: any;\n }>;\n };\n}\n\nexport class DevToolsHost {\n private subscription: {\n apiList: boolean;\n apis: Set<number>;\n } = {\n apiList: false,\n apis: new Set(),\n };\n private unsubscribe?: () => void;\n private onSendMessage: (message: HostToFrameMessage) => void;\n\n constructor(onSendMessage: (message: HostToFrameMessage) => void) {\n this.onSendMessage = onSendMessage;\n this.subscribeToDevTools();\n }\n\n onReceiveMessage(message: FrameToHostMessage) {\n switch (message.type) {\n case \"subscription\":\n this.handleSubscription(message.data);\n break;\n case \"clearEvents\":\n if (typeof message.data.apiId === \"number\") {\n DevToolsHooks.clearEventLogs(message.data.apiId);\n // The subscription will automatically trigger an update\n }\n break;\n }\n }\n\n private handleSubscription(data: FrameToHostMessage[\"data\"]) {\n const prevApiList = this.subscription.apiList;\n const prevApis = new Set(this.subscription.apis);\n\n this.subscription.apiList = data.apiList || false;\n this.subscription.apis = new Set(data.apis);\n\n // Only send update if subscription actually changed\n const apisChanged =\n prevApis.size !== this.subscription.apis.size ||\n [...this.subscription.apis].some((id) => !prevApis.has(id));\n\n if (prevApiList !== this.subscription.apiList || apisChanged) {\n this.sendUpdate();\n }\n }\n\n private subscribeToDevTools() {\n this.unsubscribe = DevToolsHooks.subscribe(() => {\n this.sendUpdate();\n });\n }\n\n private sendUpdate() {\n const update: HostToFrameMessage = {\n type: \"update\",\n data: {},\n };\n\n const allApis = DevToolsHooks.getApis();\n for (const subscriptionApiId of this.subscription.apis) {\n if (!allApis.has(subscriptionApiId)) {\n this.subscription.apis.delete(subscriptionApiId);\n }\n }\n\n if (this.subscription.apiList) {\n update.data.apiList = [...allApis.keys()].map((apiId) => ({ apiId }));\n\n if (this.subscription.apis.size === 0 && allApis.size > 0) {\n this.subscription.apis = new Set([allApis.keys().next().value!]);\n }\n }\n\n if (this.subscription.apis.size > 0) {\n update.data.apis = [];\n\n for (const apiId of this.subscription.apis) {\n const apiEntry = allApis.get(apiId);\n if (apiEntry) {\n // Collect state from api scopes (only root source)\n const state: Record<string, unknown> = {};\n if (apiEntry.api) {\n for (const [name, scope] of Object.entries(apiEntry.api)) {\n if (typeof scope === \"function\" && \"source\" in scope) {\n // Only forward scopes with source === \"root\"\n if (scope.source === \"root\") {\n const scopeValue = scope();\n state[name] = scopeValue?.getState?.() ?? scopeValue;\n }\n }\n }\n }\n\n // Extract model context from thread runtime\n const modelContext = serializeModelContext(\n apiEntry.api?.thread?.().getModelContext(),\n );\n\n update.data.apis.push({\n apiId,\n state: sanitizeForMessage(state),\n events: sanitizeForMessage(apiEntry.logs) as unknown[],\n modelContext: modelContext,\n });\n }\n }\n }\n\n if (Object.keys(update.data).length === 0) {\n return;\n }\n\n this.onSendMessage(update);\n }\n\n destroy() {\n if (this.unsubscribe) {\n this.unsubscribe();\n }\n }\n}\n"],"mappings":";;;AA4BA,IAAa,eAAb,MAA0B;CACxB,eAGI;EACF,SAAS;EACT,sBAAM,IAAI,IAAI;CAChB;CACA;CACA;CAEA,YAAY,eAAsD;EAChE,KAAK,gBAAgB;EACrB,KAAK,oBAAoB;CAC3B;CAEA,iBAAiB,SAA6B;EAC5C,QAAQ,QAAQ,MAAhB;GACE,KAAK;IACH,KAAK,mBAAmB,QAAQ,IAAI;IACpC;GACF,KAAK;IACH,IAAI,OAAO,QAAQ,KAAK,UAAU,UAChC,cAAc,eAAe,QAAQ,KAAK,KAAK;IAGjD;EACJ;CACF;CAEA,mBAA2B,MAAkC;EAC3D,MAAM,cAAc,KAAK,aAAa;EACtC,MAAM,WAAW,IAAI,IAAI,KAAK,aAAa,IAAI;EAE/C,KAAK,aAAa,UAAU,KAAK,WAAW;EAC5C,KAAK,aAAa,OAAO,IAAI,IAAI,KAAK,IAAI;EAG1C,MAAM,cACJ,SAAS,SAAS,KAAK,aAAa,KAAK,QACzC,CAAC,GAAG,KAAK,aAAa,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;EAE5D,IAAI,gBAAgB,KAAK,aAAa,WAAW,aAC/C,KAAK,WAAW;CAEpB;CAEA,sBAA8B;EAC5B,KAAK,cAAc,cAAc,gBAAgB;GAC/C,KAAK,WAAW;EAClB,CAAC;CACH;CAEA,aAAqB;EACnB,MAAM,SAA6B;GACjC,MAAM;GACN,MAAM,CAAC;EACT;EAEA,MAAM,UAAU,cAAc,QAAQ;EACtC,KAAK,MAAM,qBAAqB,KAAK,aAAa,MAChD,IAAI,CAAC,QAAQ,IAAI,iBAAiB,GAChC,KAAK,aAAa,KAAK,OAAO,iBAAiB;EAInD,IAAI,KAAK,aAAa,SAAS;GAC7B,OAAO,KAAK,UAAU,CAAC,GAAG,QAAQ,KAAK,CAAC,EAAE,KAAK,WAAW,EAAE,MAAM,EAAE;GAEpE,IAAI,KAAK,aAAa,KAAK,SAAS,KAAK,QAAQ,OAAO,GACtD,KAAK,aAAa,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,EAAE,KAAK,EAAE,KAAM,CAAC;EAEnE;EAEA,IAAI,KAAK,aAAa,KAAK,OAAO,GAAG;GACnC,OAAO,KAAK,OAAO,CAAC;GAEpB,KAAK,MAAM,SAAS,KAAK,aAAa,MAAM;IAC1C,MAAM,WAAW,QAAQ,IAAI,KAAK;IAClC,IAAI,UAAU;KAEZ,MAAM,QAAiC,CAAC;KACxC,IAAI,SAAS;WACN,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,SAAS,GAAG,GACrD,IAAI,OAAO,UAAU,cAAc,YAAY;WAEzC,MAAM,WAAW,QAAQ;QAC3B,MAAM,aAAa,MAAM;QACzB,MAAM,QAAQ,YAAY,WAAW,KAAK;OAC5C;;;KAMN,MAAM,eAAe,sBACnB,SAAS,KAAK,SAAS,EAAE,gBAAgB,CAC3C;KAEA,OAAO,KAAK,KAAK,KAAK;MACpB;MACA,OAAO,mBAAmB,KAAK;MAC/B,QAAQ,mBAAmB,SAAS,IAAI;MAC1B;KAChB,CAAC;IACH;GACF;EACF;EAEA,IAAI,OAAO,KAAK,OAAO,IAAI,EAAE,WAAW,GACtC;EAGF,KAAK,cAAc,MAAM;CAC3B;CAEA,UAAU;EACR,IAAI,KAAK,aACP,KAAK,YAAY;CAErB;AACF"}
@@ -1,2 +1,5 @@
1
- export declare const DevToolsModal: () => import("react/jsx-runtime").JSX.Element | null;
1
+ //#region src/DevToolsModal.d.ts
2
+ declare const DevToolsModal: () => import("react/jsx-runtime").JSX.Element | null;
3
+ //#endregion
4
+ export { DevToolsModal };
2
5
  //# sourceMappingURL=DevToolsModal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsModal.d.ts","sourceRoot":"","sources":["../src/DevToolsModal.tsx"],"names":[],"mappings":"AA6KA,eAAO,MAAM,aAAa,sDAWzB,CAAC"}
1
+ {"version":3,"file":"DevToolsModal.d.ts","names":[],"sources":["../src/DevToolsModal.tsx"],"mappings":";cAmLa,aAAA,oCAAa,GAAA,CAAA,OAAA"}