@vcp-dev/site-edit-bridge 0.6.10 → 0.7.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/protocol.js CHANGED
@@ -1,4 +1,7 @@
1
- import { encodeRenderDocument, } from "./document-codec.js";
1
+ import { encodeRenderDocument } from "./document-codec.js";
2
+ export const SITE_EDIT_COMPOSITION_SESSION_MISMATCH = "SITE_EDIT_COMPOSITION_SESSION_MISMATCH";
3
+ export const SITE_EDIT_COMPOSITION_SESSION_REQUIRED = "SITE_EDIT_COMPOSITION_SESSION_REQUIRED";
4
+ export const SITE_EDIT_COMPOSITION_REINITIALIZE_REQUIRED = "SITE_EDIT_COMPOSITION_REINITIALIZE_REQUIRED";
2
5
  export class SiteEditBridgeTransport {
3
6
  constructor() { }
4
7
  static parseMessage(raw, options = {}) {
@@ -12,15 +15,10 @@ export class SiteEditBridgeTransport {
12
15
  return JSON.stringify(message);
13
16
  }
14
17
  static extractRequestInfo(message) {
15
- if (typeof message === "object" &&
16
- message !== null &&
17
- "payload" in message &&
18
- typeof message.payload === "object" &&
19
- message.payload !== null) {
20
- const payload = message.payload;
21
- const id = typeof payload.id === "string" ? payload.id : "unknown";
22
- const kind = SiteEditBridgeTransport.isRequestKind(payload.kind)
23
- ? payload.kind
18
+ if (isRecord(message) && isRecord(message.payload)) {
19
+ const id = typeof message.payload.id === "string" ? message.payload.id : "unknown";
20
+ const kind = this.isRequestKind(message.payload.kind)
21
+ ? message.payload.kind
24
22
  : "get-document";
25
23
  return { id, kind };
26
24
  }
@@ -41,11 +39,10 @@ export class SiteEditBridgeTransport {
41
39
  value === "redo");
42
40
  }
43
41
  static isMessage(value, options = {}) {
44
- if (!isRecord(value) || typeof value.type !== "string") {
42
+ if (!isRecord(value) || typeof value.type !== "string")
45
43
  return false;
46
- }
47
44
  if (value.type === "request") {
48
- return SiteEditBridgeTransport.isRequestPayload(value.payload, options);
45
+ return isRequestPayload(value.payload, options);
49
46
  }
50
47
  if (value.type === "response" || value.type === "error") {
51
48
  return isRecord(value.payload) && typeof value.payload.id === "string";
@@ -56,57 +53,23 @@ export class SiteEditBridgeTransport {
56
53
  if (value.type === "auth") {
57
54
  return isRecord(value.payload) && typeof value.payload.key === "string";
58
55
  }
59
- if (value.type === "auth-ok") {
60
- return isRecord(value.payload) && value.payload.ok === true;
61
- }
62
- return false;
63
- }
64
- static isRequestPayload(payload, options = {}) {
65
- if (!isRecord(payload) ||
66
- typeof payload.id !== "string" ||
67
- !SiteEditBridgeTransport.isRequestKind(payload.kind)) {
68
- return false;
69
- }
70
- switch (payload.kind) {
71
- case "initialize-session":
72
- return (typeof payload.routeId === "string" &&
73
- (payload.mutationContext === undefined ||
74
- isValidMutationContext(payload.mutationContext)));
75
- case "get-document":
76
- case "get-style-context":
77
- return typeof payload.routeId === "string";
78
- case "get-object-edit-context":
79
- case "get-class-name-source":
80
- case "resolve-source-location":
81
- return (typeof payload.key === "string" &&
82
- (payload.routeId === undefined || typeof payload.routeId === "string"));
83
- case "get-history-status":
84
- return payload.mutationContext === undefined;
85
- case "get-source-tree":
86
- return true;
87
- case "get-source-file":
88
- return typeof payload.path === "string";
89
- case "execute":
90
- return (isOperationRequestLike(payload.request) &&
91
- (payload.request.mutationContext === undefined ||
92
- isValidMutationContext(payload.request.mutationContext)) &&
93
- (options.validateOperationRequest?.(payload.request) ?? true));
94
- case "undo":
95
- case "redo":
96
- return (payload.mutationContext === undefined ||
97
- isValidMutationContext(payload.mutationContext));
98
- }
56
+ return (value.type === "auth-ok" &&
57
+ isRecord(value.payload) &&
58
+ value.payload.ok === true);
99
59
  }
100
60
  }
101
61
  export class SiteEditBridgeSocketServer {
102
62
  constructor(options) {
103
63
  this.options = options;
64
+ this.session = {
65
+ subscribedCompositionKeys: new Set(),
66
+ };
104
67
  this.messageQueue = new SerializedSiteEditMessageQueue();
105
68
  this.eventDispatcher = new BufferedSiteEditEventDispatcher((message) => {
106
69
  this.sendJson(message);
107
70
  });
108
71
  this.unsubscribe = options.engine.subscribe((event) => {
109
- this.eventDispatcher.push(event);
72
+ this.handleEngineEvent(event);
110
73
  });
111
74
  options.socket.onmessage = (event) => {
112
75
  try {
@@ -126,138 +89,112 @@ export class SiteEditBridgeSocketServer {
126
89
  };
127
90
  options.socket.onclose = () => {
128
91
  this.unsubscribe();
92
+ this.session.activeComposition = undefined;
93
+ this.session.subscribedCompositionKeys.clear();
129
94
  };
130
95
  }
131
96
  async handleMessage(message) {
132
97
  try {
133
98
  const parsed = message;
134
- if (parsed.type !== "request") {
99
+ if (parsed.type !== "request")
135
100
  return;
136
- }
137
101
  const payload = parsed.payload;
138
102
  const { id } = payload;
139
103
  switch (payload.kind) {
140
104
  case "initialize-session": {
105
+ const selector = requireCompositionSelector(payload);
106
+ const resolution = await this.resolve(selector);
141
107
  const result = await this.options.engine.initializeSession({
142
- routeId: payload.routeId,
108
+ composition: resolution.context,
143
109
  ...(payload.mutationContext
144
110
  ? { mutationContext: payload.mutationContext }
145
111
  : {}),
146
112
  });
113
+ this.activateSession(resolution.context);
147
114
  this.sendJson({
148
115
  type: "response",
149
116
  payload: {
150
117
  id,
151
118
  kind: payload.kind,
152
- result: {
153
- ok: true,
119
+ result: addComposition({
120
+ ...result,
154
121
  data: {
155
- document: encodeRenderDocument(result.data.document),
156
- historyStatus: result.data.historyStatus,
122
+ ...result.data,
123
+ document: encodeBridgeRenderDocument(result.data.document),
157
124
  },
158
- },
125
+ }, resolution.context),
159
126
  },
160
127
  });
161
128
  return;
162
129
  }
163
- case "get-document":
164
- this.sendJson({
165
- type: "response",
166
- payload: {
167
- id,
168
- kind: payload.kind,
169
- result: {
170
- ok: true,
171
- data: encodeRenderDocument((await this.options.engine.getDocument(payload.routeId)).data),
172
- },
173
- },
174
- });
130
+ case "get-document": {
131
+ const context = await this.resolveWireContext(payload);
132
+ const result = await this.options.engine.getDocument(context);
133
+ this.sendResult(id, payload.kind, encodeDocumentResult(result, context));
175
134
  return;
176
- case "get-history-status":
177
- this.sendJson({
178
- type: "response",
179
- payload: {
180
- id,
181
- kind: payload.kind,
182
- result: await this.options.engine.getHistoryStatus(),
183
- },
184
- });
135
+ }
136
+ case "get-history-status": {
137
+ const context = await this.resolveWireContext(payload);
138
+ const result = await this.options.engine.getHistoryStatus(context);
139
+ this.sendResult(id, payload.kind, addComposition(result, context));
185
140
  return;
186
- case "get-style-context":
187
- this.sendJson({
188
- type: "response",
189
- payload: {
190
- id,
191
- kind: payload.kind,
192
- result: await this.options.engine.getStyleContext(payload.routeId),
193
- },
194
- });
141
+ }
142
+ case "get-style-context": {
143
+ const context = await this.resolveWireContext(payload);
144
+ this.sendResult(id, payload.kind, addComposition(await this.options.engine.getStyleContext(context), context));
195
145
  return;
196
- case "get-object-edit-context":
197
- this.sendJson({
198
- type: "response",
199
- payload: {
200
- id,
201
- kind: payload.kind,
202
- result: await this.options.engine.getObjectEditContext(payload.key, payload.routeId),
203
- },
204
- });
146
+ }
147
+ case "get-object-edit-context": {
148
+ const context = await this.resolveWireContext(payload);
149
+ this.sendResult(id, payload.kind, addComposition(await this.options.engine.getObjectEditContext(payload.key, context), context));
205
150
  return;
206
- case "get-class-name-source":
207
- this.sendJson({
208
- type: "response",
209
- payload: {
210
- id,
211
- kind: payload.kind,
212
- result: await this.options.engine.getClassNameSource(payload.key, payload.routeId),
213
- },
214
- });
151
+ }
152
+ case "get-class-name-source": {
153
+ const context = await this.resolveWireContext(payload);
154
+ this.sendResult(id, payload.kind, addComposition(await this.options.engine.getClassNameSource(payload.key, context), context));
215
155
  return;
216
- case "get-source-tree":
217
- this.sendJson({
218
- type: "response",
219
- payload: {
220
- id,
221
- kind: payload.kind,
222
- result: await this.options.engine.getSourceTree(),
223
- },
224
- });
156
+ }
157
+ case "get-source-tree": {
158
+ const context = await this.resolveWireContext(payload);
159
+ this.sendResult(id, payload.kind, addComposition(await this.options.engine.getSourceTree(context), context));
225
160
  return;
226
- case "get-source-file":
227
- this.sendJson({
228
- type: "response",
229
- payload: {
230
- id,
231
- kind: payload.kind,
232
- result: await this.options.engine.getSourceFile({
233
- path: payload.path,
234
- }),
235
- },
236
- });
161
+ }
162
+ case "get-source-file": {
163
+ const context = await this.resolveWireContext(payload);
164
+ this.sendResult(id, payload.kind, addComposition(await this.options.engine.getSourceFile({
165
+ path: payload.path,
166
+ composition: context,
167
+ }), context));
237
168
  return;
238
- case "resolve-source-location":
239
- this.sendJson({
240
- type: "response",
241
- payload: {
242
- id,
243
- kind: payload.kind,
244
- result: await this.options.engine.resolveSourceLocation({
245
- key: payload.key,
246
- routeId: payload.routeId,
247
- }),
248
- },
249
- });
169
+ }
170
+ case "resolve-source-location": {
171
+ const context = await this.resolveWireContext(payload);
172
+ const result = addComposition(await this.options.engine.resolveSourceLocation({
173
+ key: payload.key,
174
+ composition: context,
175
+ }), context);
176
+ this.sendResult(id, payload.kind, result);
250
177
  return;
178
+ }
251
179
  case "execute": {
252
- await this.handleBufferedOperation(id, payload.kind, () => this.options.engine.execute(payload.request));
180
+ const context = await this.resolveOperationWireContext(payload.request);
181
+ const payloadContext = await this.resolveWireContext(payload);
182
+ if (computeSiteEditCompositionKey(context) !==
183
+ computeSiteEditCompositionKey(payloadContext)) {
184
+ throw new BridgeProtocolError(SITE_EDIT_COMPOSITION_SESSION_MISMATCH, "The execute request composition does not match its operation composition.");
185
+ }
186
+ const request = await this.normalizeOperationRequest(payload.request, context);
187
+ await this.handleBufferedOperation(id, payload.kind, () => this.options.engine.execute(request));
253
188
  return;
254
189
  }
255
190
  case "undo":
256
- await this.handleBufferedOperation(id, payload.kind, () => this.options.engine.undo());
257
- return;
258
- case "redo":
259
- await this.handleBufferedOperation(id, payload.kind, () => this.options.engine.redo());
191
+ case "redo": {
192
+ const context = await this.resolveWireContext(payload);
193
+ await this.handleBufferedOperation(id, payload.kind, () => payload.kind === "undo"
194
+ ? this.options.engine.undo(context)
195
+ : this.options.engine.redo(context));
260
196
  return;
197
+ }
261
198
  }
262
199
  }
263
200
  catch (error) {
@@ -272,6 +209,67 @@ export class SiteEditBridgeSocketServer {
272
209
  });
273
210
  }
274
211
  }
212
+ async resolve(selector) {
213
+ return this.options.engine.resolveComposition(selector);
214
+ }
215
+ async resolveAndAssert(selector) {
216
+ const resolution = await this.resolve(selector);
217
+ const active = this.session.activeComposition;
218
+ if (!active) {
219
+ throw new BridgeProtocolError(SITE_EDIT_COMPOSITION_SESSION_REQUIRED, "Initialize a composition session before issuing this request.");
220
+ }
221
+ if (computeSiteEditCompositionKey(active) !==
222
+ computeSiteEditCompositionKey(resolution.context)) {
223
+ throw new BridgeProtocolError(SITE_EDIT_COMPOSITION_SESSION_MISMATCH, "The request composition does not match the active socket session.");
224
+ }
225
+ return resolution.context;
226
+ }
227
+ async resolveWireContext(payload) {
228
+ const selector = requireCompositionSelector(payload);
229
+ return this.resolveAndAssert(selector);
230
+ }
231
+ async resolveOperationWireContext(request) {
232
+ const selector = requireOperationSelector(request);
233
+ return this.resolveAndAssert(selector);
234
+ }
235
+ activateSession(context) {
236
+ this.session.activeComposition = context;
237
+ this.session.subscribedCompositionKeys.clear();
238
+ this.session.subscribedCompositionKeys.add(computeSiteEditCompositionKey(context));
239
+ }
240
+ async normalizeOperationRequest(rawRequest, context) {
241
+ const request = {
242
+ ...rawRequest,
243
+ composition: contextToSelector(context),
244
+ };
245
+ if (request.target.kind === "route") {
246
+ const rawTarget = request.target;
247
+ const targetSelector = requireCompositionSelector(rawTarget);
248
+ const targetContext = await this.resolveAndAssert(targetSelector);
249
+ request.target = {
250
+ ...rawTarget,
251
+ composition: contextToSelector(targetContext),
252
+ };
253
+ }
254
+ return request;
255
+ }
256
+ handleEngineEvent(event) {
257
+ const composition = event?.composition;
258
+ if (!isCompositionContext(composition))
259
+ return;
260
+ const key = computeSiteEditCompositionKey(composition);
261
+ if (!this.session.subscribedCompositionKeys.has(key))
262
+ return;
263
+ this.eventDispatcher.push(event);
264
+ if (event.type === "site-edit.graph.invalidated" &&
265
+ key === activeKey(this.session)) {
266
+ this.session.activeComposition = undefined;
267
+ this.session.subscribedCompositionKeys.delete(key);
268
+ }
269
+ }
270
+ sendResult(id, kind, result) {
271
+ this.sendJson({ type: "response", payload: { id, kind, result } });
272
+ }
275
273
  async handleRawMessage(raw) {
276
274
  try {
277
275
  await this.handleMessage(SiteEditBridgeTransport.parseMessage(raw, {
@@ -279,11 +277,14 @@ export class SiteEditBridgeSocketServer {
279
277
  }));
280
278
  }
281
279
  catch (error) {
282
- const message = error instanceof Error ? error.message : "Invalid websocket message";
283
280
  const requestInfo = extractRawRequestInfo(raw);
284
281
  this.sendJson({
285
282
  type: "error",
286
- payload: { ...requestInfo, message },
283
+ payload: {
284
+ ...requestInfo,
285
+ message: getBridgeErrorMessage(error),
286
+ code: getBridgeErrorCode(error),
287
+ },
287
288
  });
288
289
  }
289
290
  }
@@ -294,8 +295,7 @@ export class SiteEditBridgeSocketServer {
294
295
  this.eventDispatcher.beginBuffering();
295
296
  try {
296
297
  const result = await operation();
297
- this.sendJson({ type: "response", payload: { id, kind, result } });
298
- this.eventDispatcher.flush();
298
+ this.sendResult(id, kind, result);
299
299
  }
300
300
  catch (error) {
301
301
  this.sendJson({
@@ -307,10 +307,19 @@ export class SiteEditBridgeSocketServer {
307
307
  code: getBridgeErrorCode(error),
308
308
  },
309
309
  });
310
+ }
311
+ finally {
310
312
  this.eventDispatcher.flush();
311
313
  }
312
314
  }
313
315
  }
316
+ class BridgeProtocolError extends Error {
317
+ constructor(code, message) {
318
+ super(message);
319
+ this.code = code;
320
+ this.name = "BridgeProtocolError";
321
+ }
322
+ }
314
323
  class BufferedSiteEditEventDispatcher {
315
324
  constructor(send) {
316
325
  this.send = send;
@@ -333,9 +342,7 @@ class BufferedSiteEditEventDispatcher {
333
342
  flush() {
334
343
  const buffered = this.bufferedEvents ?? [];
335
344
  this.bufferedEvents = null;
336
- buffered.forEach((message) => {
337
- this.send(message);
338
- });
345
+ buffered.forEach((message) => this.send(message));
339
346
  }
340
347
  }
341
348
  class SerializedSiteEditMessageQueue {
@@ -345,9 +352,8 @@ class SerializedSiteEditMessageQueue {
345
352
  this.queued = 0;
346
353
  }
347
354
  enqueue(task) {
348
- if (this.queued >= this.maxQueued) {
355
+ if (this.queued >= this.maxQueued)
349
356
  throw new Error("Bridge request queue is full");
350
- }
351
357
  this.queued += 1;
352
358
  const run = async () => {
353
359
  this.queued -= 1;
@@ -358,49 +364,126 @@ class SerializedSiteEditMessageQueue {
358
364
  return next;
359
365
  }
360
366
  }
361
- function isRecord(value) {
362
- return typeof value === "object" && value !== null;
367
+ function isRequestPayload(payload, options) {
368
+ if (!isRecord(payload) ||
369
+ typeof payload.id !== "string" ||
370
+ !SiteEditBridgeTransport.isRequestKind(payload.kind))
371
+ return false;
372
+ const compositionOk = isCompositionSelector(payload.composition);
373
+ switch (payload.kind) {
374
+ case "initialize-session":
375
+ return (compositionOk &&
376
+ (payload.mutationContext === undefined ||
377
+ isMutationContextLike(payload.mutationContext)));
378
+ case "get-document":
379
+ case "get-style-context":
380
+ return compositionOk;
381
+ case "get-object-edit-context":
382
+ case "get-class-name-source":
383
+ case "resolve-source-location":
384
+ return typeof payload.key === "string" && compositionOk;
385
+ case "get-history-status":
386
+ return compositionOk;
387
+ case "get-source-tree":
388
+ return compositionOk;
389
+ case "get-source-file":
390
+ return typeof payload.path === "string" && compositionOk;
391
+ case "execute":
392
+ return (compositionOk &&
393
+ isOperationRequestLike(payload.request) &&
394
+ (payload.request.mutationContext === undefined ||
395
+ isMutationContextLike(payload.request.mutationContext)) &&
396
+ (options.validateOperationRequest?.(payload.request) ?? true));
397
+ case "undo":
398
+ case "redo":
399
+ return ((compositionOk && payload.mutationContext === undefined) ||
400
+ (compositionOk && isMutationContextLike(payload.mutationContext)));
401
+ }
363
402
  }
364
403
  function isOperationRequestLike(value) {
365
404
  return (isRecord(value) &&
366
405
  typeof value.id === "string" &&
367
406
  typeof value.siteId === "string" &&
368
407
  typeof value.baseSnapshotId === "string" &&
369
- (value.routeId === undefined || typeof value.routeId === "string") &&
408
+ isCompositionSelector(value.composition) &&
370
409
  typeof value.kind === "string" &&
371
410
  isRecord(value.target) &&
411
+ (value.target.kind !== "route" ||
412
+ isCompositionSelector(value.target.composition)) &&
372
413
  typeof value.documentVersion === "number" &&
373
414
  Number.isInteger(value.documentVersion) &&
374
415
  value.documentVersion >= 0 &&
375
416
  isRecord(value.params));
376
417
  }
377
- function isValidMutationContext(value) {
378
- return isMutationContextLike(value);
418
+ function isCompositionSelector(value) {
419
+ return (isRecord(value) &&
420
+ typeof value.routeId === "string" &&
421
+ value.routeId.length > 0 &&
422
+ (value.templateId === undefined ||
423
+ (typeof value.templateId === "string" && value.templateId.length > 0)) &&
424
+ Object.keys(value).every((key) => key === "routeId" || key === "templateId"));
379
425
  }
380
- function getBridgeErrorCode(error) {
381
- if (!error || typeof error !== "object") {
382
- return undefined;
383
- }
384
- const code = error.code;
385
- return typeof code === "string" && code.length > 0 ? code : undefined;
426
+ function isCompositionContext(value) {
427
+ return (isRecord(value) &&
428
+ typeof value.routeId === "string" &&
429
+ (value.effectiveTemplateId === undefined ||
430
+ typeof value.effectiveTemplateId === "string"));
386
431
  }
387
- function getBridgeErrorMessage(error) {
388
- if (error instanceof Error) {
389
- return error.message;
390
- }
391
- if (!error || typeof error !== "object") {
392
- return "Unknown websocket operation failure";
393
- }
394
- const message = error.message;
395
- return typeof message === "string" && message.length > 0
396
- ? message
397
- : "Unknown websocket operation failure";
432
+ function requireCompositionSelector(payload) {
433
+ if (isCompositionSelector(payload.composition))
434
+ return payload.composition;
435
+ throw new BridgeProtocolError(SITE_EDIT_COMPOSITION_SESSION_REQUIRED, "A composition selector is required for this request.");
436
+ }
437
+ function requireOperationSelector(request) {
438
+ if (isRecord(request) && isCompositionSelector(request.composition))
439
+ return request.composition;
440
+ throw new BridgeProtocolError(SITE_EDIT_COMPOSITION_SESSION_REQUIRED, "A composition selector is required for execute.");
441
+ }
442
+ function contextToSelector(context) {
443
+ return {
444
+ routeId: context.routeId,
445
+ ...(context.effectiveTemplateId
446
+ ? { templateId: context.effectiveTemplateId }
447
+ : {}),
448
+ };
449
+ }
450
+ function activeKey(session) {
451
+ return session.activeComposition
452
+ ? computeSiteEditCompositionKey(session.activeComposition)
453
+ : null;
454
+ }
455
+ function computeSiteEditCompositionKey(context) {
456
+ return JSON.stringify([context.routeId, context.effectiveTemplateId ?? null]);
457
+ }
458
+ function addComposition(result, context) {
459
+ return isRecord(result) && result.ok === true
460
+ ? { ...result, composition: context }
461
+ : result;
462
+ }
463
+ function encodeDocumentResult(result, context) {
464
+ if (!isRecord(result) || result.ok !== true)
465
+ return result;
466
+ return {
467
+ ...result,
468
+ ...(context ? { composition: context } : {}),
469
+ data: encodeBridgeRenderDocument(result.data),
470
+ };
471
+ }
472
+ function encodeBridgeRenderDocument(document) {
473
+ const value = document;
474
+ return encodeRenderDocument(value.routeId
475
+ ? value
476
+ : {
477
+ ...value,
478
+ routeId: value.composition.routeId,
479
+ });
480
+ }
481
+ function isRecord(value) {
482
+ return typeof value === "object" && value !== null;
398
483
  }
399
484
  function isMutationContextLike(value) {
400
- if (!isRecord(value)) {
401
- return false;
402
- }
403
- return (typeof value.editingSessionId === "string" &&
485
+ return (isRecord(value) &&
486
+ typeof value.editingSessionId === "string" &&
404
487
  value.editingSessionId.length > 0 &&
405
488
  typeof value.lockId === "string" &&
406
489
  value.lockId.length > 0 &&
@@ -409,6 +492,22 @@ function isMutationContextLike(value) {
409
492
  typeof value.leaseAssertion === "string" &&
410
493
  value.leaseAssertion.length > 0);
411
494
  }
495
+ function getBridgeErrorCode(error) {
496
+ if (!isRecord(error) ||
497
+ typeof error.code !== "string" ||
498
+ error.code.length === 0)
499
+ return undefined;
500
+ return error.code;
501
+ }
502
+ function getBridgeErrorMessage(error) {
503
+ if (error instanceof Error)
504
+ return error.message;
505
+ if (isRecord(error) &&
506
+ typeof error.message === "string" &&
507
+ error.message.length > 0)
508
+ return error.message;
509
+ return "Unknown websocket operation failure";
510
+ }
412
511
  function extractRawRequestInfo(raw) {
413
512
  try {
414
513
  return SiteEditBridgeTransport.extractRequestInfo(JSON.parse(raw));
package/dist/server.d.ts CHANGED
@@ -56,12 +56,15 @@ export declare class SiteEditBridgeServer {
56
56
  private readonly mutationQueue;
57
57
  private readonly eventListeners;
58
58
  private routes;
59
+ private compositions;
60
+ private compositionFiles;
61
+ private compositionResolutionError;
59
62
  private stopWatching;
60
63
  private stopWebSocketServer;
61
64
  private readonly pendingChangedFiles;
62
65
  private fileChangeTimer;
63
66
  private isStarted;
64
- private runtimeVersionFloor;
67
+ private readonly runtimeVersionFloors;
65
68
  private activeHistoryStore;
66
69
  private versionPersistence;
67
70
  constructor(options: ReturnType<typeof normalizeOptions>, server?: HttpServer, closeHttpServerOnStop?: boolean, dependencies?: SiteEditBridgeServerDependencies);
@@ -74,13 +77,12 @@ export declare class SiteEditBridgeServer {
74
77
  private createBridgeEngine;
75
78
  private bindHistorySession;
76
79
  private recordRuntimeVersion;
77
- private activateRoute;
78
- private normalizeRequest;
79
80
  private handleFileChanged;
80
81
  private handleFilesChanged;
81
82
  private flushChangedFiles;
82
- private refreshRoutes;
83
- private resolveRouteId;
83
+ private refreshCompositions;
84
+ private resolveComposition;
85
+ private getInitialDocumentVersions;
84
86
  private getRuntime;
85
87
  }
86
88
  declare function normalizeOptions(options: SiteEditBridgeServerOptions): {