@statelyai/sdk 0.34.2 → 0.36.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/README.md +20 -34
- package/dist/assetStorage.d.mts +1 -1
- package/dist/auth.d.mts +14 -1
- package/dist/bin.mjs +1 -3
- package/dist/editor-sync-types-U5uryWOk.d.mts +55 -0
- package/dist/editorHostProtocol.d.mts +203 -0
- package/dist/{editorHostProtocol-B2_t3Le7.mjs → editorHostProtocol.mjs} +1 -1
- package/dist/embed.d.mts +3 -3
- package/dist/embed.mjs +2 -2
- package/dist/{graph-DVfx7FwN.d.mts → graph-B6xUxqR5.d.mts} +1 -1
- package/dist/graph.d.mts +1 -1
- package/dist/{index-A5CMACoO.d.mts → index-CoxF4Saw.d.mts} +8 -255
- package/dist/index.d.mts +8 -31
- package/dist/index.mjs +5 -9
- package/dist/{inspect-ZVDq9tK2.mjs → inspect-BoMln78S.mjs} +1 -1
- package/dist/{inspect-DBH9oOAd.d.mts → inspect-Douvt5k_.d.mts} +1 -1
- package/dist/inspect.d.mts +2 -2
- package/dist/inspect.mjs +2 -2
- package/dist/patchTypes.d.mts +1 -1
- package/dist/{protocol-CCf9j_SZ.d.mts → protocol-CP3DSl5u.d.mts} +27 -5
- package/dist/protocol.d.mts +1 -1
- package/dist/relay.d.mts +1 -1
- package/dist/{openapi-BTDjYWXd.mjs → studio-DhzM6zFx.mjs} +639 -1
- package/dist/{studio-CFN3-0-2.d.mts → studio-DvEgrtk1.d.mts} +4 -2
- package/dist/studio.d.mts +1 -1
- package/dist/studio.mjs +2 -2
- package/dist/{version-CUFh-PYe.mjs → version-DS2izNeF.mjs} +1 -1
- package/package.json +20 -16
- package/dist/auth-CVFc85uF.d.mts +0 -15
- package/dist/dist-DsOTTfYv.mjs +0 -8361
- package/dist/editor-sync-types-D7YYz6fb.d.mts +0 -98
- package/dist/editorHostSession-DCTHhBqC.mjs +0 -912
- package/dist/editorHostSession-yGUKdLjq.d.mts +0 -325
- package/dist/editorHostSession.d.mts +0 -2
- package/dist/editorHostSession.mjs +0 -6
- package/dist/statelyPragma-YtVaBuIe.mjs +0 -102
- package/dist/studio-BZP6DaIO.mjs +0 -638
- package/dist/sync.d.mts +0 -86
- package/dist/sync.mjs +0 -4646
|
@@ -1,912 +0,0 @@
|
|
|
1
|
-
import { c as object, f as unknown, i as custom, l as record, n as array, o as literal, r as boolean, s as number, t as _enum, u as string } from "./openapi-BTDjYWXd.mjs";
|
|
2
|
-
import { t as EDITOR_PROTOCOL_VERSION } from "./editorHostProtocol-B2_t3Le7.mjs";
|
|
3
|
-
import { p as graphChangeToPatchesResult } from "./dist-DsOTTfYv.mjs";
|
|
4
|
-
import * as ts$1 from "typescript";
|
|
5
|
-
|
|
6
|
-
//#region ../api-contract/dist/editor-sync.mjs
|
|
7
|
-
const EDITOR_SYNC_PROTOCOL_VERSION = 1;
|
|
8
|
-
const EDITOR_SYNC_PROTOCOL_HEADER = "X-Stately-Editor-Sync-Version";
|
|
9
|
-
const editorSyncErrorResponseSchema = object({
|
|
10
|
-
error: string(),
|
|
11
|
-
code: string().optional()
|
|
12
|
-
}).passthrough();
|
|
13
|
-
const editorCapabilitiesSchema = object({
|
|
14
|
-
edit: boolean().optional(),
|
|
15
|
-
export: boolean().optional(),
|
|
16
|
-
ai: boolean().optional(),
|
|
17
|
-
simulate: boolean().optional(),
|
|
18
|
-
inspect: boolean().optional(),
|
|
19
|
-
maxDepth: number().optional(),
|
|
20
|
-
panels: array(string()).optional(),
|
|
21
|
-
commands: array(string()).optional()
|
|
22
|
-
}).passthrough();
|
|
23
|
-
const editorSyncAccessSchema = object({
|
|
24
|
-
level: _enum(["full", "restricted"]),
|
|
25
|
-
readOnly: boolean(),
|
|
26
|
-
readOnlyReason: _enum(["free-plan", "access-unverified"]).optional(),
|
|
27
|
-
capabilities: editorCapabilitiesSchema
|
|
28
|
-
}).passthrough();
|
|
29
|
-
const editorSyncSourceRangeSchema = object({
|
|
30
|
-
startLine: number(),
|
|
31
|
-
startChar: number(),
|
|
32
|
-
endLine: number(),
|
|
33
|
-
endChar: number()
|
|
34
|
-
});
|
|
35
|
-
const editorSyncSourceLocationSchema = object({
|
|
36
|
-
uri: string(),
|
|
37
|
-
range: editorSyncSourceRangeSchema
|
|
38
|
-
});
|
|
39
|
-
const editorSyncStateSourceLocationSchema = editorSyncSourceLocationSchema.extend({
|
|
40
|
-
path: array(string()),
|
|
41
|
-
kind: _enum([
|
|
42
|
-
"inline",
|
|
43
|
-
"objectReference",
|
|
44
|
-
"createStateConfig"
|
|
45
|
-
]),
|
|
46
|
-
symbol: string().optional(),
|
|
47
|
-
keyRange: editorSyncSourceRangeSchema.optional(),
|
|
48
|
-
referenceRange: editorSyncSourceRangeSchema.optional(),
|
|
49
|
-
keySource: object({
|
|
50
|
-
kind: _enum([
|
|
51
|
-
"const",
|
|
52
|
-
"enumMember",
|
|
53
|
-
"computedLiteral"
|
|
54
|
-
]),
|
|
55
|
-
symbol: string().optional(),
|
|
56
|
-
valueRange: editorSyncSourceRangeSchema.optional(),
|
|
57
|
-
machineLocal: boolean().optional()
|
|
58
|
-
}).optional(),
|
|
59
|
-
keyReplacementText: string().optional()
|
|
60
|
-
});
|
|
61
|
-
const machineSourceLocationsSchema = object({
|
|
62
|
-
version: literal(1),
|
|
63
|
-
profile: _enum(["xstate-v5", "xstate-v6-alpha"]).optional(),
|
|
64
|
-
profileRef: custom((value) => typeof value === "string" && value.startsWith("@statelyai/xstate@")).optional(),
|
|
65
|
-
root: editorSyncSourceLocationSchema.optional(),
|
|
66
|
-
statesObject: editorSyncStateSourceLocationSchema.optional(),
|
|
67
|
-
states: array(editorSyncStateSourceLocationSchema),
|
|
68
|
-
staticValues: array(editorSyncSourceLocationSchema.extend({ value: string() })).optional(),
|
|
69
|
-
transitionFunctions: array(editorSyncSourceLocationSchema.extend({
|
|
70
|
-
symbol: string(),
|
|
71
|
-
sourcePaths: array(array(string()))
|
|
72
|
-
})).optional()
|
|
73
|
-
}).passthrough();
|
|
74
|
-
const editorSyncSourceDocumentSchema = object({
|
|
75
|
-
uri: string(),
|
|
76
|
-
fileName: string(),
|
|
77
|
-
text: string()
|
|
78
|
-
});
|
|
79
|
-
const editorSyncDocumentContextSchema = object({
|
|
80
|
-
rootUri: string(),
|
|
81
|
-
rootFileName: string(),
|
|
82
|
-
rootDir: string(),
|
|
83
|
-
documents: array(editorSyncSourceDocumentSchema)
|
|
84
|
-
});
|
|
85
|
-
const editorSyncParseRequestSchema = editorSyncDocumentContextSchema.extend({ machineIndex: number().int().nonnegative().optional() });
|
|
86
|
-
const editorSyncParseResponseSchema = object({
|
|
87
|
-
machine: unknown(),
|
|
88
|
-
format: string(),
|
|
89
|
-
sourceLocations: machineSourceLocationsSchema.optional(),
|
|
90
|
-
access: editorSyncAccessSchema.optional()
|
|
91
|
-
}).passthrough();
|
|
92
|
-
const editorSyncApplyRequestSchema = editorSyncParseRequestSchema.extend({
|
|
93
|
-
machineConfig: unknown().optional(),
|
|
94
|
-
patches: array(unknown()).optional(),
|
|
95
|
-
prevGraph: unknown().optional(),
|
|
96
|
-
nextGraph: unknown().optional(),
|
|
97
|
-
sourceLocations: machineSourceLocationsSchema.optional(),
|
|
98
|
-
serialized: record(string(), string()).optional(),
|
|
99
|
-
preserveStatelyMetadata: boolean().optional(),
|
|
100
|
-
sourceUpdateStrategy: _enum(["preserve", "rewrite"]).optional()
|
|
101
|
-
}).passthrough();
|
|
102
|
-
const editorSyncTextReplacementSchema = object({
|
|
103
|
-
uri: string().optional(),
|
|
104
|
-
range: editorSyncSourceRangeSchema,
|
|
105
|
-
newText: string()
|
|
106
|
-
});
|
|
107
|
-
const editorSyncApplyResponseSchema = object({ replacements: array(editorSyncTextReplacementSchema) });
|
|
108
|
-
const editorSyncAccessResponseSchema = object({ access: editorSyncAccessSchema });
|
|
109
|
-
|
|
110
|
-
//#endregion
|
|
111
|
-
//#region src/editorHostSession.ts
|
|
112
|
-
let diagnosticSequence = 0;
|
|
113
|
-
function createDiagnostic(code, phase, details) {
|
|
114
|
-
return {
|
|
115
|
-
id: `stately-${Date.now().toString(36)}-${(++diagnosticSequence).toString(36)}`,
|
|
116
|
-
code,
|
|
117
|
-
phase,
|
|
118
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
119
|
-
...details ? { details } : {}
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
var EditorSyncError = class extends Error {
|
|
123
|
-
status;
|
|
124
|
-
code;
|
|
125
|
-
constructor(message, status, code) {
|
|
126
|
-
super(message);
|
|
127
|
-
this.name = "EditorSyncError";
|
|
128
|
-
this.status = status;
|
|
129
|
-
this.code = code;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
function createRemoteEditorSyncBackend(options) {
|
|
133
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
134
|
-
async function post(pathname, body) {
|
|
135
|
-
const url = new URL(pathname, `${options.editorUrl.replace(/\/+$/, "")}/`);
|
|
136
|
-
const headers = {
|
|
137
|
-
"Content-Type": "application/json",
|
|
138
|
-
[EDITOR_SYNC_PROTOCOL_HEADER]: String(EDITOR_SYNC_PROTOCOL_VERSION)
|
|
139
|
-
};
|
|
140
|
-
if (options.apiKey) headers.Authorization = `Bearer ${options.apiKey}`;
|
|
141
|
-
const response = await fetchImpl(url, {
|
|
142
|
-
method: "POST",
|
|
143
|
-
headers,
|
|
144
|
-
body: JSON.stringify(body)
|
|
145
|
-
});
|
|
146
|
-
assertEditorSyncResponseProtocol(response);
|
|
147
|
-
const data = await response.json().catch(() => null);
|
|
148
|
-
if (!response.ok) throwEditorSyncError(response.status, data);
|
|
149
|
-
return data;
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
async parse(request) {
|
|
153
|
-
return editorSyncParseResponseSchema.parse(await post("/api/editor-sync/parse", request));
|
|
154
|
-
},
|
|
155
|
-
async apply(request) {
|
|
156
|
-
return editorSyncApplyResponseSchema.parse(await post("/api/editor-sync/apply", request));
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
async function fetchEditorSyncAccess(options) {
|
|
161
|
-
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
162
|
-
const url = new URL("/api/editor-sync/access", `${options.editorUrl.replace(/\/+$/, "")}/`);
|
|
163
|
-
const headers = { [EDITOR_SYNC_PROTOCOL_HEADER]: String(EDITOR_SYNC_PROTOCOL_VERSION) };
|
|
164
|
-
if (options.apiKey) headers.Authorization = `Bearer ${options.apiKey}`;
|
|
165
|
-
const response = await fetchImpl(url, {
|
|
166
|
-
method: "GET",
|
|
167
|
-
headers
|
|
168
|
-
});
|
|
169
|
-
assertEditorSyncResponseProtocol(response);
|
|
170
|
-
const data = await response.json().catch(() => null);
|
|
171
|
-
if (!response.ok) throwEditorSyncError(response.status, data);
|
|
172
|
-
return editorSyncAccessResponseSchema.parse(data).access;
|
|
173
|
-
}
|
|
174
|
-
function throwEditorSyncError(status, data) {
|
|
175
|
-
const parsed = editorSyncErrorResponseSchema.safeParse(data);
|
|
176
|
-
const error = parsed.success ? parsed.data : void 0;
|
|
177
|
-
throw new EditorSyncError(error?.error ?? `HTTP ${status}`, status, error?.code);
|
|
178
|
-
}
|
|
179
|
-
function assertEditorSyncResponseProtocol(response) {
|
|
180
|
-
const selectedVersion = response.headers.get(EDITOR_SYNC_PROTOCOL_HEADER);
|
|
181
|
-
if (selectedVersion === null || selectedVersion === String(EDITOR_SYNC_PROTOCOL_VERSION)) return;
|
|
182
|
-
throw new Error(`Editor Sync protocol ${selectedVersion} is unsupported; this client supports ${EDITOR_SYNC_PROTOCOL_VERSION}.`);
|
|
183
|
-
}
|
|
184
|
-
const SOURCE_SAVE_REMINDER_ID = "source-save-reminder";
|
|
185
|
-
var EditorHostSession = class {
|
|
186
|
-
editorProtocolState = "awaiting";
|
|
187
|
-
currentGraph;
|
|
188
|
-
lastPersistedGraph;
|
|
189
|
-
currentFormat;
|
|
190
|
-
currentSourceLocations;
|
|
191
|
-
access;
|
|
192
|
-
watchedSourceUris = /* @__PURE__ */ new Set();
|
|
193
|
-
watcher;
|
|
194
|
-
changeWatcher;
|
|
195
|
-
retrieveRequestCount = 0;
|
|
196
|
-
pendingRetrievals = /* @__PURE__ */ new Map();
|
|
197
|
-
constructor(options, saveReminderState = { shown: false }, selfEditState = { count: 0 }) {
|
|
198
|
-
this.options = options;
|
|
199
|
-
this.saveReminderState = saveReminderState;
|
|
200
|
-
this.selfEditState = selfEditState;
|
|
201
|
-
this.watcher = options.source.watchSavedDocuments?.((uri) => this.handleSavedDocument(uri));
|
|
202
|
-
this.changeWatcher = options.source.watchChangedDocuments?.((uri) => {
|
|
203
|
-
if (!this.isExternalSourceDocument(uri)) return;
|
|
204
|
-
if (this.saveReminderState.shown) return;
|
|
205
|
-
this.saveReminderState.shown = true;
|
|
206
|
-
this.options.send({
|
|
207
|
-
type: "@statelyai.toast",
|
|
208
|
-
id: SOURCE_SAVE_REMINDER_ID,
|
|
209
|
-
message: "Save code to see changes.",
|
|
210
|
-
toastType: "warning"
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
dispose() {
|
|
215
|
-
this.watcher?.dispose();
|
|
216
|
-
this.changeWatcher?.dispose();
|
|
217
|
-
for (const pending of this.pendingRetrievals.values()) pending.reject(/* @__PURE__ */ new Error("Editor session disposed before export completed."));
|
|
218
|
-
this.pendingRetrievals.clear();
|
|
219
|
-
}
|
|
220
|
-
notifySavedDocument(uri = this.options.source.rootUri) {
|
|
221
|
-
return this.handleSavedDocument(uri);
|
|
222
|
-
}
|
|
223
|
-
async receive(message) {
|
|
224
|
-
if (message.type !== "@statelyai.ready" && this.editorProtocolState !== "compatible") return;
|
|
225
|
-
switch (message.type) {
|
|
226
|
-
case "@statelyai.ready":
|
|
227
|
-
if (this.editorProtocolState === "incompatible") break;
|
|
228
|
-
if (message.protocolVersion !== void 0 && message.protocolVersion !== EDITOR_PROTOCOL_VERSION) {
|
|
229
|
-
this.editorProtocolState = "incompatible";
|
|
230
|
-
this.options.send({
|
|
231
|
-
type: "@statelyai.error",
|
|
232
|
-
code: "unsupported_protocol",
|
|
233
|
-
message: `Editor protocol ${message.protocolVersion} is unsupported; this client supports ${EDITOR_PROTOCOL_VERSION}.`
|
|
234
|
-
});
|
|
235
|
-
break;
|
|
236
|
-
}
|
|
237
|
-
this.editorProtocolState = "compatible";
|
|
238
|
-
try {
|
|
239
|
-
if (message.protocolVersion !== void 0) this.options.send({
|
|
240
|
-
type: "@statelyai.handshake",
|
|
241
|
-
protocolVersion: EDITOR_PROTOCOL_VERSION,
|
|
242
|
-
client: this.options.client
|
|
243
|
-
});
|
|
244
|
-
await this.initialize();
|
|
245
|
-
} catch (error) {
|
|
246
|
-
const message = formatError(error, "Failed to initialize the visual editor.");
|
|
247
|
-
this.options.send({
|
|
248
|
-
type: "@statelyai.error",
|
|
249
|
-
code: "initialization_failed",
|
|
250
|
-
message
|
|
251
|
-
});
|
|
252
|
-
this.options.showError?.(message);
|
|
253
|
-
}
|
|
254
|
-
break;
|
|
255
|
-
case "@statelyai.loaded":
|
|
256
|
-
this.currentGraph = message.graph;
|
|
257
|
-
this.lastPersistedGraph = message.graph;
|
|
258
|
-
this.currentSourceLocations = mergeSourceLocations(this.currentSourceLocations, message.sourceLocations);
|
|
259
|
-
break;
|
|
260
|
-
case "@statelyai.change":
|
|
261
|
-
this.currentGraph = message.graph;
|
|
262
|
-
this.currentSourceLocations = mergeSourceLocations(this.currentSourceLocations, message.sourceLocations);
|
|
263
|
-
break;
|
|
264
|
-
case "@statelyai.save":
|
|
265
|
-
try {
|
|
266
|
-
await this.save(message);
|
|
267
|
-
} catch (error) {
|
|
268
|
-
const text = formatError(error, "Failed to apply Viz changes.");
|
|
269
|
-
this.reportSourceSyncError(text, "save", {
|
|
270
|
-
errorName: error instanceof Error ? error.name : void 0,
|
|
271
|
-
sourceUpdateStrategy: message.sourceUpdateStrategy ?? this.options.sourceUpdateStrategy ?? "preserve",
|
|
272
|
-
canRewrite: (message.sourceUpdateStrategy ?? this.options.sourceUpdateStrategy ?? "preserve") === "preserve"
|
|
273
|
-
}, message.requestId);
|
|
274
|
-
}
|
|
275
|
-
break;
|
|
276
|
-
case "@statelyai.refresh":
|
|
277
|
-
await this.handleSavedDocument(this.options.source.rootUri);
|
|
278
|
-
break;
|
|
279
|
-
case "@statelyai.retrieved":
|
|
280
|
-
this.resolveRetrieved(message.requestId, message.data);
|
|
281
|
-
break;
|
|
282
|
-
case "@statelyai.error":
|
|
283
|
-
if (message.requestId) {
|
|
284
|
-
const pending = this.pendingRetrievals.get(message.requestId);
|
|
285
|
-
if (pending) {
|
|
286
|
-
this.pendingRetrievals.delete(message.requestId);
|
|
287
|
-
pending.reject(new Error(message.message));
|
|
288
|
-
break;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
this.options.showError?.(message.diagnostic ? `${message.message} (diagnostic ${message.diagnostic.id})` : message.message);
|
|
292
|
-
break;
|
|
293
|
-
case "@statelyai.clipboardRead": {
|
|
294
|
-
let text = "";
|
|
295
|
-
try {
|
|
296
|
-
text = await this.options.readClipboard?.() ?? "";
|
|
297
|
-
} catch {}
|
|
298
|
-
this.options.send({
|
|
299
|
-
type: "@statelyai.clipboardReadResponse",
|
|
300
|
-
requestId: message.requestId,
|
|
301
|
-
text
|
|
302
|
-
});
|
|
303
|
-
break;
|
|
304
|
-
}
|
|
305
|
-
case "@statelyai.clipboardWrite": {
|
|
306
|
-
let ok = false;
|
|
307
|
-
try {
|
|
308
|
-
await this.options.writeClipboard?.(message.text);
|
|
309
|
-
ok = Boolean(this.options.writeClipboard);
|
|
310
|
-
} catch {}
|
|
311
|
-
this.options.send({
|
|
312
|
-
type: "@statelyai.clipboardWriteResponse",
|
|
313
|
-
requestId: message.requestId,
|
|
314
|
-
ok
|
|
315
|
-
});
|
|
316
|
-
break;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
async initialize() {
|
|
321
|
-
const documents = await this.options.source.collectDocuments();
|
|
322
|
-
const update = await this.options.sync.parse({
|
|
323
|
-
rootUri: this.options.source.rootUri,
|
|
324
|
-
rootFileName: this.options.source.rootFileName,
|
|
325
|
-
rootDir: this.options.source.rootDir,
|
|
326
|
-
...this.options.source.machineIndex !== void 0 ? { machineIndex: this.options.source.machineIndex } : {},
|
|
327
|
-
documents
|
|
328
|
-
});
|
|
329
|
-
this.currentFormat = update.format;
|
|
330
|
-
this.currentSourceLocations = update.sourceLocations;
|
|
331
|
-
this.access = update.access ?? this.options.access;
|
|
332
|
-
this.updateWatchedSourceUris(update.sourceLocations);
|
|
333
|
-
if (this.options.apiKey) this.options.send({
|
|
334
|
-
type: "@statelyai.setApiKey",
|
|
335
|
-
apiKey: this.options.apiKey
|
|
336
|
-
});
|
|
337
|
-
this.options.send({
|
|
338
|
-
type: "@statelyai.init",
|
|
339
|
-
machine: update.machine,
|
|
340
|
-
format: update.format,
|
|
341
|
-
sourceLocations: update.sourceLocations,
|
|
342
|
-
mode: this.access?.readOnly ? "viewing" : "editing",
|
|
343
|
-
readOnly: this.access?.readOnly,
|
|
344
|
-
readOnlyReason: this.access?.readOnlyReason,
|
|
345
|
-
capabilities: this.access?.capabilities,
|
|
346
|
-
theme: this.options.getTheme?.() ?? "light",
|
|
347
|
-
unsavedIndicator: this.options.init?.unsavedIndicator ?? { enabled: true },
|
|
348
|
-
settings: this.options.init?.settings,
|
|
349
|
-
panels: this.options.init?.panels,
|
|
350
|
-
...this.options.init?.panels === void 0 && {
|
|
351
|
-
leftPanels: this.options.init?.leftPanels ?? [],
|
|
352
|
-
rightPanels: this.options.init?.rightPanels ?? [],
|
|
353
|
-
activePanels: this.options.init?.activePanels ?? []
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
async save(message) {
|
|
358
|
-
this.currentSourceLocations = mergeSourceLocations(this.currentSourceLocations, message.sourceLocations);
|
|
359
|
-
this.updateWatchedSourceUris(this.currentSourceLocations);
|
|
360
|
-
if (this.access?.readOnly) {
|
|
361
|
-
const text = "Your Stately plan allows read-only editor sync.";
|
|
362
|
-
this.options.send({
|
|
363
|
-
type: "@statelyai.toast",
|
|
364
|
-
message: text,
|
|
365
|
-
toastType: "error"
|
|
366
|
-
});
|
|
367
|
-
this.options.showError?.(text);
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
const validationErrors = (message.validations ?? []).filter((validation) => validation.level === "error");
|
|
371
|
-
if (validationErrors.length > 0) {
|
|
372
|
-
const text = formatValidationErrorMessage(validationErrors);
|
|
373
|
-
this.options.send({
|
|
374
|
-
type: "@statelyai.toast",
|
|
375
|
-
message: text,
|
|
376
|
-
toastType: "error"
|
|
377
|
-
});
|
|
378
|
-
this.options.showError?.(text);
|
|
379
|
-
return;
|
|
380
|
-
}
|
|
381
|
-
const previousGraph = this.lastPersistedGraph ?? this.currentGraph;
|
|
382
|
-
let patches = message.patches;
|
|
383
|
-
if (!patches?.length && previousGraph !== void 0) try {
|
|
384
|
-
const semanticChange = graphChangeToPatchesResult(previousGraph, message.graph);
|
|
385
|
-
if (semanticChange.patches.length === 0 && semanticChange.unsupportedChanges.length === 0) {
|
|
386
|
-
this.currentGraph = message.graph;
|
|
387
|
-
this.lastPersistedGraph = message.graph;
|
|
388
|
-
this.options.send({
|
|
389
|
-
type: "@statelyai.saved",
|
|
390
|
-
...message.requestId ? { requestId: message.requestId } : {},
|
|
391
|
-
graph: message.graph
|
|
392
|
-
});
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
395
|
-
patches = semanticChange.patches;
|
|
396
|
-
} catch {}
|
|
397
|
-
if (!patches?.length && graphsEqual(previousGraph, message.graph)) {
|
|
398
|
-
this.currentGraph = message.graph;
|
|
399
|
-
this.lastPersistedGraph = message.graph;
|
|
400
|
-
this.options.send({
|
|
401
|
-
type: "@statelyai.saved",
|
|
402
|
-
...message.requestId ? { requestId: message.requestId } : {},
|
|
403
|
-
graph: message.graph
|
|
404
|
-
});
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
const documents = await this.options.source.collectDocuments(sourceLocationUris(this.currentSourceLocations));
|
|
408
|
-
const serialized = await this.getSerializedPayload();
|
|
409
|
-
const sourceUpdateStrategy = message.sourceUpdateStrategy ?? this.options.sourceUpdateStrategy ?? "preserve";
|
|
410
|
-
const response = await this.options.sync.apply({
|
|
411
|
-
rootUri: this.options.source.rootUri,
|
|
412
|
-
rootFileName: this.options.source.rootFileName,
|
|
413
|
-
rootDir: this.options.source.rootDir,
|
|
414
|
-
...this.options.source.machineIndex !== void 0 ? { machineIndex: this.options.source.machineIndex } : {},
|
|
415
|
-
documents,
|
|
416
|
-
machineConfig: message.machineConfig,
|
|
417
|
-
patches,
|
|
418
|
-
prevGraph: previousGraph,
|
|
419
|
-
nextGraph: message.graph,
|
|
420
|
-
sourceLocations: this.currentSourceLocations,
|
|
421
|
-
serialized,
|
|
422
|
-
preserveStatelyMetadata: this.options.source.getPreserveStatelyMetadata?.(this.options.source.rootUri) ?? true,
|
|
423
|
-
sourceUpdateStrategy
|
|
424
|
-
});
|
|
425
|
-
assertSyntacticallyValidSourceUpdates(documents, response.replacements, this.options.source.rootUri);
|
|
426
|
-
if (response.replacements.length === 0) {
|
|
427
|
-
this.reportSourceSyncError("Could not write visual changes to the source file. Your visual edits are still unsaved.", "save", {
|
|
428
|
-
reason: "no_replacements",
|
|
429
|
-
patchCount: patches?.length ?? 0,
|
|
430
|
-
profile: this.currentSourceLocations?.profileRef ?? this.currentSourceLocations?.profile,
|
|
431
|
-
sourceFile: this.options.source.rootFileName.split(/[\\/]/).pop(),
|
|
432
|
-
sourceUpdateStrategy,
|
|
433
|
-
canRewrite: sourceUpdateStrategy === "preserve"
|
|
434
|
-
}, message.requestId);
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
this.selfEditState.count++;
|
|
438
|
-
try {
|
|
439
|
-
const touchedUris = await this.options.source.applyReplacements(response.replacements, this.options.source.rootUri);
|
|
440
|
-
await this.options.source.saveDocuments?.(touchedUris);
|
|
441
|
-
} finally {
|
|
442
|
-
this.selfEditState.count--;
|
|
443
|
-
}
|
|
444
|
-
this.currentGraph = message.graph;
|
|
445
|
-
this.lastPersistedGraph = message.graph;
|
|
446
|
-
this.options.send({
|
|
447
|
-
type: "@statelyai.saved",
|
|
448
|
-
...message.requestId ? { requestId: message.requestId } : {},
|
|
449
|
-
graph: message.graph
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
isExternalSourceDocument(uri) {
|
|
453
|
-
return (uri === this.options.source.rootUri || this.watchedSourceUris.has(uri)) && this.selfEditState.count === 0;
|
|
454
|
-
}
|
|
455
|
-
async handleSavedDocument(uri) {
|
|
456
|
-
if (!this.isExternalSourceDocument(uri)) return;
|
|
457
|
-
if (this.saveReminderState.shown) this.options.send({
|
|
458
|
-
type: "@statelyai.toast.dismiss",
|
|
459
|
-
id: SOURCE_SAVE_REMINDER_ID
|
|
460
|
-
});
|
|
461
|
-
this.saveReminderState.shown = false;
|
|
462
|
-
if (this.editorProtocolState !== "compatible") return;
|
|
463
|
-
try {
|
|
464
|
-
const documents = await this.options.source.collectDocuments(sourceLocationUris(this.currentSourceLocations));
|
|
465
|
-
const update = await this.options.sync.parse({
|
|
466
|
-
rootUri: this.options.source.rootUri,
|
|
467
|
-
rootFileName: this.options.source.rootFileName,
|
|
468
|
-
rootDir: this.options.source.rootDir,
|
|
469
|
-
...this.options.source.machineIndex !== void 0 ? { machineIndex: this.options.source.machineIndex } : {},
|
|
470
|
-
documents
|
|
471
|
-
});
|
|
472
|
-
this.currentFormat = update.format;
|
|
473
|
-
this.currentSourceLocations = update.sourceLocations;
|
|
474
|
-
this.access = update.access ?? this.access;
|
|
475
|
-
this.updateWatchedSourceUris(update.sourceLocations);
|
|
476
|
-
this.options.send({
|
|
477
|
-
type: "@statelyai.update",
|
|
478
|
-
machine: update.machine,
|
|
479
|
-
format: update.format,
|
|
480
|
-
sourceLocations: update.sourceLocations
|
|
481
|
-
});
|
|
482
|
-
} catch (error) {
|
|
483
|
-
this.reportSourceSyncError(formatError(error, "Failed to read the saved document."), "update", {
|
|
484
|
-
errorName: error instanceof Error ? error.name : void 0,
|
|
485
|
-
sourceFile: this.options.source.rootFileName.split(/[\\/]/).pop()
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
reportSourceSyncError(message, phase, details, requestId) {
|
|
490
|
-
const diagnostic = createDiagnostic(phase === "save" ? "source_sync_failed" : "source_update_failed", phase, {
|
|
491
|
-
protocolVersion: EDITOR_PROTOCOL_VERSION,
|
|
492
|
-
client: this.options.client,
|
|
493
|
-
...details
|
|
494
|
-
});
|
|
495
|
-
this.options.send({
|
|
496
|
-
type: "@statelyai.error",
|
|
497
|
-
code: diagnostic.code,
|
|
498
|
-
message,
|
|
499
|
-
diagnostic,
|
|
500
|
-
...requestId ? { requestId } : {}
|
|
501
|
-
});
|
|
502
|
-
this.options.send({
|
|
503
|
-
type: "@statelyai.toast",
|
|
504
|
-
message: phase === "save" ? "Visual changes were not written to the source file." : "The source file could not be applied to the visual editor.",
|
|
505
|
-
toastType: "error"
|
|
506
|
-
});
|
|
507
|
-
this.options.showError?.(`${message} (diagnostic ${diagnostic.id})`);
|
|
508
|
-
}
|
|
509
|
-
updateWatchedSourceUris(sourceLocations) {
|
|
510
|
-
this.watchedSourceUris.clear();
|
|
511
|
-
for (const uri of stateSourceLocationUris(sourceLocations)) if (uri !== this.options.source.rootUri) this.watchedSourceUris.add(uri);
|
|
512
|
-
}
|
|
513
|
-
async getSerializedPayload() {
|
|
514
|
-
const format = this.currentFormat;
|
|
515
|
-
if (!format || format === "xstate") return void 0;
|
|
516
|
-
try {
|
|
517
|
-
return { [format]: await this.requestSerialized(format) };
|
|
518
|
-
} catch {
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
requestSerialized(format) {
|
|
523
|
-
const requestId = `retrieve-${++this.retrieveRequestCount}`;
|
|
524
|
-
return new Promise((resolve, reject) => {
|
|
525
|
-
this.pendingRetrievals.set(requestId, {
|
|
526
|
-
resolve,
|
|
527
|
-
reject
|
|
528
|
-
});
|
|
529
|
-
this.options.send({
|
|
530
|
-
type: "@statelyai.retrieve",
|
|
531
|
-
requestId,
|
|
532
|
-
format
|
|
533
|
-
});
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
resolveRetrieved(requestId, data) {
|
|
537
|
-
const pending = this.pendingRetrievals.get(requestId);
|
|
538
|
-
if (!pending) return;
|
|
539
|
-
this.pendingRetrievals.delete(requestId);
|
|
540
|
-
pending.resolve(typeof data === "string" ? data : JSON.stringify(data, null, 2));
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
/**
|
|
544
|
-
* Runs one source-sync session per discovered machine while presenting the
|
|
545
|
-
* editor's project/workspace protocol as a single surface.
|
|
546
|
-
*/
|
|
547
|
-
var EditorHostWorkspaceSession = class {
|
|
548
|
-
children = /* @__PURE__ */ new Map();
|
|
549
|
-
machineDefinitions = /* @__PURE__ */ new Map();
|
|
550
|
-
initialMessages = /* @__PURE__ */ new Map();
|
|
551
|
-
selectedMachineId;
|
|
552
|
-
sentHandshake = false;
|
|
553
|
-
sentApiKey = false;
|
|
554
|
-
initialized = false;
|
|
555
|
-
projectWorkspaceOpen;
|
|
556
|
-
retrieveRequestCount = 0;
|
|
557
|
-
pendingRetrievals = /* @__PURE__ */ new Map();
|
|
558
|
-
saveReminderStates = /* @__PURE__ */ new Map();
|
|
559
|
-
selfEditStates = /* @__PURE__ */ new Map();
|
|
560
|
-
constructor(options) {
|
|
561
|
-
this.options = options;
|
|
562
|
-
if (options.machines.length === 0) throw new Error("A visual editor workspace needs at least one machine.");
|
|
563
|
-
this.selectedMachineId = options.currentMachineId && options.machines.some((machine) => machine.id === options.currentMachineId) ? options.currentMachineId : options.machines[0].id;
|
|
564
|
-
this.projectWorkspaceOpen = options.projectWorkspaceOpen ?? false;
|
|
565
|
-
for (const machine of options.machines) {
|
|
566
|
-
const saveReminderState = this.saveReminderStates.get(machine.source.rootUri) ?? { shown: false };
|
|
567
|
-
this.saveReminderStates.set(machine.source.rootUri, saveReminderState);
|
|
568
|
-
const selfEditState = this.selfEditStates.get(machine.source.rootUri) ?? { count: 0 };
|
|
569
|
-
this.selfEditStates.set(machine.source.rootUri, selfEditState);
|
|
570
|
-
this.children.set(machine.id, new EditorHostSession({
|
|
571
|
-
...options,
|
|
572
|
-
source: machine.source,
|
|
573
|
-
send: (message) => this.handleChildMessage(machine, message)
|
|
574
|
-
}, saveReminderState, selfEditState));
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
async receive(message) {
|
|
578
|
-
if (message.type === "@statelyai.ready") {
|
|
579
|
-
await Promise.all([...this.children.values()].map((session) => session.receive(message)));
|
|
580
|
-
this.flushProjectInit();
|
|
581
|
-
return;
|
|
582
|
-
}
|
|
583
|
-
if (message.type === "@statelyai.project.machineSelected") {
|
|
584
|
-
if (this.children.has(message.machineId)) this.selectedMachineId = message.machineId;
|
|
585
|
-
return;
|
|
586
|
-
}
|
|
587
|
-
if (message.type === "@statelyai.project.workspaceOpenChanged") {
|
|
588
|
-
this.projectWorkspaceOpen = message.open;
|
|
589
|
-
return;
|
|
590
|
-
}
|
|
591
|
-
if (message.type === "@statelyai.project.workspaceAction") return;
|
|
592
|
-
if ((message.type === "@statelyai.retrieved" || message.type === "@statelyai.error") && message.requestId) {
|
|
593
|
-
const pending = this.pendingRetrievals.get(message.requestId);
|
|
594
|
-
if (pending) {
|
|
595
|
-
this.pendingRetrievals.delete(message.requestId);
|
|
596
|
-
await this.children.get(pending.machineId)?.receive({
|
|
597
|
-
...message,
|
|
598
|
-
requestId: pending.childRequestId,
|
|
599
|
-
machineId: pending.machineId
|
|
600
|
-
});
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
const routedMessage = message.type === "@statelyai.save" ? normalizeWorkspaceSaveMessage(message, this.options.machines) : message;
|
|
605
|
-
const machineId = ("machineId" in routedMessage ? routedMessage.machineId : void 0) ?? this.selectedMachineId;
|
|
606
|
-
const child = this.children.get(machineId);
|
|
607
|
-
if (child) await child.receive(routedMessage);
|
|
608
|
-
}
|
|
609
|
-
selectMachine(machineId) {
|
|
610
|
-
if (!this.children.has(machineId)) return;
|
|
611
|
-
this.selectedMachineId = machineId;
|
|
612
|
-
this.options.send({
|
|
613
|
-
type: "@statelyai.project.selectMachine",
|
|
614
|
-
machineId
|
|
615
|
-
});
|
|
616
|
-
}
|
|
617
|
-
dispose() {
|
|
618
|
-
for (const child of this.children.values()) child.dispose();
|
|
619
|
-
this.children.clear();
|
|
620
|
-
this.pendingRetrievals.clear();
|
|
621
|
-
}
|
|
622
|
-
handleChildMessage(machine, message) {
|
|
623
|
-
switch (message.type) {
|
|
624
|
-
case "@statelyai.init":
|
|
625
|
-
this.initialMessages.set(machine.id, message);
|
|
626
|
-
this.machineDefinitions.set(machine.id, {
|
|
627
|
-
id: machine.id,
|
|
628
|
-
name: machine.name,
|
|
629
|
-
sourceReference: machine.sourceReference,
|
|
630
|
-
sourceUri: machine.source.rootUri,
|
|
631
|
-
machine: message.machine,
|
|
632
|
-
format: message.format,
|
|
633
|
-
sourceLocations: message.sourceLocations
|
|
634
|
-
});
|
|
635
|
-
if (this.initialMessages.size === this.children.size) this.flushProjectInit();
|
|
636
|
-
return;
|
|
637
|
-
case "@statelyai.update": {
|
|
638
|
-
const previous = this.machineDefinitions.get(machine.id);
|
|
639
|
-
this.machineDefinitions.set(machine.id, {
|
|
640
|
-
id: machine.id,
|
|
641
|
-
name: machine.name,
|
|
642
|
-
sourceReference: machine.sourceReference,
|
|
643
|
-
sourceUri: machine.source.rootUri,
|
|
644
|
-
machine: message.machine,
|
|
645
|
-
format: message.format,
|
|
646
|
-
sourceLocations: message.sourceLocations,
|
|
647
|
-
...previous?.projectId ? { projectId: previous.projectId } : {}
|
|
648
|
-
});
|
|
649
|
-
if (this.initialized) this.options.send({
|
|
650
|
-
type: "@statelyai.project.update",
|
|
651
|
-
machines: this.getProjectMachines(),
|
|
652
|
-
source: "external",
|
|
653
|
-
currentMachineId: this.selectedMachineId,
|
|
654
|
-
projectWorkspace: this.getProjectWorkspace(),
|
|
655
|
-
projectWorkspaceOpen: this.projectWorkspaceOpen
|
|
656
|
-
});
|
|
657
|
-
return;
|
|
658
|
-
}
|
|
659
|
-
case "@statelyai.handshake":
|
|
660
|
-
if (this.sentHandshake) return;
|
|
661
|
-
this.sentHandshake = true;
|
|
662
|
-
this.options.send(message);
|
|
663
|
-
return;
|
|
664
|
-
case "@statelyai.setApiKey":
|
|
665
|
-
if (this.sentApiKey) return;
|
|
666
|
-
this.sentApiKey = true;
|
|
667
|
-
this.options.send(message);
|
|
668
|
-
return;
|
|
669
|
-
case "@statelyai.retrieve": {
|
|
670
|
-
const requestId = `workspace-retrieve-${++this.retrieveRequestCount}`;
|
|
671
|
-
this.pendingRetrievals.set(requestId, {
|
|
672
|
-
machineId: machine.id,
|
|
673
|
-
childRequestId: message.requestId
|
|
674
|
-
});
|
|
675
|
-
this.options.send({
|
|
676
|
-
...message,
|
|
677
|
-
requestId,
|
|
678
|
-
machineId: machine.id
|
|
679
|
-
});
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
case "@statelyai.saved":
|
|
683
|
-
case "@statelyai.toast":
|
|
684
|
-
case "@statelyai.toast.dismiss":
|
|
685
|
-
case "@statelyai.error":
|
|
686
|
-
this.options.send({
|
|
687
|
-
...message,
|
|
688
|
-
machineId: machine.id
|
|
689
|
-
});
|
|
690
|
-
return;
|
|
691
|
-
default: this.options.send(message);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
flushProjectInit() {
|
|
695
|
-
if (this.initialized || this.initialMessages.size === 0) return;
|
|
696
|
-
const first = this.initialMessages.values().next().value;
|
|
697
|
-
if (!first) return;
|
|
698
|
-
if (!this.machineDefinitions.has(this.selectedMachineId)) {
|
|
699
|
-
const firstAvailableMachineId = this.machineDefinitions.keys().next().value;
|
|
700
|
-
if (!firstAvailableMachineId) return;
|
|
701
|
-
this.selectedMachineId = firstAvailableMachineId;
|
|
702
|
-
}
|
|
703
|
-
this.initialized = true;
|
|
704
|
-
this.options.send({
|
|
705
|
-
type: "@statelyai.project.init",
|
|
706
|
-
machines: this.getProjectMachines(),
|
|
707
|
-
chrome: this.options.showHeader ? { header: true } : void 0,
|
|
708
|
-
currentMachineId: this.selectedMachineId,
|
|
709
|
-
mode: first.mode,
|
|
710
|
-
theme: first.theme,
|
|
711
|
-
readOnly: first.readOnly,
|
|
712
|
-
readOnlyReason: first.readOnlyReason,
|
|
713
|
-
capabilities: first.capabilities,
|
|
714
|
-
settings: first.settings,
|
|
715
|
-
panels: first.panels,
|
|
716
|
-
unsavedIndicator: first.unsavedIndicator,
|
|
717
|
-
projectWorkspace: this.getProjectWorkspace(),
|
|
718
|
-
projectWorkspaceOpen: this.projectWorkspaceOpen
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
|
-
getProjectMachines() {
|
|
722
|
-
return this.options.machines.flatMap((machine) => {
|
|
723
|
-
const definition = this.machineDefinitions.get(machine.id);
|
|
724
|
-
return definition ? [definition] : [];
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
getProjectWorkspace() {
|
|
728
|
-
return { project: {
|
|
729
|
-
id: "source-workspace",
|
|
730
|
-
name: this.options.workspaceName ?? "Source workspace",
|
|
731
|
-
machines: this.options.machines.flatMap((machine) => this.machineDefinitions.has(machine.id) ? [{
|
|
732
|
-
id: machine.id,
|
|
733
|
-
name: machine.name
|
|
734
|
-
}] : [])
|
|
735
|
-
} };
|
|
736
|
-
}
|
|
737
|
-
};
|
|
738
|
-
function normalizeWorkspaceSaveMessage(message, machines) {
|
|
739
|
-
const sourceReferences = new Map(machines.flatMap((machine) => machine.sourceReference ? [[machine.id, machine.sourceReference]] : []));
|
|
740
|
-
if (sourceReferences.size === 0) return message;
|
|
741
|
-
try {
|
|
742
|
-
const usedReferences = /* @__PURE__ */ new Set();
|
|
743
|
-
const graph = structuredClone(message.graph);
|
|
744
|
-
const machineConfig = structuredClone(message.machineConfig);
|
|
745
|
-
normalizeInvokeSources(graph, sourceReferences, usedReferences);
|
|
746
|
-
normalizeInvokeSources(machineConfig, sourceReferences, usedReferences);
|
|
747
|
-
if (usedReferences.size === 0) return message;
|
|
748
|
-
addWorkspaceActorImplementations(graph, usedReferences);
|
|
749
|
-
const patches = message.patches ? structuredClone(message.patches) : void 0;
|
|
750
|
-
if (patches) {
|
|
751
|
-
normalizeInvokeSources(patches, sourceReferences, usedReferences);
|
|
752
|
-
for (const sourceReference of usedReferences) {
|
|
753
|
-
if (patches.some((patch) => isRecord(patch) && patch.op === "createImplementation" && patch.sourceType === "actor" && isRecord(patch.implementation) && patch.implementation.id === sourceReference)) continue;
|
|
754
|
-
patches.push({
|
|
755
|
-
op: "createImplementation",
|
|
756
|
-
sourceType: "actor",
|
|
757
|
-
implementation: {
|
|
758
|
-
id: sourceReference,
|
|
759
|
-
name: sourceReference,
|
|
760
|
-
code: sourceReference
|
|
761
|
-
}
|
|
762
|
-
});
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
return {
|
|
766
|
-
...message,
|
|
767
|
-
graph,
|
|
768
|
-
machineConfig,
|
|
769
|
-
...patches ? { patches } : {}
|
|
770
|
-
};
|
|
771
|
-
} catch {
|
|
772
|
-
return message;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
function normalizeInvokeSources(value, sourceReferences, usedReferences) {
|
|
776
|
-
if (Array.isArray(value)) {
|
|
777
|
-
for (const item of value) normalizeInvokeSources(item, sourceReferences, usedReferences);
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
|
-
if (!isRecord(value)) return;
|
|
781
|
-
if (typeof value.src === "string") {
|
|
782
|
-
const sourceReference = sourceReferences.get(value.src);
|
|
783
|
-
if (sourceReference) {
|
|
784
|
-
value.src = sourceReference;
|
|
785
|
-
usedReferences.add(sourceReference);
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
for (const child of Object.values(value)) normalizeInvokeSources(child, sourceReferences, usedReferences);
|
|
789
|
-
}
|
|
790
|
-
function addWorkspaceActorImplementations(graph, sourceReferences) {
|
|
791
|
-
if (!isRecord(graph) || !isRecord(graph.data)) return;
|
|
792
|
-
if (!isRecord(graph.data.implementations)) graph.data.implementations = {};
|
|
793
|
-
const implementations = graph.data.implementations;
|
|
794
|
-
if (!isRecord(implementations)) return;
|
|
795
|
-
const actors = Array.isArray(implementations.actors) ? implementations.actors : implementations.actors = [];
|
|
796
|
-
for (const sourceReference of sourceReferences) {
|
|
797
|
-
if (actors.some((actor) => isRecord(actor) && actor.id === sourceReference)) continue;
|
|
798
|
-
actors.push({
|
|
799
|
-
id: sourceReference,
|
|
800
|
-
name: sourceReference,
|
|
801
|
-
description: null,
|
|
802
|
-
inputSchema: null,
|
|
803
|
-
outputSchema: null,
|
|
804
|
-
code: {
|
|
805
|
-
body: sourceReference,
|
|
806
|
-
lang: "ts",
|
|
807
|
-
deps: {}
|
|
808
|
-
}
|
|
809
|
-
});
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
function isRecord(value) {
|
|
813
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
814
|
-
}
|
|
815
|
-
function assertSyntacticallyValidSourceUpdates(documents, replacements, rootUri) {
|
|
816
|
-
const documentsByIdentifier = /* @__PURE__ */ new Map();
|
|
817
|
-
for (const document of documents) {
|
|
818
|
-
documentsByIdentifier.set(document.uri, document);
|
|
819
|
-
documentsByIdentifier.set(document.fileName, document);
|
|
820
|
-
}
|
|
821
|
-
const replacementsByUri = /* @__PURE__ */ new Map();
|
|
822
|
-
for (const replacement of replacements) {
|
|
823
|
-
const uri = replacement.uri ?? rootUri;
|
|
824
|
-
const current = replacementsByUri.get(uri) ?? [];
|
|
825
|
-
current.push(replacement);
|
|
826
|
-
replacementsByUri.set(uri, current);
|
|
827
|
-
}
|
|
828
|
-
for (const [uri, documentReplacements] of replacementsByUri) {
|
|
829
|
-
const document = documentsByIdentifier.get(uri);
|
|
830
|
-
if (!document || !/\.[cm]?[jt]sx?$/i.test(document.fileName)) continue;
|
|
831
|
-
const candidate = applySourceReplacements(document.text, documentReplacements);
|
|
832
|
-
const diagnostics = getIntroducedSyntacticDiagnostics(document.fileName, document.text, candidate);
|
|
833
|
-
if (diagnostics.length) {
|
|
834
|
-
const detail = ts$1.flattenDiagnosticMessageText(diagnostics[0].messageText, "\n");
|
|
835
|
-
throw new Error(`Stately refused to write invalid source to ${document.fileName}: ${detail}`);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
function getIntroducedSyntacticDiagnostics(fileName, original, candidate) {
|
|
840
|
-
const getDiagnostics = (text) => ts$1.transpileModule(text, {
|
|
841
|
-
fileName,
|
|
842
|
-
reportDiagnostics: true,
|
|
843
|
-
compilerOptions: {
|
|
844
|
-
allowJs: true,
|
|
845
|
-
jsx: ts$1.JsxEmit.Preserve,
|
|
846
|
-
target: ts$1.ScriptTarget.Latest
|
|
847
|
-
}
|
|
848
|
-
}).diagnostics ?? [];
|
|
849
|
-
const originalCounts = /* @__PURE__ */ new Map();
|
|
850
|
-
for (const diagnostic of getDiagnostics(original)) {
|
|
851
|
-
const key = diagnosticKey(diagnostic);
|
|
852
|
-
originalCounts.set(key, (originalCounts.get(key) ?? 0) + 1);
|
|
853
|
-
}
|
|
854
|
-
return getDiagnostics(candidate).filter((diagnostic) => {
|
|
855
|
-
const key = diagnosticKey(diagnostic);
|
|
856
|
-
const remaining = originalCounts.get(key) ?? 0;
|
|
857
|
-
if (remaining === 0) return true;
|
|
858
|
-
originalCounts.set(key, remaining - 1);
|
|
859
|
-
return false;
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
function diagnosticKey(diagnostic) {
|
|
863
|
-
return `${diagnostic.code}:${ts$1.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`;
|
|
864
|
-
}
|
|
865
|
-
function applySourceReplacements(source, replacements) {
|
|
866
|
-
const lineStarts = [0];
|
|
867
|
-
for (let index = 0; index < source.length; index++) if (source.charCodeAt(index) === 10) lineStarts.push(index + 1);
|
|
868
|
-
const offsetAt = (line, character) => (lineStarts[Math.min(Math.max(line, 0), lineStarts.length - 1)] ?? 0) + character;
|
|
869
|
-
return [...replacements].sort((left, right) => offsetAt(right.range.startLine, right.range.startChar) - offsetAt(left.range.startLine, left.range.startChar)).reduce((text, replacement) => {
|
|
870
|
-
const start = offsetAt(replacement.range.startLine, replacement.range.startChar);
|
|
871
|
-
const end = offsetAt(replacement.range.endLine, replacement.range.endChar);
|
|
872
|
-
return `${text.slice(0, start)}${replacement.newText}${text.slice(end)}`;
|
|
873
|
-
}, source);
|
|
874
|
-
}
|
|
875
|
-
function graphsEqual(left, right) {
|
|
876
|
-
if (left === void 0 || right === void 0) return false;
|
|
877
|
-
try {
|
|
878
|
-
return JSON.stringify(left) === JSON.stringify(right);
|
|
879
|
-
} catch {
|
|
880
|
-
return false;
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
function mergeSourceLocations(previous, next) {
|
|
884
|
-
if (!next) return previous;
|
|
885
|
-
if (!next.profile && previous?.profile) return {
|
|
886
|
-
...next,
|
|
887
|
-
profile: previous.profile
|
|
888
|
-
};
|
|
889
|
-
return next;
|
|
890
|
-
}
|
|
891
|
-
function formatError(error, fallback) {
|
|
892
|
-
return error instanceof Error ? error.message : fallback;
|
|
893
|
-
}
|
|
894
|
-
function formatValidationErrorMessage(errors) {
|
|
895
|
-
const first = errors[0];
|
|
896
|
-
if (errors.length === 1 && first) return `Cannot save Viz changes: ${first.message}`;
|
|
897
|
-
return `Cannot save Viz changes: ${errors.length} validation errors. First: ${first?.message ?? "Unknown validation error"}`;
|
|
898
|
-
}
|
|
899
|
-
function sourceLocationUris(sourceLocations) {
|
|
900
|
-
return [...new Set([
|
|
901
|
-
sourceLocations?.root?.uri,
|
|
902
|
-
...(sourceLocations?.states ?? []).map((location) => location.uri),
|
|
903
|
-
...(sourceLocations?.staticValues ?? []).map((location) => location.uri),
|
|
904
|
-
...(sourceLocations?.transitionFunctions ?? []).map((location) => location.uri)
|
|
905
|
-
].filter((uri) => Boolean(uri)))];
|
|
906
|
-
}
|
|
907
|
-
function stateSourceLocationUris(sourceLocations) {
|
|
908
|
-
return [...new Set((sourceLocations?.states ?? []).map((location) => location.uri).filter(Boolean))];
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
//#endregion
|
|
912
|
-
export { fetchEditorSyncAccess as a, createRemoteEditorSyncBackend as i, EditorHostWorkspaceSession as n, EditorSyncError as r, EditorHostSession as t };
|