sunpeak 0.9.3 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/chatgpt/conversation.d.ts +5 -2
- package/dist/chatgpt/iframe-resource.d.ts +69 -0
- package/dist/chatgpt/index.cjs +2 -1
- package/dist/chatgpt/index.cjs.map +1 -1
- package/dist/chatgpt/index.d.ts +1 -0
- package/dist/chatgpt/index.js +2 -1
- package/dist/chatgpt/simple-sidebar.d.ts +2 -2
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -2
- package/dist/{simulator-url-CG8lAAC3.cjs → simulator-url-BpCa95pE.cjs} +876 -251
- package/dist/simulator-url-BpCa95pE.cjs.map +1 -0
- package/dist/{simulator-url-CexnaL-e.js → simulator-url-q5tHLc4-.js} +876 -251
- package/dist/simulator-url-q5tHLc4-.js.map +1 -0
- package/dist/style.css +12 -0
- package/dist/types/simulation.d.ts +4 -1
- package/package.json +1 -1
- package/template/README.md +2 -2
- package/template/dist/albums.js +7 -7
- package/template/dist/albums.json +1 -1
- package/template/dist/carousel.js +6 -6
- package/template/dist/carousel.json +1 -1
- package/template/dist/map.js +17 -17
- package/template/dist/map.json +1 -1
- package/template/dist/review.js +7 -7
- package/template/dist/review.json +1 -1
- package/template/node_modules/.vite/deps/_metadata.json +19 -19
- package/template/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/template/src/components/album/album-carousel.tsx +28 -3
- package/template/src/components/carousel/carousel.tsx +28 -3
- package/dist/simulator-url-CG8lAAC3.cjs.map +0 -1
- package/dist/simulator-url-CexnaL-e.js.map +0 -1
|
@@ -57,19 +57,38 @@ class OpenAiProvider {
|
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
getAPI() {
|
|
60
|
-
var _a2, _b2, _c, _d, _e, _f, _g;
|
|
61
60
|
if (typeof window === "undefined" || !window.openai) {
|
|
62
61
|
return null;
|
|
63
62
|
}
|
|
64
|
-
const api = window.openai;
|
|
65
63
|
return {
|
|
66
|
-
callTool: (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
callTool: (...args) => {
|
|
65
|
+
var _a2, _b2;
|
|
66
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.callTool) == null ? void 0 : _b2.call(_a2, ...args);
|
|
67
|
+
},
|
|
68
|
+
sendFollowUpMessage: (...args) => {
|
|
69
|
+
var _a2, _b2;
|
|
70
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.sendFollowUpMessage) == null ? void 0 : _b2.call(_a2, ...args);
|
|
71
|
+
},
|
|
72
|
+
openExternal: (...args) => {
|
|
73
|
+
var _a2, _b2;
|
|
74
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.openExternal) == null ? void 0 : _b2.call(_a2, ...args);
|
|
75
|
+
},
|
|
76
|
+
requestDisplayMode: (...args) => {
|
|
77
|
+
var _a2, _b2;
|
|
78
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.requestDisplayMode) == null ? void 0 : _b2.call(_a2, ...args);
|
|
79
|
+
},
|
|
80
|
+
requestModal: (...args) => {
|
|
81
|
+
var _a2, _b2;
|
|
82
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.requestModal) == null ? void 0 : _b2.call(_a2, ...args);
|
|
83
|
+
},
|
|
84
|
+
notifyIntrinsicHeight: (...args) => {
|
|
85
|
+
var _a2, _b2;
|
|
86
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.notifyIntrinsicHeight) == null ? void 0 : _b2.call(_a2, ...args);
|
|
87
|
+
},
|
|
88
|
+
setWidgetState: (...args) => {
|
|
89
|
+
var _a2, _b2;
|
|
90
|
+
return (_b2 = (_a2 = window.openai) == null ? void 0 : _a2.setWidgetState) == null ? void 0 : _b2.call(_a2, ...args);
|
|
91
|
+
}
|
|
73
92
|
};
|
|
74
93
|
}
|
|
75
94
|
}
|
|
@@ -172,8 +191,17 @@ function useWidgetState(defaultState) {
|
|
|
172
191
|
}
|
|
173
192
|
return typeof defaultState === "function" ? defaultState() : defaultState ?? null;
|
|
174
193
|
});
|
|
194
|
+
const hasSentInitialState = React.useRef(false);
|
|
195
|
+
React.useEffect(() => {
|
|
196
|
+
if (!hasSentInitialState.current && widgetStateFromProvider == null && widgetState != null && (api == null ? void 0 : api.setWidgetState)) {
|
|
197
|
+
hasSentInitialState.current = true;
|
|
198
|
+
api.setWidgetState(widgetState);
|
|
199
|
+
}
|
|
200
|
+
}, [api, widgetState, widgetStateFromProvider]);
|
|
175
201
|
React.useEffect(() => {
|
|
176
|
-
|
|
202
|
+
if (widgetStateFromProvider != null) {
|
|
203
|
+
_setWidgetState(widgetStateFromProvider);
|
|
204
|
+
}
|
|
177
205
|
}, [widgetStateFromProvider]);
|
|
178
206
|
const setWidgetState = React.useCallback(
|
|
179
207
|
(state) => {
|
|
@@ -5625,7 +5653,7 @@ const useEscCloseStack = (listening, cb) => {
|
|
|
5625
5653
|
}, [id, listening, latestCallback]);
|
|
5626
5654
|
};
|
|
5627
5655
|
const __vite_import_meta_env__ = { "DEV": false, "MODE": "production" };
|
|
5628
|
-
const META_ENV = typeof { url: typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("simulator-url-
|
|
5656
|
+
const META_ENV = typeof { url: typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("simulator-url-BpCa95pE.cjs", document.baseURI).href } !== "undefined" ? __vite_import_meta_env__ : void 0;
|
|
5629
5657
|
const NODE_ENV = typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.NODE_ENV) ? (_b = process.env) == null ? void 0 : _b.NODE_ENV : "production";
|
|
5630
5658
|
const isDev = NODE_ENV === "development" || !!(META_ENV == null ? void 0 : META_ENV.DEV);
|
|
5631
5659
|
const isJSDomLike = typeof navigator !== "undefined" && /(jsdom|happy-dom)/i.test(navigator.userAgent) || typeof globalThis.happyDOM === "object";
|
|
@@ -7520,9 +7548,11 @@ function SidebarTextarea({
|
|
|
7520
7548
|
onFocus,
|
|
7521
7549
|
onBlur,
|
|
7522
7550
|
placeholder,
|
|
7523
|
-
|
|
7551
|
+
maxRows = 8,
|
|
7524
7552
|
error
|
|
7525
7553
|
}) {
|
|
7554
|
+
const contentRows = (value == null ? void 0 : value.split("\n").length) ?? 1;
|
|
7555
|
+
const rows = Math.min(contentRows, maxRows);
|
|
7526
7556
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
7527
7557
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7528
7558
|
Textarea,
|
|
@@ -7534,7 +7564,8 @@ function SidebarTextarea({
|
|
|
7534
7564
|
placeholder,
|
|
7535
7565
|
rows,
|
|
7536
7566
|
size: "2xs",
|
|
7537
|
-
className: "text-[10px] font-mono",
|
|
7567
|
+
className: "text-[10px] font-mono resize-y",
|
|
7568
|
+
style: { whiteSpace: "pre", overflowX: "auto", overflowWrap: "normal" },
|
|
7538
7569
|
invalid: !!error
|
|
7539
7570
|
}
|
|
7540
7571
|
),
|
|
@@ -7560,8 +7591,591 @@ const SCREEN_WIDTHS = {
|
|
|
7560
7591
|
tablet: 768,
|
|
7561
7592
|
full: 1024
|
|
7562
7593
|
};
|
|
7594
|
+
const ALLOWED_SCRIPT_ORIGINS = [
|
|
7595
|
+
"https://sandbox.sunpeakai.com",
|
|
7596
|
+
"http://localhost",
|
|
7597
|
+
"https://localhost",
|
|
7598
|
+
"http://127.0.0.1",
|
|
7599
|
+
"https://127.0.0.1"
|
|
7600
|
+
];
|
|
7601
|
+
const ALLOWED_PARENT_ORIGINS = [
|
|
7602
|
+
"https://app.sunpeak.ai",
|
|
7603
|
+
"http://localhost",
|
|
7604
|
+
"https://localhost",
|
|
7605
|
+
"http://127.0.0.1",
|
|
7606
|
+
"https://127.0.0.1"
|
|
7607
|
+
];
|
|
7608
|
+
function escapeHtml(str) {
|
|
7609
|
+
return str.replace(/[&<>"']/g, (c) => {
|
|
7610
|
+
const entities = {
|
|
7611
|
+
"&": "&",
|
|
7612
|
+
"<": "<",
|
|
7613
|
+
">": ">",
|
|
7614
|
+
'"': """,
|
|
7615
|
+
"'": "'"
|
|
7616
|
+
};
|
|
7617
|
+
return entities[c] ?? c;
|
|
7618
|
+
});
|
|
7619
|
+
}
|
|
7620
|
+
function isAllowedScriptSrc(src) {
|
|
7621
|
+
if (!src) {
|
|
7622
|
+
return false;
|
|
7623
|
+
}
|
|
7624
|
+
if (src.startsWith("/") && !src.startsWith("//")) {
|
|
7625
|
+
return true;
|
|
7626
|
+
}
|
|
7627
|
+
if (!src.includes("://")) {
|
|
7628
|
+
return false;
|
|
7629
|
+
}
|
|
7630
|
+
try {
|
|
7631
|
+
const url = new URL(src);
|
|
7632
|
+
if (url.origin === window.location.origin) {
|
|
7633
|
+
return true;
|
|
7634
|
+
}
|
|
7635
|
+
if (url.hostname === "localhost" || url.hostname === "127.0.0.1") {
|
|
7636
|
+
return true;
|
|
7637
|
+
}
|
|
7638
|
+
return ALLOWED_SCRIPT_ORIGINS.some((allowed) => {
|
|
7639
|
+
try {
|
|
7640
|
+
const allowedUrl = new URL(allowed);
|
|
7641
|
+
return url.origin === allowedUrl.origin;
|
|
7642
|
+
} catch {
|
|
7643
|
+
return false;
|
|
7644
|
+
}
|
|
7645
|
+
});
|
|
7646
|
+
} catch {
|
|
7647
|
+
return false;
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7650
|
+
function generateCSP(csp, scriptSrc) {
|
|
7651
|
+
let scriptOrigin = "";
|
|
7652
|
+
try {
|
|
7653
|
+
const scriptUrl = new URL(scriptSrc, window.location.origin);
|
|
7654
|
+
scriptOrigin = scriptUrl.origin;
|
|
7655
|
+
} catch {
|
|
7656
|
+
}
|
|
7657
|
+
const directives = [
|
|
7658
|
+
"default-src 'self'",
|
|
7659
|
+
// Allow inline scripts for the bridge, blob: for dynamic content, and the script origin
|
|
7660
|
+
`script-src 'self' 'unsafe-inline' blob: ${scriptOrigin}`.trim(),
|
|
7661
|
+
// Allow inline styles and data: URIs for images embedded in CSS
|
|
7662
|
+
`style-src 'self' 'unsafe-inline' ${scriptOrigin}`.trim(),
|
|
7663
|
+
// Disallow iframes within the iframe (no nesting)
|
|
7664
|
+
"frame-src 'none'",
|
|
7665
|
+
// Disallow form submissions
|
|
7666
|
+
"form-action 'none'",
|
|
7667
|
+
// Disallow changing the base URL
|
|
7668
|
+
"base-uri 'self'"
|
|
7669
|
+
];
|
|
7670
|
+
const connectSources = /* @__PURE__ */ new Set(["'self'"]);
|
|
7671
|
+
if (scriptOrigin) {
|
|
7672
|
+
connectSources.add(scriptOrigin);
|
|
7673
|
+
}
|
|
7674
|
+
if (csp == null ? void 0 : csp.connect_domains) {
|
|
7675
|
+
for (const domain of csp.connect_domains) {
|
|
7676
|
+
connectSources.add(domain);
|
|
7677
|
+
}
|
|
7678
|
+
}
|
|
7679
|
+
directives.push(`connect-src ${Array.from(connectSources).join(" ")}`);
|
|
7680
|
+
const resourceSources = /* @__PURE__ */ new Set(["'self'", "data:", "blob:"]);
|
|
7681
|
+
if (scriptOrigin) {
|
|
7682
|
+
resourceSources.add(scriptOrigin);
|
|
7683
|
+
}
|
|
7684
|
+
if (csp == null ? void 0 : csp.resource_domains) {
|
|
7685
|
+
for (const domain of csp.resource_domains) {
|
|
7686
|
+
resourceSources.add(domain);
|
|
7687
|
+
}
|
|
7688
|
+
}
|
|
7689
|
+
const resourceList = Array.from(resourceSources).join(" ");
|
|
7690
|
+
directives.push(`img-src ${resourceList}`);
|
|
7691
|
+
directives.push(`font-src ${resourceList}`);
|
|
7692
|
+
directives.push(`media-src ${resourceList}`);
|
|
7693
|
+
return directives.join("; ");
|
|
7694
|
+
}
|
|
7695
|
+
function generateBridgeScript(allowedParentOrigins) {
|
|
7696
|
+
const originsJson = JSON.stringify(allowedParentOrigins);
|
|
7697
|
+
return `
|
|
7698
|
+
<script>
|
|
7699
|
+
(function() {
|
|
7700
|
+
// Allowed origins that can send messages to this iframe
|
|
7701
|
+
var allowedOrigins = ${originsJson};
|
|
7702
|
+
|
|
7703
|
+
// MessagePort for secure communication with parent (set during handshake)
|
|
7704
|
+
var messagePort = null;
|
|
7705
|
+
|
|
7706
|
+
// Queue messages until port is ready
|
|
7707
|
+
var messageQueue = [];
|
|
7708
|
+
|
|
7709
|
+
// Check if an origin is allowed (handles localhost with any port)
|
|
7710
|
+
function isAllowedOrigin(origin) {
|
|
7711
|
+
// Note: We no longer accept 'null' origin - MessageChannel provides security
|
|
7712
|
+
for (var i = 0; i < allowedOrigins.length; i++) {
|
|
7713
|
+
if (origin === allowedOrigins[i]) return true;
|
|
7714
|
+
// Handle localhost/127.0.0.1 with any port
|
|
7715
|
+
if (allowedOrigins[i].indexOf('localhost') !== -1 || allowedOrigins[i].indexOf('127.0.0.1') !== -1) {
|
|
7716
|
+
try {
|
|
7717
|
+
var allowed = new URL(allowedOrigins[i]);
|
|
7718
|
+
var test = new URL(origin);
|
|
7719
|
+
if (test.hostname === allowed.hostname && test.protocol === allowed.protocol) return true;
|
|
7720
|
+
} catch (e) {}
|
|
7721
|
+
}
|
|
7722
|
+
}
|
|
7723
|
+
return false;
|
|
7724
|
+
}
|
|
7725
|
+
|
|
7726
|
+
// Send message via MessagePort (queues if port not ready)
|
|
7727
|
+
function sendToParent(message) {
|
|
7728
|
+
if (messagePort) {
|
|
7729
|
+
messagePort.postMessage(message);
|
|
7730
|
+
} else {
|
|
7731
|
+
messageQueue.push(message);
|
|
7732
|
+
}
|
|
7733
|
+
}
|
|
7734
|
+
|
|
7735
|
+
// Flush queued messages once port is ready
|
|
7736
|
+
function flushMessageQueue() {
|
|
7737
|
+
while (messageQueue.length > 0) {
|
|
7738
|
+
var msg = messageQueue.shift();
|
|
7739
|
+
messagePort.postMessage(msg);
|
|
7740
|
+
}
|
|
7741
|
+
}
|
|
7742
|
+
|
|
7743
|
+
// Set up window.openai with placeholder values (updated via MessageChannel)
|
|
7744
|
+
window.openai = {
|
|
7745
|
+
theme: 'dark',
|
|
7746
|
+
locale: 'en-US',
|
|
7747
|
+
displayMode: 'inline',
|
|
7748
|
+
maxHeight: undefined,
|
|
7749
|
+
userAgent: { device: { type: 'desktop' }, capabilities: { hover: true, touch: false } },
|
|
7750
|
+
safeArea: { insets: { top: 0, bottom: 0, left: 0, right: 0 } },
|
|
7751
|
+
view: null,
|
|
7752
|
+
toolInput: {},
|
|
7753
|
+
toolOutput: null,
|
|
7754
|
+
toolResponseMetadata: null,
|
|
7755
|
+
widgetState: null,
|
|
7756
|
+
|
|
7757
|
+
// API methods that send messages to parent via MessagePort
|
|
7758
|
+
callTool: function(name, args) {
|
|
7759
|
+
sendToParent({ type: 'openai:callTool', payload: { name, args } });
|
|
7760
|
+
},
|
|
7761
|
+
sendFollowUpMessage: function(params) {
|
|
7762
|
+
sendToParent({ type: 'openai:sendFollowUpMessage', payload: params });
|
|
7763
|
+
},
|
|
7764
|
+
openExternal: function(params) {
|
|
7765
|
+
sendToParent({ type: 'openai:openExternal', payload: params });
|
|
7766
|
+
},
|
|
7767
|
+
requestDisplayMode: function(params) {
|
|
7768
|
+
sendToParent({ type: 'openai:requestDisplayMode', payload: params });
|
|
7769
|
+
},
|
|
7770
|
+
requestModal: function(params) {
|
|
7771
|
+
sendToParent({ type: 'openai:requestModal', payload: params });
|
|
7772
|
+
},
|
|
7773
|
+
notifyIntrinsicHeight: function(height) {
|
|
7774
|
+
// Height updates use postMessage directly to avoid delays during handshake.
|
|
7775
|
+
// This is safe because height values are validated on the parent side.
|
|
7776
|
+
window.parent.postMessage({ type: 'openai:notifyIntrinsicHeight', payload: { height } }, '*');
|
|
7777
|
+
},
|
|
7778
|
+
setWidgetState: function(state) {
|
|
7779
|
+
sendToParent({ type: 'openai:setWidgetState', payload: state });
|
|
7780
|
+
},
|
|
7781
|
+
};
|
|
7782
|
+
|
|
7783
|
+
// Handle incoming messages on the MessagePort
|
|
7784
|
+
function handlePortMessage(event) {
|
|
7785
|
+
var data = event.data;
|
|
7786
|
+
if (!data || typeof data !== 'object') return;
|
|
7787
|
+
|
|
7788
|
+
if (data.type === 'openai:init' || data.type === 'openai:update') {
|
|
7789
|
+
var payload = data.payload || {};
|
|
7790
|
+
|
|
7791
|
+
// Update window.openai with new values
|
|
7792
|
+
if (payload.theme !== undefined) {
|
|
7793
|
+
window.openai.theme = payload.theme;
|
|
7794
|
+
// Also set data-theme attribute for CSS theming
|
|
7795
|
+
document.documentElement.dataset.theme = payload.theme;
|
|
7796
|
+
}
|
|
7797
|
+
if (payload.displayMode !== undefined) window.openai.displayMode = payload.displayMode;
|
|
7798
|
+
if (payload.locale !== undefined) window.openai.locale = payload.locale;
|
|
7799
|
+
if (payload.maxHeight !== undefined) window.openai.maxHeight = payload.maxHeight;
|
|
7800
|
+
if (payload.userAgent !== undefined) window.openai.userAgent = payload.userAgent;
|
|
7801
|
+
if (payload.safeArea !== undefined) window.openai.safeArea = payload.safeArea;
|
|
7802
|
+
if (payload.view !== undefined) window.openai.view = payload.view;
|
|
7803
|
+
if (payload.toolInput !== undefined) window.openai.toolInput = payload.toolInput;
|
|
7804
|
+
if (payload.toolOutput !== undefined) window.openai.toolOutput = payload.toolOutput;
|
|
7805
|
+
if (payload.toolResponseMetadata !== undefined) window.openai.toolResponseMetadata = payload.toolResponseMetadata;
|
|
7806
|
+
if (payload.widgetState !== undefined) window.openai.widgetState = payload.widgetState;
|
|
7807
|
+
|
|
7808
|
+
// Dispatch custom event so widgets can react to changes
|
|
7809
|
+
// Must match SET_GLOBALS_EVENT_TYPE ('openai:set_globals') in providers/openai/types.ts
|
|
7810
|
+
window.dispatchEvent(new CustomEvent('openai:set_globals', { detail: { globals: payload } }));
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
|
|
7814
|
+
// Listen for handshake message from parent (transfers MessagePort)
|
|
7815
|
+
window.addEventListener('message', function(event) {
|
|
7816
|
+
// Strict source validation: only accept messages from parent window
|
|
7817
|
+
if (event.source !== window.parent) {
|
|
7818
|
+
console.warn('[IframeBridge] Rejected message from non-parent source');
|
|
7819
|
+
return;
|
|
7820
|
+
}
|
|
7821
|
+
|
|
7822
|
+
// Validate message origin (allows localhost with any port)
|
|
7823
|
+
if (!isAllowedOrigin(event.origin)) {
|
|
7824
|
+
console.warn('[IframeBridge] Rejected message from untrusted origin:', event.origin);
|
|
7825
|
+
return;
|
|
7826
|
+
}
|
|
7827
|
+
|
|
7828
|
+
// Handle handshake with MessagePort transfer
|
|
7829
|
+
if (event.data && event.data.type === 'openai:handshake' && event.ports && event.ports.length > 0) {
|
|
7830
|
+
messagePort = event.ports[0];
|
|
7831
|
+
messagePort.onmessage = handlePortMessage;
|
|
7832
|
+
messagePort.start();
|
|
7833
|
+
|
|
7834
|
+
// Flush any queued messages
|
|
7835
|
+
flushMessageQueue();
|
|
7836
|
+
|
|
7837
|
+
// Confirm handshake complete
|
|
7838
|
+
sendToParent({ type: 'openai:handshake_complete' });
|
|
7839
|
+
}
|
|
7840
|
+
});
|
|
7841
|
+
|
|
7842
|
+
// Signal to parent that we're ready for handshake
|
|
7843
|
+
window.parent.postMessage({ type: 'openai:ready' }, '*');
|
|
7844
|
+
|
|
7845
|
+
// Auto-measure and report content height immediately
|
|
7846
|
+
var lastHeight = 0;
|
|
7847
|
+
var pendingFrame = null;
|
|
7848
|
+
function reportHeight() {
|
|
7849
|
+
var height = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
7850
|
+
if (height > 0 && height !== lastHeight) {
|
|
7851
|
+
lastHeight = height;
|
|
7852
|
+
window.openai.notifyIntrinsicHeight(height);
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7855
|
+
|
|
7856
|
+
// Schedule height report on next animation frame (batches rapid changes)
|
|
7857
|
+
function scheduleHeightReport() {
|
|
7858
|
+
if (pendingFrame) return;
|
|
7859
|
+
pendingFrame = requestAnimationFrame(function() {
|
|
7860
|
+
pendingFrame = null;
|
|
7861
|
+
reportHeight();
|
|
7862
|
+
});
|
|
7863
|
+
}
|
|
7864
|
+
|
|
7865
|
+
// Report height immediately when ready
|
|
7866
|
+
if (document.readyState === 'complete') {
|
|
7867
|
+
reportHeight();
|
|
7868
|
+
} else {
|
|
7869
|
+
window.addEventListener('load', reportHeight);
|
|
7870
|
+
}
|
|
7871
|
+
|
|
7872
|
+
// Use ResizeObserver to track size changes
|
|
7873
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
7874
|
+
var resizeObserver = new ResizeObserver(function() {
|
|
7875
|
+
scheduleHeightReport();
|
|
7876
|
+
});
|
|
7877
|
+
function observeElements() {
|
|
7878
|
+
if (document.body) resizeObserver.observe(document.body);
|
|
7879
|
+
if (document.documentElement) resizeObserver.observe(document.documentElement);
|
|
7880
|
+
// Also observe the root element if it exists
|
|
7881
|
+
var root = document.getElementById('root');
|
|
7882
|
+
if (root) resizeObserver.observe(root);
|
|
7883
|
+
}
|
|
7884
|
+
if (document.body) {
|
|
7885
|
+
observeElements();
|
|
7886
|
+
} else {
|
|
7887
|
+
document.addEventListener('DOMContentLoaded', observeElements);
|
|
7888
|
+
}
|
|
7889
|
+
}
|
|
7890
|
+
|
|
7891
|
+
// Use MutationObserver to detect DOM changes that may affect height
|
|
7892
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
7893
|
+
var mutationObserver = new MutationObserver(function() {
|
|
7894
|
+
scheduleHeightReport();
|
|
7895
|
+
});
|
|
7896
|
+
function observeMutations() {
|
|
7897
|
+
mutationObserver.observe(document.body, {
|
|
7898
|
+
childList: true,
|
|
7899
|
+
subtree: true,
|
|
7900
|
+
attributes: true,
|
|
7901
|
+
characterData: true
|
|
7902
|
+
});
|
|
7903
|
+
}
|
|
7904
|
+
if (document.body) {
|
|
7905
|
+
observeMutations();
|
|
7906
|
+
} else {
|
|
7907
|
+
document.addEventListener('DOMContentLoaded', observeMutations);
|
|
7908
|
+
}
|
|
7909
|
+
}
|
|
7910
|
+
})();
|
|
7911
|
+
<\/script>
|
|
7912
|
+
`;
|
|
7913
|
+
}
|
|
7914
|
+
function generateScriptHtml(scriptSrc, theme, cspPolicy) {
|
|
7915
|
+
const safeScriptSrc = escapeHtml(scriptSrc);
|
|
7916
|
+
const safeCsp = escapeHtml(cspPolicy);
|
|
7917
|
+
return `<!DOCTYPE html>
|
|
7918
|
+
<html lang="en" data-theme="${theme}">
|
|
7919
|
+
<head>
|
|
7920
|
+
<meta charset="UTF-8" />
|
|
7921
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7922
|
+
<meta http-equiv="Content-Security-Policy" content="${safeCsp}" />
|
|
7923
|
+
<title>Resource</title>
|
|
7924
|
+
<style>
|
|
7925
|
+
html, body, #root {
|
|
7926
|
+
margin: 0;
|
|
7927
|
+
padding: 0;
|
|
7928
|
+
height: 100%;
|
|
7929
|
+
width: 100%;
|
|
7930
|
+
}
|
|
7931
|
+
body {
|
|
7932
|
+
background: transparent;
|
|
7933
|
+
}
|
|
7934
|
+
</style>
|
|
7935
|
+
</head>
|
|
7936
|
+
<body>
|
|
7937
|
+
<div id="root"></div>
|
|
7938
|
+
<script src="${safeScriptSrc}"><\/script>
|
|
7939
|
+
</body>
|
|
7940
|
+
</html>`;
|
|
7941
|
+
}
|
|
7942
|
+
function injectBridgeScript(htmlContent, bridgeScript) {
|
|
7943
|
+
const headMatch = htmlContent.match(/<head[^>]*>/i);
|
|
7944
|
+
if (headMatch) {
|
|
7945
|
+
const insertPos = headMatch.index + headMatch[0].length;
|
|
7946
|
+
return htmlContent.slice(0, insertPos) + bridgeScript + htmlContent.slice(insertPos);
|
|
7947
|
+
}
|
|
7948
|
+
const doctypeMatch = htmlContent.match(/<!DOCTYPE[^>]*>/i);
|
|
7949
|
+
if (doctypeMatch) {
|
|
7950
|
+
const insertPos = doctypeMatch.index + doctypeMatch[0].length;
|
|
7951
|
+
return htmlContent.slice(0, insertPos) + bridgeScript + htmlContent.slice(insertPos);
|
|
7952
|
+
}
|
|
7953
|
+
return bridgeScript + htmlContent;
|
|
7954
|
+
}
|
|
7955
|
+
function IframeResource({ scriptSrc, className, style, csp }) {
|
|
7956
|
+
const iframeRef = React.useRef(null);
|
|
7957
|
+
const messageChannelRef = React.useRef(null);
|
|
7958
|
+
const messagePortRef = React.useRef(null);
|
|
7959
|
+
const [isHeightReady, setIsHeightReady] = React__namespace.useState(false);
|
|
7960
|
+
React__namespace.useEffect(() => {
|
|
7961
|
+
setIsHeightReady(false);
|
|
7962
|
+
const timeout = setTimeout(() => {
|
|
7963
|
+
setIsHeightReady(true);
|
|
7964
|
+
}, 500);
|
|
7965
|
+
return () => clearTimeout(timeout);
|
|
7966
|
+
}, [scriptSrc]);
|
|
7967
|
+
const theme = useTheme();
|
|
7968
|
+
const displayMode = useDisplayMode();
|
|
7969
|
+
const locale = useLocale();
|
|
7970
|
+
const maxHeight = useMaxHeight();
|
|
7971
|
+
const userAgent = useUserAgent();
|
|
7972
|
+
const safeArea = useSafeArea();
|
|
7973
|
+
const view = useView();
|
|
7974
|
+
const toolInput = useToolInput();
|
|
7975
|
+
const toolOutput = useWidgetProps();
|
|
7976
|
+
const toolResponseMetadata = useToolResponseMetadata();
|
|
7977
|
+
const [widgetState] = useWidgetState();
|
|
7978
|
+
const currentState = React__namespace.useMemo(
|
|
7979
|
+
() => ({
|
|
7980
|
+
theme,
|
|
7981
|
+
displayMode,
|
|
7982
|
+
locale,
|
|
7983
|
+
maxHeight,
|
|
7984
|
+
userAgent,
|
|
7985
|
+
safeArea,
|
|
7986
|
+
view,
|
|
7987
|
+
toolInput,
|
|
7988
|
+
toolOutput,
|
|
7989
|
+
toolResponseMetadata,
|
|
7990
|
+
widgetState
|
|
7991
|
+
}),
|
|
7992
|
+
[
|
|
7993
|
+
theme,
|
|
7994
|
+
displayMode,
|
|
7995
|
+
locale,
|
|
7996
|
+
maxHeight,
|
|
7997
|
+
userAgent,
|
|
7998
|
+
safeArea,
|
|
7999
|
+
view,
|
|
8000
|
+
toolInput,
|
|
8001
|
+
toolOutput,
|
|
8002
|
+
toolResponseMetadata,
|
|
8003
|
+
widgetState
|
|
8004
|
+
]
|
|
8005
|
+
);
|
|
8006
|
+
const sendUpdate = React.useCallback(
|
|
8007
|
+
(type) => {
|
|
8008
|
+
const port = messagePortRef.current;
|
|
8009
|
+
if (port) {
|
|
8010
|
+
const message = {
|
|
8011
|
+
type,
|
|
8012
|
+
payload: currentState
|
|
8013
|
+
};
|
|
8014
|
+
port.postMessage(message);
|
|
8015
|
+
}
|
|
8016
|
+
},
|
|
8017
|
+
[currentState]
|
|
8018
|
+
);
|
|
8019
|
+
const sendUpdateRef = React.useRef(sendUpdate);
|
|
8020
|
+
React.useEffect(() => {
|
|
8021
|
+
sendUpdateRef.current = sendUpdate;
|
|
8022
|
+
}, [sendUpdate]);
|
|
8023
|
+
const handlePortMessage = React.useCallback(
|
|
8024
|
+
(event) => {
|
|
8025
|
+
var _a2, _b2;
|
|
8026
|
+
if (!event.data || typeof event.data !== "object" || typeof event.data.type !== "string") {
|
|
8027
|
+
return;
|
|
8028
|
+
}
|
|
8029
|
+
const { type } = event.data;
|
|
8030
|
+
switch (type) {
|
|
8031
|
+
case "openai:handshake_complete":
|
|
8032
|
+
sendUpdateRef.current("openai:init");
|
|
8033
|
+
break;
|
|
8034
|
+
case "openai:requestDisplayMode": {
|
|
8035
|
+
const payload = event.data.payload;
|
|
8036
|
+
if (!payload || typeof payload !== "object" || !("mode" in payload) || typeof payload.mode !== "string") {
|
|
8037
|
+
console.warn("[IframeResource] Invalid requestDisplayMode payload");
|
|
8038
|
+
return;
|
|
8039
|
+
}
|
|
8040
|
+
const validModes = ["inline", "pip", "fullscreen"];
|
|
8041
|
+
const mode = payload.mode;
|
|
8042
|
+
if (!validModes.includes(mode)) {
|
|
8043
|
+
console.warn("[IframeResource] Invalid display mode:", mode);
|
|
8044
|
+
return;
|
|
8045
|
+
}
|
|
8046
|
+
if (typeof window !== "undefined" && ((_a2 = window.openai) == null ? void 0 : _a2.requestDisplayMode)) {
|
|
8047
|
+
window.openai.requestDisplayMode({ mode });
|
|
8048
|
+
}
|
|
8049
|
+
break;
|
|
8050
|
+
}
|
|
8051
|
+
case "openai:setWidgetState": {
|
|
8052
|
+
const payload = event.data.payload;
|
|
8053
|
+
if (payload !== null && (typeof payload !== "object" || Array.isArray(payload))) {
|
|
8054
|
+
console.warn("[IframeResource] Invalid widgetState payload");
|
|
8055
|
+
return;
|
|
8056
|
+
}
|
|
8057
|
+
if (typeof window !== "undefined" && ((_b2 = window.openai) == null ? void 0 : _b2.setWidgetState)) {
|
|
8058
|
+
window.openai.setWidgetState(payload);
|
|
8059
|
+
}
|
|
8060
|
+
break;
|
|
8061
|
+
}
|
|
8062
|
+
case "openai:notifyIntrinsicHeight": {
|
|
8063
|
+
const payload = event.data.payload;
|
|
8064
|
+
if (!payload || typeof payload !== "object" || !("height" in payload) || typeof payload.height !== "number") {
|
|
8065
|
+
console.warn("[IframeResource] Invalid notifyIntrinsicHeight payload");
|
|
8066
|
+
return;
|
|
8067
|
+
}
|
|
8068
|
+
const height = payload.height;
|
|
8069
|
+
if (height <= 0 || height > 1e5) {
|
|
8070
|
+
console.warn("[IframeResource] Height out of range:", height);
|
|
8071
|
+
return;
|
|
8072
|
+
}
|
|
8073
|
+
if (iframeRef.current) {
|
|
8074
|
+
iframeRef.current.style.height = `${height}px`;
|
|
8075
|
+
}
|
|
8076
|
+
break;
|
|
8077
|
+
}
|
|
8078
|
+
case "openai:callTool":
|
|
8079
|
+
case "openai:sendFollowUpMessage":
|
|
8080
|
+
case "openai:openExternal":
|
|
8081
|
+
case "openai:requestModal":
|
|
8082
|
+
console.log(`[IframeResource] Received ${type}:`, event.data.payload);
|
|
8083
|
+
break;
|
|
8084
|
+
}
|
|
8085
|
+
},
|
|
8086
|
+
[]
|
|
8087
|
+
// No dependencies - uses refs for changing values
|
|
8088
|
+
);
|
|
8089
|
+
React.useEffect(() => {
|
|
8090
|
+
const handleMessage = (event) => {
|
|
8091
|
+
if (iframeRef.current && event.source !== iframeRef.current.contentWindow) {
|
|
8092
|
+
return;
|
|
8093
|
+
}
|
|
8094
|
+
if (!event.data || typeof event.data !== "object" || typeof event.data.type !== "string") {
|
|
8095
|
+
return;
|
|
8096
|
+
}
|
|
8097
|
+
if (event.data.type === "openai:ready") {
|
|
8098
|
+
const channel = new MessageChannel();
|
|
8099
|
+
messageChannelRef.current = channel;
|
|
8100
|
+
messagePortRef.current = channel.port1;
|
|
8101
|
+
channel.port1.onmessage = handlePortMessage;
|
|
8102
|
+
channel.port1.start();
|
|
8103
|
+
const iframe = iframeRef.current;
|
|
8104
|
+
if (iframe == null ? void 0 : iframe.contentWindow) {
|
|
8105
|
+
iframe.contentWindow.postMessage({ type: "openai:handshake" }, "*", [channel.port2]);
|
|
8106
|
+
}
|
|
8107
|
+
}
|
|
8108
|
+
if (event.data.type === "openai:notifyIntrinsicHeight") {
|
|
8109
|
+
const payload = event.data.payload;
|
|
8110
|
+
if (!payload || typeof payload !== "object" || !("height" in payload) || typeof payload.height !== "number") {
|
|
8111
|
+
return;
|
|
8112
|
+
}
|
|
8113
|
+
const height = payload.height;
|
|
8114
|
+
if (height <= 0 || height > 1e5) {
|
|
8115
|
+
return;
|
|
8116
|
+
}
|
|
8117
|
+
if (iframeRef.current) {
|
|
8118
|
+
iframeRef.current.style.height = `${height}px`;
|
|
8119
|
+
setIsHeightReady(true);
|
|
8120
|
+
}
|
|
8121
|
+
}
|
|
8122
|
+
};
|
|
8123
|
+
window.addEventListener("message", handleMessage);
|
|
8124
|
+
return () => {
|
|
8125
|
+
window.removeEventListener("message", handleMessage);
|
|
8126
|
+
if (messagePortRef.current) {
|
|
8127
|
+
messagePortRef.current.close();
|
|
8128
|
+
}
|
|
8129
|
+
};
|
|
8130
|
+
}, [handlePortMessage]);
|
|
8131
|
+
React.useEffect(() => {
|
|
8132
|
+
sendUpdate("openai:update");
|
|
8133
|
+
}, [sendUpdate]);
|
|
8134
|
+
const isValidScriptSrc = React.useMemo(() => isAllowedScriptSrc(scriptSrc), [scriptSrc]);
|
|
8135
|
+
const blobUrl = React.useMemo(() => {
|
|
8136
|
+
if (!isValidScriptSrc) {
|
|
8137
|
+
console.error("[IframeResource] Script source not allowed:", scriptSrc);
|
|
8138
|
+
const errorHtml = `<!DOCTYPE html><html><body><h1>Error</h1><p>Script source not allowed.</p></body></html>`;
|
|
8139
|
+
const blob2 = new Blob([errorHtml], { type: "text/html" });
|
|
8140
|
+
return URL.createObjectURL(blob2);
|
|
8141
|
+
}
|
|
8142
|
+
const absoluteScriptSrc = scriptSrc.startsWith("/") ? `${window.location.origin}${scriptSrc}` : scriptSrc;
|
|
8143
|
+
const cspPolicy = generateCSP(csp, absoluteScriptSrc);
|
|
8144
|
+
const bridgeScript = generateBridgeScript(ALLOWED_PARENT_ORIGINS);
|
|
8145
|
+
const html = injectBridgeScript(
|
|
8146
|
+
generateScriptHtml(absoluteScriptSrc, theme ?? "dark", cspPolicy),
|
|
8147
|
+
bridgeScript
|
|
8148
|
+
);
|
|
8149
|
+
const blob = new Blob([html], { type: "text/html" });
|
|
8150
|
+
return URL.createObjectURL(blob);
|
|
8151
|
+
}, [scriptSrc, theme, isValidScriptSrc, csp]);
|
|
8152
|
+
React.useEffect(() => {
|
|
8153
|
+
return () => URL.revokeObjectURL(blobUrl);
|
|
8154
|
+
}, [blobUrl]);
|
|
8155
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8156
|
+
"iframe",
|
|
8157
|
+
{
|
|
8158
|
+
ref: iframeRef,
|
|
8159
|
+
src: blobUrl,
|
|
8160
|
+
className,
|
|
8161
|
+
style: {
|
|
8162
|
+
border: "none",
|
|
8163
|
+
width: "100%",
|
|
8164
|
+
height: "100%",
|
|
8165
|
+
// Hide until first height update to prevent flash of incorrect size
|
|
8166
|
+
opacity: isHeightReady ? 1 : 0,
|
|
8167
|
+
transition: "opacity 0.1s ease-in",
|
|
8168
|
+
...style
|
|
8169
|
+
},
|
|
8170
|
+
title: "Resource Preview",
|
|
8171
|
+
sandbox: "allow-scripts",
|
|
8172
|
+
allow: "accelerometer 'none'; autoplay 'none'; camera 'none'; display-capture 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; payment 'none'; publickey-credentials-get 'none'; usb 'none'; xr-spatial-tracking 'none'"
|
|
8173
|
+
}
|
|
8174
|
+
);
|
|
8175
|
+
}
|
|
7563
8176
|
function Conversation({
|
|
7564
8177
|
children,
|
|
8178
|
+
iframeScriptSrc,
|
|
7565
8179
|
screenWidth,
|
|
7566
8180
|
appName = "Sunpeak",
|
|
7567
8181
|
appIcon,
|
|
@@ -7573,6 +8187,8 @@ function Conversation({
|
|
|
7573
8187
|
const userAgent = useUserAgent();
|
|
7574
8188
|
const isDesktop = (userAgent == null ? void 0 : userAgent.device.type) === "desktop";
|
|
7575
8189
|
const containerWidth = screenWidth === "full" ? "100%" : `${SCREEN_WIDTHS[screenWidth]}px`;
|
|
8190
|
+
const widgetCSP = resourceMeta == null ? void 0 : resourceMeta["openai/widgetCSP"];
|
|
8191
|
+
const content = iframeScriptSrc ? /* @__PURE__ */ jsxRuntime.jsx(IframeResource, { scriptSrc: iframeScriptSrc, className: "h-full w-full", csp: widgetCSP }) : children;
|
|
7576
8192
|
if (displayMode === "fullscreen") {
|
|
7577
8193
|
const handleClose = () => {
|
|
7578
8194
|
if (api == null ? void 0 : api.requestDisplayMode) {
|
|
@@ -7622,7 +8238,7 @@ function Conversation({
|
|
|
7622
8238
|
}
|
|
7623
8239
|
) })
|
|
7624
8240
|
] }),
|
|
7625
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto", children }) }),
|
|
8241
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto", children: content }) }),
|
|
7626
8242
|
/* @__PURE__ */ jsxRuntime.jsx("footer", { className: "bg-surface", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[48rem] mx-auto px-4 py-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7627
8243
|
"input",
|
|
7628
8244
|
{
|
|
@@ -7712,10 +8328,10 @@ function Conversation({
|
|
|
7712
8328
|
children: /* @__PURE__ */ jsxRuntime.jsx(CloseBold, { className: "h-4 w-4" })
|
|
7713
8329
|
}
|
|
7714
8330
|
),
|
|
7715
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full rounded-2xl sm:rounded-3xl shadow-[0px_0px_0px_1px_#fff3,0px_6px_20px_rgba(0,0,0,0.1)] md:-mx-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto bg-white dark:bg-[#212121]", children }) })
|
|
8331
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full rounded-2xl sm:rounded-3xl shadow-[0px_0px_0px_1px_#fff3,0px_6px_20px_rgba(0,0,0,0.1)] md:-mx-4", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full w-full max-w-full overflow-auto bg-white dark:bg-[#212121]", children: content }) })
|
|
7716
8332
|
]
|
|
7717
8333
|
}
|
|
7718
|
-
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "no-scrollbar relative mb-2 @w-sm/main:w-full mx-0 max-sm:-mx-[1rem] max-sm:w-[100cqw] max-sm:overflow-hidden overflow-visible", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full", children }) }) })
|
|
8334
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "no-scrollbar relative mb-2 @w-sm/main:w-full mx-0 max-sm:-mx-[1rem] max-sm:w-[100cqw] max-sm:overflow-hidden overflow-visible", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative overflow-hidden h-full", children: content }) }) })
|
|
7719
8335
|
}
|
|
7720
8336
|
)
|
|
7721
8337
|
] }) }) })
|
|
@@ -7791,8 +8407,8 @@ class MockOpenAI {
|
|
|
7791
8407
|
console.log("Mock notifyIntrinsicHeight:", height);
|
|
7792
8408
|
}
|
|
7793
8409
|
async setWidgetState(state) {
|
|
7794
|
-
this.widgetState = state;
|
|
7795
|
-
this.emitUpdate({ widgetState:
|
|
8410
|
+
this.widgetState = { ...this.widgetState, ...state };
|
|
8411
|
+
this.emitUpdate({ widgetState: this.widgetState });
|
|
7796
8412
|
}
|
|
7797
8413
|
setTheme(theme) {
|
|
7798
8414
|
this.theme = theme;
|
|
@@ -8003,11 +8619,17 @@ function ChatGPTSimulator({
|
|
|
8003
8619
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- only initialize once
|
|
8004
8620
|
[]
|
|
8005
8621
|
);
|
|
8622
|
+
if (typeof window !== "undefined") {
|
|
8623
|
+
window.openai = mock;
|
|
8624
|
+
resetProviderCache();
|
|
8625
|
+
}
|
|
8006
8626
|
React.useEffect(() => {
|
|
8007
8627
|
var _a2, _b2;
|
|
8008
8628
|
if (selectedSim) {
|
|
8009
8629
|
mock.toolInput = ((_a2 = selectedSim.callToolRequestParams) == null ? void 0 : _a2.arguments) ?? {};
|
|
8010
|
-
|
|
8630
|
+
if (selectedSim.widgetState !== void 0) {
|
|
8631
|
+
mock.setWidgetStateExternal(selectedSim.widgetState);
|
|
8632
|
+
}
|
|
8011
8633
|
mock.toolOutput = ((_b2 = selectedSim.callToolResult) == null ? void 0 : _b2.structuredContent) ?? null;
|
|
8012
8634
|
}
|
|
8013
8635
|
}, [selectedSimulationName, selectedSim, mock]);
|
|
@@ -8019,7 +8641,7 @@ function ChatGPTSimulator({
|
|
|
8019
8641
|
const safeArea = useSafeArea();
|
|
8020
8642
|
const view = useView();
|
|
8021
8643
|
const toolInput = useToolInput();
|
|
8022
|
-
const
|
|
8644
|
+
const widgetState = useWidgetGlobal("widgetState");
|
|
8023
8645
|
const toolResponseMetadata = useToolResponseMetadata();
|
|
8024
8646
|
const toolOutput = useWidgetProps();
|
|
8025
8647
|
const [toolInputJson, setToolInputJson] = React.useState(
|
|
@@ -8043,12 +8665,6 @@ function ChatGPTSimulator({
|
|
|
8043
8665
|
const [toolResponseMetadataError, setToolResponseMetadataError] = React.useState("");
|
|
8044
8666
|
const [widgetStateError, setWidgetStateError] = React.useState("");
|
|
8045
8667
|
const [viewParamsError, setViewParamsError] = React.useState("");
|
|
8046
|
-
React.useLayoutEffect(() => {
|
|
8047
|
-
if (mock && typeof window !== "undefined") {
|
|
8048
|
-
window.openai = mock;
|
|
8049
|
-
resetProviderCache();
|
|
8050
|
-
}
|
|
8051
|
-
}, [mock]);
|
|
8052
8668
|
React.useEffect(() => {
|
|
8053
8669
|
if (mock) {
|
|
8054
8670
|
mock.emitUpdate({
|
|
@@ -8131,16 +8747,21 @@ function ChatGPTSimulator({
|
|
|
8131
8747
|
}
|
|
8132
8748
|
};
|
|
8133
8749
|
const SelectedComponent = selectedSim == null ? void 0 : selectedSim.resourceComponent;
|
|
8750
|
+
const iframeScriptSrc = !SelectedComponent ? selectedSim == null ? void 0 : selectedSim.resourceScript : void 0;
|
|
8134
8751
|
const content = SelectedComponent ? /* @__PURE__ */ jsxRuntime.jsx(SelectedComponent, {}) : children;
|
|
8135
8752
|
return /* @__PURE__ */ jsxRuntime.jsx(ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8136
8753
|
SimpleSidebar,
|
|
8137
8754
|
{
|
|
8138
8755
|
controls: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
8139
|
-
simulationNames.length >
|
|
8756
|
+
simulationNames.length > 1 && /* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Simulation", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8140
8757
|
SidebarSelect,
|
|
8141
8758
|
{
|
|
8142
8759
|
value: selectedSimulationName,
|
|
8143
|
-
onChange: (value) =>
|
|
8760
|
+
onChange: (value) => {
|
|
8761
|
+
const newSim = simulations[value];
|
|
8762
|
+
mock.setWidgetStateExternal((newSim == null ? void 0 : newSim.widgetState) ?? null);
|
|
8763
|
+
setSelectedSimulationName(value);
|
|
8764
|
+
},
|
|
8144
8765
|
options: simulationNames.map((name) => {
|
|
8145
8766
|
const sim = simulations[name];
|
|
8146
8767
|
const resourceTitle = sim.resource.title || sim.resource.name;
|
|
@@ -8165,237 +8786,254 @@ function ChatGPTSimulator({
|
|
|
8165
8786
|
]
|
|
8166
8787
|
}
|
|
8167
8788
|
) }),
|
|
8168
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
value: theme,
|
|
8172
|
-
onChange: (value) => mock.setTheme(value),
|
|
8173
|
-
options: [
|
|
8174
|
-
{ value: "light", label: "Light" },
|
|
8175
|
-
{ value: "dark", label: "Dark" }
|
|
8176
|
-
]
|
|
8177
|
-
}
|
|
8178
|
-
) }),
|
|
8179
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Display Mode", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8180
|
-
SidebarToggle,
|
|
8181
|
-
{
|
|
8182
|
-
value: displayMode,
|
|
8183
|
-
onChange: (value) => {
|
|
8184
|
-
const newMode = value;
|
|
8185
|
-
if (isMobileWidth(screenWidth) && newMode === "pip") {
|
|
8186
|
-
mock.setDisplayMode("fullscreen");
|
|
8187
|
-
} else {
|
|
8188
|
-
mock.setDisplayMode(newMode);
|
|
8189
|
-
}
|
|
8190
|
-
},
|
|
8191
|
-
options: [
|
|
8192
|
-
{ value: "inline", label: "Inline" },
|
|
8193
|
-
{ value: "pip", label: "PiP" },
|
|
8194
|
-
{ value: "fullscreen", label: "Full" }
|
|
8195
|
-
]
|
|
8196
|
-
}
|
|
8197
|
-
) }),
|
|
8198
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
8199
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Locale", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8200
|
-
SidebarInput,
|
|
8789
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarCollapsibleControl, { label: "Runtime Globals", defaultCollapsed: false, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
8790
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Theme", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8791
|
+
SidebarToggle,
|
|
8201
8792
|
{
|
|
8202
|
-
value:
|
|
8203
|
-
onChange: (value) => mock.
|
|
8204
|
-
|
|
8793
|
+
value: theme,
|
|
8794
|
+
onChange: (value) => mock.setTheme(value),
|
|
8795
|
+
options: [
|
|
8796
|
+
{ value: "light", label: "Light" },
|
|
8797
|
+
{ value: "dark", label: "Dark" }
|
|
8798
|
+
]
|
|
8205
8799
|
}
|
|
8206
8800
|
) }),
|
|
8207
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "
|
|
8208
|
-
|
|
8801
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Display Mode", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8802
|
+
SidebarToggle,
|
|
8209
8803
|
{
|
|
8210
|
-
|
|
8211
|
-
value: displayMode === "pip" && maxHeight !== void 0 ? String(maxHeight) : "",
|
|
8804
|
+
value: displayMode,
|
|
8212
8805
|
onChange: (value) => {
|
|
8213
|
-
|
|
8214
|
-
|
|
8806
|
+
const newMode = value;
|
|
8807
|
+
if (isMobileWidth(screenWidth) && newMode === "pip") {
|
|
8808
|
+
mock.setDisplayMode("fullscreen");
|
|
8809
|
+
} else {
|
|
8810
|
+
mock.setDisplayMode(newMode);
|
|
8215
8811
|
}
|
|
8216
8812
|
},
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "User Agent - Device", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8223
|
-
SidebarSelect,
|
|
8224
|
-
{
|
|
8225
|
-
value: (userAgent == null ? void 0 : userAgent.device.type) ?? "desktop",
|
|
8226
|
-
onChange: (value) => {
|
|
8227
|
-
const deviceType = value;
|
|
8228
|
-
let capabilities;
|
|
8229
|
-
switch (deviceType) {
|
|
8230
|
-
case "mobile":
|
|
8231
|
-
capabilities = { hover: false, touch: true };
|
|
8232
|
-
break;
|
|
8233
|
-
case "tablet":
|
|
8234
|
-
capabilities = { hover: false, touch: true };
|
|
8235
|
-
break;
|
|
8236
|
-
case "desktop":
|
|
8237
|
-
capabilities = { hover: true, touch: false };
|
|
8238
|
-
break;
|
|
8239
|
-
case "unknown":
|
|
8240
|
-
default:
|
|
8241
|
-
capabilities = { hover: true, touch: false };
|
|
8242
|
-
break;
|
|
8243
|
-
}
|
|
8244
|
-
mock.setUserAgent({
|
|
8245
|
-
...userAgent,
|
|
8246
|
-
device: { type: deviceType },
|
|
8247
|
-
capabilities
|
|
8248
|
-
});
|
|
8249
|
-
},
|
|
8250
|
-
options: [
|
|
8251
|
-
{ value: "mobile", label: "Mobile" },
|
|
8252
|
-
{ value: "tablet", label: "Tablet" },
|
|
8253
|
-
{ value: "desktop", label: "Desktop" },
|
|
8254
|
-
{ value: "unknown", label: "Unknown" }
|
|
8255
|
-
]
|
|
8256
|
-
}
|
|
8257
|
-
) }),
|
|
8258
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-4", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Capabilities", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
8259
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8260
|
-
SidebarCheckbox,
|
|
8261
|
-
{
|
|
8262
|
-
checked: (userAgent == null ? void 0 : userAgent.capabilities.hover) ?? true,
|
|
8263
|
-
onChange: (checked) => mock.setUserAgent({
|
|
8264
|
-
...userAgent,
|
|
8265
|
-
device: (userAgent == null ? void 0 : userAgent.device) ?? { type: "desktop" },
|
|
8266
|
-
capabilities: {
|
|
8267
|
-
hover: checked,
|
|
8268
|
-
touch: (userAgent == null ? void 0 : userAgent.capabilities.touch) ?? false
|
|
8269
|
-
}
|
|
8270
|
-
}),
|
|
8271
|
-
label: "Hover"
|
|
8813
|
+
options: [
|
|
8814
|
+
{ value: "inline", label: "Inline" },
|
|
8815
|
+
{ value: "pip", label: "PiP" },
|
|
8816
|
+
{ value: "fullscreen", label: "Full" }
|
|
8817
|
+
]
|
|
8272
8818
|
}
|
|
8273
|
-
),
|
|
8274
|
-
/* @__PURE__ */ jsxRuntime.
|
|
8275
|
-
|
|
8276
|
-
{
|
|
8277
|
-
checked: (userAgent == null ? void 0 : userAgent.capabilities.touch) ?? false,
|
|
8278
|
-
onChange: (checked) => mock.setUserAgent({
|
|
8279
|
-
...userAgent,
|
|
8280
|
-
device: (userAgent == null ? void 0 : userAgent.device) ?? { type: "desktop" },
|
|
8281
|
-
capabilities: {
|
|
8282
|
-
hover: (userAgent == null ? void 0 : userAgent.capabilities.hover) ?? true,
|
|
8283
|
-
touch: checked
|
|
8284
|
-
}
|
|
8285
|
-
}),
|
|
8286
|
-
label: "Touch"
|
|
8287
|
-
}
|
|
8288
|
-
)
|
|
8289
|
-
] }) }) }),
|
|
8290
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Safe Area Insets", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-1", children: [
|
|
8291
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
8292
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-[9px] text-secondary", children: "Top" }),
|
|
8293
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8819
|
+
) }),
|
|
8820
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
8821
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Locale", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8294
8822
|
SidebarInput,
|
|
8295
8823
|
{
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
insets: {
|
|
8300
|
-
...safeArea == null ? void 0 : safeArea.insets,
|
|
8301
|
-
top: Number(value),
|
|
8302
|
-
bottom: (safeArea == null ? void 0 : safeArea.insets.bottom) ?? 0,
|
|
8303
|
-
left: (safeArea == null ? void 0 : safeArea.insets.left) ?? 0,
|
|
8304
|
-
right: (safeArea == null ? void 0 : safeArea.insets.right) ?? 0
|
|
8305
|
-
}
|
|
8306
|
-
})
|
|
8824
|
+
value: locale,
|
|
8825
|
+
onChange: (value) => mock.setLocale(value),
|
|
8826
|
+
placeholder: "e.g. en-US"
|
|
8307
8827
|
}
|
|
8308
|
-
)
|
|
8309
|
-
|
|
8310
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
8311
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-[9px] text-secondary", children: "Bottom" }),
|
|
8312
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8828
|
+
) }),
|
|
8829
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Max Height (PiP)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8313
8830
|
SidebarInput,
|
|
8314
8831
|
{
|
|
8315
8832
|
type: "number",
|
|
8316
|
-
value:
|
|
8317
|
-
onChange: (value) =>
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
top: (safeArea == null ? void 0 : safeArea.insets.top) ?? 0,
|
|
8321
|
-
bottom: Number(value),
|
|
8322
|
-
left: (safeArea == null ? void 0 : safeArea.insets.left) ?? 0,
|
|
8323
|
-
right: (safeArea == null ? void 0 : safeArea.insets.right) ?? 0
|
|
8833
|
+
value: displayMode === "pip" && maxHeight !== void 0 ? String(maxHeight) : "",
|
|
8834
|
+
onChange: (value) => {
|
|
8835
|
+
if (displayMode === "pip") {
|
|
8836
|
+
mock.setMaxHeight(value ? Number(value) : 480);
|
|
8324
8837
|
}
|
|
8325
|
-
}
|
|
8838
|
+
},
|
|
8839
|
+
placeholder: displayMode === "pip" ? "480" : "-",
|
|
8840
|
+
disabled: displayMode !== "pip"
|
|
8326
8841
|
}
|
|
8327
|
-
)
|
|
8842
|
+
) })
|
|
8328
8843
|
] }),
|
|
8329
|
-
/* @__PURE__ */ jsxRuntime.
|
|
8330
|
-
|
|
8844
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "User Agent - Device", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8845
|
+
SidebarSelect,
|
|
8846
|
+
{
|
|
8847
|
+
value: (userAgent == null ? void 0 : userAgent.device.type) ?? "desktop",
|
|
8848
|
+
onChange: (value) => {
|
|
8849
|
+
const deviceType = value;
|
|
8850
|
+
let capabilities;
|
|
8851
|
+
switch (deviceType) {
|
|
8852
|
+
case "mobile":
|
|
8853
|
+
capabilities = { hover: false, touch: true };
|
|
8854
|
+
break;
|
|
8855
|
+
case "tablet":
|
|
8856
|
+
capabilities = { hover: false, touch: true };
|
|
8857
|
+
break;
|
|
8858
|
+
case "desktop":
|
|
8859
|
+
capabilities = { hover: true, touch: false };
|
|
8860
|
+
break;
|
|
8861
|
+
case "unknown":
|
|
8862
|
+
default:
|
|
8863
|
+
capabilities = { hover: true, touch: false };
|
|
8864
|
+
break;
|
|
8865
|
+
}
|
|
8866
|
+
mock.setUserAgent({
|
|
8867
|
+
...userAgent,
|
|
8868
|
+
device: { type: deviceType },
|
|
8869
|
+
capabilities
|
|
8870
|
+
});
|
|
8871
|
+
},
|
|
8872
|
+
options: [
|
|
8873
|
+
{ value: "mobile", label: "Mobile" },
|
|
8874
|
+
{ value: "tablet", label: "Tablet" },
|
|
8875
|
+
{ value: "desktop", label: "Desktop" },
|
|
8876
|
+
{ value: "unknown", label: "Unknown" }
|
|
8877
|
+
]
|
|
8878
|
+
}
|
|
8879
|
+
) }),
|
|
8880
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "pl-4", children: /* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Capabilities", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
8331
8881
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8332
|
-
|
|
8882
|
+
SidebarCheckbox,
|
|
8333
8883
|
{
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
|
|
8338
|
-
|
|
8339
|
-
|
|
8340
|
-
|
|
8341
|
-
left: Number(value),
|
|
8342
|
-
right: (safeArea == null ? void 0 : safeArea.insets.right) ?? 0
|
|
8884
|
+
checked: (userAgent == null ? void 0 : userAgent.capabilities.hover) ?? true,
|
|
8885
|
+
onChange: (checked) => mock.setUserAgent({
|
|
8886
|
+
...userAgent,
|
|
8887
|
+
device: (userAgent == null ? void 0 : userAgent.device) ?? { type: "desktop" },
|
|
8888
|
+
capabilities: {
|
|
8889
|
+
hover: checked,
|
|
8890
|
+
touch: (userAgent == null ? void 0 : userAgent.capabilities.touch) ?? false
|
|
8343
8891
|
}
|
|
8344
|
-
})
|
|
8892
|
+
}),
|
|
8893
|
+
label: "Hover"
|
|
8345
8894
|
}
|
|
8346
|
-
)
|
|
8347
|
-
] }),
|
|
8348
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
8349
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-[9px] text-secondary", children: "Right" }),
|
|
8895
|
+
),
|
|
8350
8896
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8351
|
-
|
|
8897
|
+
SidebarCheckbox,
|
|
8352
8898
|
{
|
|
8353
|
-
|
|
8354
|
-
|
|
8355
|
-
|
|
8356
|
-
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
left: (safeArea == null ? void 0 : safeArea.insets.left) ?? 0,
|
|
8361
|
-
right: Number(value)
|
|
8899
|
+
checked: (userAgent == null ? void 0 : userAgent.capabilities.touch) ?? false,
|
|
8900
|
+
onChange: (checked) => mock.setUserAgent({
|
|
8901
|
+
...userAgent,
|
|
8902
|
+
device: (userAgent == null ? void 0 : userAgent.device) ?? { type: "desktop" },
|
|
8903
|
+
capabilities: {
|
|
8904
|
+
hover: (userAgent == null ? void 0 : userAgent.capabilities.hover) ?? true,
|
|
8905
|
+
touch: checked
|
|
8362
8906
|
}
|
|
8363
|
-
})
|
|
8907
|
+
}),
|
|
8908
|
+
label: "Touch"
|
|
8364
8909
|
}
|
|
8365
8910
|
)
|
|
8366
|
-
] })
|
|
8911
|
+
] }) }) }),
|
|
8912
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "Safe Area Insets", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-4 gap-1", children: [
|
|
8913
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8914
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-secondary", children: "↑" }),
|
|
8915
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8916
|
+
SidebarInput,
|
|
8917
|
+
{
|
|
8918
|
+
type: "number",
|
|
8919
|
+
value: String((safeArea == null ? void 0 : safeArea.insets.top) ?? 0),
|
|
8920
|
+
onChange: (value) => mock.setSafeArea({
|
|
8921
|
+
insets: {
|
|
8922
|
+
...safeArea == null ? void 0 : safeArea.insets,
|
|
8923
|
+
top: Number(value),
|
|
8924
|
+
bottom: (safeArea == null ? void 0 : safeArea.insets.bottom) ?? 0,
|
|
8925
|
+
left: (safeArea == null ? void 0 : safeArea.insets.left) ?? 0,
|
|
8926
|
+
right: (safeArea == null ? void 0 : safeArea.insets.right) ?? 0
|
|
8927
|
+
}
|
|
8928
|
+
})
|
|
8929
|
+
}
|
|
8930
|
+
)
|
|
8931
|
+
] }),
|
|
8932
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8933
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-secondary", children: "↓" }),
|
|
8934
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8935
|
+
SidebarInput,
|
|
8936
|
+
{
|
|
8937
|
+
type: "number",
|
|
8938
|
+
value: String((safeArea == null ? void 0 : safeArea.insets.bottom) ?? 0),
|
|
8939
|
+
onChange: (value) => mock.setSafeArea({
|
|
8940
|
+
insets: {
|
|
8941
|
+
...safeArea == null ? void 0 : safeArea.insets,
|
|
8942
|
+
top: (safeArea == null ? void 0 : safeArea.insets.top) ?? 0,
|
|
8943
|
+
bottom: Number(value),
|
|
8944
|
+
left: (safeArea == null ? void 0 : safeArea.insets.left) ?? 0,
|
|
8945
|
+
right: (safeArea == null ? void 0 : safeArea.insets.right) ?? 0
|
|
8946
|
+
}
|
|
8947
|
+
})
|
|
8948
|
+
}
|
|
8949
|
+
)
|
|
8950
|
+
] }),
|
|
8951
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8952
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-secondary", children: "←" }),
|
|
8953
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8954
|
+
SidebarInput,
|
|
8955
|
+
{
|
|
8956
|
+
type: "number",
|
|
8957
|
+
value: String((safeArea == null ? void 0 : safeArea.insets.left) ?? 0),
|
|
8958
|
+
onChange: (value) => mock.setSafeArea({
|
|
8959
|
+
insets: {
|
|
8960
|
+
...safeArea == null ? void 0 : safeArea.insets,
|
|
8961
|
+
top: (safeArea == null ? void 0 : safeArea.insets.top) ?? 0,
|
|
8962
|
+
bottom: (safeArea == null ? void 0 : safeArea.insets.bottom) ?? 0,
|
|
8963
|
+
left: Number(value),
|
|
8964
|
+
right: (safeArea == null ? void 0 : safeArea.insets.right) ?? 0
|
|
8965
|
+
}
|
|
8966
|
+
})
|
|
8967
|
+
}
|
|
8968
|
+
)
|
|
8969
|
+
] }),
|
|
8970
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
8971
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-secondary", children: "→" }),
|
|
8972
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8973
|
+
SidebarInput,
|
|
8974
|
+
{
|
|
8975
|
+
type: "number",
|
|
8976
|
+
value: String((safeArea == null ? void 0 : safeArea.insets.right) ?? 0),
|
|
8977
|
+
onChange: (value) => mock.setSafeArea({
|
|
8978
|
+
insets: {
|
|
8979
|
+
...safeArea == null ? void 0 : safeArea.insets,
|
|
8980
|
+
top: (safeArea == null ? void 0 : safeArea.insets.top) ?? 0,
|
|
8981
|
+
bottom: (safeArea == null ? void 0 : safeArea.insets.bottom) ?? 0,
|
|
8982
|
+
left: (safeArea == null ? void 0 : safeArea.insets.left) ?? 0,
|
|
8983
|
+
right: Number(value)
|
|
8984
|
+
}
|
|
8985
|
+
})
|
|
8986
|
+
}
|
|
8987
|
+
)
|
|
8988
|
+
] })
|
|
8989
|
+
] }) }),
|
|
8990
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "View Mode", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8991
|
+
SidebarSelect,
|
|
8992
|
+
{
|
|
8993
|
+
value: (view == null ? void 0 : view.mode) ?? "default",
|
|
8994
|
+
onChange: (value) => mock.setView(
|
|
8995
|
+
value === "default" ? null : {
|
|
8996
|
+
mode: value,
|
|
8997
|
+
params: view == null ? void 0 : view.params
|
|
8998
|
+
}
|
|
8999
|
+
),
|
|
9000
|
+
options: [
|
|
9001
|
+
{ value: "default", label: "Default (null)" },
|
|
9002
|
+
{ value: "modal", label: "Modal" }
|
|
9003
|
+
]
|
|
9004
|
+
}
|
|
9005
|
+
) }),
|
|
9006
|
+
view && view.mode !== "default" && /* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "View Params (JSON)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9007
|
+
SidebarTextarea,
|
|
9008
|
+
{
|
|
9009
|
+
value: viewParamsJson,
|
|
9010
|
+
onChange: (json) => validateJSON(json, setViewParamsJson, setViewParamsError),
|
|
9011
|
+
onFocus: () => setEditingField("viewParams"),
|
|
9012
|
+
onBlur: () => commitJSON(viewParamsJson, setViewParamsError, (parsed) => {
|
|
9013
|
+
if (view) {
|
|
9014
|
+
mock.setView({ ...view, params: parsed ?? void 0 });
|
|
9015
|
+
}
|
|
9016
|
+
}),
|
|
9017
|
+
error: viewParamsError,
|
|
9018
|
+
maxRows: 2
|
|
9019
|
+
}
|
|
9020
|
+
) }),
|
|
9021
|
+
/* @__PURE__ */ jsxRuntime.jsx(SidebarCollapsibleControl, { label: "Widget State (JSON)", defaultCollapsed: false, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9022
|
+
SidebarTextarea,
|
|
9023
|
+
{
|
|
9024
|
+
value: widgetStateJson,
|
|
9025
|
+
onChange: (json) => validateJSON(json, setWidgetStateJson, setWidgetStateError),
|
|
9026
|
+
onFocus: () => setEditingField("widgetState"),
|
|
9027
|
+
onBlur: () => commitJSON(
|
|
9028
|
+
widgetStateJson,
|
|
9029
|
+
setWidgetStateError,
|
|
9030
|
+
(parsed) => mock.setWidgetStateExternal(parsed)
|
|
9031
|
+
),
|
|
9032
|
+
error: widgetStateError,
|
|
9033
|
+
maxRows: 8
|
|
9034
|
+
}
|
|
9035
|
+
) })
|
|
8367
9036
|
] }) }),
|
|
8368
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "View Mode", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8369
|
-
SidebarSelect,
|
|
8370
|
-
{
|
|
8371
|
-
value: (view == null ? void 0 : view.mode) ?? "default",
|
|
8372
|
-
onChange: (value) => mock.setView(
|
|
8373
|
-
value === "default" ? null : {
|
|
8374
|
-
mode: value,
|
|
8375
|
-
params: view == null ? void 0 : view.params
|
|
8376
|
-
}
|
|
8377
|
-
),
|
|
8378
|
-
options: [
|
|
8379
|
-
{ value: "default", label: "Default (null)" },
|
|
8380
|
-
{ value: "modal", label: "Modal" }
|
|
8381
|
-
]
|
|
8382
|
-
}
|
|
8383
|
-
) }),
|
|
8384
|
-
view && view.mode !== "default" && /* @__PURE__ */ jsxRuntime.jsx(SidebarControl, { label: "View Params (JSON)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8385
|
-
SidebarTextarea,
|
|
8386
|
-
{
|
|
8387
|
-
value: viewParamsJson,
|
|
8388
|
-
onChange: (json) => validateJSON(json, setViewParamsJson, setViewParamsError),
|
|
8389
|
-
onFocus: () => setEditingField("viewParams"),
|
|
8390
|
-
onBlur: () => commitJSON(viewParamsJson, setViewParamsError, (parsed) => {
|
|
8391
|
-
if (view) {
|
|
8392
|
-
mock.setView({ ...view, params: parsed ?? void 0 });
|
|
8393
|
-
}
|
|
8394
|
-
}),
|
|
8395
|
-
error: viewParamsError,
|
|
8396
|
-
rows: 2
|
|
8397
|
-
}
|
|
8398
|
-
) }),
|
|
8399
9037
|
/* @__PURE__ */ jsxRuntime.jsx(SidebarCollapsibleControl, { label: "Tool Input (JSON)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8400
9038
|
SidebarTextarea,
|
|
8401
9039
|
{
|
|
@@ -8408,7 +9046,7 @@ function ChatGPTSimulator({
|
|
|
8408
9046
|
(parsed) => mock.setToolInput(parsed ?? {})
|
|
8409
9047
|
),
|
|
8410
9048
|
error: toolInputError,
|
|
8411
|
-
|
|
9049
|
+
maxRows: 8
|
|
8412
9050
|
}
|
|
8413
9051
|
) }),
|
|
8414
9052
|
/* @__PURE__ */ jsxRuntime.jsx(SidebarCollapsibleControl, { label: "Tool Output (JSON)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8423,7 +9061,7 @@ function ChatGPTSimulator({
|
|
|
8423
9061
|
(parsed) => mock.setToolOutput(parsed)
|
|
8424
9062
|
),
|
|
8425
9063
|
error: toolOutputError,
|
|
8426
|
-
|
|
9064
|
+
maxRows: 8
|
|
8427
9065
|
}
|
|
8428
9066
|
) }),
|
|
8429
9067
|
/* @__PURE__ */ jsxRuntime.jsx(SidebarCollapsibleControl, { label: "Tool Response Metadata (JSON)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8438,22 +9076,7 @@ function ChatGPTSimulator({
|
|
|
8438
9076
|
(parsed) => mock.setToolResponseMetadata(parsed)
|
|
8439
9077
|
),
|
|
8440
9078
|
error: toolResponseMetadataError,
|
|
8441
|
-
|
|
8442
|
-
}
|
|
8443
|
-
) }),
|
|
8444
|
-
/* @__PURE__ */ jsxRuntime.jsx(SidebarCollapsibleControl, { label: "Widget State (JSON)", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8445
|
-
SidebarTextarea,
|
|
8446
|
-
{
|
|
8447
|
-
value: widgetStateJson,
|
|
8448
|
-
onChange: (json) => validateJSON(json, setWidgetStateJson, setWidgetStateError),
|
|
8449
|
-
onFocus: () => setEditingField("widgetState"),
|
|
8450
|
-
onBlur: () => commitJSON(
|
|
8451
|
-
widgetStateJson,
|
|
8452
|
-
setWidgetStateError,
|
|
8453
|
-
(parsed) => mock.setWidgetStateExternal(parsed)
|
|
8454
|
-
),
|
|
8455
|
-
error: widgetStateError,
|
|
8456
|
-
rows: 8
|
|
9079
|
+
maxRows: 8
|
|
8457
9080
|
}
|
|
8458
9081
|
) })
|
|
8459
9082
|
] }),
|
|
@@ -8465,6 +9088,7 @@ function ChatGPTSimulator({
|
|
|
8465
9088
|
appIcon,
|
|
8466
9089
|
userMessage,
|
|
8467
9090
|
resourceMeta: selectedSim == null ? void 0 : selectedSim.resource._meta,
|
|
9091
|
+
iframeScriptSrc,
|
|
8468
9092
|
children: content
|
|
8469
9093
|
},
|
|
8470
9094
|
selectedSimulationName
|
|
@@ -8517,6 +9141,7 @@ function createSimulatorUrl(params, basePath = "/") {
|
|
|
8517
9141
|
return queryString ? `${basePath}?${queryString}` : basePath;
|
|
8518
9142
|
}
|
|
8519
9143
|
exports.ChatGPTSimulator = ChatGPTSimulator;
|
|
9144
|
+
exports.IframeResource = IframeResource;
|
|
8520
9145
|
exports.SCREEN_WIDTHS = SCREEN_WIDTHS;
|
|
8521
9146
|
exports.ThemeProvider = ThemeProvider;
|
|
8522
9147
|
exports.clsx = clsx;
|
|
@@ -8542,4 +9167,4 @@ exports.useWidgetAPI = useWidgetAPI;
|
|
|
8542
9167
|
exports.useWidgetGlobal = useWidgetGlobal;
|
|
8543
9168
|
exports.useWidgetProps = useWidgetProps;
|
|
8544
9169
|
exports.useWidgetState = useWidgetState;
|
|
8545
|
-
//# sourceMappingURL=simulator-url-
|
|
9170
|
+
//# sourceMappingURL=simulator-url-BpCa95pE.cjs.map
|