@opengeni/sdk 0.57.0 → 1.0.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 +1017 -26
- package/dist/accounts.d.ts +153 -0
- package/dist/accounts.js +307 -0
- package/dist/accounts.js.map +1 -0
- package/dist/adapters/express.d.ts +31 -0
- package/dist/adapters/express.js +87 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/hono.d.ts +16 -0
- package/dist/adapters/hono.js +8 -0
- package/dist/adapters/hono.js.map +1 -0
- package/dist/adapters/next.d.ts +29 -0
- package/dist/adapters/next.js +22 -0
- package/dist/adapters/next.js.map +1 -0
- package/dist/allowance-refusal.d.ts +2 -0
- package/dist/allowance-refusal.js +50 -0
- package/dist/allowance-refusal.js.map +1 -0
- package/dist/artifact-catalog.d.ts +31 -0
- package/dist/artifact-client.d.ts +23 -11
- package/dist/artifacts.d.ts +1 -1
- package/dist/artifacts.js +7 -5
- package/dist/automations-client.d.ts +17 -0
- package/dist/automations.d.ts +3 -0
- package/dist/automations.js +84 -0
- package/dist/automations.js.map +1 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.js +47 -0
- package/dist/browser.js.map +1 -0
- package/dist/chat/fold.d.ts +75 -0
- package/dist/chat/handler.d.ts +41 -0
- package/dist/chat/http.d.ts +67 -0
- package/dist/chat/ids.d.ts +34 -0
- package/dist/chat/index.d.ts +9 -0
- package/dist/chat/index.js +1694 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/openai.d.ts +30 -0
- package/dist/chat/opengeni.d.ts +128 -0
- package/dist/chat/types.d.ts +207 -0
- package/dist/chat/vercel.d.ts +49 -0
- package/dist/chats.d.ts +8 -0
- package/dist/{chunk-JDLDDRNE.js → chunk-2UXZUCEZ.js} +291 -34
- package/dist/chunk-2UXZUCEZ.js.map +1 -0
- package/dist/chunk-4SMEOV3P.js +246 -0
- package/dist/chunk-4SMEOV3P.js.map +1 -0
- package/dist/{chunk-JRPFWI6T.js → chunk-AH5D5Q5V.js} +31 -35
- package/dist/chunk-AH5D5Q5V.js.map +1 -0
- package/dist/chunk-APXVSSSY.js +301 -0
- package/dist/chunk-APXVSSSY.js.map +1 -0
- package/dist/chunk-DUVIYER4.js +639 -0
- package/dist/chunk-DUVIYER4.js.map +1 -0
- package/dist/{chunk-PKQ377ED.js → chunk-FG3OO5LM.js} +2686 -611
- package/dist/chunk-FG3OO5LM.js.map +1 -0
- package/dist/chunk-GZYZT22T.js +260 -0
- package/dist/chunk-GZYZT22T.js.map +1 -0
- package/dist/chunk-HMGADJGZ.js +150 -0
- package/dist/chunk-HMGADJGZ.js.map +1 -0
- package/dist/{chunk-YKZME56C.js → chunk-KWADQ227.js} +3 -3
- package/dist/{chunk-YKZME56C.js.map → chunk-KWADQ227.js.map} +1 -1
- package/dist/chunk-LY2K6ELJ.js +126 -0
- package/dist/chunk-LY2K6ELJ.js.map +1 -0
- package/dist/chunk-MOTJYIYL.js +340 -0
- package/dist/chunk-MOTJYIYL.js.map +1 -0
- package/dist/{chunk-ST5DDKJP.js → chunk-NC57YMUO.js} +121 -3
- package/dist/chunk-NC57YMUO.js.map +1 -0
- package/dist/chunk-RWKB6YZG.js +1270 -0
- package/dist/chunk-RWKB6YZG.js.map +1 -0
- package/dist/chunk-U6CV2SXO.js +195 -0
- package/dist/chunk-U6CV2SXO.js.map +1 -0
- package/dist/chunk-UM4ZXXJR.js +9 -0
- package/dist/chunk-UM4ZXXJR.js.map +1 -0
- package/dist/chunk-V6GIY62B.js +229 -0
- package/dist/chunk-V6GIY62B.js.map +1 -0
- package/dist/chunk-WU6GQG25.js +268 -0
- package/dist/chunk-WU6GQG25.js.map +1 -0
- package/dist/{chunk-VWE2QIVO.js → chunk-XNG7YGR3.js} +23 -6
- package/dist/chunk-XNG7YGR3.js.map +1 -0
- package/dist/{chunk-HJ3HHUT5.js → chunk-YIKA2QT4.js} +33 -2
- package/dist/chunk-YIKA2QT4.js.map +1 -0
- package/dist/chunk-ZKPY6YAJ.js +135 -0
- package/dist/chunk-ZKPY6YAJ.js.map +1 -0
- package/dist/client.d.ts +740 -94
- package/dist/codex-realtime-controller.d.ts +3 -0
- package/dist/codex-realtime-controller.js +2 -2
- package/dist/codex-realtime-v3.d.ts +13 -2
- package/dist/company-brain.d.ts +22 -0
- package/dist/company-profile.d.ts +14 -1
- package/dist/core.d.ts +9 -3
- package/dist/core.js +25 -6
- package/dist/deprecation.d.ts +47 -0
- package/dist/document-authority-client.d.ts +51 -0
- package/dist/document-authority.d.ts +2 -0
- package/dist/document-authority.js +12 -0
- package/dist/document-authority.js.map +1 -0
- package/dist/editable-artifacts/browser-session.d.ts +7 -3
- package/dist/editable-artifacts/controller.d.ts +4 -1
- package/dist/editable-artifacts/errors.d.ts +1 -1
- package/dist/editable-artifacts/http-live-transport.d.ts +6 -2
- package/dist/editable-artifacts/index.d.ts +2 -0
- package/dist/editable-artifacts/open-failure.d.ts +9 -0
- package/dist/editable-artifacts/types.d.ts +6 -3
- package/dist/editable-artifacts/worker/kernel-adapter.d.ts +1 -1
- package/dist/editable-artifacts-worker.js +44 -17
- package/dist/editable-artifacts-worker.js.map +1 -1
- package/dist/editable-artifacts.js +240 -121
- package/dist/editable-artifacts.js.map +1 -1
- package/dist/embedding-client.d.ts +129 -0
- package/dist/errors.d.ts +36 -1
- package/dist/feedback.d.ts +23 -0
- package/dist/gateway-realtime-transport.js +1 -1
- package/dist/github-repositories.d.ts +10 -0
- package/dist/github-repositories.js +36 -0
- package/dist/github-repositories.js.map +1 -0
- package/dist/index.d.ts +56 -11
- package/dist/index.js +242 -125
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +84 -1
- package/dist/interaction.js +6 -1
- package/dist/knowledge.d.ts +7 -0
- package/dist/knowledge.js +20 -0
- package/dist/knowledge.js.map +1 -0
- package/dist/message-links.d.ts +68 -0
- package/dist/model-context.d.ts +68 -0
- package/dist/model-display.d.ts +2 -0
- package/dist/model-display.js +15 -0
- package/dist/model-display.js.map +1 -0
- package/dist/model-picker-order.d.ts +1 -0
- package/dist/model-picker-order.js +10 -0
- package/dist/model-picker-order.js.map +1 -0
- package/dist/organization-integration-policy.d.ts +26 -0
- package/dist/organization-integration-policy.js +26 -0
- package/dist/organization-integration-policy.js.map +1 -0
- package/dist/organization-private-session-settings.d.ts +6 -0
- package/dist/organization-private-session-settings.js +22 -0
- package/dist/organization-private-session-settings.js.map +1 -0
- package/dist/organization-user-setup.d.ts +8 -0
- package/dist/organization-user-setup.js +16 -0
- package/dist/organization-user-setup.js.map +1 -0
- package/dist/pr-review-client.d.ts +16 -0
- package/dist/pr-review.d.ts +4 -0
- package/dist/pr-review.js +62 -0
- package/dist/pr-review.js.map +1 -0
- package/dist/preference-registry.d.ts +9 -1
- package/dist/proxy.d.ts +7 -5
- package/dist/realtime.d.ts +3 -1
- package/dist/realtime.js +6 -6
- package/dist/realtime.js.map +1 -1
- package/dist/retained-artifacts.d.ts +5 -1
- package/dist/session-history-import.d.ts +22 -0
- package/dist/session-history-import.js +36 -0
- package/dist/session-history-import.js.map +1 -0
- package/dist/session-list-entries.d.ts +1 -0
- package/dist/session-list-entries.js +7 -0
- package/dist/session-list-entries.js.map +1 -0
- package/dist/session-message-search.d.ts +53 -0
- package/dist/session-proxy-client.d.ts +24 -0
- package/dist/session-proxy.d.ts +245 -0
- package/dist/session-proxy.js +24 -0
- package/dist/session-proxy.js.map +1 -0
- package/dist/session-titles.d.ts +2 -0
- package/dist/site-browser-entry.d.ts +1 -0
- package/dist/site-browser-runtime.gen.d.ts +1 -0
- package/dist/site-document.d.ts +5 -0
- package/dist/site-document.js +20 -0
- package/dist/site-document.js.map +1 -0
- package/dist/site-document.test.d.ts +1 -0
- package/dist/site-http.d.ts +16 -0
- package/dist/site-tool-bridge.d.ts +44 -0
- package/dist/site.d.ts +101 -0
- package/dist/site.js +49 -0
- package/dist/site.js.map +1 -0
- package/dist/skills.d.ts +75 -0
- package/dist/stream.d.ts +2 -0
- package/dist/tenant-workspaces.d.ts +47 -0
- package/dist/tenant-workspaces.js +8 -0
- package/dist/tenant-workspaces.js.map +1 -0
- package/dist/tool-auth.d.ts +87 -0
- package/dist/tool-auth.js +23 -0
- package/dist/tool-auth.js.map +1 -0
- package/dist/tool-display-metadata.d.ts +3 -0
- package/dist/tools-FXBLUWAE.js +12 -0
- package/dist/tools-FXBLUWAE.js.map +1 -0
- package/dist/tools.d.ts +61 -0
- package/dist/types.d.ts +2863 -424
- package/dist/usage-allowances.d.ts +36 -0
- package/dist/usage-allowances.js +80 -0
- package/dist/usage-allowances.js.map +1 -0
- package/dist/workspace-artifacts.d.ts +33 -5
- package/dist/workspace-instruction-policies.d.ts +24 -2
- package/dist/workspace-integrations.d.ts +74 -0
- package/dist/workspace-integrations.js +65 -0
- package/dist/workspace-integrations.js.map +1 -0
- package/dist/workspace-learning.d.ts +124 -0
- package/dist/workspace-state.d.ts +8 -71
- package/package.json +108 -3
- package/src/accounts.ts +443 -0
- package/src/adapters/express.ts +136 -0
- package/src/adapters/hono.ts +18 -0
- package/src/adapters/next.ts +42 -0
- package/src/allowance-refusal.ts +5 -0
- package/src/artifact-catalog.ts +41 -0
- package/src/artifact-client.ts +43 -52
- package/src/artifacts.ts +7 -1
- package/src/automations-client.ts +124 -0
- package/src/automations.ts +15 -0
- package/src/browser.ts +54 -0
- package/src/chat/fold.ts +431 -0
- package/src/chat/handler.ts +240 -0
- package/src/chat/http.ts +257 -0
- package/src/chat/ids.ts +85 -0
- package/src/chat/index.ts +87 -0
- package/src/chat/openai.ts +439 -0
- package/src/chat/opengeni.ts +722 -0
- package/src/chat/types.ts +219 -0
- package/src/chat/vercel.ts +204 -0
- package/src/chats.ts +16 -0
- package/src/client.ts +4084 -515
- package/src/codex-realtime-controller.ts +235 -5
- package/src/codex-realtime-v3.ts +162 -31
- package/src/codex-realtime.ts +1 -1
- package/src/company-brain.ts +59 -0
- package/src/company-profile.ts +17 -1
- package/src/core.ts +23 -1
- package/src/deprecation.ts +149 -0
- package/src/document-authority-client.ts +219 -0
- package/src/document-authority.ts +17 -0
- package/src/editable-artifacts/browser-session.ts +36 -22
- package/src/editable-artifacts/controller.ts +102 -47
- package/src/editable-artifacts/errors.ts +2 -0
- package/src/editable-artifacts/http-live-transport.ts +62 -37
- package/src/editable-artifacts/index.ts +6 -0
- package/src/editable-artifacts/open-failure.ts +79 -0
- package/src/editable-artifacts/storage.ts +31 -40
- package/src/editable-artifacts/types.ts +6 -3
- package/src/editable-artifacts/worker/kernel-adapter.ts +23 -7
- package/src/editable-artifacts/worker/runtime.ts +26 -13
- package/src/editable-artifacts/worker/wire-codec.ts +23 -5
- package/src/embedding-client.ts +519 -0
- package/src/errors.ts +169 -2
- package/src/feedback.ts +20 -0
- package/src/gateway-realtime-transport.ts +3 -3
- package/src/github-repositories.ts +60 -0
- package/src/index.ts +561 -41
- package/src/interaction.ts +276 -4
- package/src/knowledge.ts +72 -0
- package/src/message-links.ts +178 -0
- package/src/model-context.ts +112 -0
- package/src/model-display.ts +10 -0
- package/src/model-picker-order.ts +6 -0
- package/src/organization-integration-policy.ts +54 -0
- package/src/organization-private-session-settings.ts +33 -0
- package/src/organization-user-setup.ts +31 -0
- package/src/pr-review-client.ts +92 -0
- package/src/pr-review.ts +17 -0
- package/src/preference-registry.ts +11 -0
- package/src/proxy.ts +17 -6
- package/src/realtime.ts +1 -0
- package/src/retained-artifacts.ts +101 -0
- package/src/session-history-import.ts +84 -0
- package/src/session-list-entries.ts +1 -0
- package/src/session-message-search.ts +47 -0
- package/src/session-proxy-client.ts +64 -0
- package/src/session-proxy.ts +1473 -0
- package/src/session-titles.ts +10 -0
- package/src/site-browser-entry.ts +6 -0
- package/src/site-browser-runtime.gen.ts +2 -0
- package/src/site-document.test.ts +64 -0
- package/src/site-document.ts +18 -0
- package/src/site-http.ts +162 -0
- package/src/site-tool-bridge.ts +146 -0
- package/src/site.ts +585 -0
- package/src/skills.ts +69 -0
- package/src/sse.ts +8 -2
- package/src/stream.ts +38 -4
- package/src/tenant-workspaces.ts +148 -0
- package/src/tool-auth.ts +301 -0
- package/src/tool-display-metadata.ts +19 -0
- package/src/tools.ts +396 -0
- package/src/types.ts +3346 -501
- package/src/usage-allowances.ts +189 -0
- package/src/workspace-artifacts.ts +40 -6
- package/src/workspace-instruction-policies.ts +26 -1
- package/src/workspace-integrations.ts +402 -0
- package/src/workspace-learning.ts +138 -0
- package/src/workspace-state.ts +8 -82
- package/dist/chunk-GU6JF75T.js +0 -119
- package/dist/chunk-GU6JF75T.js.map +0 -1
- package/dist/chunk-HJ3HHUT5.js.map +0 -1
- package/dist/chunk-JDLDDRNE.js.map +0 -1
- package/dist/chunk-JRPFWI6T.js.map +0 -1
- package/dist/chunk-PKQ377ED.js.map +0 -1
- package/dist/chunk-ST5DDKJP.js.map +0 -1
- package/dist/chunk-VWE2QIVO.js.map +0 -1
|
@@ -2,16 +2,24 @@ import {
|
|
|
2
2
|
decodeEditableArtifactMutationIntent,
|
|
3
3
|
EDITABLE_ARTIFACT_COMMAND_MAX_BYTES,
|
|
4
4
|
EDITABLE_ARTIFACT_INTENT_MAX_BYTES,
|
|
5
|
+
EDITABLE_ARTIFACT_INTENT_PROTOCOL_VERSION,
|
|
5
6
|
EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES,
|
|
6
7
|
hashEditableArtifactMutationIntentBytes,
|
|
7
8
|
} from "@opengeni/contracts/editable-artifacts";
|
|
8
9
|
import {
|
|
10
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
9
11
|
decodeCommittedTransactionSummary,
|
|
10
12
|
MAX_COMMITTED_TRANSACTION_BYTES,
|
|
11
13
|
} from "@opengeni/contracts/editable-artifact-committed-transaction";
|
|
12
14
|
import { editableArtifactCodecFor } from "@opengeni/contracts/editable-artifact-codec-registry";
|
|
15
|
+
import { EDITABLE_ARTIFACT_LIVE_WIRE_VERSION } from "@opengeni/contracts/editable-artifact-live";
|
|
13
16
|
import { decodeEditableArtifactSerializedCommit } from "@opengeni/contracts/editable-artifact-serialized-commit";
|
|
17
|
+
import { SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION } from "@opengeni/contracts/editable-artifact-versions";
|
|
14
18
|
import { EditableArtifactSyncError } from "./errors";
|
|
19
|
+
import {
|
|
20
|
+
classifyEditableArtifactOpenFailure,
|
|
21
|
+
type EditableArtifactOpenFailureReporter,
|
|
22
|
+
} from "./open-failure";
|
|
15
23
|
import { EditableArtifactStorageConflictError } from "./storage";
|
|
16
24
|
import type { EditableArtifactStoragePort, EditableArtifactStorageScope } from "./storage";
|
|
17
25
|
import type {
|
|
@@ -42,7 +50,6 @@ import type {
|
|
|
42
50
|
EditableArtifactWorkerKernel,
|
|
43
51
|
} from "./types";
|
|
44
52
|
|
|
45
|
-
const DEFAULT_PROTOCOL_VERSION = 1;
|
|
46
53
|
const DEFAULT_REPLAY_PAGE_SIZE = 256;
|
|
47
54
|
const DEFAULT_MAX_QUEUE_MESSAGES = 512;
|
|
48
55
|
const DEFAULT_MAX_QUEUE_BYTES = 8 * 1024 * 1024;
|
|
@@ -70,7 +77,7 @@ export type CreateEditableArtifactSyncControllerOptions = {
|
|
|
70
77
|
kernelVersion: string;
|
|
71
78
|
modelSchemaVersion: number;
|
|
72
79
|
commandVersion: number;
|
|
73
|
-
protocolVersion
|
|
80
|
+
protocolVersion: number;
|
|
74
81
|
replayPageSize?: number;
|
|
75
82
|
maxQueuedMessages?: number;
|
|
76
83
|
maxQueuedBytes?: number;
|
|
@@ -87,6 +94,8 @@ export type CreateEditableArtifactSyncControllerOptions = {
|
|
|
87
94
|
maxReconnectAttempts?: number;
|
|
88
95
|
scheduler?: EditableArtifactSyncScheduler;
|
|
89
96
|
clientTransactionIdFactory?: () => string;
|
|
97
|
+
/** Receives bounded categories/codes only; never workbook or formula content. */
|
|
98
|
+
onOpenFailure?: EditableArtifactOpenFailureReporter;
|
|
90
99
|
/** Tests/embedded runtimes may inject; defaults to a fresh per-controller UUID. */
|
|
91
100
|
writerReplicaIdFactory?: () => string;
|
|
92
101
|
};
|
|
@@ -186,6 +195,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
186
195
|
private readonly maxReconnectAttempts: number;
|
|
187
196
|
private readonly scheduler: EditableArtifactSyncScheduler;
|
|
188
197
|
private readonly clientTransactionIdFactory: () => string;
|
|
198
|
+
private readonly onOpenFailure: EditableArtifactOpenFailureReporter | undefined;
|
|
189
199
|
|
|
190
200
|
private readonly abortController = new AbortController();
|
|
191
201
|
private readonly listeners = new Set<EditableArtifactSyncListener>();
|
|
@@ -258,10 +268,10 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
258
268
|
);
|
|
259
269
|
this.modelSchemaVersion = positiveSafeInteger(options.modelSchemaVersion, "modelSchemaVersion");
|
|
260
270
|
this.commandVersion = positiveSafeInteger(options.commandVersion, "commandVersion");
|
|
261
|
-
this.protocolVersion = positiveSafeInteger(
|
|
262
|
-
|
|
263
|
-
"protocolVersion"
|
|
264
|
-
|
|
271
|
+
this.protocolVersion = positiveSafeInteger(options.protocolVersion, "protocolVersion");
|
|
272
|
+
if (this.protocolVersion !== EDITABLE_ARTIFACT_INTENT_PROTOCOL_VERSION) {
|
|
273
|
+
throw new TypeError("protocolVersion is incompatible with the current intent protocol");
|
|
274
|
+
}
|
|
265
275
|
this.replayPageSize = positiveSafeInteger(
|
|
266
276
|
options.replayPageSize ?? DEFAULT_REPLAY_PAGE_SIZE,
|
|
267
277
|
"replayPageSize",
|
|
@@ -324,6 +334,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
324
334
|
this.scheduler = options.scheduler ?? defaultScheduler;
|
|
325
335
|
this.clientTransactionIdFactory =
|
|
326
336
|
options.clientTransactionIdFactory ?? (() => crypto.randomUUID());
|
|
337
|
+
this.onOpenFailure = options.onOpenFailure;
|
|
327
338
|
}
|
|
328
339
|
|
|
329
340
|
start(): void {
|
|
@@ -331,6 +342,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
331
342
|
this.runTask = this.run().catch((error: unknown) => {
|
|
332
343
|
if (this.abortController.signal.aborted) return;
|
|
333
344
|
const failure = asError(error);
|
|
345
|
+
this.reportOpenFailure(failure);
|
|
334
346
|
if (failure instanceof EditableArtifactSyncError && failure.code === "unsupported_protocol") {
|
|
335
347
|
this.lastError = failure;
|
|
336
348
|
this.setState("unsupported");
|
|
@@ -366,6 +378,15 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
366
378
|
}
|
|
367
379
|
|
|
368
380
|
getView(): EditableArtifactSyncView {
|
|
381
|
+
const blockedPending = this.allBlockedPending();
|
|
382
|
+
const authoringBlockedReason =
|
|
383
|
+
this.modality !== "spreadsheet" && blockedPending.length > 0
|
|
384
|
+
? "pending_conflict"
|
|
385
|
+
: this.orderedPending().some(
|
|
386
|
+
(transaction) => transaction.replicaId !== this.writerReplicaId,
|
|
387
|
+
)
|
|
388
|
+
? "prior_writer"
|
|
389
|
+
: undefined;
|
|
369
390
|
return {
|
|
370
391
|
artifactId: this.artifactId,
|
|
371
392
|
modality: this.modality,
|
|
@@ -374,7 +395,8 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
374
395
|
headSequence: this.headSequence,
|
|
375
396
|
writable: this.writable,
|
|
376
397
|
pendingTransactions: this.pending.size,
|
|
377
|
-
blockedPending
|
|
398
|
+
blockedPending,
|
|
399
|
+
authoringBlockedReason,
|
|
378
400
|
queuedMessages: this.liveQueue.length,
|
|
379
401
|
reconnectAttempt: this.reconnectAttempt,
|
|
380
402
|
lastError: this.lastError,
|
|
@@ -664,7 +686,8 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
664
686
|
try {
|
|
665
687
|
await this.restoreReplica(stored);
|
|
666
688
|
await this.replacePendingOverlay();
|
|
667
|
-
} catch {
|
|
689
|
+
} catch (error) {
|
|
690
|
+
this.reportOpenFailure(error);
|
|
668
691
|
await this.kernel.reset();
|
|
669
692
|
this.replica = null;
|
|
670
693
|
this.retainedTailTransactions = 0;
|
|
@@ -680,8 +703,8 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
680
703
|
stored.snapshot,
|
|
681
704
|
this.artifactId,
|
|
682
705
|
this.modality,
|
|
683
|
-
|
|
684
|
-
|
|
706
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
707
|
+
SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
|
|
685
708
|
this.modelSchemaVersion,
|
|
686
709
|
this.maxSnapshotBytes,
|
|
687
710
|
);
|
|
@@ -701,12 +724,19 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
701
724
|
stored.snapshot.modality === "spreadsheet" ? stored.snapshot.causalFrontier : null;
|
|
702
725
|
let nativeRevision =
|
|
703
726
|
stored.snapshot.modality === "spreadsheet" ? null : stored.snapshot.nativeRevision;
|
|
727
|
+
const retainedAcceptances: {
|
|
728
|
+
transaction: EditableArtifactCommittedTransaction;
|
|
729
|
+
pending: Pick<
|
|
730
|
+
EditableArtifactPendingTransaction,
|
|
731
|
+
"clientTransactionId" | "requestHash" | "intentBytes"
|
|
732
|
+
>;
|
|
733
|
+
}[] = [];
|
|
704
734
|
for (const transaction of stored.tail) {
|
|
705
|
-
validateCommittedTransaction(
|
|
735
|
+
const embeddedPending = validateCommittedTransaction(
|
|
706
736
|
transaction,
|
|
707
737
|
this.artifactId,
|
|
708
738
|
this.modality,
|
|
709
|
-
|
|
739
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
710
740
|
this.maxCommittedTransactionBytes,
|
|
711
741
|
);
|
|
712
742
|
if (transaction.startSequence !== cursor + 1) {
|
|
@@ -715,6 +745,15 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
715
745
|
requireStateHash(transaction.priorStateHash, stateHash, "retained transaction prior state");
|
|
716
746
|
const applied = await this.kernel.applyRecovered(transaction);
|
|
717
747
|
requireStateHash(applied.stateHash, transaction.stateHash, "retained transaction");
|
|
748
|
+
if (embeddedPending) {
|
|
749
|
+
const pending = this.pending.get(embeddedPending.clientTransactionId);
|
|
750
|
+
if (
|
|
751
|
+
pending?.requestHash === embeddedPending.requestHash &&
|
|
752
|
+
bytesEqual(pending.intentBytes, embeddedPending.intentBytes)
|
|
753
|
+
) {
|
|
754
|
+
retainedAcceptances.push({ transaction, pending: embeddedPending });
|
|
755
|
+
}
|
|
756
|
+
}
|
|
718
757
|
cursor = transaction.endSequence;
|
|
719
758
|
stateHash = transaction.stateHash;
|
|
720
759
|
if (transaction.modality === "spreadsheet") {
|
|
@@ -750,6 +789,14 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
750
789
|
this.retainedTailTransactions = stored.tail.length;
|
|
751
790
|
this.cursor = cursor;
|
|
752
791
|
this.headSequence = cursor;
|
|
792
|
+
// Reload may interrupt between retaining a commit and deleting its WAL entry.
|
|
793
|
+
// Only settle exact embedded identities after the entire retained head verifies;
|
|
794
|
+
// otherwise speculative replay mistakes our own committed edit for a conflict.
|
|
795
|
+
// Callers restore the pending overlay after this confirmed projection is ready.
|
|
796
|
+
for (const { transaction, pending } of retainedAcceptances) {
|
|
797
|
+
this.recordAcceptedMappingIdentity(transaction.transactionId, pending);
|
|
798
|
+
await this.settlePending(transaction, true);
|
|
799
|
+
}
|
|
753
800
|
}
|
|
754
801
|
|
|
755
802
|
private async run(): Promise<void> {
|
|
@@ -776,6 +823,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
776
823
|
delayMs = this.reconnectDelayMs;
|
|
777
824
|
}
|
|
778
825
|
const failure = asError(error);
|
|
826
|
+
this.reportOpenFailure(failure);
|
|
779
827
|
this.lastError = failure;
|
|
780
828
|
if (failure instanceof EditableArtifactSyncError && failure.requiresSnapshot) {
|
|
781
829
|
this.requireSnapshot = true;
|
|
@@ -956,14 +1004,11 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
956
1004
|
if (bootstrap.modality !== this.modality) {
|
|
957
1005
|
throw invalidBootstrap("bootstrap modality does not match the controller");
|
|
958
1006
|
}
|
|
959
|
-
this.
|
|
960
|
-
if (
|
|
961
|
-
bootstrap.kernelVersion !== this.kernelVersion ||
|
|
962
|
-
bootstrap.modelSchemaVersion !== this.modelSchemaVersion
|
|
963
|
-
) {
|
|
1007
|
+
this.requireLiveProtocol(bootstrap.liveProtocolVersion);
|
|
1008
|
+
if (bootstrap.modelSchemaVersion !== this.modelSchemaVersion) {
|
|
964
1009
|
throw new EditableArtifactSyncError(
|
|
965
1010
|
"unsupported_protocol",
|
|
966
|
-
`artifact
|
|
1011
|
+
`artifact schema ${bootstrap.modelSchemaVersion} is incompatible with ${this.modelSchemaVersion}`,
|
|
967
1012
|
);
|
|
968
1013
|
}
|
|
969
1014
|
requireSha256(bootstrap.headStateHash, "bootstrap.headStateHash");
|
|
@@ -1035,8 +1080,8 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1035
1080
|
snapshot,
|
|
1036
1081
|
this.artifactId,
|
|
1037
1082
|
this.modality,
|
|
1038
|
-
|
|
1039
|
-
|
|
1083
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
1084
|
+
SPREADSHEET_COLLABORATION_SNAPSHOT_VERSION,
|
|
1040
1085
|
this.modelSchemaVersion,
|
|
1041
1086
|
this.maxSnapshotBytes,
|
|
1042
1087
|
);
|
|
@@ -1136,7 +1181,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1136
1181
|
transaction,
|
|
1137
1182
|
this.artifactId,
|
|
1138
1183
|
this.modality,
|
|
1139
|
-
|
|
1184
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
1140
1185
|
this.maxCommittedTransactionBytes,
|
|
1141
1186
|
);
|
|
1142
1187
|
pageBytes += estimateCommittedTransactionBytes(transaction);
|
|
@@ -1167,7 +1212,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1167
1212
|
message,
|
|
1168
1213
|
this.artifactId,
|
|
1169
1214
|
this.modality,
|
|
1170
|
-
|
|
1215
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
1171
1216
|
this.maxCommittedTransactionBytes,
|
|
1172
1217
|
);
|
|
1173
1218
|
bytes = estimateLiveMessageBytes(message);
|
|
@@ -1271,7 +1316,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1271
1316
|
transaction,
|
|
1272
1317
|
this.artifactId,
|
|
1273
1318
|
this.modality,
|
|
1274
|
-
|
|
1319
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
1275
1320
|
this.maxCommittedTransactionBytes,
|
|
1276
1321
|
);
|
|
1277
1322
|
if (embeddedPending) {
|
|
@@ -1568,7 +1613,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1568
1613
|
receipt.committed,
|
|
1569
1614
|
this.artifactId,
|
|
1570
1615
|
this.modality,
|
|
1571
|
-
|
|
1616
|
+
COMMITTED_TRANSACTION_PROTOCOL_VERSION,
|
|
1572
1617
|
this.maxCommittedTransactionBytes,
|
|
1573
1618
|
);
|
|
1574
1619
|
this.recordAcceptedMapping(receipt);
|
|
@@ -1641,7 +1686,7 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1641
1686
|
"sync ticket is not bound to the requested writer replica",
|
|
1642
1687
|
);
|
|
1643
1688
|
}
|
|
1644
|
-
this.
|
|
1689
|
+
this.requireLiveProtocol(ticket.protocolVersion);
|
|
1645
1690
|
boundedNonEmpty(ticket.token, "ticket.token", MAX_TICKET_BYTES);
|
|
1646
1691
|
const expiresAt = Date.parse(ticket.expiresAt);
|
|
1647
1692
|
if (!Number.isFinite(expiresAt)) {
|
|
@@ -1758,11 +1803,11 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1758
1803
|
);
|
|
1759
1804
|
}
|
|
1760
1805
|
|
|
1761
|
-
private
|
|
1762
|
-
if (actual !==
|
|
1806
|
+
private requireLiveProtocol(actual: number): void {
|
|
1807
|
+
if (actual !== EDITABLE_ARTIFACT_LIVE_WIRE_VERSION) {
|
|
1763
1808
|
throw new EditableArtifactSyncError(
|
|
1764
1809
|
"unsupported_protocol",
|
|
1765
|
-
`
|
|
1810
|
+
`live protocol ${actual} is incompatible with ${EDITABLE_ARTIFACT_LIVE_WIRE_VERSION}`,
|
|
1766
1811
|
);
|
|
1767
1812
|
}
|
|
1768
1813
|
}
|
|
@@ -1794,6 +1839,16 @@ class EditableArtifactSyncControllerImpl implements EditableArtifactSyncControll
|
|
|
1794
1839
|
this.liveWaiters.clear();
|
|
1795
1840
|
}
|
|
1796
1841
|
|
|
1842
|
+
private reportOpenFailure(error: unknown): void {
|
|
1843
|
+
const event = classifyEditableArtifactOpenFailure(error);
|
|
1844
|
+
if (event === null || this.onOpenFailure === undefined) return;
|
|
1845
|
+
try {
|
|
1846
|
+
this.onOpenFailure(event);
|
|
1847
|
+
} catch {
|
|
1848
|
+
// Observability must never change recovery or availability behavior.
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1797
1852
|
private fail(error: Error): void {
|
|
1798
1853
|
this.lastError = error;
|
|
1799
1854
|
this.setState("failed");
|
|
@@ -1971,7 +2026,7 @@ function validateCommittedTransaction(
|
|
|
1971
2026
|
transaction: EditableArtifactCommittedTransaction,
|
|
1972
2027
|
artifactId: EditableArtifactId,
|
|
1973
2028
|
modality: EditableArtifactModality,
|
|
1974
|
-
|
|
2029
|
+
operationProtocolVersion: number,
|
|
1975
2030
|
maxCommittedTransactionBytes: number,
|
|
1976
2031
|
): Readonly<{
|
|
1977
2032
|
clientTransactionId: string;
|
|
@@ -2000,10 +2055,10 @@ function validateCommittedTransaction(
|
|
|
2000
2055
|
throw invalidSequence("transaction committedTransactionBytes exceeds the configured bound");
|
|
2001
2056
|
}
|
|
2002
2057
|
if (transaction.modality === "spreadsheet") {
|
|
2003
|
-
if (transaction.
|
|
2058
|
+
if (transaction.operationProtocolVersion !== operationProtocolVersion) {
|
|
2004
2059
|
throw new EditableArtifactSyncError(
|
|
2005
2060
|
"unsupported_protocol",
|
|
2006
|
-
`transaction protocol ${transaction.
|
|
2061
|
+
`transaction operation protocol ${transaction.operationProtocolVersion} is incompatible with ${operationProtocolVersion}`,
|
|
2007
2062
|
);
|
|
2008
2063
|
}
|
|
2009
2064
|
validateFrontier(transaction.causalFrontier, "causalFrontier");
|
|
@@ -2015,7 +2070,7 @@ function validateCommittedTransaction(
|
|
|
2015
2070
|
}
|
|
2016
2071
|
if (
|
|
2017
2072
|
summary.transactionId !== transaction.transactionId ||
|
|
2018
|
-
summary.operationProtocolVersion !== transaction.
|
|
2073
|
+
summary.operationProtocolVersion !== transaction.operationProtocolVersion ||
|
|
2019
2074
|
summary.priorStateHash !== transaction.priorStateHash ||
|
|
2020
2075
|
summary.stateHash !== transaction.stateHash ||
|
|
2021
2076
|
!frontiersEqual(summary.resultingCausalFrontier, transaction.causalFrontier)
|
|
@@ -2061,8 +2116,8 @@ function validateSnapshot(
|
|
|
2061
2116
|
snapshot: EditableArtifactStoredReplica["snapshot"],
|
|
2062
2117
|
artifactId: EditableArtifactId,
|
|
2063
2118
|
modality: EditableArtifactModality,
|
|
2064
|
-
|
|
2065
|
-
|
|
2119
|
+
operationProtocolVersion: number,
|
|
2120
|
+
snapshotVersion: number,
|
|
2066
2121
|
modelSchemaVersion: number,
|
|
2067
2122
|
maxSnapshotBytes: number,
|
|
2068
2123
|
): void {
|
|
@@ -2076,22 +2131,22 @@ function validateSnapshot(
|
|
|
2076
2131
|
positiveSafeInteger(snapshot.modelSchemaVersion, "snapshot.modelSchemaVersion");
|
|
2077
2132
|
if (snapshot.modality === "spreadsheet") {
|
|
2078
2133
|
validateFrontier(snapshot.causalFrontier, "snapshot.causalFrontier");
|
|
2079
|
-
if (
|
|
2134
|
+
if (
|
|
2135
|
+
snapshot.operationProtocolVersion !== operationProtocolVersion ||
|
|
2136
|
+
snapshot.snapshotVersion !== snapshotVersion
|
|
2137
|
+
) {
|
|
2080
2138
|
throw new EditableArtifactSyncError(
|
|
2081
2139
|
"unsupported_protocol",
|
|
2082
|
-
`snapshot
|
|
2140
|
+
`snapshot operation/state versions ${snapshot.operationProtocolVersion}/${snapshot.snapshotVersion} are incompatible with ${operationProtocolVersion}/${snapshotVersion}`,
|
|
2083
2141
|
);
|
|
2084
2142
|
}
|
|
2085
2143
|
} else {
|
|
2086
2144
|
requireNativeRevision(snapshot.nativeRevision, "snapshot.nativeRevision");
|
|
2087
2145
|
}
|
|
2088
|
-
if (
|
|
2089
|
-
snapshot.kernelVersion !== kernelVersion ||
|
|
2090
|
-
snapshot.modelSchemaVersion !== modelSchemaVersion
|
|
2091
|
-
) {
|
|
2146
|
+
if (snapshot.modelSchemaVersion !== modelSchemaVersion) {
|
|
2092
2147
|
throw new EditableArtifactSyncError(
|
|
2093
2148
|
"unsupported_protocol",
|
|
2094
|
-
`snapshot
|
|
2149
|
+
`snapshot schema ${snapshot.modelSchemaVersion} is incompatible with ${modelSchemaVersion}`,
|
|
2095
2150
|
);
|
|
2096
2151
|
}
|
|
2097
2152
|
if (!(snapshot.bytes instanceof Uint8Array)) {
|
|
@@ -2131,7 +2186,7 @@ function validateLiveMessage(
|
|
|
2131
2186
|
message: EditableArtifactLiveMessage,
|
|
2132
2187
|
artifactId: EditableArtifactId,
|
|
2133
2188
|
modality: EditableArtifactModality,
|
|
2134
|
-
|
|
2189
|
+
operationProtocolVersion: number,
|
|
2135
2190
|
maxCommittedTransactionBytes: number,
|
|
2136
2191
|
): void {
|
|
2137
2192
|
if (!message || typeof message !== "object") {
|
|
@@ -2142,7 +2197,7 @@ function validateLiveMessage(
|
|
|
2142
2197
|
message.transaction,
|
|
2143
2198
|
artifactId,
|
|
2144
2199
|
modality,
|
|
2145
|
-
|
|
2200
|
+
operationProtocolVersion,
|
|
2146
2201
|
maxCommittedTransactionBytes,
|
|
2147
2202
|
);
|
|
2148
2203
|
return;
|
|
@@ -2198,7 +2253,7 @@ function estimateCommittedTransactionBytes(
|
|
|
2198
2253
|
function requireStateHash(actual: string, expected: string, source: string): void {
|
|
2199
2254
|
if (actual !== expected) {
|
|
2200
2255
|
throw new EditableArtifactSyncError(
|
|
2201
|
-
"
|
|
2256
|
+
"authored_causal_mismatch",
|
|
2202
2257
|
`${source} produced state hash ${actual}; expected ${expected}`,
|
|
2203
2258
|
{ retryable: true, requiresSnapshot: true },
|
|
2204
2259
|
);
|
|
@@ -2209,7 +2264,7 @@ function requireDigest(actual: string, expected: string, source: string): void {
|
|
|
2209
2264
|
requireSha256(actual, `${source} computed digest`);
|
|
2210
2265
|
if (actual !== expected) {
|
|
2211
2266
|
throw new EditableArtifactSyncError(
|
|
2212
|
-
"
|
|
2267
|
+
"byte_corruption",
|
|
2213
2268
|
`${source} bytes produced digest ${actual}; expected ${expected}`,
|
|
2214
2269
|
{ retryable: true, requiresSnapshot: true },
|
|
2215
2270
|
);
|
|
@@ -2230,7 +2285,7 @@ function requireFrontier(
|
|
|
2230
2285
|
)
|
|
2231
2286
|
) {
|
|
2232
2287
|
throw new EditableArtifactSyncError(
|
|
2233
|
-
"
|
|
2288
|
+
"authored_causal_mismatch",
|
|
2234
2289
|
`${source} causal frontier does not match the authoritative barrier`,
|
|
2235
2290
|
{ retryable: true, requiresSnapshot: true },
|
|
2236
2291
|
);
|
|
@@ -2416,7 +2471,7 @@ function requireNativeRevisionEqual(actual: number, expected: number, source: st
|
|
|
2416
2471
|
requireNativeRevision(expected, `${source} expected native revision`);
|
|
2417
2472
|
if (actual !== expected) {
|
|
2418
2473
|
throw new EditableArtifactSyncError(
|
|
2419
|
-
"
|
|
2474
|
+
"authored_causal_mismatch",
|
|
2420
2475
|
`${source} native revision ${actual} does not match ${expected}`,
|
|
2421
2476
|
{ retryable: true, requiresSnapshot: true },
|
|
2422
2477
|
);
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
EDITABLE_ARTIFACT_COMMAND_MAX_BYTES,
|
|
12
12
|
EDITABLE_ARTIFACT_INTENT_MAX_BYTES,
|
|
13
13
|
EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES,
|
|
14
|
+
currentEditableArtifactCompatibility,
|
|
14
15
|
hashEditableArtifactMutationIntentBytes,
|
|
15
16
|
} from "@opengeni/contracts/editable-artifacts";
|
|
16
17
|
import { MAX_COMMITTED_TRANSACTION_BYTES } from "@opengeni/contracts/editable-artifact-committed-transaction";
|
|
@@ -34,7 +35,7 @@ import type {
|
|
|
34
35
|
} from "./types";
|
|
35
36
|
|
|
36
37
|
const LIVE_PATH = "/v1/editable-artifacts/live";
|
|
37
|
-
const LIVE_SUBPROTOCOL = "opengeni-artifact-
|
|
38
|
+
const LIVE_SUBPROTOCOL = "opengeni-artifact-v2";
|
|
38
39
|
const DEFAULT_MAX_SERVER_FRAME_BYTES = 8 * 1024 * 1024 + 64 * 1024;
|
|
39
40
|
const DEFAULT_MAX_SNAPSHOT_BYTES = EDITABLE_ARTIFACT_PRODUCT_MAX_SNAPSHOT_BYTES;
|
|
40
41
|
const DEFAULT_HANDSHAKE_TIMEOUT_MS = 20_000;
|
|
@@ -81,9 +82,13 @@ export type EditableArtifactWebSocketLike = {
|
|
|
81
82
|
export type CreateEditableArtifactHttpLiveTransportOptions = Readonly<{
|
|
82
83
|
baseUrl: string | URL;
|
|
83
84
|
workspaceId: string;
|
|
84
|
-
|
|
85
|
+
modality: EditableArtifactModality;
|
|
86
|
+
liveProtocolVersion: number;
|
|
85
87
|
kernelVersion: string;
|
|
86
88
|
modelSchemaVersion: number;
|
|
89
|
+
snapshotVersion: number;
|
|
90
|
+
commandProtocolVersion: number;
|
|
91
|
+
committedTransactionProtocolVersion: number;
|
|
87
92
|
apiKey?: string;
|
|
88
93
|
headers?: Readonly<Record<string, string>> | (() => Readonly<Record<string, string>>);
|
|
89
94
|
credentials?: RequestCredentials;
|
|
@@ -111,9 +116,13 @@ class HttpLiveTransport implements EditableArtifactSyncTransport {
|
|
|
111
116
|
private readonly baseUrl: URL;
|
|
112
117
|
private readonly socketUrl: URL;
|
|
113
118
|
private readonly workspaceId: string;
|
|
114
|
-
private readonly
|
|
119
|
+
private readonly modality: EditableArtifactModality;
|
|
120
|
+
private readonly liveProtocolVersion: number;
|
|
115
121
|
private readonly kernelVersion: string;
|
|
116
122
|
private readonly modelSchemaVersion: number;
|
|
123
|
+
private readonly snapshotVersion: number;
|
|
124
|
+
private readonly commandProtocolVersion: number;
|
|
125
|
+
private readonly committedTransactionProtocolVersion: number;
|
|
117
126
|
private readonly apiKey: string | undefined;
|
|
118
127
|
private readonly headerSource: CreateEditableArtifactHttpLiveTransportOptions["headers"];
|
|
119
128
|
private readonly credentials: RequestCredentials;
|
|
@@ -132,9 +141,34 @@ class HttpLiveTransport implements EditableArtifactSyncTransport {
|
|
|
132
141
|
const insecure = options.allowInsecureDevelopmentTransport ?? false;
|
|
133
142
|
requireTransportSecurity(this.baseUrl, this.socketUrl, insecure);
|
|
134
143
|
this.workspaceId = boundedString(options.workspaceId, "workspaceId", 256);
|
|
135
|
-
|
|
144
|
+
const current = currentEditableArtifactCompatibility(options.modality);
|
|
145
|
+
this.modality = options.modality;
|
|
146
|
+
this.liveProtocolVersion = exactVersion(
|
|
147
|
+
options.liveProtocolVersion,
|
|
148
|
+
current.liveProtocolVersion,
|
|
149
|
+
"liveProtocolVersion",
|
|
150
|
+
);
|
|
136
151
|
this.kernelVersion = boundedString(options.kernelVersion, "kernelVersion", 512);
|
|
137
|
-
this.modelSchemaVersion =
|
|
152
|
+
this.modelSchemaVersion = exactVersion(
|
|
153
|
+
options.modelSchemaVersion,
|
|
154
|
+
current.modelSchemaVersion,
|
|
155
|
+
"modelSchemaVersion",
|
|
156
|
+
);
|
|
157
|
+
this.snapshotVersion = exactVersion(
|
|
158
|
+
options.snapshotVersion,
|
|
159
|
+
current.snapshotVersion,
|
|
160
|
+
"snapshotVersion",
|
|
161
|
+
);
|
|
162
|
+
this.commandProtocolVersion = exactVersion(
|
|
163
|
+
options.commandProtocolVersion,
|
|
164
|
+
current.commandProtocolVersion,
|
|
165
|
+
"commandProtocolVersion",
|
|
166
|
+
);
|
|
167
|
+
this.committedTransactionProtocolVersion = exactVersion(
|
|
168
|
+
options.committedTransactionProtocolVersion,
|
|
169
|
+
current.committedTransactionProtocolVersion,
|
|
170
|
+
"committedTransactionProtocolVersion",
|
|
171
|
+
);
|
|
138
172
|
this.apiKey = options.apiKey;
|
|
139
173
|
if (this.apiKey !== undefined) boundedString(this.apiKey, "apiKey", 16 * 1024);
|
|
140
174
|
this.headerSource = options.headers;
|
|
@@ -187,9 +221,13 @@ class HttpLiveTransport implements EditableArtifactSyncTransport {
|
|
|
187
221
|
},
|
|
188
222
|
body: JSON.stringify({
|
|
189
223
|
replicaId: input.replicaId,
|
|
190
|
-
|
|
224
|
+
modality: this.modality,
|
|
225
|
+
liveProtocolVersion: this.liveProtocolVersion,
|
|
191
226
|
kernelVersion: this.kernelVersion,
|
|
192
227
|
modelSchemaVersion: this.modelSchemaVersion,
|
|
228
|
+
snapshotVersion: this.snapshotVersion,
|
|
229
|
+
commandProtocolVersion: this.commandProtocolVersion,
|
|
230
|
+
committedTransactionProtocolVersion: this.committedTransactionProtocolVersion,
|
|
193
231
|
}),
|
|
194
232
|
signal: input.signal,
|
|
195
233
|
});
|
|
@@ -211,7 +249,7 @@ class HttpLiveTransport implements EditableArtifactSyncTransport {
|
|
|
211
249
|
);
|
|
212
250
|
}
|
|
213
251
|
const value = await readBoundedJson(response, MAX_TICKET_RESPONSE_BYTES);
|
|
214
|
-
return validateTicket(value, input.artifactId, input.replicaId, this.
|
|
252
|
+
return validateTicket(value, input.artifactId, input.replicaId, this.liveProtocolVersion);
|
|
215
253
|
}
|
|
216
254
|
|
|
217
255
|
async openLive(input: {
|
|
@@ -246,6 +284,7 @@ class HttpLiveTransport implements EditableArtifactSyncTransport {
|
|
|
246
284
|
input.resume.modality === "spreadsheet"
|
|
247
285
|
? {
|
|
248
286
|
...commonResume,
|
|
287
|
+
modality: "spreadsheet",
|
|
249
288
|
localCausalFrontier: cloneFrontier(input.resume.causalFrontier),
|
|
250
289
|
}
|
|
251
290
|
: {
|
|
@@ -458,7 +497,7 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
458
497
|
}
|
|
459
498
|
const commonBootstrap = {
|
|
460
499
|
artifactId: this.ticket.artifactId,
|
|
461
|
-
|
|
500
|
+
liveProtocolVersion: this.ticket.protocolVersion,
|
|
462
501
|
headSequence: boundarySequence,
|
|
463
502
|
headStateHash: boundaryStateHash,
|
|
464
503
|
kernelVersion: snapshot?.kernelVersion ?? this.kernelVersion,
|
|
@@ -549,12 +588,6 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
549
588
|
if (pending.artifactId !== this.ticket.artifactId) {
|
|
550
589
|
throw new TypeError("pending transaction belongs to another artifact");
|
|
551
590
|
}
|
|
552
|
-
if (pending.protocolVersion !== this.ticket.protocolVersion) {
|
|
553
|
-
throw new EditableArtifactTransportError("pending protocol does not match live stream", {
|
|
554
|
-
code: "unsupported",
|
|
555
|
-
retryable: false,
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
591
|
if (
|
|
559
592
|
pending.commandBytes.byteLength >
|
|
560
593
|
Math.min(open.maxCommandBytes, EDITABLE_ARTIFACT_COMMAND_MAX_BYTES)
|
|
@@ -581,7 +614,7 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
581
614
|
}
|
|
582
615
|
const frame = encodeEditableArtifactLiveMutationWireFrame({
|
|
583
616
|
type: "mutation",
|
|
584
|
-
protocolVersion:
|
|
617
|
+
protocolVersion: this.ticket.protocolVersion,
|
|
585
618
|
artifactId: pending.artifactId,
|
|
586
619
|
streamEpoch: open.streamEpoch,
|
|
587
620
|
requestHash: pending.requestHash,
|
|
@@ -756,15 +789,9 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
756
789
|
if (frame.transaction.artifactId !== this.ticket.artifactId) {
|
|
757
790
|
throw new TypeError("live transaction belongs to another artifact");
|
|
758
791
|
}
|
|
759
|
-
if (
|
|
792
|
+
if (frame.transaction.modality !== this.ticket.modality) {
|
|
760
793
|
throw new TypeError("live transaction modality mismatch");
|
|
761
794
|
}
|
|
762
|
-
if (
|
|
763
|
-
(frame.transaction.modality === undefined ||
|
|
764
|
-
frame.transaction.modality === "spreadsheet") &&
|
|
765
|
-
frame.transaction.protocolVersion !== this.ticket.protocolVersion
|
|
766
|
-
)
|
|
767
|
-
throw new TypeError("live transaction protocol mismatch");
|
|
768
795
|
if (
|
|
769
796
|
frame.transaction.committedTransactionBytes.byteLength >
|
|
770
797
|
this.limits.maxCommittedTransactionBytes
|
|
@@ -849,7 +876,7 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
849
876
|
if (frame.protocolVersion !== this.ticket.protocolVersion) {
|
|
850
877
|
throw new TypeError("live snapshot protocol mismatch");
|
|
851
878
|
}
|
|
852
|
-
if (
|
|
879
|
+
if (frame.modality !== this.ticket.modality) {
|
|
853
880
|
throw new TypeError("live snapshot modality mismatch");
|
|
854
881
|
}
|
|
855
882
|
if (this.snapshotAssembly === null) {
|
|
@@ -895,7 +922,8 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
895
922
|
...commonSnapshot,
|
|
896
923
|
modality: "spreadsheet" as const,
|
|
897
924
|
causalFrontier: cloneFrontier(frame.causalFrontier),
|
|
898
|
-
|
|
925
|
+
operationProtocolVersion: frame.operationProtocolVersion,
|
|
926
|
+
snapshotVersion: frame.snapshotVersion,
|
|
899
927
|
})
|
|
900
928
|
: Object.freeze({
|
|
901
929
|
...commonSnapshot,
|
|
@@ -968,7 +996,7 @@ class HttpLiveConnection implements EditableArtifactLiveConnection {
|
|
|
968
996
|
if (frame.protocolVersion !== this.ticket.protocolVersion) {
|
|
969
997
|
throw new TypeError("live server frame protocol mismatch");
|
|
970
998
|
}
|
|
971
|
-
if (frame.type === "open" &&
|
|
999
|
+
if (frame.type === "open" && frame.modality !== this.ticket.modality) {
|
|
972
1000
|
throw new TypeError("live open modality does not match its ticket");
|
|
973
1001
|
}
|
|
974
1002
|
if (this.openFrame && frame.streamEpoch !== this.openFrame.streamEpoch) {
|
|
@@ -1113,16 +1141,6 @@ function cloneCommitted(
|
|
|
1113
1141
|
};
|
|
1114
1142
|
}
|
|
1115
1143
|
|
|
1116
|
-
function transactionModality(
|
|
1117
|
-
transaction: EditableArtifactCommittedTransaction | ContractCommittedTransaction,
|
|
1118
|
-
): EditableArtifactModality {
|
|
1119
|
-
return transaction.modality ?? "spreadsheet";
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
function serverModality(value: EditableArtifactModality | undefined): EditableArtifactModality {
|
|
1123
|
-
return value ?? "spreadsheet";
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
1144
|
function serializedBoundaryRevision(
|
|
1127
1145
|
snapshot: EditableArtifactSnapshot | null,
|
|
1128
1146
|
resume:
|
|
@@ -1148,8 +1166,7 @@ function snapshotChunkAuthorityEqual(
|
|
|
1148
1166
|
frame: Extract<EditableArtifactLiveServerFrame, { type: "snapshot" }>,
|
|
1149
1167
|
metadata: SnapshotAssembly["metadata"],
|
|
1150
1168
|
): boolean {
|
|
1151
|
-
|
|
1152
|
-
if (modality !== serverModality(metadata.modality)) return false;
|
|
1169
|
+
if (frame.modality !== metadata.modality) return false;
|
|
1153
1170
|
if ("causalFrontier" in frame) {
|
|
1154
1171
|
if (!("causalFrontier" in metadata)) return false;
|
|
1155
1172
|
return frontiersEqual(frame.causalFrontier, metadata.causalFrontier);
|
|
@@ -1414,6 +1431,14 @@ function positiveU16(value: unknown, label: string): number {
|
|
|
1414
1431
|
return number;
|
|
1415
1432
|
}
|
|
1416
1433
|
|
|
1434
|
+
function exactVersion(value: unknown, expected: number, label: string): number {
|
|
1435
|
+
const actual = positiveU16(value, label);
|
|
1436
|
+
if (actual !== expected) {
|
|
1437
|
+
throw new TypeError(`${label} ${actual} is incompatible with current version ${expected}`);
|
|
1438
|
+
}
|
|
1439
|
+
return actual;
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1417
1442
|
function positiveBounded(value: unknown, maximum: number, label: string): number {
|
|
1418
1443
|
if (!Number.isSafeInteger(value) || (value as number) <= 0 || (value as number) > maximum) {
|
|
1419
1444
|
throw new TypeError(`${label} is invalid`);
|
|
@@ -16,6 +16,12 @@ export type {
|
|
|
16
16
|
} from "./browser-session";
|
|
17
17
|
export { EditableArtifactSyncError, EditableArtifactTransportError } from "./errors";
|
|
18
18
|
export type { EditableArtifactSyncErrorCode } from "./errors";
|
|
19
|
+
export { classifyEditableArtifactOpenFailure } from "./open-failure";
|
|
20
|
+
export type {
|
|
21
|
+
EditableArtifactOpenFailureCategory,
|
|
22
|
+
EditableArtifactOpenFailureEvent,
|
|
23
|
+
EditableArtifactOpenFailureReporter,
|
|
24
|
+
} from "./open-failure";
|
|
19
25
|
export { createEditableArtifactHttpLiveTransport } from "./http-live-transport";
|
|
20
26
|
export type {
|
|
21
27
|
CreateEditableArtifactHttpLiveTransportOptions,
|