skybridge 0.0.0-dev.8f4dd70 → 0.0.0-dev.92a31f3

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 (97) hide show
  1. package/README.md +196 -1
  2. package/dist/src/server/server.d.ts +1 -0
  3. package/dist/src/server/server.js +16 -9
  4. package/dist/src/server/server.js.map +1 -1
  5. package/dist/src/server/templateHelper.d.ts +15 -0
  6. package/dist/src/server/templateHelper.js +29 -0
  7. package/dist/src/server/templateHelper.js.map +1 -0
  8. package/dist/src/server/templates/development.hbs +12 -0
  9. package/dist/src/server/templates/production.hbs +6 -0
  10. package/dist/src/test/widget.test.js +23 -2
  11. package/dist/src/test/widget.test.js.map +1 -1
  12. package/dist/src/web/hooks/index.d.ts +13 -0
  13. package/dist/src/web/hooks/index.js +14 -0
  14. package/dist/src/web/hooks/index.js.map +1 -0
  15. package/dist/src/web/hooks/use-call-tool.d.ts +54 -0
  16. package/dist/src/web/hooks/use-call-tool.js +44 -0
  17. package/dist/src/web/hooks/use-call-tool.js.map +1 -0
  18. package/dist/src/web/hooks/use-call-tool.test.js +66 -0
  19. package/dist/src/web/hooks/use-call-tool.test.js.map +1 -0
  20. package/dist/src/web/hooks/use-display-mode.d.ts +4 -0
  21. package/dist/src/web/hooks/use-display-mode.js +7 -0
  22. package/dist/src/web/hooks/use-display-mode.js.map +1 -0
  23. package/dist/src/web/hooks/use-display-mode.test.d.ts +1 -0
  24. package/dist/src/web/hooks/use-display-mode.test.js +40 -0
  25. package/dist/src/web/hooks/use-display-mode.test.js.map +1 -0
  26. package/dist/src/web/hooks/use-locale.d.ts +1 -0
  27. package/dist/src/web/hooks/use-locale.js +5 -0
  28. package/dist/src/web/hooks/use-locale.js.map +1 -0
  29. package/dist/src/web/hooks/use-locale.test.d.ts +1 -0
  30. package/dist/src/web/hooks/use-locale.test.js +21 -0
  31. package/dist/src/web/hooks/use-locale.test.js.map +1 -0
  32. package/dist/src/web/hooks/use-open-external.d.ts +1 -0
  33. package/dist/src/web/hooks/use-open-external.js +6 -0
  34. package/dist/src/web/hooks/use-open-external.js.map +1 -0
  35. package/dist/src/web/hooks/use-open-external.test.d.ts +1 -0
  36. package/dist/src/web/hooks/use-open-external.test.js +24 -0
  37. package/dist/src/web/hooks/use-open-external.test.js.map +1 -0
  38. package/dist/src/web/{use-openai-global.d.ts → hooks/use-openai-global.d.ts} +1 -1
  39. package/dist/src/web/{use-openai-global.js → hooks/use-openai-global.js} +4 -2
  40. package/dist/src/web/hooks/use-openai-global.js.map +1 -0
  41. package/dist/src/web/hooks/use-request-modal.d.ts +5 -0
  42. package/dist/src/web/hooks/use-request-modal.js +9 -0
  43. package/dist/src/web/hooks/use-request-modal.js.map +1 -0
  44. package/dist/src/web/hooks/use-request-modal.test.d.ts +1 -0
  45. package/dist/src/web/hooks/use-request-modal.test.js +24 -0
  46. package/dist/src/web/hooks/use-request-modal.test.js.map +1 -0
  47. package/dist/src/web/hooks/use-send-follow-up-message.d.ts +1 -0
  48. package/dist/src/web/hooks/use-send-follow-up-message.js +11 -0
  49. package/dist/src/web/hooks/use-send-follow-up-message.js.map +1 -0
  50. package/dist/src/web/hooks/use-theme.d.ts +1 -0
  51. package/dist/src/web/hooks/use-theme.js +5 -0
  52. package/dist/src/web/hooks/use-theme.js.map +1 -0
  53. package/dist/src/web/hooks/use-theme.test.d.ts +1 -0
  54. package/dist/src/web/hooks/use-theme.test.js +26 -0
  55. package/dist/src/web/hooks/use-theme.test.js.map +1 -0
  56. package/dist/src/web/hooks/use-tool-info.d.ts +18 -0
  57. package/dist/src/web/hooks/use-tool-info.js +22 -0
  58. package/dist/src/web/hooks/use-tool-info.js.map +1 -0
  59. package/dist/src/web/hooks/use-tool-info.test.d.ts +1 -0
  60. package/dist/src/web/hooks/use-tool-info.test.js +59 -0
  61. package/dist/src/web/hooks/use-tool-info.test.js.map +1 -0
  62. package/dist/src/web/hooks/use-tool-output.d.ts +4 -0
  63. package/dist/src/web/hooks/use-tool-output.js +9 -0
  64. package/dist/src/web/hooks/use-tool-output.js.map +1 -0
  65. package/dist/src/web/hooks/use-tool-response-metadata.d.ts +4 -0
  66. package/dist/src/web/hooks/use-tool-response-metadata.js +8 -0
  67. package/dist/src/web/hooks/use-tool-response-metadata.js.map +1 -0
  68. package/dist/src/web/hooks/use-user-agent.d.ts +1 -0
  69. package/dist/src/web/hooks/use-user-agent.js +5 -0
  70. package/dist/src/web/hooks/use-user-agent.js.map +1 -0
  71. package/dist/src/web/hooks/use-user-agent.test.d.ts +1 -0
  72. package/dist/src/web/hooks/use-user-agent.test.js +31 -0
  73. package/dist/src/web/hooks/use-user-agent.test.js.map +1 -0
  74. package/dist/src/web/hooks/use-widget-state.d.ts +4 -0
  75. package/dist/src/web/hooks/use-widget-state.js +30 -0
  76. package/dist/src/web/hooks/use-widget-state.js.map +1 -0
  77. package/dist/src/web/hooks/use-widget-state.test.d.ts +1 -0
  78. package/dist/src/web/hooks/use-widget-state.test.js +60 -0
  79. package/dist/src/web/hooks/use-widget-state.test.js.map +1 -0
  80. package/dist/src/web/index.d.ts +2 -2
  81. package/dist/src/web/index.js +2 -2
  82. package/dist/src/web/index.js.map +1 -1
  83. package/dist/src/web/plugin.d.ts +2 -0
  84. package/dist/src/web/plugin.js +28 -0
  85. package/dist/src/web/plugin.js.map +1 -0
  86. package/dist/src/web/types.d.ts +20 -4
  87. package/dist/src/web/types.js.map +1 -1
  88. package/dist/vitest.config.js +0 -1
  89. package/dist/vitest.config.js.map +1 -1
  90. package/package.json +12 -4
  91. package/dist/src/test/setup.js +0 -9
  92. package/dist/src/test/setup.js.map +0 -1
  93. package/dist/src/web/use-openai-global.js.map +0 -1
  94. package/dist/src/web/use-tool-output.d.ts +0 -3
  95. package/dist/src/web/use-tool-output.js +0 -5
  96. package/dist/src/web/use-tool-output.js.map +0 -1
  97. /package/dist/src/{test/setup.d.ts → web/hooks/use-call-tool.test.d.ts} +0 -0
@@ -0,0 +1,40 @@
1
+ import { useDisplayMode } from "./use-display-mode.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach, } from "vitest";
3
+ import { renderHook, act } from "@testing-library/react";
4
+ describe("useDisplayMode", () => {
5
+ let OpenaiMock;
6
+ beforeEach(() => {
7
+ OpenaiMock = {
8
+ displayMode: "inline",
9
+ requestDisplayMode: vi.fn().mockResolvedValue({ mode: "inline" }),
10
+ };
11
+ vi.stubGlobal("openai", OpenaiMock);
12
+ });
13
+ afterEach(() => {
14
+ vi.unstubAllGlobals();
15
+ vi.resetAllMocks();
16
+ });
17
+ it("should return the current display mode from window.openai.displayMode", () => {
18
+ OpenaiMock.displayMode = "inline";
19
+ const { result } = renderHook(() => useDisplayMode());
20
+ expect(result.current[0]).toBe("inline");
21
+ });
22
+ it("should return different display modes when window.openai.displayMode changes", () => {
23
+ OpenaiMock.displayMode = "inline";
24
+ const { result, rerender } = renderHook(() => useDisplayMode());
25
+ expect(result.current[0]).toBe("inline");
26
+ OpenaiMock.displayMode = "fullscreen";
27
+ rerender();
28
+ expect(result.current[0]).toBe("fullscreen");
29
+ });
30
+ it("should call window.openai.requestDisplayMode with correct mode when setDisplayMode is called", async () => {
31
+ const { result } = renderHook(() => useDisplayMode());
32
+ await act(async () => {
33
+ await result.current[1]("fullscreen");
34
+ });
35
+ expect(OpenaiMock.requestDisplayMode).toHaveBeenCalledWith({
36
+ mode: "fullscreen",
37
+ });
38
+ });
39
+ });
40
+ //# sourceMappingURL=use-display-mode.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-display-mode.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-display-mode.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,QAAQ,EACR,EAAE,EACF,MAAM,EACN,EAAE,EACF,UAAU,EACV,SAAS,GAEV,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAGzD,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,UAGH,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG;YACX,WAAW,EAAE,QAAQ;YACrB,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;SAClE,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC;QAClC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QAEtD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC;QAClC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QAEhE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEzC,UAAU,CAAC,WAAW,GAAG,YAAY,CAAC;QACtC,QAAQ,EAAE,CAAC;QAEX,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC5G,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QAEtD,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;YACnB,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC;YACzD,IAAI,EAAE,YAAY;SACnB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useLocale(): string;
@@ -0,0 +1,5 @@
1
+ import { useOpenAiGlobal } from "./use-openai-global.js";
2
+ export function useLocale() {
3
+ return useOpenAiGlobal("locale");
4
+ }
5
+ //# sourceMappingURL=use-locale.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-locale.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-locale.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,UAAU,SAAS;IACvB,OAAO,eAAe,CAAC,QAAQ,CAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ import { useLocale } from "./use-locale.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
+ import { renderHook } from "@testing-library/react";
4
+ describe("useLocale", () => {
5
+ let OpenaiMock;
6
+ beforeEach(() => {
7
+ OpenaiMock = {
8
+ locale: "en-US",
9
+ };
10
+ vi.stubGlobal("openai", OpenaiMock);
11
+ });
12
+ afterEach(() => {
13
+ vi.unstubAllGlobals();
14
+ vi.resetAllMocks();
15
+ });
16
+ it("should return the current locale from window.openai.locale", () => {
17
+ const { result } = renderHook(() => useLocale());
18
+ expect(result.current).toBe("en-US");
19
+ });
20
+ });
21
+ //# sourceMappingURL=use-locale.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-locale.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-locale.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAI,UAEH,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG;YACX,MAAM,EAAE,OAAO;SAChB,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAEjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useOpenExternal(): (href: string) => void;
@@ -0,0 +1,6 @@
1
+ export function useOpenExternal() {
2
+ return (href) => {
3
+ window.openai.openExternal({ href });
4
+ };
5
+ }
6
+ //# sourceMappingURL=use-open-external.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-open-external.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-open-external.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,IAAY,EAAE,EAAE;QACtB,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { useOpenExternal } from "./use-open-external.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
+ import { renderHook } from "@testing-library/react";
4
+ describe("useOpenExternal", () => {
5
+ let openExternalMock;
6
+ beforeEach(() => {
7
+ openExternalMock = vi.fn();
8
+ vi.stubGlobal("openai", {
9
+ openExternal: openExternalMock,
10
+ });
11
+ });
12
+ afterEach(() => {
13
+ vi.unstubAllGlobals();
14
+ vi.resetAllMocks();
15
+ });
16
+ it("should return a function that calls window.openai.openExternal with the href", () => {
17
+ const { result } = renderHook(() => useOpenExternal());
18
+ const href = "https://example.com";
19
+ result.current(href);
20
+ expect(openExternalMock).toHaveBeenCalledTimes(1);
21
+ expect(openExternalMock).toHaveBeenCalledWith({ href });
22
+ });
23
+ });
24
+ //# sourceMappingURL=use-open-external.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-open-external.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-open-external.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,gBAA0C,CAAC;IAE/C,UAAU,CAAC,GAAG,EAAE;QACd,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;YACtB,YAAY,EAAE,gBAAgB;SAC/B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC;QAEvD,MAAM,IAAI,GAAG,qBAAqB,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAErB,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +1,2 @@
1
- import { type OpenAiGlobals } from "./types.js";
1
+ import { type OpenAiGlobals } from "../types.js";
2
2
  export declare function useOpenAiGlobal<K extends keyof OpenAiGlobals>(key: K): OpenAiGlobals[K] | undefined;
@@ -1,13 +1,15 @@
1
1
  import { useSyncExternalStore } from "react";
2
- import { SET_GLOBALS_EVENT_TYPE, SetGlobalsEvent } from "./types.js";
2
+ import { SET_GLOBALS_EVENT_TYPE, SetGlobalsEvent, } from "../types.js";
3
3
  export function useOpenAiGlobal(key) {
4
+ if (!window.openai) {
5
+ console.warn("openai is not defined on window. Please make sure to only call this hook inside the OpenAI iFrame skybridge runtime.");
6
+ }
4
7
  return useSyncExternalStore((onChange) => {
5
8
  const handleSetGlobal = (event) => {
6
9
  const value = event.detail.globals[key];
7
10
  if (value === undefined) {
8
11
  return;
9
12
  }
10
- console.dir(event.detail.globals, { depth: Infinity });
11
13
  onChange();
12
14
  };
13
15
  window.addEventListener(SET_GLOBALS_EVENT_TYPE, handleSetGlobal, {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-openai-global.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-openai-global.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,eAAe,GAEhB,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,eAAe,CAC7B,GAAM;IAEN,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CACV,sHAAsH,CACvH,CAAC;IACJ,CAAC;IAED,OAAO,oBAAoB,CACzB,CAAC,QAAQ,EAAE,EAAE;QACX,MAAM,eAAe,GAAG,CAAC,KAAsB,EAAE,EAAE;YACjD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YAED,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,eAAe,EAAE;YAC/D,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE;YACV,MAAM,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;QACtE,CAAC,CAAC;IACJ,CAAC,EACD,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAC3B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { RequestModalOptions } from "../types.js";
2
+ /**
3
+ * Triggers a modal containing the widget rendered in display mode "modal"
4
+ */
5
+ export declare function useRequestModal(): (options: RequestModalOptions) => void;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Triggers a modal containing the widget rendered in display mode "modal"
3
+ */
4
+ export function useRequestModal() {
5
+ return (options) => {
6
+ window.openai.requestModal(options);
7
+ };
8
+ }
9
+ //# sourceMappingURL=use-request-modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-request-modal.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-request-modal.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,OAA4B,EAAE,EAAE;QACtC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { useRequestModal } from "./use-request-modal.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
+ import { renderHook } from "@testing-library/react";
4
+ describe("useRequestModal", () => {
5
+ let requestModalMock;
6
+ beforeEach(() => {
7
+ requestModalMock = vi.fn();
8
+ vi.stubGlobal("openai", {
9
+ requestModal: requestModalMock,
10
+ });
11
+ });
12
+ afterEach(() => {
13
+ vi.unstubAllGlobals();
14
+ vi.resetAllMocks();
15
+ });
16
+ it("should return a function that calls window.openai.requestModal with the options", () => {
17
+ const { result } = renderHook(() => useRequestModal());
18
+ const options = { title: "Test Modal" };
19
+ result.current(options);
20
+ expect(requestModalMock).toHaveBeenCalledTimes(1);
21
+ expect(requestModalMock).toHaveBeenCalledWith(options);
22
+ });
23
+ });
24
+ //# sourceMappingURL=use-request-modal.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-request-modal.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-request-modal.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,gBAA0C,CAAC;IAE/C,UAAU,CAAC,GAAG,EAAE;QACd,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;YACtB,YAAY,EAAE,gBAAgB;SAC/B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC;QAEvD,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAExB,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useSendFollowUpMessage(): (prompt: string) => Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { useCallback } from "react";
2
+ export function useSendFollowUpMessage() {
3
+ const sendFollowUpMessage = useCallback(async (prompt) => {
4
+ if (!window.openai?.sendFollowUpMessage) {
5
+ throw new Error("window.openai.sendFollowUpMessage is not available");
6
+ }
7
+ return window.openai.sendFollowUpMessage({ prompt });
8
+ }, []);
9
+ return sendFollowUpMessage;
10
+ }
11
+ //# sourceMappingURL=use-send-follow-up-message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-send-follow-up-message.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-send-follow-up-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,MAAM,UAAU,sBAAsB;IACpC,MAAM,mBAAmB,GAAG,WAAW,CACrC,KAAK,EAAE,MAAc,EAAiB,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC,EACD,EAAE,CACH,CAAC;IAEF,OAAO,mBAAmB,CAAC;AAC7B,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useTheme(): import("../types.js").Theme;
@@ -0,0 +1,5 @@
1
+ import { useOpenAiGlobal } from "./use-openai-global.js";
2
+ export function useTheme() {
3
+ return useOpenAiGlobal("theme");
4
+ }
5
+ //# sourceMappingURL=use-theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-theme.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,UAAU,QAAQ;IACtB,OAAO,eAAe,CAAC,OAAO,CAAE,CAAC;AACnC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { useTheme } from "./use-theme.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
+ import { renderHook } from "@testing-library/react";
4
+ describe("useTheme", () => {
5
+ let OpenaiMock;
6
+ beforeEach(() => {
7
+ OpenaiMock = {
8
+ theme: "light",
9
+ };
10
+ vi.stubGlobal("openai", OpenaiMock);
11
+ });
12
+ afterEach(() => {
13
+ vi.unstubAllGlobals();
14
+ vi.resetAllMocks();
15
+ });
16
+ it("should return the current theme from window.openai.theme", () => {
17
+ const { result } = renderHook(() => useTheme());
18
+ expect(result.current).toBe("light");
19
+ });
20
+ it("should return dark theme when set to dark", () => {
21
+ OpenaiMock.theme = "dark";
22
+ const { result } = renderHook(() => useTheme());
23
+ expect(result.current).toBe("dark");
24
+ });
25
+ });
26
+ //# sourceMappingURL=use-theme.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-theme.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-theme.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAI,UAEH,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG;YACX,KAAK,EAAE,OAAO;SACf,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,UAAU,CAAC,KAAK,GAAG,MAAM,CAAC;QAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type UnknownObject } from "skybridge/web";
2
+ type BaseToolState<TStatus extends "pending" | "success", ToolInput extends UnknownObject, ToolOutput extends UnknownObject = UnknownObject, ToolResponseMetadata extends UnknownObject = UnknownObject> = {
3
+ status: TStatus;
4
+ isPending: TStatus extends "pending" ? true : false;
5
+ isSuccess: TStatus extends "success" ? true : false;
6
+ input: ToolInput;
7
+ output: TStatus extends "success" ? ToolOutput : undefined;
8
+ responseMetadata: TStatus extends "success" ? ToolResponseMetadata : undefined;
9
+ };
10
+ type PendingToolState<ToolInput extends UnknownObject> = BaseToolState<"pending", ToolInput>;
11
+ type SuccessToolState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = BaseToolState<"success", ToolInput, ToolOutput, ToolResponseMetadata>;
12
+ type ToolState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = PendingToolState<ToolInput> | SuccessToolState<ToolInput, ToolOutput, ToolResponseMetadata>;
13
+ export declare function useToolInfo<ToolSignature extends Partial<{
14
+ input: UnknownObject;
15
+ output: UnknownObject;
16
+ responseMetadata: UnknownObject;
17
+ }>>(): ToolState<ToolSignature["input"] extends UnknownObject ? ToolSignature["input"] : {}, ToolSignature["output"] extends UnknownObject ? ToolSignature["output"] : UnknownObject, ToolSignature["responseMetadata"] extends UnknownObject ? ToolSignature["responseMetadata"] : UnknownObject>;
18
+ export {};
@@ -0,0 +1,22 @@
1
+ import { useEffect, useState } from "react";
2
+ import { useOpenAiGlobal } from "skybridge/web";
3
+ export function useToolInfo() {
4
+ const [status, setStatus] = useState("pending");
5
+ const input = useOpenAiGlobal("toolInput");
6
+ const output = useOpenAiGlobal("toolOutput") ?? undefined;
7
+ const responseMetadata = useOpenAiGlobal("toolResponseMetadata") ?? undefined;
8
+ useEffect(() => {
9
+ setStatus(output === undefined && responseMetadata === undefined
10
+ ? "pending"
11
+ : "success");
12
+ }, [output, responseMetadata]);
13
+ return {
14
+ input,
15
+ status,
16
+ isPending: status === "pending",
17
+ isSuccess: status === "success",
18
+ output,
19
+ responseMetadata,
20
+ };
21
+ }
22
+ //# sourceMappingURL=use-tool-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-info.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-tool-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAsB,MAAM,eAAe,CAAC;AAoCpE,MAAM,UAAU,WAAW;IAOzB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAwB,SAAS,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,eAAe,CAAC,WAAW,CAAE,CAAC;IAC5C,MAAM,MAAM,GAAG,eAAe,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC;IAC1D,MAAM,gBAAgB,GAAG,eAAe,CAAC,sBAAsB,CAAC,IAAI,SAAS,CAAC;IAE9E,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,CACP,MAAM,KAAK,SAAS,IAAI,gBAAgB,KAAK,SAAS;YACpD,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,SAAS,CACd,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE/B,OAAO;QACL,KAAK;QACL,MAAM;QACN,SAAS,EAAE,MAAM,KAAK,SAAS;QAC/B,SAAS,EAAE,MAAM,KAAK,SAAS;QAC/B,MAAM;QACN,gBAAgB;KASjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ import { fireEvent, renderHook, waitFor, act } from "@testing-library/react";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { useToolInfo } from "./use-tool-info.js";
4
+ import { SET_GLOBALS_EVENT_TYPE, SetGlobalsEvent, } from "../types.js";
5
+ describe("useToolInfo", () => {
6
+ let OpenaiMock;
7
+ beforeEach(() => {
8
+ OpenaiMock = {
9
+ toolInput: { name: "pokemon", args: { name: "pikachu" } },
10
+ toolOutput: null,
11
+ toolResponseMetadata: null,
12
+ };
13
+ vi.stubGlobal("openai", OpenaiMock);
14
+ });
15
+ afterEach(() => {
16
+ vi.unstubAllGlobals();
17
+ vi.resetAllMocks();
18
+ });
19
+ it("should return toolInput on initial mount window.openai", () => {
20
+ const { result } = renderHook(() => useToolInfo());
21
+ expect(result.current).toMatchObject({
22
+ input: { name: "pokemon", args: { name: "pikachu" } },
23
+ status: "pending",
24
+ isPending: true,
25
+ isSuccess: false,
26
+ });
27
+ });
28
+ it("should eventually return tool output and response metadata once tool call completes", async () => {
29
+ const toolOutput = {
30
+ name: "pikachu",
31
+ color: "yellow",
32
+ description: "When several of these POKéMON gather, their\felectricity could build and cause lightning storms.",
33
+ };
34
+ const toolResponseMetadata = { id: 12 };
35
+ const { result } = renderHook(() => useToolInfo());
36
+ act(() => {
37
+ OpenaiMock.toolOutput = toolOutput;
38
+ OpenaiMock.toolResponseMetadata = toolResponseMetadata;
39
+ fireEvent(window, new SetGlobalsEvent(SET_GLOBALS_EVENT_TYPE, {
40
+ detail: {
41
+ globals: {
42
+ toolOutput,
43
+ toolResponseMetadata,
44
+ },
45
+ },
46
+ }));
47
+ });
48
+ await waitFor(() => {
49
+ expect(result.current).toMatchObject({
50
+ status: "success",
51
+ isPending: false,
52
+ isSuccess: true,
53
+ output: toolOutput,
54
+ responseMetadata: toolResponseMetadata,
55
+ });
56
+ });
57
+ });
58
+ });
59
+ //# sourceMappingURL=use-tool-info.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-info.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-tool-info.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,sBAAsB,EACtB,eAAe,GAEhB,MAAM,aAAa,CAAC;AAErB,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,UAGH,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG;YACX,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;YACzD,UAAU,EAAE,IAAI;YAChB,oBAAoB,EAAE,IAAI;SAC3B,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC;YACnC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;YACrD,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,KAAK,IAAI,EAAE;QACnG,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,QAAQ;YACf,WAAW,EACT,kGAAkG;SACrG,CAAC;QACF,MAAM,oBAAoB,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;QACxC,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAEnD,GAAG,CAAC,GAAG,EAAE;YACP,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;YACnC,UAAU,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;YACvD,SAAS,CACP,MAAM,EACN,IAAI,eAAe,CAAC,sBAAsB,EAAE;gBAC1C,MAAM,EAAE;oBACN,OAAO,EAAE;wBACP,UAAU;wBACV,oBAAoB;qBACrB;iBACF;aACF,CAAC,CACH,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC;gBACnC,MAAM,EAAE,SAAS;gBACjB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,UAAU;gBAClB,gBAAgB,EAAE,oBAAoB;aACvC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @deprecated This hook is deprecated. Use `useToolInfo()` instead and access the `output` property.
3
+ */
4
+ export declare function useToolOutput(): import("../types.js").UnknownObject | undefined;
@@ -0,0 +1,9 @@
1
+ import { useToolInfo } from "./use-tool-info.js";
2
+ /**
3
+ * @deprecated This hook is deprecated. Use `useToolInfo()` instead and access the `output` property.
4
+ */
5
+ export function useToolOutput() {
6
+ const { output } = useToolInfo();
7
+ return output;
8
+ }
9
+ //# sourceMappingURL=use-tool-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-output.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-tool-output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;IAEjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @deprecated This hook is deprecated. Use `useToolInfo()` instead and access the `responseMetadata` property.
3
+ */
4
+ export declare function useToolResponseMetadata(): import("../types.js").UnknownObject | null | undefined;
@@ -0,0 +1,8 @@
1
+ import { useOpenAiGlobal } from "./use-openai-global.js";
2
+ /**
3
+ * @deprecated This hook is deprecated. Use `useToolInfo()` instead and access the `responseMetadata` property.
4
+ */
5
+ export function useToolResponseMetadata() {
6
+ return useOpenAiGlobal("toolResponseMetadata");
7
+ }
8
+ //# sourceMappingURL=use-tool-response-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-response-metadata.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-tool-response-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,eAAe,CAAC,sBAAsB,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function useUserAgent(): import("../types.js").UserAgent;
@@ -0,0 +1,5 @@
1
+ import { useOpenAiGlobal } from "./use-openai-global.js";
2
+ export function useUserAgent() {
3
+ return useOpenAiGlobal("userAgent");
4
+ }
5
+ //# sourceMappingURL=use-user-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-user-agent.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-user-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,UAAU,YAAY;IAC1B,OAAO,eAAe,CAAC,WAAW,CAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { useUserAgent } from "./use-user-agent.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach, } from "vitest";
3
+ import { renderHook } from "@testing-library/react";
4
+ describe("useUserAgent", () => {
5
+ let OpenaiMock;
6
+ beforeEach(() => {
7
+ OpenaiMock = {
8
+ userAgent: {
9
+ device: { type: "mobile" },
10
+ capabilities: { hover: false, touch: true },
11
+ },
12
+ };
13
+ vi.stubGlobal("openai", OpenaiMock);
14
+ });
15
+ afterEach(() => {
16
+ vi.unstubAllGlobals();
17
+ vi.resetAllMocks();
18
+ });
19
+ it("should return the current user agent from window.openai.userAgent", () => {
20
+ OpenaiMock.userAgent = {
21
+ device: { type: "mobile" },
22
+ capabilities: { hover: false, touch: true },
23
+ };
24
+ const { result } = renderHook(() => useUserAgent());
25
+ expect(result.current).toEqual({
26
+ device: { type: "mobile" },
27
+ capabilities: { hover: false, touch: true },
28
+ });
29
+ });
30
+ });
31
+ //# sourceMappingURL=use-user-agent.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-user-agent.test.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-user-agent.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACL,QAAQ,EACR,EAAE,EACF,MAAM,EACN,EAAE,EACF,UAAU,EACV,SAAS,GAEV,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGpD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,UAEH,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG;YACX,SAAS,EAAE;gBACT,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC1B,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;aAC5C;SACF,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,UAAU,CAAC,SAAS,GAAG;YACrB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;SAC5C,CAAC;QACF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;QAEpD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;YAC7B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type SetStateAction } from "react";
2
+ import type { UnknownObject } from "../types.js";
3
+ export declare function useWidgetState<T extends UnknownObject>(defaultState: T | (() => T)): readonly [T, (state: SetStateAction<T>) => void];
4
+ export declare function useWidgetState<T extends UnknownObject>(defaultState?: T | (() => T | null) | null): readonly [T | null, (state: SetStateAction<T | null>) => void];
@@ -0,0 +1,30 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ import { useOpenAiGlobal } from "./use-openai-global.js";
3
+ export function useWidgetState(defaultState) {
4
+ const widgetStateFromWindow = useOpenAiGlobal("widgetState");
5
+ const [widgetState, _setWidgetState] = useState(() => {
6
+ if (widgetStateFromWindow !== null) {
7
+ return widgetStateFromWindow;
8
+ }
9
+ return typeof defaultState === "function"
10
+ ? defaultState()
11
+ : defaultState ?? null;
12
+ });
13
+ useEffect(() => {
14
+ // Fixes openai implementation bug
15
+ if (widgetStateFromWindow !== null) {
16
+ _setWidgetState(widgetStateFromWindow);
17
+ }
18
+ }, [widgetStateFromWindow]);
19
+ const setWidgetState = useCallback((state) => {
20
+ _setWidgetState((prevState) => {
21
+ const newState = typeof state === "function" ? state(prevState) : state;
22
+ if (newState !== null) {
23
+ window.openai.setWidgetState(newState);
24
+ }
25
+ return newState;
26
+ });
27
+ }, [window.openai.setWidgetState]);
28
+ return [widgetState, setWidgetState];
29
+ }
30
+ //# sourceMappingURL=use-widget-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-widget-state.js","sourceRoot":"","sources":["../../../../src/web/hooks/use-widget-state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAuB,MAAM,OAAO,CAAC;AAE9E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAQzD,MAAM,UAAU,cAAc,CAC5B,YAA0C;IAE1C,MAAM,qBAAqB,GAAG,eAAe,CAAC,aAAa,CAAM,CAAC;IAElE,MAAM,CAAC,WAAW,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAW,GAAG,EAAE;QAC7D,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO,qBAAqB,CAAC;QAC/B,CAAC;QAED,OAAO,OAAO,YAAY,KAAK,UAAU;YACvC,CAAC,CAAC,YAAY,EAAE;YAChB,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,kCAAkC;QAClC,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;YACnC,eAAe,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAE5B,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,KAA+B,EAAE,EAAE;QAClC,eAAe,CAAC,CAAC,SAAS,EAAE,EAAE;YAC5B,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAExE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;IACL,CAAC,EACD,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAC/B,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,cAAc,CAAU,CAAC;AAChD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ import { useWidgetState } from "./use-widget-state.js";
2
+ import { describe, it, expect, vi, beforeEach, afterEach, } from "vitest";
3
+ import { renderHook, act } from "@testing-library/react";
4
+ describe("useWidgetState", () => {
5
+ let OpenaiMock;
6
+ beforeEach(() => {
7
+ OpenaiMock = {
8
+ widgetState: null,
9
+ setWidgetState: vi.fn().mockResolvedValue(undefined),
10
+ };
11
+ vi.stubGlobal("openai", OpenaiMock);
12
+ });
13
+ afterEach(() => {
14
+ vi.unstubAllGlobals();
15
+ vi.resetAllMocks();
16
+ });
17
+ const defaultState = { count: 0, name: "test" };
18
+ const windowState = { count: 5, name: "window" };
19
+ it("should initialize with default state when window.openai.widgetState is null", () => {
20
+ OpenaiMock.widgetState = null;
21
+ const { result } = renderHook(() => useWidgetState(defaultState));
22
+ expect(result.current[0]).toEqual(defaultState);
23
+ });
24
+ it("should initialize with window.openai.widgetState when available", () => {
25
+ OpenaiMock.widgetState = windowState;
26
+ const { result } = renderHook(() => useWidgetState(defaultState));
27
+ expect(result.current[0]).toEqual(windowState);
28
+ });
29
+ it("should call window.openai.setWidgetState when setWidgetState is called with a new state", async () => {
30
+ const { result } = renderHook(() => useWidgetState(defaultState));
31
+ const newState = { count: 10, name: "updated" };
32
+ act(() => {
33
+ result.current[1](newState);
34
+ });
35
+ expect(OpenaiMock.setWidgetState).toHaveBeenCalledWith(newState);
36
+ expect(result.current[0]).toEqual(newState);
37
+ });
38
+ it("should call window.openai.setWidgetState when setWidgetState is called with a function updater", async () => {
39
+ const { result } = renderHook(() => useWidgetState(defaultState));
40
+ act(() => {
41
+ result.current[1]((prev) => ({ ...prev, count: prev.count + 1 }));
42
+ });
43
+ expect(OpenaiMock.setWidgetState).toHaveBeenCalledWith({
44
+ count: 1,
45
+ name: "test",
46
+ });
47
+ expect(result.current[0]).toEqual({ count: 1, name: "test" });
48
+ });
49
+ it("should update state when window.openai.widgetState changes", () => {
50
+ OpenaiMock.widgetState = defaultState;
51
+ const { result, rerender } = renderHook(() => useWidgetState(defaultState));
52
+ expect(result.current[0]).toEqual(defaultState);
53
+ // Simulate window.openai.widgetState changing
54
+ OpenaiMock.widgetState = windowState;
55
+ // Trigger re-render to simulate the useEffect running
56
+ rerender();
57
+ expect(result.current[0]).toEqual(windowState);
58
+ });
59
+ });
60
+ //# sourceMappingURL=use-widget-state.test.js.map