@opengeni/react 3.5.1-canary.0 → 3.7.0-canary.0
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/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +229 -6
- package/dist/artifacts.js.map +1 -1
- package/dist/{chunk-IB27C53Y.js → chunk-C6WDLHBA.js} +31 -23
- package/dist/chunk-C6WDLHBA.js.map +1 -0
- package/dist/{chunk-WY3MELVJ.js → chunk-DOK4KZF2.js} +119 -8
- package/dist/chunk-DOK4KZF2.js.map +1 -0
- package/dist/{chunk-TJFMMDQU.js → chunk-FJBOU2TH.js} +112 -6
- package/dist/chunk-FJBOU2TH.js.map +1 -0
- package/dist/{chunk-UNCXXIQR.js → chunk-R55HFTT3.js} +66 -24
- package/dist/chunk-R55HFTT3.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/components/artifacts/index.d.ts +1 -1
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +45 -3
- package/dist/components/composer.d.ts +2 -0
- package/dist/components/session-chrome.d.ts +1 -1
- package/dist/composer.js +1 -1
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-YZ3ZKWMM.js} +2 -1
- package/dist/fleet-decision-row-YZ3ZKWMM.js.map +1 -0
- package/dist/hooks/use-file-attachments.d.ts +6 -0
- package/dist/hooks/use-sandbox-files.d.ts +4 -1
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/index.js +114 -58
- package/dist/index.js.map +1 -1
- package/dist/session-ui.js +2 -2
- package/dist/session.js +2 -2
- package/dist/timeline/registry.d.ts +2 -0
- package/dist/timeline/types.d.ts +1 -1
- package/package.json +2 -2
- package/src/artifacts.ts +3 -0
- package/src/client.ts +2 -1
- package/src/components/artifacts/index.ts +3 -0
- package/src/components/artifacts/published-html-artifact-frame.tsx +284 -4
- package/src/components/composer.tsx +89 -25
- package/src/components/message-timeline.tsx +32 -8
- package/src/components/sandbox-workspace.tsx +11 -1
- package/src/components/session-chrome.tsx +3 -3
- package/src/hooks/use-file-attachments.ts +34 -0
- package/src/hooks/use-sandbox-files.ts +68 -20
- package/src/hooks/use-session-events.ts +21 -26
- package/src/hooks/use-workspace-edit.ts +23 -5
- package/src/timeline/fleet-decision-projection.ts +2 -1
- package/src/timeline/fleet-decision-row.tsx +1 -0
- package/src/timeline/projection.ts +151 -7
- package/src/timeline/registry.ts +15 -3
- package/src/timeline/tool-renderers.tsx +117 -1
- package/src/timeline/types.ts +8 -1
- package/dist/chunk-IB27C53Y.js.map +0 -1
- package/dist/chunk-TJFMMDQU.js.map +0 -1
- package/dist/chunk-UNCXXIQR.js.map +0 -1
- package/dist/chunk-WY3MELVJ.js.map +0 -1
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
package/dist/artifacts.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Public artifact surfaces. Import from `@opengeni/react/artifacts`. */
|
|
2
|
-
export { ArtifactSurface, DocumentArtifactSurface, DocumentEditor, DocumentProjectionArtifactSurface, DocumentProjectionEditor, BrowserEditableArtifactWorkbench, EditableDocumentArtifactSurface, EditableArtifactWorkbench, EditableArtifactWorkbenchHost, EditablePresentationArtifactSurface, EditableSpreadsheetArtifactSurface, EditableSpreadsheetGrid, PresentationArtifactSurface, PresentationEditor, PresentationProjectionArtifactSurface, PresentationProjectionEditor, PublishedHtmlArtifactFrame, PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, SpreadsheetArtifactSurface, SpreadsheetGrid, SpreadsheetProjectionGrid, type ArtifactModality, type ArtifactSurfaceProps, type DocumentArtifactSurfaceProps, type DocumentCommit, type DocumentCommitHandler, type DocumentEditorProps, type DocumentEditorProjection, type DocumentLayoutMode, type DocumentProjectionArtifactSurfaceProps, type DocumentProjectionBlock, type DocumentProjectionChange, type DocumentProjectionComment, type DocumentProjectionEditorProps, type DocumentProjectionPageBreak, type DocumentProjectionPageGeometry, type DocumentProjectionParagraph, type DocumentProjectionParagraphStyle, type DocumentProjectionSection, type DocumentProjectionTable, type DocumentProjectionTextRun, type DocumentProjectionTextStyle, type DocumentSelection, type BrowserEditableArtifactWorkbenchOptions, type BrowserEditableArtifactWorkbenchProps, type EditableDocumentArtifactSurfaceProps, type EditableArtifactWorkbenchHostProps, type EditableArtifactWorkbenchProps, type EditablePresentationArtifactSurfaceProps, type EditableSpreadsheetArtifactSurfaceProps, type EditableSpreadsheetGridProps, type PresentationArtifactSurfaceProps, type PresentationCommit, type PresentationCommitHandler, type PresentationEditorProps, type PresentationEditorProjection, type PresentationProjectionArtifactSurfaceProps, type PresentationProjectionChart, type PresentationProjectionChartSeries, type PresentationProjectionConnector, type PresentationProjectionEditorProps, type PublishedHtmlArtifactFrameProps, type PresentationProjectionElementMetadata, type PresentationProjectionElement, type PresentationProjectionFill, type PresentationProjectionGroup, type PresentationProjectionImage, type PresentationProjectionLine, type PresentationProjectionPosition, type PresentationProjectionRichText, type PresentationProjectionShape, type PresentationProjectionTable, type PresentationProjectionTableCell, type PresentationProjectionTextParagraph, type PresentationProjectionTextRun, type PresentationProjectionTextStyle, type PresentationSlideProjection, type SpreadsheetArtifactSurfaceProps, type SpreadsheetCommit, type SpreadsheetRangeCommit, type SpreadsheetGridProps, type SpreadsheetGridProjection, type SpreadsheetProjectionCell, type SpreadsheetProjectionGridProps, type SpreadsheetSelection, type SpreadsheetViewport, } from "./components/artifacts/index.js";
|
|
2
|
+
export { ArtifactSurface, DocumentArtifactSurface, DocumentEditor, DocumentProjectionArtifactSurface, DocumentProjectionEditor, BrowserEditableArtifactWorkbench, EditableDocumentArtifactSurface, EditableArtifactWorkbench, EditableArtifactWorkbenchHost, EditablePresentationArtifactSurface, EditableSpreadsheetArtifactSurface, EditableSpreadsheetGrid, PresentationArtifactSurface, PresentationEditor, PresentationProjectionArtifactSurface, PresentationProjectionEditor, PublishedHtmlArtifactFrame, PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX, openGeniSiteBridgePortFromBootstrap, publishedHtmlArtifactDocument, SpreadsheetArtifactSurface, SpreadsheetGrid, SpreadsheetProjectionGrid, type ArtifactModality, type ArtifactSurfaceProps, type DocumentArtifactSurfaceProps, type DocumentCommit, type DocumentCommitHandler, type DocumentEditorProps, type DocumentEditorProjection, type DocumentLayoutMode, type DocumentProjectionArtifactSurfaceProps, type DocumentProjectionBlock, type DocumentProjectionChange, type DocumentProjectionComment, type DocumentProjectionEditorProps, type DocumentProjectionPageBreak, type DocumentProjectionPageGeometry, type DocumentProjectionParagraph, type DocumentProjectionParagraphStyle, type DocumentProjectionSection, type DocumentProjectionTable, type DocumentProjectionTextRun, type DocumentProjectionTextStyle, type DocumentSelection, type BrowserEditableArtifactWorkbenchOptions, type BrowserEditableArtifactWorkbenchProps, type EditableDocumentArtifactSurfaceProps, type EditableArtifactWorkbenchHostProps, type EditableArtifactWorkbenchProps, type EditablePresentationArtifactSurfaceProps, type EditableSpreadsheetArtifactSurfaceProps, type EditableSpreadsheetGridProps, type PresentationArtifactSurfaceProps, type PresentationCommit, type PresentationCommitHandler, type PresentationEditorProps, type PresentationEditorProjection, type PresentationProjectionArtifactSurfaceProps, type PresentationProjectionChart, type PresentationProjectionChartSeries, type PresentationProjectionConnector, type PresentationProjectionEditorProps, type PublishedHtmlArtifactFrameProps, type PublishedHtmlArtifactToolBridge, type PresentationProjectionElementMetadata, type PresentationProjectionElement, type PresentationProjectionFill, type PresentationProjectionGroup, type PresentationProjectionImage, type PresentationProjectionLine, type PresentationProjectionPosition, type PresentationProjectionRichText, type PresentationProjectionShape, type PresentationProjectionTable, type PresentationProjectionTableCell, type PresentationProjectionTextParagraph, type PresentationProjectionTextRun, type PresentationProjectionTextStyle, type PresentationSlideProjection, type SpreadsheetArtifactSurfaceProps, type SpreadsheetCommit, type SpreadsheetRangeCommit, type SpreadsheetGridProps, type SpreadsheetGridProjection, type SpreadsheetProjectionCell, type SpreadsheetProjectionGridProps, type SpreadsheetSelection, type SpreadsheetViewport, } from "./components/artifacts/index.js";
|
package/dist/artifacts.js
CHANGED
|
@@ -26,6 +26,17 @@ import {
|
|
|
26
26
|
import "./chunk-22KP6LR5.js";
|
|
27
27
|
|
|
28
28
|
// src/components/artifacts/published-html-artifact-frame.tsx
|
|
29
|
+
import {
|
|
30
|
+
OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,
|
|
31
|
+
OPENGENI_SITE_BRIDGE_READY,
|
|
32
|
+
OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
33
|
+
OPENGENI_SITE_BRIDGE_VERSION,
|
|
34
|
+
isOpenGeniSiteBridgeCancelMessage,
|
|
35
|
+
isOpenGeniSiteBridgeConnectMessage,
|
|
36
|
+
isOpenGeniSiteBridgeRequestMessage,
|
|
37
|
+
sanitizeOpenGeniSiteToolCallRequest
|
|
38
|
+
} from "@opengeni/sdk/site";
|
|
39
|
+
import { useEffect, useRef } from "react";
|
|
29
40
|
import { jsx } from "react/jsx-runtime";
|
|
30
41
|
var PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX = [
|
|
31
42
|
"allow-downloads",
|
|
@@ -38,25 +49,235 @@ var PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX = [
|
|
|
38
49
|
"allow-presentation",
|
|
39
50
|
"allow-scripts"
|
|
40
51
|
].join(" ");
|
|
52
|
+
var SITE_BRIDGE_BOOTSTRAP_SCRIPT = `<script>(()=>{const key=${JSON.stringify(
|
|
53
|
+
OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL
|
|
54
|
+
)};const parentWindow=window.parent;if(parentWindow===window)return;window.addEventListener("message",event=>{const data=event.data;if(event.source!==parentWindow||!data||data.type!==${JSON.stringify(
|
|
55
|
+
OPENGENI_SITE_BRIDGE_READY
|
|
56
|
+
)}||data.version!==${OPENGENI_SITE_BRIDGE_VERSION}||event.ports.length!==1)return;const port=event.ports[0];const previous=window[key]?.port;if(previous&&previous!==port)previous.close();Object.defineProperty(window,key,{configurable:true,value:{port}});port.start();});})();</script>`;
|
|
57
|
+
function publishedHtmlArtifactDocument(html, toolBridgeEnabled) {
|
|
58
|
+
if (!toolBridgeEnabled) return html;
|
|
59
|
+
const doctypeEnd = leadingDoctypeEnd(html);
|
|
60
|
+
if (doctypeEnd >= 0) {
|
|
61
|
+
return `${html.slice(0, doctypeEnd + 1)}${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html.slice(doctypeEnd + 1)}`;
|
|
62
|
+
}
|
|
63
|
+
return `${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html}`;
|
|
64
|
+
}
|
|
65
|
+
function leadingDoctypeEnd(html) {
|
|
66
|
+
const lower = html.toLowerCase();
|
|
67
|
+
let cursor = html.charCodeAt(0) === 65279 ? 1 : 0;
|
|
68
|
+
while (cursor < html.length) {
|
|
69
|
+
while (/\s/.test(html[cursor] ?? "")) cursor += 1;
|
|
70
|
+
if (!html.startsWith("<!--", cursor)) break;
|
|
71
|
+
const commentEnd = html.indexOf("-->", cursor + 4);
|
|
72
|
+
if (commentEnd < 0) return -1;
|
|
73
|
+
cursor = commentEnd + 3;
|
|
74
|
+
}
|
|
75
|
+
if (!lower.startsWith("<!doctype", cursor)) return -1;
|
|
76
|
+
return html.indexOf(">", cursor + 9);
|
|
77
|
+
}
|
|
41
78
|
function PublishedHtmlArtifactFrame(props) {
|
|
79
|
+
const frameRef = useRef(null);
|
|
80
|
+
const bridgeRef = useRef(props.toolBridge);
|
|
81
|
+
const onFrameLoadRef = useRef(() => void 0);
|
|
82
|
+
const frameLoadPendingRef = useRef(false);
|
|
83
|
+
const toolBridgeEnabled = props.toolBridge !== void 0;
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
bridgeRef.current = props.toolBridge;
|
|
86
|
+
}, [props.toolBridge]);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (!toolBridgeEnabled || typeof window === "undefined") return;
|
|
89
|
+
const requests = new SiteBridgeRequestRegistry();
|
|
90
|
+
const attachToolPort = (data, ports) => {
|
|
91
|
+
const port = openGeniSiteBridgePortFromBootstrap(data, ports);
|
|
92
|
+
if (!port) return;
|
|
93
|
+
requests.replacePort(port);
|
|
94
|
+
port.addEventListener("message", (portEvent) => {
|
|
95
|
+
const message = portEvent.data;
|
|
96
|
+
if (isOpenGeniSiteBridgeCancelMessage(message)) {
|
|
97
|
+
requests.cancel(port, message.requestId);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (!isOpenGeniSiteBridgeRequestMessage(message)) return;
|
|
101
|
+
const controller = requests.start(port, message.requestId);
|
|
102
|
+
if (!controller) {
|
|
103
|
+
port.postMessage({
|
|
104
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
105
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
106
|
+
requestId: message.requestId,
|
|
107
|
+
ok: false,
|
|
108
|
+
error: {
|
|
109
|
+
code: "duplicate_request_id",
|
|
110
|
+
message: "A Site tool request with this id is already running",
|
|
111
|
+
retryable: false
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
void handleSiteBridgeRequest(bridgeRef.current, message, controller.signal).then((value) => {
|
|
117
|
+
if (!controller.signal.aborted) {
|
|
118
|
+
port.postMessage({
|
|
119
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
120
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
121
|
+
requestId: message.requestId,
|
|
122
|
+
ok: true,
|
|
123
|
+
value
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}).catch((error) => {
|
|
127
|
+
if (!controller.signal.aborted) {
|
|
128
|
+
port.postMessage({
|
|
129
|
+
type: OPENGENI_SITE_BRIDGE_RESPONSE,
|
|
130
|
+
version: OPENGENI_SITE_BRIDGE_VERSION,
|
|
131
|
+
requestId: message.requestId,
|
|
132
|
+
ok: false,
|
|
133
|
+
error: siteBridgeError(error)
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}).finally(() => requests.complete(port, message.requestId, controller));
|
|
137
|
+
});
|
|
138
|
+
port.addEventListener("messageerror", () => requests.closePort(port));
|
|
139
|
+
port.start();
|
|
140
|
+
port.postMessage({
|
|
141
|
+
type: OPENGENI_SITE_BRIDGE_READY,
|
|
142
|
+
version: OPENGENI_SITE_BRIDGE_VERSION
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
const documentLease = new SiteBridgeDocumentLease(attachToolPort, () => requests.closeAll());
|
|
146
|
+
const onFrameLoad = () => {
|
|
147
|
+
frameLoadPendingRef.current = false;
|
|
148
|
+
const frameWindow = frameRef.current?.contentWindow ?? null;
|
|
149
|
+
if (!frameWindow) return;
|
|
150
|
+
documentLease.load(frameWindow);
|
|
151
|
+
};
|
|
152
|
+
onFrameLoadRef.current = onFrameLoad;
|
|
153
|
+
if (frameLoadPendingRef.current) {
|
|
154
|
+
frameLoadPendingRef.current = false;
|
|
155
|
+
onFrameLoad();
|
|
156
|
+
}
|
|
157
|
+
return () => {
|
|
158
|
+
onFrameLoadRef.current = () => void 0;
|
|
159
|
+
documentLease.close();
|
|
160
|
+
};
|
|
161
|
+
}, [props.html, toolBridgeEnabled]);
|
|
42
162
|
return /* @__PURE__ */ jsx(
|
|
43
163
|
"iframe",
|
|
44
164
|
{
|
|
165
|
+
ref: frameRef,
|
|
45
166
|
title: props.title,
|
|
46
167
|
sandbox: PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX,
|
|
47
168
|
referrerPolicy: "no-referrer",
|
|
48
|
-
srcDoc: props.html,
|
|
169
|
+
srcDoc: publishedHtmlArtifactDocument(props.html, toolBridgeEnabled),
|
|
170
|
+
onLoad: () => {
|
|
171
|
+
frameLoadPendingRef.current = true;
|
|
172
|
+
onFrameLoadRef.current();
|
|
173
|
+
},
|
|
49
174
|
className: props.className,
|
|
50
175
|
style: props.style
|
|
51
176
|
}
|
|
52
177
|
);
|
|
53
178
|
}
|
|
179
|
+
var SiteBridgeRequestRegistry = class {
|
|
180
|
+
controllersByPort = /* @__PURE__ */ new Map();
|
|
181
|
+
replacePort(port) {
|
|
182
|
+
this.closeAll();
|
|
183
|
+
this.controllersByPort.set(port, /* @__PURE__ */ new Map());
|
|
184
|
+
}
|
|
185
|
+
start(port, requestId) {
|
|
186
|
+
const controllers = this.controllersByPort.get(port);
|
|
187
|
+
if (!controllers || controllers.has(requestId)) return null;
|
|
188
|
+
const controller = new AbortController();
|
|
189
|
+
controllers.set(requestId, controller);
|
|
190
|
+
return controller;
|
|
191
|
+
}
|
|
192
|
+
cancel(port, requestId) {
|
|
193
|
+
const controllers = this.controllersByPort.get(port);
|
|
194
|
+
const controller = controllers?.get(requestId);
|
|
195
|
+
if (!controller) return;
|
|
196
|
+
controller.abort(new Error("Site tool request cancelled"));
|
|
197
|
+
controllers.delete(requestId);
|
|
198
|
+
}
|
|
199
|
+
complete(port, requestId, controller) {
|
|
200
|
+
const controllers = this.controllersByPort.get(port);
|
|
201
|
+
if (controllers?.get(requestId) === controller) controllers.delete(requestId);
|
|
202
|
+
}
|
|
203
|
+
closePort(port) {
|
|
204
|
+
const controllers = this.controllersByPort.get(port);
|
|
205
|
+
if (!controllers) return;
|
|
206
|
+
for (const controller of controllers.values()) {
|
|
207
|
+
controller.abort(new Error("Site tool bridge port closed"));
|
|
208
|
+
}
|
|
209
|
+
controllers.clear();
|
|
210
|
+
this.controllersByPort.delete(port);
|
|
211
|
+
port.close();
|
|
212
|
+
}
|
|
213
|
+
closeAll() {
|
|
214
|
+
for (const port of [...this.controllersByPort.keys()]) this.closePort(port);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
var SiteBridgeDocumentLease = class {
|
|
218
|
+
constructor(attachToolPort, closeActivePorts, createMessageChannel = () => new MessageChannel()) {
|
|
219
|
+
this.attachToolPort = attachToolPort;
|
|
220
|
+
this.closeActivePorts = closeActivePorts;
|
|
221
|
+
this.createMessageChannel = createMessageChannel;
|
|
222
|
+
}
|
|
223
|
+
loaded = false;
|
|
224
|
+
bootstrapPort = null;
|
|
225
|
+
load(frameWindow) {
|
|
226
|
+
if (this.loaded) {
|
|
227
|
+
this.close();
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
this.loaded = true;
|
|
231
|
+
const channel = this.createMessageChannel();
|
|
232
|
+
this.bootstrapPort = channel.port1;
|
|
233
|
+
channel.port1.addEventListener("message", (event) => {
|
|
234
|
+
this.attachToolPort(event.data, event.ports);
|
|
235
|
+
});
|
|
236
|
+
channel.port1.start();
|
|
237
|
+
frameWindow.postMessage(
|
|
238
|
+
{
|
|
239
|
+
type: OPENGENI_SITE_BRIDGE_READY,
|
|
240
|
+
version: OPENGENI_SITE_BRIDGE_VERSION
|
|
241
|
+
},
|
|
242
|
+
"*",
|
|
243
|
+
[channel.port2]
|
|
244
|
+
);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
close() {
|
|
248
|
+
this.bootstrapPort?.close();
|
|
249
|
+
this.bootstrapPort = null;
|
|
250
|
+
this.closeActivePorts();
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
function openGeniSiteBridgePortFromBootstrap(data, ports) {
|
|
254
|
+
if (!isOpenGeniSiteBridgeConnectMessage(data)) return null;
|
|
255
|
+
return ports.length === 1 ? ports[0] : null;
|
|
256
|
+
}
|
|
257
|
+
async function handleSiteBridgeRequest(bridge, message, signal) {
|
|
258
|
+
if (!bridge) throw new Error("Site tool bridge is unavailable");
|
|
259
|
+
if (message.method === "catalog") return await bridge.catalog({ signal });
|
|
260
|
+
if (message.method === "declarations") {
|
|
261
|
+
if (!bridge.declarations) throw new Error("Site tool declarations are unavailable");
|
|
262
|
+
return await bridge.declarations({ signal });
|
|
263
|
+
}
|
|
264
|
+
return await bridge.call(sanitizeOpenGeniSiteToolCallRequest(message.payload), { signal });
|
|
265
|
+
}
|
|
266
|
+
function siteBridgeError(error) {
|
|
267
|
+
const candidate = error;
|
|
268
|
+
return {
|
|
269
|
+
code: typeof candidate?.code === "string" ? candidate.code : "site_tool_call_failed",
|
|
270
|
+
message: typeof candidate?.message === "string" ? candidate.message : "Site tool request failed",
|
|
271
|
+
retryable: candidate?.retryable === true,
|
|
272
|
+
outcomeUnknown: candidate?.outcomeUnknown === true
|
|
273
|
+
};
|
|
274
|
+
}
|
|
54
275
|
|
|
55
276
|
// src/components/artifacts/editable-artifact-workbench.tsx
|
|
56
277
|
import {
|
|
57
278
|
createBrowserEditableArtifactSession
|
|
58
279
|
} from "@opengeni/sdk/editable-artifacts";
|
|
59
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
280
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
60
281
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
61
282
|
function EditableArtifactWorkbench({
|
|
62
283
|
session,
|
|
@@ -87,13 +308,13 @@ function EditableArtifactWorkbenchHost({
|
|
|
87
308
|
spreadsheet,
|
|
88
309
|
presentation
|
|
89
310
|
}) {
|
|
90
|
-
const createSessionRef =
|
|
311
|
+
const createSessionRef = useRef2(createSession);
|
|
91
312
|
const [retryEpoch, setRetryEpoch] = useState(0);
|
|
92
313
|
const [state, setState] = useState({ key: null, session: null, error: null });
|
|
93
|
-
|
|
314
|
+
useEffect2(() => {
|
|
94
315
|
createSessionRef.current = createSession;
|
|
95
316
|
}, [createSession]);
|
|
96
|
-
|
|
317
|
+
useEffect2(() => {
|
|
97
318
|
let owned = null;
|
|
98
319
|
setState({ key: sessionKey, session: null, error: null });
|
|
99
320
|
try {
|
|
@@ -194,6 +415,8 @@ export {
|
|
|
194
415
|
PublishedHtmlArtifactFrame,
|
|
195
416
|
SpreadsheetArtifactSurface,
|
|
196
417
|
SpreadsheetGrid,
|
|
197
|
-
SpreadsheetProjectionGrid
|
|
418
|
+
SpreadsheetProjectionGrid,
|
|
419
|
+
openGeniSiteBridgePortFromBootstrap,
|
|
420
|
+
publishedHtmlArtifactDocument
|
|
198
421
|
};
|
|
199
422
|
//# sourceMappingURL=artifacts.js.map
|
package/dist/artifacts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/artifacts/published-html-artifact-frame.tsx","../src/components/artifacts/editable-artifact-workbench.tsx"],"sourcesContent":["import type { CSSProperties } from \"react\";\n\nexport const PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX = [\n \"allow-downloads\",\n \"allow-forms\",\n \"allow-modals\",\n \"allow-orientation-lock\",\n \"allow-pointer-lock\",\n \"allow-popups\",\n \"allow-popups-to-escape-sandbox\",\n \"allow-presentation\",\n \"allow-scripts\",\n].join(\" \");\n\nexport type PublishedHtmlArtifactFrameProps = {\n html: string;\n title: string;\n className?: string;\n style?: CSSProperties;\n};\n\n/**\n * Render exact published HTML in an opaque-origin iframe. Artifact scripts,\n * external resources, forms, popups, and downloads work without granting\n * parent-origin authority, shared cookies/storage, or top-level navigation.\n */\nexport function PublishedHtmlArtifactFrame(props: PublishedHtmlArtifactFrameProps) {\n return (\n <iframe\n title={props.title}\n sandbox={PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX}\n referrerPolicy=\"no-referrer\"\n srcDoc={props.html}\n className={props.className}\n style={props.style}\n />\n );\n}\n","import {\n createBrowserEditableArtifactSession,\n type CreateBrowserEditableArtifactSessionOptions,\n type EditableArtifactBrowserRuntime,\n type EditableArtifactSession,\n} from \"@opengeni/sdk/editable-artifacts\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { EditableArtifactMessage } from \"./editable-artifact-ui\";\nimport {\n EditableDocumentArtifactSurface,\n type EditableDocumentArtifactSurfaceProps,\n} from \"./editable-document\";\nimport {\n EditablePresentationArtifactSurface,\n type EditablePresentationArtifactSurfaceProps,\n} from \"./editable-presentation\";\nimport {\n EditableSpreadsheetArtifactSurface,\n type EditableSpreadsheetArtifactSurfaceProps,\n} from \"./editable-spreadsheet\";\n\nexport type EditableArtifactWorkbenchProps = Readonly<{\n session: EditableArtifactSession;\n document?: Omit<EditableDocumentArtifactSurfaceProps, \"session\">;\n spreadsheet?: Omit<EditableSpreadsheetArtifactSurfaceProps, \"session\">;\n presentation?: Omit<EditablePresentationArtifactSurfaceProps, \"session\">;\n}>;\n\nexport type EditableArtifactWorkbenchHostProps = Omit<EditableArtifactWorkbenchProps, \"session\"> &\n Readonly<{\n /**\n * Complete identity of the browser session authority. Change this when the\n * artifact, deployment, principal, or authorization epoch changes.\n */\n sessionKey: string;\n /** Called for the active keyed lifecycle and again only after replacement or retry. */\n createSession: () => EditableArtifactSession;\n }>;\n\ntype DefaultBrowserArtifactTransport = Omit<\n NonNullable<CreateBrowserEditableArtifactSessionOptions[\"transport\"]>,\n \"apiKey\" | \"fetch\" | \"headers\" | \"webSocketFactory\"\n> &\n Readonly<{\n /** Static deployment auth headers; rotate authorizationEpoch when they change. */\n headers?: Readonly<Record<string, string>>;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchOptions = Omit<\n CreateBrowserEditableArtifactSessionOptions,\n \"runtime\" | \"storage\" | \"transport\"\n> &\n Readonly<{\n /** Default module Worker only; custom Worker hosts use EditableArtifactWorkbenchHost. */\n runtime: Omit<EditableArtifactBrowserRuntime, \"workerFactory\">;\n /** Default fetch/WebSocket only; static deployment auth headers are supported. */\n transport?: DefaultBrowserArtifactTransport;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchProps = Omit<\n EditableArtifactWorkbenchProps,\n \"session\"\n> &\n Readonly<{ options: BrowserEditableArtifactWorkbenchOptions }>;\n\n/**\n * One modality-neutral SDK workbench. Embedding hosts keep one route/component;\n * each artifact still renders through its complete first-party editor surface.\n */\nexport function EditableArtifactWorkbench({\n session,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchProps) {\n switch (session.modality) {\n case \"document\":\n return (\n <EditableDocumentArtifactSurface\n {...document}\n session={session}\n title={document?.title ?? \"Document\"}\n />\n );\n case \"spreadsheet\":\n return <EditableSpreadsheetArtifactSurface {...spreadsheet} session={session} />;\n case \"presentation\":\n return <EditablePresentationArtifactSurface {...presentation} session={session} />;\n }\n}\n\n/**\n * Route/embed composition that owns exactly one SDK session. The host supplies\n * the authenticated SDK factory; React guarantees replacement and teardown.\n */\nexport function EditableArtifactWorkbenchHost({\n sessionKey,\n createSession,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchHostProps) {\n const createSessionRef = useRef(createSession);\n const [retryEpoch, setRetryEpoch] = useState(0);\n const [state, setState] = useState<\n | Readonly<{ key: string; session: EditableArtifactSession; error: null }>\n | Readonly<{ key: string | null; session: null; error: Error | null }>\n >({ key: null, session: null, error: null });\n\n useEffect(() => {\n createSessionRef.current = createSession;\n }, [createSession]);\n\n useEffect(() => {\n let owned: EditableArtifactSession | null = null;\n setState({ key: sessionKey, session: null, error: null });\n try {\n owned = createSessionRef.current();\n setState({ key: sessionKey, session: owned, error: null });\n } catch (cause) {\n setState({\n key: sessionKey,\n session: null,\n error: cause instanceof Error ? cause : new Error(\"Could not create artifact session\"),\n });\n }\n return () => {\n const closing = owned;\n owned = null;\n if (closing) void closing.close().catch(() => undefined);\n };\n }, [retryEpoch, sessionKey]);\n\n const retry = useCallback(() => setRetryEpoch((value) => value + 1), []);\n const currentError = state.key === sessionKey ? state.error : null;\n if (state.key === sessionKey && state.session) {\n return (\n <EditableArtifactWorkbench\n session={state.session}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n }\n return (\n <EditableArtifactMessage\n title={currentError ? \"Could not open this artifact\" : \"Opening artifact\"}\n detail={currentError?.message ?? \"Starting the secure editing session…\"}\n retry={currentError ? retry : undefined}\n />\n );\n}\n\n/**\n * Complete default-browser composition for embedders: verified WASM Worker,\n * durable IndexedDB state, authenticated live sync, teardown, and the matching\n * first-party editor. Advanced/custom transports compose the lower-level host.\n */\nexport function BrowserEditableArtifactWorkbench({\n options,\n document,\n spreadsheet,\n presentation,\n}: BrowserEditableArtifactWorkbenchProps) {\n const sessionKey = browserSessionKey(options);\n const createSession = useCallback(() => createBrowserEditableArtifactSession(options), [options]);\n return (\n <EditableArtifactWorkbenchHost\n sessionKey={sessionKey}\n createSession={createSession}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n}\n\nfunction browserSessionKey(options: BrowserEditableArtifactWorkbenchOptions): string {\n const transport = options.transport\n ? {\n ...options.transport,\n // Credentials must not be copied into React lifecycle keys. The\n // authorization epoch is the explicit credential/grant rotation fence.\n headers: options.transport.headers\n ? Object.keys(options.transport.headers).sort()\n : undefined,\n }\n : null;\n return JSON.stringify(\n {\n baseUrl: options.baseUrl,\n workspaceId: options.workspaceId,\n artifact: { id: options.artifact.id, modality: options.artifact.modality },\n storageAuthority: options.storageAuthority,\n runtime: options.runtime,\n replicaId: options.replicaId ?? null,\n transport,\n },\n (_key, value: unknown) => (value instanceof URL ? value.href : value),\n );\n}\n"],"mappings":"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","names":["jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/artifacts/published-html-artifact-frame.tsx","../src/components/artifacts/editable-artifact-workbench.tsx"],"sourcesContent":["import {\n OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,\n OPENGENI_SITE_BRIDGE_READY,\n OPENGENI_SITE_BRIDGE_RESPONSE,\n OPENGENI_SITE_BRIDGE_VERSION,\n isOpenGeniSiteBridgeCancelMessage,\n isOpenGeniSiteBridgeConnectMessage,\n isOpenGeniSiteBridgeRequestMessage,\n sanitizeOpenGeniSiteToolCallRequest,\n type OpenGeniSiteBridgeResponseMessage,\n type OpenGeniSiteToolCatalog,\n} from \"@opengeni/sdk/site\";\nimport type {\n ToolGatewayCallRequest,\n ToolGatewayCallResponse,\n ToolGatewayDeclarationsResponse,\n} from \"@opengeni/sdk\";\nimport { useEffect, useRef, type CSSProperties } from \"react\";\n\nexport const PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX = [\n \"allow-downloads\",\n \"allow-forms\",\n \"allow-modals\",\n \"allow-orientation-lock\",\n \"allow-pointer-lock\",\n \"allow-popups\",\n \"allow-popups-to-escape-sandbox\",\n \"allow-presentation\",\n \"allow-scripts\",\n].join(\" \");\n\nexport type PublishedHtmlArtifactFrameProps = {\n html: string;\n title: string;\n className?: string;\n style?: CSSProperties;\n toolBridge?: PublishedHtmlArtifactToolBridge;\n};\n\nexport type PublishedHtmlArtifactToolBridge = {\n catalog: (options: { signal: AbortSignal }) => Promise<OpenGeniSiteToolCatalog>;\n call: (\n request: ToolGatewayCallRequest,\n options: { signal: AbortSignal },\n ) => Promise<ToolGatewayCallResponse>;\n declarations?: (options: { signal: AbortSignal }) => Promise<ToolGatewayDeclarationsResponse>;\n};\n\nconst SITE_BRIDGE_BOOTSTRAP_SCRIPT = `<script>(()=>{const key=${JSON.stringify(\n OPENGENI_SITE_BRIDGE_BOOTSTRAP_GLOBAL,\n)};const parentWindow=window.parent;if(parentWindow===window)return;window.addEventListener(\"message\",event=>{const data=event.data;if(event.source!==parentWindow||!data||data.type!==${JSON.stringify(\n OPENGENI_SITE_BRIDGE_READY,\n)}||data.version!==${OPENGENI_SITE_BRIDGE_VERSION}||event.ports.length!==1)return;const port=event.ports[0];const previous=window[key]?.port;if(previous&&previous!==port)previous.close();Object.defineProperty(window,key,{configurable:true,value:{port}});port.start();});})();</script>`;\n\nexport function publishedHtmlArtifactDocument(html: string, toolBridgeEnabled: boolean): string {\n if (!toolBridgeEnabled) return html;\n const doctypeEnd = leadingDoctypeEnd(html);\n if (doctypeEnd >= 0) {\n return `${html.slice(0, doctypeEnd + 1)}${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html.slice(doctypeEnd + 1)}`;\n }\n return `${SITE_BRIDGE_BOOTSTRAP_SCRIPT}${html}`;\n}\n\nfunction leadingDoctypeEnd(html: string): number {\n const lower = html.toLowerCase();\n let cursor = html.charCodeAt(0) === 0xfeff ? 1 : 0;\n while (cursor < html.length) {\n while (/\\s/.test(html[cursor] ?? \"\")) cursor += 1;\n if (!html.startsWith(\"<!--\", cursor)) break;\n const commentEnd = html.indexOf(\"-->\", cursor + 4);\n if (commentEnd < 0) return -1;\n cursor = commentEnd + 3;\n }\n if (!lower.startsWith(\"<!doctype\", cursor)) return -1;\n return html.indexOf(\">\", cursor + 9);\n}\n\n/**\n * Render exact published HTML in an opaque-origin iframe. Artifact scripts,\n * external resources, forms, popups, downloads, and the host-filtered tool\n * bridge work without granting parent-origin authority, shared cookies/storage,\n * or top-level navigation.\n */\nexport function PublishedHtmlArtifactFrame(props: PublishedHtmlArtifactFrameProps) {\n const frameRef = useRef<HTMLIFrameElement | null>(null);\n const bridgeRef = useRef(props.toolBridge);\n const onFrameLoadRef = useRef<() => void>(() => undefined);\n const frameLoadPendingRef = useRef(false);\n const toolBridgeEnabled = props.toolBridge !== undefined;\n useEffect(() => {\n bridgeRef.current = props.toolBridge;\n }, [props.toolBridge]);\n useEffect(() => {\n if (!toolBridgeEnabled || typeof window === \"undefined\") return;\n const requests = new SiteBridgeRequestRegistry();\n const attachToolPort = (data: unknown, ports: readonly MessagePort[]) => {\n const port = openGeniSiteBridgePortFromBootstrap(data, ports);\n if (!port) return;\n requests.replacePort(port);\n port.addEventListener(\"message\", (portEvent: MessageEvent<unknown>) => {\n const message = portEvent.data;\n if (isOpenGeniSiteBridgeCancelMessage(message)) {\n requests.cancel(port, message.requestId);\n return;\n }\n if (!isOpenGeniSiteBridgeRequestMessage(message)) return;\n const controller = requests.start(port, message.requestId);\n if (!controller) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: false,\n error: {\n code: \"duplicate_request_id\",\n message: \"A Site tool request with this id is already running\",\n retryable: false,\n },\n } satisfies OpenGeniSiteBridgeResponseMessage);\n return;\n }\n void handleSiteBridgeRequest(bridgeRef.current, message, controller.signal)\n .then((value) => {\n if (!controller.signal.aborted) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: true,\n value,\n } satisfies OpenGeniSiteBridgeResponseMessage);\n }\n })\n .catch((error) => {\n if (!controller.signal.aborted) {\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_RESPONSE,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n requestId: message.requestId,\n ok: false,\n error: siteBridgeError(error),\n } satisfies OpenGeniSiteBridgeResponseMessage);\n }\n })\n .finally(() => requests.complete(port, message.requestId, controller));\n });\n port.addEventListener(\"messageerror\", () => requests.closePort(port));\n port.start();\n port.postMessage({\n type: OPENGENI_SITE_BRIDGE_READY,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n });\n };\n const documentLease = new SiteBridgeDocumentLease(attachToolPort, () => requests.closeAll());\n const onFrameLoad = () => {\n frameLoadPendingRef.current = false;\n const frameWindow = frameRef.current?.contentWindow ?? null;\n if (!frameWindow) return;\n documentLease.load(frameWindow);\n };\n onFrameLoadRef.current = onFrameLoad;\n if (frameLoadPendingRef.current) {\n frameLoadPendingRef.current = false;\n onFrameLoad();\n }\n return () => {\n onFrameLoadRef.current = () => undefined;\n documentLease.close();\n };\n }, [props.html, toolBridgeEnabled]);\n return (\n <iframe\n ref={frameRef}\n title={props.title}\n sandbox={PUBLISHED_HTML_ARTIFACT_IFRAME_SANDBOX}\n referrerPolicy=\"no-referrer\"\n srcDoc={publishedHtmlArtifactDocument(props.html, toolBridgeEnabled)}\n onLoad={() => {\n frameLoadPendingRef.current = true;\n onFrameLoadRef.current();\n }}\n className={props.className}\n style={props.style}\n />\n );\n}\n\nexport class SiteBridgeRequestRegistry {\n private readonly controllersByPort = new Map<MessagePort, Map<string, AbortController>>();\n\n replacePort(port: MessagePort): void {\n this.closeAll();\n this.controllersByPort.set(port, new Map());\n }\n\n start(port: MessagePort, requestId: string): AbortController | null {\n const controllers = this.controllersByPort.get(port);\n if (!controllers || controllers.has(requestId)) return null;\n const controller = new AbortController();\n controllers.set(requestId, controller);\n return controller;\n }\n\n cancel(port: MessagePort, requestId: string): void {\n const controllers = this.controllersByPort.get(port);\n const controller = controllers?.get(requestId);\n if (!controller) return;\n controller.abort(new Error(\"Site tool request cancelled\"));\n controllers!.delete(requestId);\n }\n\n complete(port: MessagePort, requestId: string, controller: AbortController): void {\n const controllers = this.controllersByPort.get(port);\n if (controllers?.get(requestId) === controller) controllers.delete(requestId);\n }\n\n closePort(port: MessagePort): void {\n const controllers = this.controllersByPort.get(port);\n if (!controllers) return;\n for (const controller of controllers.values()) {\n controller.abort(new Error(\"Site tool bridge port closed\"));\n }\n controllers.clear();\n this.controllersByPort.delete(port);\n port.close();\n }\n\n closeAll(): void {\n for (const port of [...this.controllersByPort.keys()]) this.closePort(port);\n }\n}\n\nexport class SiteBridgeDocumentLease {\n private loaded = false;\n private bootstrapPort: MessagePort | null = null;\n\n constructor(\n private readonly attachToolPort: (data: unknown, ports: readonly MessagePort[]) => void,\n private readonly closeActivePorts: () => void,\n private readonly createMessageChannel: () => MessageChannel = () => new MessageChannel(),\n ) {}\n\n load(frameWindow: Pick<Window, \"postMessage\">): boolean {\n if (this.loaded) {\n this.close();\n return false;\n }\n this.loaded = true;\n const channel = this.createMessageChannel();\n this.bootstrapPort = channel.port1;\n channel.port1.addEventListener(\"message\", (event: MessageEvent<unknown>) => {\n this.attachToolPort(event.data, event.ports);\n });\n channel.port1.start();\n frameWindow.postMessage(\n {\n type: OPENGENI_SITE_BRIDGE_READY,\n version: OPENGENI_SITE_BRIDGE_VERSION,\n },\n \"*\",\n [channel.port2],\n );\n return true;\n }\n\n close(): void {\n this.bootstrapPort?.close();\n this.bootstrapPort = null;\n this.closeActivePorts();\n }\n}\n\nexport function openGeniSiteBridgePortFromBootstrap(\n data: unknown,\n ports: readonly MessagePort[],\n): MessagePort | null {\n if (!isOpenGeniSiteBridgeConnectMessage(data)) return null;\n return ports.length === 1 ? ports[0]! : null;\n}\n\nasync function handleSiteBridgeRequest(\n bridge: PublishedHtmlArtifactToolBridge | undefined,\n message: Parameters<typeof isOpenGeniSiteBridgeRequestMessage>[0] & {\n method: \"catalog\" | \"call\" | \"declarations\";\n requestId: string;\n payload?: ToolGatewayCallRequest;\n },\n signal: AbortSignal,\n): Promise<OpenGeniSiteToolCatalog | ToolGatewayCallResponse | ToolGatewayDeclarationsResponse> {\n if (!bridge) throw new Error(\"Site tool bridge is unavailable\");\n if (message.method === \"catalog\") return await bridge.catalog({ signal });\n if (message.method === \"declarations\") {\n if (!bridge.declarations) throw new Error(\"Site tool declarations are unavailable\");\n return await bridge.declarations({ signal });\n }\n return await bridge.call(sanitizeOpenGeniSiteToolCallRequest(message.payload!), { signal });\n}\n\nexport function siteBridgeError(error: unknown): {\n code: string;\n message: string;\n retryable: boolean;\n outcomeUnknown: boolean;\n} {\n const candidate = error as {\n code?: unknown;\n message?: unknown;\n retryable?: unknown;\n outcomeUnknown?: unknown;\n };\n return {\n code: typeof candidate?.code === \"string\" ? candidate.code : \"site_tool_call_failed\",\n message:\n typeof candidate?.message === \"string\" ? candidate.message : \"Site tool request failed\",\n retryable: candidate?.retryable === true,\n outcomeUnknown: candidate?.outcomeUnknown === true,\n };\n}\n","import {\n createBrowserEditableArtifactSession,\n type CreateBrowserEditableArtifactSessionOptions,\n type EditableArtifactBrowserRuntime,\n type EditableArtifactSession,\n} from \"@opengeni/sdk/editable-artifacts\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { EditableArtifactMessage } from \"./editable-artifact-ui\";\nimport {\n EditableDocumentArtifactSurface,\n type EditableDocumentArtifactSurfaceProps,\n} from \"./editable-document\";\nimport {\n EditablePresentationArtifactSurface,\n type EditablePresentationArtifactSurfaceProps,\n} from \"./editable-presentation\";\nimport {\n EditableSpreadsheetArtifactSurface,\n type EditableSpreadsheetArtifactSurfaceProps,\n} from \"./editable-spreadsheet\";\n\nexport type EditableArtifactWorkbenchProps = Readonly<{\n session: EditableArtifactSession;\n document?: Omit<EditableDocumentArtifactSurfaceProps, \"session\">;\n spreadsheet?: Omit<EditableSpreadsheetArtifactSurfaceProps, \"session\">;\n presentation?: Omit<EditablePresentationArtifactSurfaceProps, \"session\">;\n}>;\n\nexport type EditableArtifactWorkbenchHostProps = Omit<EditableArtifactWorkbenchProps, \"session\"> &\n Readonly<{\n /**\n * Complete identity of the browser session authority. Change this when the\n * artifact, deployment, principal, or authorization epoch changes.\n */\n sessionKey: string;\n /** Called for the active keyed lifecycle and again only after replacement or retry. */\n createSession: () => EditableArtifactSession;\n }>;\n\ntype DefaultBrowserArtifactTransport = Omit<\n NonNullable<CreateBrowserEditableArtifactSessionOptions[\"transport\"]>,\n \"apiKey\" | \"fetch\" | \"headers\" | \"webSocketFactory\"\n> &\n Readonly<{\n /** Static deployment auth headers; rotate authorizationEpoch when they change. */\n headers?: Readonly<Record<string, string>>;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchOptions = Omit<\n CreateBrowserEditableArtifactSessionOptions,\n \"runtime\" | \"storage\" | \"transport\"\n> &\n Readonly<{\n /** Default module Worker only; custom Worker hosts use EditableArtifactWorkbenchHost. */\n runtime: Omit<EditableArtifactBrowserRuntime, \"workerFactory\">;\n /** Default fetch/WebSocket only; static deployment auth headers are supported. */\n transport?: DefaultBrowserArtifactTransport;\n }>;\n\nexport type BrowserEditableArtifactWorkbenchProps = Omit<\n EditableArtifactWorkbenchProps,\n \"session\"\n> &\n Readonly<{ options: BrowserEditableArtifactWorkbenchOptions }>;\n\n/**\n * One modality-neutral SDK workbench. Embedding hosts keep one route/component;\n * each artifact still renders through its complete first-party editor surface.\n */\nexport function EditableArtifactWorkbench({\n session,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchProps) {\n switch (session.modality) {\n case \"document\":\n return (\n <EditableDocumentArtifactSurface\n {...document}\n session={session}\n title={document?.title ?? \"Document\"}\n />\n );\n case \"spreadsheet\":\n return <EditableSpreadsheetArtifactSurface {...spreadsheet} session={session} />;\n case \"presentation\":\n return <EditablePresentationArtifactSurface {...presentation} session={session} />;\n }\n}\n\n/**\n * Route/embed composition that owns exactly one SDK session. The host supplies\n * the authenticated SDK factory; React guarantees replacement and teardown.\n */\nexport function EditableArtifactWorkbenchHost({\n sessionKey,\n createSession,\n document,\n spreadsheet,\n presentation,\n}: EditableArtifactWorkbenchHostProps) {\n const createSessionRef = useRef(createSession);\n const [retryEpoch, setRetryEpoch] = useState(0);\n const [state, setState] = useState<\n | Readonly<{ key: string; session: EditableArtifactSession; error: null }>\n | Readonly<{ key: string | null; session: null; error: Error | null }>\n >({ key: null, session: null, error: null });\n\n useEffect(() => {\n createSessionRef.current = createSession;\n }, [createSession]);\n\n useEffect(() => {\n let owned: EditableArtifactSession | null = null;\n setState({ key: sessionKey, session: null, error: null });\n try {\n owned = createSessionRef.current();\n setState({ key: sessionKey, session: owned, error: null });\n } catch (cause) {\n setState({\n key: sessionKey,\n session: null,\n error: cause instanceof Error ? cause : new Error(\"Could not create artifact session\"),\n });\n }\n return () => {\n const closing = owned;\n owned = null;\n if (closing) void closing.close().catch(() => undefined);\n };\n }, [retryEpoch, sessionKey]);\n\n const retry = useCallback(() => setRetryEpoch((value) => value + 1), []);\n const currentError = state.key === sessionKey ? state.error : null;\n if (state.key === sessionKey && state.session) {\n return (\n <EditableArtifactWorkbench\n session={state.session}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n }\n return (\n <EditableArtifactMessage\n title={currentError ? \"Could not open this artifact\" : \"Opening artifact\"}\n detail={currentError?.message ?? \"Starting the secure editing session…\"}\n retry={currentError ? retry : undefined}\n />\n );\n}\n\n/**\n * Complete default-browser composition for embedders: verified WASM Worker,\n * durable IndexedDB state, authenticated live sync, teardown, and the matching\n * first-party editor. Advanced/custom transports compose the lower-level host.\n */\nexport function BrowserEditableArtifactWorkbench({\n options,\n document,\n spreadsheet,\n presentation,\n}: BrowserEditableArtifactWorkbenchProps) {\n const sessionKey = browserSessionKey(options);\n const createSession = useCallback(() => createBrowserEditableArtifactSession(options), [options]);\n return (\n <EditableArtifactWorkbenchHost\n sessionKey={sessionKey}\n createSession={createSession}\n {...(document ? { document } : {})}\n {...(spreadsheet ? { spreadsheet } : {})}\n {...(presentation ? { presentation } : {})}\n />\n );\n}\n\nfunction browserSessionKey(options: BrowserEditableArtifactWorkbenchOptions): string {\n const transport = options.transport\n ? {\n ...options.transport,\n // Credentials must not be copied into React lifecycle keys. The\n // authorization epoch is the explicit credential/grant rotation fence.\n headers: options.transport.headers\n ? Object.keys(options.transport.headers).sort()\n : undefined,\n }\n : null;\n return JSON.stringify(\n {\n baseUrl: options.baseUrl,\n workspaceId: options.workspaceId,\n artifact: { id: options.artifact.id, modality: options.artifact.modality },\n storageAuthority: options.storageAuthority,\n runtime: options.runtime,\n replicaId: options.replicaId ?? null,\n transport,\n },\n (_key, value: unknown) => (value instanceof URL ? value.href : value),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAMP,SAAS,WAAW,cAAkC;AA0JlD;AAxJG,IAAM,yCAAyC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG;AAmBV,IAAM,+BAA+B,2BAA2B,KAAK;AAAA,EACnE;AACF,CAAC,wLAAwL,KAAK;AAAA,EAC5L;AACF,CAAC,oBAAoB,4BAA4B;AAE1C,SAAS,8BAA8B,MAAc,mBAAoC;AAC9F,MAAI,CAAC,kBAAmB,QAAO;AAC/B,QAAM,aAAa,kBAAkB,IAAI;AACzC,MAAI,cAAc,GAAG;AACnB,WAAO,GAAG,KAAK,MAAM,GAAG,aAAa,CAAC,CAAC,GAAG,4BAA4B,GAAG,KAAK,MAAM,aAAa,CAAC,CAAC;AAAA,EACrG;AACA,SAAO,GAAG,4BAA4B,GAAG,IAAI;AAC/C;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,QAAM,QAAQ,KAAK,YAAY;AAC/B,MAAI,SAAS,KAAK,WAAW,CAAC,MAAM,QAAS,IAAI;AACjD,SAAO,SAAS,KAAK,QAAQ;AAC3B,WAAO,KAAK,KAAK,KAAK,MAAM,KAAK,EAAE,EAAG,WAAU;AAChD,QAAI,CAAC,KAAK,WAAW,QAAQ,MAAM,EAAG;AACtC,UAAM,aAAa,KAAK,QAAQ,OAAO,SAAS,CAAC;AACjD,QAAI,aAAa,EAAG,QAAO;AAC3B,aAAS,aAAa;AAAA,EACxB;AACA,MAAI,CAAC,MAAM,WAAW,aAAa,MAAM,EAAG,QAAO;AACnD,SAAO,KAAK,QAAQ,KAAK,SAAS,CAAC;AACrC;AAQO,SAAS,2BAA2B,OAAwC;AACjF,QAAM,WAAW,OAAiC,IAAI;AACtD,QAAM,YAAY,OAAO,MAAM,UAAU;AACzC,QAAM,iBAAiB,OAAmB,MAAM,MAAS;AACzD,QAAM,sBAAsB,OAAO,KAAK;AACxC,QAAM,oBAAoB,MAAM,eAAe;AAC/C,YAAU,MAAM;AACd,cAAU,UAAU,MAAM;AAAA,EAC5B,GAAG,CAAC,MAAM,UAAU,CAAC;AACrB,YAAU,MAAM;AACd,QAAI,CAAC,qBAAqB,OAAO,WAAW,YAAa;AACzD,UAAM,WAAW,IAAI,0BAA0B;AAC/C,UAAM,iBAAiB,CAAC,MAAe,UAAkC;AACvE,YAAM,OAAO,oCAAoC,MAAM,KAAK;AAC5D,UAAI,CAAC,KAAM;AACX,eAAS,YAAY,IAAI;AACzB,WAAK,iBAAiB,WAAW,CAAC,cAAqC;AACrE,cAAM,UAAU,UAAU;AAC1B,YAAI,kCAAkC,OAAO,GAAG;AAC9C,mBAAS,OAAO,MAAM,QAAQ,SAAS;AACvC;AAAA,QACF;AACA,YAAI,CAAC,mCAAmC,OAAO,EAAG;AAClD,cAAM,aAAa,SAAS,MAAM,MAAM,QAAQ,SAAS;AACzD,YAAI,CAAC,YAAY;AACf,eAAK,YAAY;AAAA,YACf,MAAM;AAAA,YACN,SAAS;AAAA,YACT,WAAW,QAAQ;AAAA,YACnB,IAAI;AAAA,YACJ,OAAO;AAAA,cACL,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW;AAAA,YACb;AAAA,UACF,CAA6C;AAC7C;AAAA,QACF;AACA,aAAK,wBAAwB,UAAU,SAAS,SAAS,WAAW,MAAM,EACvE,KAAK,CAAC,UAAU;AACf,cAAI,CAAC,WAAW,OAAO,SAAS;AAC9B,iBAAK,YAAY;AAAA,cACf,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW,QAAQ;AAAA,cACnB,IAAI;AAAA,cACJ;AAAA,YACF,CAA6C;AAAA,UAC/C;AAAA,QACF,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,cAAI,CAAC,WAAW,OAAO,SAAS;AAC9B,iBAAK,YAAY;AAAA,cACf,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW,QAAQ;AAAA,cACnB,IAAI;AAAA,cACJ,OAAO,gBAAgB,KAAK;AAAA,YAC9B,CAA6C;AAAA,UAC/C;AAAA,QACF,CAAC,EACA,QAAQ,MAAM,SAAS,SAAS,MAAM,QAAQ,WAAW,UAAU,CAAC;AAAA,MACzE,CAAC;AACD,WAAK,iBAAiB,gBAAgB,MAAM,SAAS,UAAU,IAAI,CAAC;AACpE,WAAK,MAAM;AACX,WAAK,YAAY;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AACA,UAAM,gBAAgB,IAAI,wBAAwB,gBAAgB,MAAM,SAAS,SAAS,CAAC;AAC3F,UAAM,cAAc,MAAM;AACxB,0BAAoB,UAAU;AAC9B,YAAM,cAAc,SAAS,SAAS,iBAAiB;AACvD,UAAI,CAAC,YAAa;AAClB,oBAAc,KAAK,WAAW;AAAA,IAChC;AACA,mBAAe,UAAU;AACzB,QAAI,oBAAoB,SAAS;AAC/B,0BAAoB,UAAU;AAC9B,kBAAY;AAAA,IACd;AACA,WAAO,MAAM;AACX,qBAAe,UAAU,MAAM;AAC/B,oBAAc,MAAM;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,iBAAiB,CAAC;AAClC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,OAAO,MAAM;AAAA,MACb,SAAS;AAAA,MACT,gBAAe;AAAA,MACf,QAAQ,8BAA8B,MAAM,MAAM,iBAAiB;AAAA,MACnE,QAAQ,MAAM;AACZ,4BAAoB,UAAU;AAC9B,uBAAe,QAAQ;AAAA,MACzB;AAAA,MACA,WAAW,MAAM;AAAA,MACjB,OAAO,MAAM;AAAA;AAAA,EACf;AAEJ;AAEO,IAAM,4BAAN,MAAgC;AAAA,EACpB,oBAAoB,oBAAI,IAA+C;AAAA,EAExF,YAAY,MAAyB;AACnC,SAAK,SAAS;AACd,SAAK,kBAAkB,IAAI,MAAM,oBAAI,IAAI,CAAC;AAAA,EAC5C;AAAA,EAEA,MAAM,MAAmB,WAA2C;AAClE,UAAM,cAAc,KAAK,kBAAkB,IAAI,IAAI;AACnD,QAAI,CAAC,eAAe,YAAY,IAAI,SAAS,EAAG,QAAO;AACvD,UAAM,aAAa,IAAI,gBAAgB;AACvC,gBAAY,IAAI,WAAW,UAAU;AACrC,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAmB,WAAyB;AACjD,UAAM,cAAc,KAAK,kBAAkB,IAAI,IAAI;AACnD,UAAM,aAAa,aAAa,IAAI,SAAS;AAC7C,QAAI,CAAC,WAAY;AACjB,eAAW,MAAM,IAAI,MAAM,6BAA6B,CAAC;AACzD,gBAAa,OAAO,SAAS;AAAA,EAC/B;AAAA,EAEA,SAAS,MAAmB,WAAmB,YAAmC;AAChF,UAAM,cAAc,KAAK,kBAAkB,IAAI,IAAI;AACnD,QAAI,aAAa,IAAI,SAAS,MAAM,WAAY,aAAY,OAAO,SAAS;AAAA,EAC9E;AAAA,EAEA,UAAU,MAAyB;AACjC,UAAM,cAAc,KAAK,kBAAkB,IAAI,IAAI;AACnD,QAAI,CAAC,YAAa;AAClB,eAAW,cAAc,YAAY,OAAO,GAAG;AAC7C,iBAAW,MAAM,IAAI,MAAM,8BAA8B,CAAC;AAAA,IAC5D;AACA,gBAAY,MAAM;AAClB,SAAK,kBAAkB,OAAO,IAAI;AAClC,SAAK,MAAM;AAAA,EACb;AAAA,EAEA,WAAiB;AACf,eAAW,QAAQ,CAAC,GAAG,KAAK,kBAAkB,KAAK,CAAC,EAAG,MAAK,UAAU,IAAI;AAAA,EAC5E;AACF;AAEO,IAAM,0BAAN,MAA8B;AAAA,EAInC,YACmB,gBACA,kBACA,uBAA6C,MAAM,IAAI,eAAe,GACvF;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAPK,SAAS;AAAA,EACT,gBAAoC;AAAA,EAQ5C,KAAK,aAAmD;AACtD,QAAI,KAAK,QAAQ;AACf,WAAK,MAAM;AACX,aAAO;AAAA,IACT;AACA,SAAK,SAAS;AACd,UAAM,UAAU,KAAK,qBAAqB;AAC1C,SAAK,gBAAgB,QAAQ;AAC7B,YAAQ,MAAM,iBAAiB,WAAW,CAAC,UAAiC;AAC1E,WAAK,eAAe,MAAM,MAAM,MAAM,KAAK;AAAA,IAC7C,CAAC;AACD,YAAQ,MAAM,MAAM;AACpB,gBAAY;AAAA,MACV;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA;AAAA,MACA,CAAC,QAAQ,KAAK;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAc;AACZ,SAAK,eAAe,MAAM;AAC1B,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AAAA,EACxB;AACF;AAEO,SAAS,oCACd,MACA,OACoB;AACpB,MAAI,CAAC,mCAAmC,IAAI,EAAG,QAAO;AACtD,SAAO,MAAM,WAAW,IAAI,MAAM,CAAC,IAAK;AAC1C;AAEA,eAAe,wBACb,QACA,SAKA,QAC8F;AAC9F,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,iCAAiC;AAC9D,MAAI,QAAQ,WAAW,UAAW,QAAO,MAAM,OAAO,QAAQ,EAAE,OAAO,CAAC;AACxE,MAAI,QAAQ,WAAW,gBAAgB;AACrC,QAAI,CAAC,OAAO,aAAc,OAAM,IAAI,MAAM,wCAAwC;AAClF,WAAO,MAAM,OAAO,aAAa,EAAE,OAAO,CAAC;AAAA,EAC7C;AACA,SAAO,MAAM,OAAO,KAAK,oCAAoC,QAAQ,OAAQ,GAAG,EAAE,OAAO,CAAC;AAC5F;AAEO,SAAS,gBAAgB,OAK9B;AACA,QAAM,YAAY;AAMlB,SAAO;AAAA,IACL,MAAM,OAAO,WAAW,SAAS,WAAW,UAAU,OAAO;AAAA,IAC7D,SACE,OAAO,WAAW,YAAY,WAAW,UAAU,UAAU;AAAA,IAC/D,WAAW,WAAW,cAAc;AAAA,IACpC,gBAAgB,WAAW,mBAAmB;AAAA,EAChD;AACF;;;AC7TA;AAAA,EACE;AAAA,OAIK;AACP,SAAS,aAAa,aAAAA,YAAW,UAAAC,SAAQ,gBAAgB;AAyEjD,gBAAAC,YAAA;AATD,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmC;AACjC,UAAQ,QAAQ,UAAU;AAAA,IACxB,KAAK;AACH,aACE,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ;AAAA,UACA,OAAO,UAAU,SAAS;AAAA;AAAA,MAC5B;AAAA,IAEJ,KAAK;AACH,aAAO,gBAAAA,KAAC,sCAAoC,GAAG,aAAa,SAAkB;AAAA,IAChF,KAAK;AACH,aAAO,gBAAAA,KAAC,uCAAqC,GAAG,cAAc,SAAkB;AAAA,EACpF;AACF;AAMO,SAAS,8BAA8B;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AACrC,QAAM,mBAAmBC,QAAO,aAAa;AAC7C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,CAAC;AAC9C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAGxB,EAAE,KAAK,MAAM,SAAS,MAAM,OAAO,KAAK,CAAC;AAE3C,EAAAC,WAAU,MAAM;AACd,qBAAiB,UAAU;AAAA,EAC7B,GAAG,CAAC,aAAa,CAAC;AAElB,EAAAA,WAAU,MAAM;AACd,QAAI,QAAwC;AAC5C,aAAS,EAAE,KAAK,YAAY,SAAS,MAAM,OAAO,KAAK,CAAC;AACxD,QAAI;AACF,cAAQ,iBAAiB,QAAQ;AACjC,eAAS,EAAE,KAAK,YAAY,SAAS,OAAO,OAAO,KAAK,CAAC;AAAA,IAC3D,SAAS,OAAO;AACd,eAAS;AAAA,QACP,KAAK;AAAA,QACL,SAAS;AAAA,QACT,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,mCAAmC;AAAA,MACvF,CAAC;AAAA,IACH;AACA,WAAO,MAAM;AACX,YAAM,UAAU;AAChB,cAAQ;AACR,UAAI,QAAS,MAAK,QAAQ,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,IACzD;AAAA,EACF,GAAG,CAAC,YAAY,UAAU,CAAC;AAE3B,QAAM,QAAQ,YAAY,MAAM,cAAc,CAAC,UAAU,QAAQ,CAAC,GAAG,CAAC,CAAC;AACvE,QAAM,eAAe,MAAM,QAAQ,aAAa,MAAM,QAAQ;AAC9D,MAAI,MAAM,QAAQ,cAAc,MAAM,SAAS;AAC7C,WACE,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM;AAAA,QACd,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,QAC/B,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,QACrC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA;AAAA,IAC1C;AAAA,EAEJ;AACA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,eAAe,iCAAiC;AAAA,MACvD,QAAQ,cAAc,WAAW;AAAA,MACjC,OAAO,eAAe,QAAQ;AAAA;AAAA,EAChC;AAEJ;AAOO,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0C;AACxC,QAAM,aAAa,kBAAkB,OAAO;AAC5C,QAAM,gBAAgB,YAAY,MAAM,qCAAqC,OAAO,GAAG,CAAC,OAAO,CAAC;AAChG,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACC,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/B,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,MACrC,GAAI,eAAe,EAAE,aAAa,IAAI,CAAC;AAAA;AAAA,EAC1C;AAEJ;AAEA,SAAS,kBAAkB,SAA0D;AACnF,QAAM,YAAY,QAAQ,YACtB;AAAA,IACE,GAAG,QAAQ;AAAA;AAAA;AAAA,IAGX,SAAS,QAAQ,UAAU,UACvB,OAAO,KAAK,QAAQ,UAAU,OAAO,EAAE,KAAK,IAC5C;AAAA,EACN,IACA;AACJ,SAAO,KAAK;AAAA,IACV;AAAA,MACE,SAAS,QAAQ;AAAA,MACjB,aAAa,QAAQ;AAAA,MACrB,UAAU,EAAE,IAAI,QAAQ,SAAS,IAAI,UAAU,QAAQ,SAAS,SAAS;AAAA,MACzE,kBAAkB,QAAQ;AAAA,MAC1B,SAAS,QAAQ;AAAA,MACjB,WAAW,QAAQ,aAAa;AAAA,MAChC;AAAA,IACF;AAAA,IACA,CAAC,MAAM,UAAoB,iBAAiB,MAAM,MAAM,OAAO;AAAA,EACjE;AACF;","names":["useEffect","useRef","jsx","useRef","useEffect"]}
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
groupTimeline,
|
|
21
21
|
isActionableHumanInputRequest,
|
|
22
22
|
sessionStatusFromEvents
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-FJBOU2TH.js";
|
|
24
24
|
|
|
25
25
|
// src/embedded-session-client.ts
|
|
26
26
|
var requiredMethods = [
|
|
@@ -196,10 +196,7 @@ import {
|
|
|
196
196
|
sessionEventStreamCoveredThrough
|
|
197
197
|
} from "@opengeni/sdk";
|
|
198
198
|
import { startTransition, useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
199
|
-
var
|
|
200
|
-
var OLDER_PAGE_SIZE = 5e3;
|
|
201
|
-
var NEWER_PAGE_SIZE = 5e3;
|
|
202
|
-
var OLDEST_PAGE_SIZE = 1e3;
|
|
199
|
+
var SESSION_HISTORY_PAGE_SIZE = 255;
|
|
203
200
|
var INITIAL_FETCH_CAP = 1;
|
|
204
201
|
var OLDER_GROUP_TARGET = 32;
|
|
205
202
|
var OLDER_FETCH_CAP = 2;
|
|
@@ -207,9 +204,9 @@ var NEWER_GROUP_TARGET = 32;
|
|
|
207
204
|
var NEWER_FETCH_CAP = 2;
|
|
208
205
|
var OLDEST_GROUP_TARGET = 32;
|
|
209
206
|
var OLDEST_FETCH_CAP = 2;
|
|
210
|
-
var BOUNDARY_PAGE_CAP =
|
|
207
|
+
var BOUNDARY_PAGE_CAP = 1;
|
|
211
208
|
var FOREGROUND_DIRECT_REPLAY_MAX_SEQUENCES = 16;
|
|
212
|
-
var FOREGROUND_COMPACT_PROBE_MAX_SEQUENCES =
|
|
209
|
+
var FOREGROUND_COMPACT_PROBE_MAX_SEQUENCES = SESSION_HISTORY_PAGE_SIZE;
|
|
213
210
|
var FOREGROUND_COMPACT_CATCHUP_MAX_EVENTS = 128;
|
|
214
211
|
var FOREGROUND_COMPACT_CATCHUP_MAX_GROUPS = 16;
|
|
215
212
|
var FOREGROUND_COMPACT_CATCHUP_MAX_BYTES = 512 * 1024;
|
|
@@ -441,17 +438,7 @@ function useSessionEvents(sessionId, options = {}) {
|
|
|
441
438
|
setHasOlder(true);
|
|
442
439
|
}
|
|
443
440
|
} else if (plan.kind === "reload") {
|
|
444
|
-
eventWindowRef.current = EMPTY_EVENT_WINDOW;
|
|
445
|
-
oldestSequenceRef.current = null;
|
|
446
|
-
newestSequenceRef.current = null;
|
|
447
|
-
hasOlderRef.current = false;
|
|
448
|
-
hasNewerRef.current = false;
|
|
449
441
|
initialWindowLoadedRef.current = false;
|
|
450
|
-
streamResumeSequenceRef.current = after;
|
|
451
|
-
setEventWindow(EMPTY_EVENT_WINDOW);
|
|
452
|
-
setHasOlder(false);
|
|
453
|
-
setHasNewer(false);
|
|
454
|
-
setInitialLoading(true);
|
|
455
442
|
setError(null);
|
|
456
443
|
}
|
|
457
444
|
}
|
|
@@ -459,9 +446,10 @@ function useSessionEvents(sessionId, options = {}) {
|
|
|
459
446
|
setConnectionState("connecting");
|
|
460
447
|
const window = await loadEventWindow(client, workspaceId, sessionId, {
|
|
461
448
|
before: Number.MAX_SAFE_INTEGER,
|
|
462
|
-
pageSize:
|
|
449
|
+
pageSize: SESSION_HISTORY_PAGE_SIZE,
|
|
463
450
|
targetGroups: Number.POSITIVE_INFINITY,
|
|
464
451
|
maxFetches: INITIAL_FETCH_CAP,
|
|
452
|
+
boundaryPageCap: BOUNDARY_PAGE_CAP,
|
|
465
453
|
signal: controller.signal
|
|
466
454
|
});
|
|
467
455
|
if (!isCurrent()) {
|
|
@@ -579,7 +567,7 @@ function useSessionEvents(sessionId, options = {}) {
|
|
|
579
567
|
try {
|
|
580
568
|
const window = await loadEventWindow(client, workspaceId, sessionId, {
|
|
581
569
|
before,
|
|
582
|
-
pageSize:
|
|
570
|
+
pageSize: SESSION_HISTORY_PAGE_SIZE,
|
|
583
571
|
targetGroups: OLDER_GROUP_TARGET,
|
|
584
572
|
maxFetches: OLDER_FETCH_CAP
|
|
585
573
|
});
|
|
@@ -670,7 +658,7 @@ function useSessionEvents(sessionId, options = {}) {
|
|
|
670
658
|
try {
|
|
671
659
|
const window = await loadForwardEventWindow(client, workspaceId, sessionId, {
|
|
672
660
|
after: 0,
|
|
673
|
-
pageSize:
|
|
661
|
+
pageSize: SESSION_HISTORY_PAGE_SIZE,
|
|
674
662
|
targetGroups: OLDEST_GROUP_TARGET,
|
|
675
663
|
maxFetches: OLDEST_FETCH_CAP
|
|
676
664
|
});
|
|
@@ -734,7 +722,7 @@ function useSessionEvents(sessionId, options = {}) {
|
|
|
734
722
|
try {
|
|
735
723
|
const window = await loadForwardEventWindow(client, workspaceId, sessionId, {
|
|
736
724
|
after: afterSequence,
|
|
737
|
-
pageSize:
|
|
725
|
+
pageSize: SESSION_HISTORY_PAGE_SIZE,
|
|
738
726
|
targetGroups: NEWER_GROUP_TARGET,
|
|
739
727
|
maxFetches: NEWER_FETCH_CAP
|
|
740
728
|
});
|
|
@@ -1141,7 +1129,7 @@ async function loadEventWindow(client, workspaceId, sessionId, options) {
|
|
|
1141
1129
|
}
|
|
1142
1130
|
}
|
|
1143
1131
|
let snapPages = 0;
|
|
1144
|
-
while (!reachedStart && findBoundaryIndex(buffer) === -1 && snapPages <
|
|
1132
|
+
while (!reachedStart && findBoundaryIndex(buffer) === -1 && snapPages < (options.boundaryPageCap ?? 0)) {
|
|
1145
1133
|
const page = await loadPreviousPage(client, workspaceId, sessionId, cursor, {
|
|
1146
1134
|
pageSize: options.pageSize,
|
|
1147
1135
|
...options.signal ? { signal: options.signal } : {}
|
|
@@ -1360,6 +1348,8 @@ function useFileAttachments(options = {}) {
|
|
|
1360
1348
|
const { client, workspaceId } = useEmbeddedFileAttachments(options);
|
|
1361
1349
|
const pasteFilter = options.pasteFilter ?? isImage;
|
|
1362
1350
|
const [attachments, setAttachments] = useState3([]);
|
|
1351
|
+
const attachmentsRef = useRef3(attachments);
|
|
1352
|
+
attachmentsRef.current = attachments;
|
|
1363
1353
|
const sources = useRef3(/* @__PURE__ */ new Map());
|
|
1364
1354
|
const previewUrls = useRef3(/* @__PURE__ */ new Map());
|
|
1365
1355
|
const previewRetainers = useRef3(/* @__PURE__ */ new Map());
|
|
@@ -1557,6 +1547,23 @@ function useFileAttachments(options = {}) {
|
|
|
1557
1547
|
},
|
|
1558
1548
|
[workspaceId]
|
|
1559
1549
|
);
|
|
1550
|
+
const loadPreview = useCallback3(
|
|
1551
|
+
async (id, signal) => {
|
|
1552
|
+
const generation = scopeGeneration.current;
|
|
1553
|
+
const attachment = attachmentsRef.current.find((candidate) => candidate.id === id);
|
|
1554
|
+
const createDownloadUrl = client.createFileDownloadUrl;
|
|
1555
|
+
if (!attachment || attachment.status !== "ready" || !attachment.file || !attachment.contentType.startsWith("image/") || typeof createDownloadUrl !== "function" || signal?.aborted) {
|
|
1556
|
+
return void 0;
|
|
1557
|
+
}
|
|
1558
|
+
const fileId = attachment.file.id;
|
|
1559
|
+
const signed = await createDownloadUrl.call(client, workspaceId, fileId, { signal });
|
|
1560
|
+
if (scopeGeneration.current !== generation || signal?.aborted) return void 0;
|
|
1561
|
+
const current = attachmentsRef.current.find((candidate) => candidate.id === id);
|
|
1562
|
+
if (current?.status !== "ready" || current.file?.id !== fileId) return void 0;
|
|
1563
|
+
return signed.url;
|
|
1564
|
+
},
|
|
1565
|
+
[client, workspaceId]
|
|
1566
|
+
);
|
|
1560
1567
|
const remove = useCallback3(
|
|
1561
1568
|
(id) => {
|
|
1562
1569
|
sources.current.delete(id);
|
|
@@ -1589,6 +1596,7 @@ function useFileAttachments(options = {}) {
|
|
|
1589
1596
|
addFiles,
|
|
1590
1597
|
addFromPaste,
|
|
1591
1598
|
restoreReadyFiles,
|
|
1599
|
+
...typeof client.createFileDownloadUrl === "function" ? { loadPreview } : {},
|
|
1592
1600
|
retry,
|
|
1593
1601
|
retainPreview,
|
|
1594
1602
|
remove,
|
|
@@ -2579,4 +2587,4 @@ export {
|
|
|
2579
2587
|
isHumanInputEvent,
|
|
2580
2588
|
useHumanInputRequests
|
|
2581
2589
|
};
|
|
2582
|
-
//# sourceMappingURL=chunk-
|
|
2590
|
+
//# sourceMappingURL=chunk-C6WDLHBA.js.map
|