@superdoc-dev/cli 0.2.0-next.53 → 0.2.0-next.55
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/index.js +416 -89
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1210,7 +1210,7 @@ var init_operation_definitions = __esm(() => {
|
|
|
1210
1210
|
},
|
|
1211
1211
|
insert: {
|
|
1212
1212
|
memberPath: "insert",
|
|
1213
|
-
description: "Insert content at a target position. Supports text (default), markdown, and html content types via the `type` field.",
|
|
1213
|
+
description: "Insert content at a target position, or at the end of the document when target is omitted. Supports text (default), markdown, and html content types via the `type` field.",
|
|
1214
1214
|
expectedResult: "Returns a TextMutationReceipt with applied status; receipt reports NO_OP if the insertion point is invalid or content is empty.",
|
|
1215
1215
|
requiresDocumentContext: true,
|
|
1216
1216
|
metadata: mutationOperation({
|
|
@@ -1293,7 +1293,7 @@ var init_operation_definitions = __esm(() => {
|
|
|
1293
1293
|
...FORMAT_INLINE_ALIAS_OPERATION_DEFINITIONS,
|
|
1294
1294
|
"styles.apply": {
|
|
1295
1295
|
memberPath: "styles.apply",
|
|
1296
|
-
description: "Apply document-level default style changes to the stylesheet (word/styles.xml). Targets docDefaults run
|
|
1296
|
+
description: "Apply document-level default style changes to the stylesheet (word/styles.xml). Targets docDefaults run and paragraph channels with set-style patch semantics.",
|
|
1297
1297
|
expectedResult: "Returns a StylesApplyReceipt with per-channel success/failure details for each property change.",
|
|
1298
1298
|
requiresDocumentContext: true,
|
|
1299
1299
|
metadata: mutationOperation({
|
|
@@ -8292,6 +8292,16 @@ function normalizeSessionType(value) {
|
|
|
8292
8292
|
return "collab";
|
|
8293
8293
|
return "local";
|
|
8294
8294
|
}
|
|
8295
|
+
function normalizeUser(value) {
|
|
8296
|
+
const record = asRecord(value);
|
|
8297
|
+
if (!record)
|
|
8298
|
+
return;
|
|
8299
|
+
if (typeof record.name !== "string" || record.name.length === 0)
|
|
8300
|
+
return;
|
|
8301
|
+
if (typeof record.email !== "string")
|
|
8302
|
+
return;
|
|
8303
|
+
return { name: record.name, email: record.email };
|
|
8304
|
+
}
|
|
8295
8305
|
function normalizeCollaborationProfile(value) {
|
|
8296
8306
|
const record = asRecord(value);
|
|
8297
8307
|
if (!record)
|
|
@@ -8301,6 +8311,8 @@ function normalizeCollaborationProfile(value) {
|
|
|
8301
8311
|
const documentId = record.documentId;
|
|
8302
8312
|
const tokenEnv = record.tokenEnv;
|
|
8303
8313
|
const syncTimeoutMs = record.syncTimeoutMs;
|
|
8314
|
+
const onMissing = record.onMissing;
|
|
8315
|
+
const bootstrapSettlingMs = record.bootstrapSettlingMs;
|
|
8304
8316
|
if (providerType !== "hocuspocus" && providerType !== "y-websocket")
|
|
8305
8317
|
return;
|
|
8306
8318
|
if (typeof url !== "string" || url.length === 0)
|
|
@@ -8312,28 +8324,39 @@ function normalizeCollaborationProfile(value) {
|
|
|
8312
8324
|
if (syncTimeoutMs != null && (typeof syncTimeoutMs !== "number" || !Number.isFinite(syncTimeoutMs) || syncTimeoutMs <= 0)) {
|
|
8313
8325
|
return;
|
|
8314
8326
|
}
|
|
8327
|
+
if (onMissing != null && onMissing !== "seedFromDoc" && onMissing !== "blank" && onMissing !== "error") {
|
|
8328
|
+
return;
|
|
8329
|
+
}
|
|
8330
|
+
if (bootstrapSettlingMs != null && (typeof bootstrapSettlingMs !== "number" || !Number.isFinite(bootstrapSettlingMs) || bootstrapSettlingMs <= 0)) {
|
|
8331
|
+
return;
|
|
8332
|
+
}
|
|
8315
8333
|
return {
|
|
8316
8334
|
providerType,
|
|
8317
8335
|
url,
|
|
8318
8336
|
documentId,
|
|
8319
8337
|
tokenEnv: typeof tokenEnv === "string" ? tokenEnv : undefined,
|
|
8320
|
-
syncTimeoutMs: typeof syncTimeoutMs === "number" ? syncTimeoutMs : undefined
|
|
8338
|
+
syncTimeoutMs: typeof syncTimeoutMs === "number" ? syncTimeoutMs : undefined,
|
|
8339
|
+
onMissing,
|
|
8340
|
+
bootstrapSettlingMs: typeof bootstrapSettlingMs === "number" ? bootstrapSettlingMs : undefined
|
|
8321
8341
|
};
|
|
8322
8342
|
}
|
|
8323
8343
|
function normalizeContextMetadata(metadata) {
|
|
8324
8344
|
const sessionType = normalizeSessionType(metadata.sessionType);
|
|
8325
8345
|
const collaboration = normalizeCollaborationProfile(metadata.collaboration);
|
|
8346
|
+
const user = normalizeUser(metadata.user);
|
|
8326
8347
|
if (sessionType === "collab" && collaboration) {
|
|
8327
8348
|
return {
|
|
8328
8349
|
...metadata,
|
|
8329
8350
|
sessionType,
|
|
8330
|
-
collaboration
|
|
8351
|
+
collaboration,
|
|
8352
|
+
user
|
|
8331
8353
|
};
|
|
8332
8354
|
}
|
|
8333
8355
|
return {
|
|
8334
8356
|
...metadata,
|
|
8335
8357
|
sessionType: "local",
|
|
8336
|
-
collaboration: undefined
|
|
8358
|
+
collaboration: undefined,
|
|
8359
|
+
user
|
|
8337
8360
|
};
|
|
8338
8361
|
}
|
|
8339
8362
|
function sleep(ms) {
|
|
@@ -8747,6 +8770,7 @@ function createInitialContextMetadata(io, paths, contextId, input) {
|
|
|
8747
8770
|
revision: 0,
|
|
8748
8771
|
sessionType,
|
|
8749
8772
|
collaboration: sessionType === "collab" ? input.collaboration : undefined,
|
|
8773
|
+
user: input.user,
|
|
8750
8774
|
openedAt: timestamp,
|
|
8751
8775
|
updatedAt: timestamp,
|
|
8752
8776
|
sourceSnapshot: input.sourceSnapshot
|
|
@@ -9196,6 +9220,14 @@ var init_cli_only_operation_definitions = __esm(() => {
|
|
|
9196
9220
|
documentId: { type: "string" },
|
|
9197
9221
|
url: { type: "string" }
|
|
9198
9222
|
}
|
|
9223
|
+
},
|
|
9224
|
+
bootstrap: {
|
|
9225
|
+
type: "object",
|
|
9226
|
+
properties: {
|
|
9227
|
+
roomState: { type: "string" },
|
|
9228
|
+
bootstrapApplied: { type: "boolean" },
|
|
9229
|
+
bootstrapSource: { type: "string" }
|
|
9230
|
+
}
|
|
9199
9231
|
}
|
|
9200
9232
|
},
|
|
9201
9233
|
required: ["contextId", "sessionType"]
|
|
@@ -10153,6 +10185,36 @@ function resolveSegmentPosition(targetOffset, segmentStart, segmentLength, docFr
|
|
|
10153
10185
|
}
|
|
10154
10186
|
return docFrom + (targetOffset - segmentStart);
|
|
10155
10187
|
}
|
|
10188
|
+
function computeTextContentLength(blockNode) {
|
|
10189
|
+
let length = 0;
|
|
10190
|
+
const walk = (node2) => {
|
|
10191
|
+
if (node2.isText) {
|
|
10192
|
+
length += (node2.text ?? "").length;
|
|
10193
|
+
return;
|
|
10194
|
+
}
|
|
10195
|
+
if (node2.isLeaf) {
|
|
10196
|
+
length += 1;
|
|
10197
|
+
return;
|
|
10198
|
+
}
|
|
10199
|
+
let first2 = true;
|
|
10200
|
+
for (let i = 0;i < node2.childCount; i++) {
|
|
10201
|
+
const child = node2.child(i);
|
|
10202
|
+
if (child.isBlock && !first2)
|
|
10203
|
+
length += 1;
|
|
10204
|
+
walk(child);
|
|
10205
|
+
first2 = false;
|
|
10206
|
+
}
|
|
10207
|
+
};
|
|
10208
|
+
let first = true;
|
|
10209
|
+
for (let i = 0;i < blockNode.childCount; i++) {
|
|
10210
|
+
const child = blockNode.child(i);
|
|
10211
|
+
if (child.isBlock && !first)
|
|
10212
|
+
length += 1;
|
|
10213
|
+
walk(child);
|
|
10214
|
+
first = false;
|
|
10215
|
+
}
|
|
10216
|
+
return length;
|
|
10217
|
+
}
|
|
10156
10218
|
function resolveTextRangeInBlock(blockNode, blockPos, range) {
|
|
10157
10219
|
if (range.start < 0 || range.end < range.start)
|
|
10158
10220
|
return null;
|
|
@@ -10210,6 +10272,21 @@ function resolveTextRangeInBlock(blockNode, blockPos, range) {
|
|
|
10210
10272
|
return { from: fromPos, to: toPos };
|
|
10211
10273
|
}
|
|
10212
10274
|
|
|
10275
|
+
// ../../packages/super-editor/src/document-api-adapters/helpers/text-mutation-resolution.ts
|
|
10276
|
+
function readTextAtResolvedRange(editor, range) {
|
|
10277
|
+
return editor.state.doc.textBetween(range.from, range.to, `
|
|
10278
|
+
`, OBJECT_REPLACEMENT_CHAR);
|
|
10279
|
+
}
|
|
10280
|
+
function buildTextMutationResolution(input) {
|
|
10281
|
+
return {
|
|
10282
|
+
...input.requestedTarget ? { requestedTarget: input.requestedTarget } : {},
|
|
10283
|
+
target: input.target,
|
|
10284
|
+
range: { from: input.range.from, to: input.range.to },
|
|
10285
|
+
text: input.text
|
|
10286
|
+
};
|
|
10287
|
+
}
|
|
10288
|
+
var OBJECT_REPLACEMENT_CHAR = "";
|
|
10289
|
+
|
|
10213
10290
|
// ../../packages/super-editor/src/document-api-adapters/helpers/adapter-utils.ts
|
|
10214
10291
|
function findTextBlockCandidates(index, blockId) {
|
|
10215
10292
|
return index.candidates.filter((candidate) => candidate.nodeId === blockId && isTextBlockCandidate(candidate));
|
|
@@ -10236,22 +10313,100 @@ function resolveTextTarget(editor, target) {
|
|
|
10236
10313
|
return null;
|
|
10237
10314
|
return resolveTextRangeInBlock(block.node, block.pos, target.range);
|
|
10238
10315
|
}
|
|
10316
|
+
function collectTopLevelPositions(doc) {
|
|
10317
|
+
const positions = new Set;
|
|
10318
|
+
let offset = 0;
|
|
10319
|
+
for (let i = 0;i < doc.childCount; i++) {
|
|
10320
|
+
positions.add(offset);
|
|
10321
|
+
offset += doc.child(i).nodeSize;
|
|
10322
|
+
}
|
|
10323
|
+
return positions;
|
|
10324
|
+
}
|
|
10239
10325
|
function resolveDefaultInsertTarget(editor) {
|
|
10240
10326
|
const index = getBlockIndex(editor);
|
|
10241
|
-
const
|
|
10242
|
-
const
|
|
10243
|
-
|
|
10327
|
+
const doc = editor.state.doc;
|
|
10328
|
+
const topLevelPositions = collectTopLevelPositions(doc);
|
|
10329
|
+
for (let i = index.candidates.length - 1;i >= 0; i--) {
|
|
10330
|
+
const candidate = index.candidates[i];
|
|
10331
|
+
if (topLevelPositions.has(candidate.pos) && isTextBlockCandidate(candidate)) {
|
|
10332
|
+
const textLength = computeTextContentLength(candidate.node);
|
|
10333
|
+
const range = resolveTextRangeInBlock(candidate.node, candidate.pos, { start: textLength, end: textLength });
|
|
10334
|
+
if (!range)
|
|
10335
|
+
continue;
|
|
10336
|
+
return {
|
|
10337
|
+
kind: "text-block",
|
|
10338
|
+
target: {
|
|
10339
|
+
kind: "text",
|
|
10340
|
+
blockId: candidate.nodeId,
|
|
10341
|
+
range: { start: textLength, end: textLength }
|
|
10342
|
+
},
|
|
10343
|
+
range
|
|
10344
|
+
};
|
|
10345
|
+
}
|
|
10346
|
+
}
|
|
10347
|
+
if (doc.content.size > 0) {
|
|
10348
|
+
return { kind: "structural-end", insertPos: doc.content.size };
|
|
10349
|
+
}
|
|
10350
|
+
return null;
|
|
10351
|
+
}
|
|
10352
|
+
function insertParagraphAtEnd(editor, pos, text, applyMeta) {
|
|
10353
|
+
const schema = editor.state.schema;
|
|
10354
|
+
const textNode = schema.text(text);
|
|
10355
|
+
const paragraph = schema.nodes.paragraph.create(null, textNode);
|
|
10356
|
+
const tr = editor.state.tr;
|
|
10357
|
+
tr.insert(pos, paragraph);
|
|
10358
|
+
if (applyMeta)
|
|
10359
|
+
applyMeta(tr);
|
|
10360
|
+
editor.dispatch(tr);
|
|
10361
|
+
}
|
|
10362
|
+
function resolveWriteTarget(editor, request) {
|
|
10363
|
+
const requestedTarget = request.target;
|
|
10364
|
+
if (request.kind === "insert" && !request.target) {
|
|
10365
|
+
const fallback = resolveDefaultInsertTarget(editor);
|
|
10366
|
+
if (!fallback)
|
|
10367
|
+
return null;
|
|
10368
|
+
if (fallback.kind === "structural-end") {
|
|
10369
|
+
const pos = fallback.insertPos;
|
|
10370
|
+
const syntheticRange = { from: pos, to: pos };
|
|
10371
|
+
const syntheticTarget = { kind: "text", blockId: "", range: { start: 0, end: 0 } };
|
|
10372
|
+
return {
|
|
10373
|
+
requestedTarget,
|
|
10374
|
+
effectiveTarget: syntheticTarget,
|
|
10375
|
+
range: syntheticRange,
|
|
10376
|
+
resolution: buildTextMutationResolution({
|
|
10377
|
+
requestedTarget,
|
|
10378
|
+
target: syntheticTarget,
|
|
10379
|
+
range: syntheticRange,
|
|
10380
|
+
text: ""
|
|
10381
|
+
}),
|
|
10382
|
+
structuralEnd: true
|
|
10383
|
+
};
|
|
10384
|
+
}
|
|
10385
|
+
const text2 = readTextAtResolvedRange(editor, fallback.range);
|
|
10386
|
+
return {
|
|
10387
|
+
requestedTarget,
|
|
10388
|
+
effectiveTarget: fallback.target,
|
|
10389
|
+
range: fallback.range,
|
|
10390
|
+
resolution: buildTextMutationResolution({
|
|
10391
|
+
requestedTarget,
|
|
10392
|
+
target: fallback.target,
|
|
10393
|
+
range: fallback.range,
|
|
10394
|
+
text: text2
|
|
10395
|
+
})
|
|
10396
|
+
};
|
|
10397
|
+
}
|
|
10398
|
+
const target = request.target;
|
|
10399
|
+
if (!target)
|
|
10244
10400
|
return null;
|
|
10245
|
-
const range =
|
|
10401
|
+
const range = resolveTextTarget(editor, target);
|
|
10246
10402
|
if (!range)
|
|
10247
10403
|
return null;
|
|
10404
|
+
const text = readTextAtResolvedRange(editor, range);
|
|
10248
10405
|
return {
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
10253
|
-
},
|
|
10254
|
-
range
|
|
10406
|
+
requestedTarget,
|
|
10407
|
+
effectiveTarget: target,
|
|
10408
|
+
range,
|
|
10409
|
+
resolution: buildTextMutationResolution({ requestedTarget, target, range, text })
|
|
10255
10410
|
};
|
|
10256
10411
|
}
|
|
10257
10412
|
function addDiagnostic(diagnostics, message) {
|
|
@@ -24670,21 +24825,6 @@ var init_executor = __esm(() => {
|
|
|
24670
24825
|
TEXT_STYLE_KEYS = ["color", "fontSize", "letterSpacing", "vertAlign", "position"];
|
|
24671
24826
|
});
|
|
24672
24827
|
|
|
24673
|
-
// ../../packages/super-editor/src/document-api-adapters/helpers/text-mutation-resolution.ts
|
|
24674
|
-
function readTextAtResolvedRange(editor, range) {
|
|
24675
|
-
return editor.state.doc.textBetween(range.from, range.to, `
|
|
24676
|
-
`, OBJECT_REPLACEMENT_CHAR);
|
|
24677
|
-
}
|
|
24678
|
-
function buildTextMutationResolution(input) {
|
|
24679
|
-
return {
|
|
24680
|
-
...input.requestedTarget ? { requestedTarget: input.requestedTarget } : {},
|
|
24681
|
-
target: input.target,
|
|
24682
|
-
range: { from: input.range.from, to: input.range.to },
|
|
24683
|
-
text: input.text
|
|
24684
|
-
};
|
|
24685
|
-
}
|
|
24686
|
-
var OBJECT_REPLACEMENT_CHAR = "";
|
|
24687
|
-
|
|
24688
24828
|
// ../../node_modules/.pnpm/bail@2.0.2/node_modules/bail/index.js
|
|
24689
24829
|
function bail(error) {
|
|
24690
24830
|
if (error) {
|
|
@@ -70722,39 +70862,6 @@ function normalizeFormatLocator(input) {
|
|
|
70722
70862
|
};
|
|
70723
70863
|
return { target };
|
|
70724
70864
|
}
|
|
70725
|
-
function resolveWriteTarget(editor, request) {
|
|
70726
|
-
const requestedTarget = request.target;
|
|
70727
|
-
if (request.kind === "insert" && !request.target) {
|
|
70728
|
-
const fallback = resolveDefaultInsertTarget(editor);
|
|
70729
|
-
if (!fallback)
|
|
70730
|
-
return null;
|
|
70731
|
-
const text6 = readTextAtResolvedRange(editor, fallback.range);
|
|
70732
|
-
return {
|
|
70733
|
-
requestedTarget,
|
|
70734
|
-
effectiveTarget: fallback.target,
|
|
70735
|
-
range: fallback.range,
|
|
70736
|
-
resolution: buildTextMutationResolution({
|
|
70737
|
-
requestedTarget,
|
|
70738
|
-
target: fallback.target,
|
|
70739
|
-
range: fallback.range,
|
|
70740
|
-
text: text6
|
|
70741
|
-
})
|
|
70742
|
-
};
|
|
70743
|
-
}
|
|
70744
|
-
const target = request.target;
|
|
70745
|
-
if (!target)
|
|
70746
|
-
return null;
|
|
70747
|
-
const range = resolveTextTarget(editor, target);
|
|
70748
|
-
if (!range)
|
|
70749
|
-
return null;
|
|
70750
|
-
const text5 = readTextAtResolvedRange(editor, range);
|
|
70751
|
-
return {
|
|
70752
|
-
requestedTarget,
|
|
70753
|
-
effectiveTarget: target,
|
|
70754
|
-
range,
|
|
70755
|
-
resolution: buildTextMutationResolution({ requestedTarget, target, range, text: text5 })
|
|
70756
|
-
};
|
|
70757
|
-
}
|
|
70758
70865
|
function mapPlanReceiptToTextReceipt(_receipt, resolution) {
|
|
70759
70866
|
return { success: true, resolution };
|
|
70760
70867
|
}
|
|
@@ -70829,6 +70936,16 @@ function writeWrapper(editor, request, options) {
|
|
|
70829
70936
|
if (options?.dryRun) {
|
|
70830
70937
|
return { success: true, resolution: resolved.resolution };
|
|
70831
70938
|
}
|
|
70939
|
+
if (resolved.structuralEnd && normalizedRequest.kind === "insert") {
|
|
70940
|
+
const insertPos = resolved.range.from;
|
|
70941
|
+
const text5 = normalizedRequest.text ?? "";
|
|
70942
|
+
const receipt3 = executeDomainCommand(editor, () => {
|
|
70943
|
+
const meta = mode === "tracked" ? applyTrackedMutationMeta : applyDirectMutationMeta;
|
|
70944
|
+
insertParagraphAtEnd(editor, insertPos, text5, meta);
|
|
70945
|
+
return true;
|
|
70946
|
+
}, { expectedRevision: options?.expectedRevision });
|
|
70947
|
+
return mapPlanReceiptToTextReceipt(receipt3, resolved.resolution);
|
|
70948
|
+
}
|
|
70832
70949
|
const stepId = v4();
|
|
70833
70950
|
let op;
|
|
70834
70951
|
let stepDef;
|
|
@@ -70989,8 +71106,14 @@ function insertStructuredWrapper(editor, input, options) {
|
|
|
70989
71106
|
if (!fallback) {
|
|
70990
71107
|
throw new DocumentApiAdapterError("TARGET_NOT_FOUND", "No default insertion point available.");
|
|
70991
71108
|
}
|
|
70992
|
-
|
|
70993
|
-
|
|
71109
|
+
if (fallback.kind === "structural-end") {
|
|
71110
|
+
const pos = fallback.insertPos;
|
|
71111
|
+
resolvedRange = { from: pos, to: pos };
|
|
71112
|
+
effectiveTarget = { kind: "text", blockId: "", range: { start: 0, end: 0 } };
|
|
71113
|
+
} else {
|
|
71114
|
+
resolvedRange = fallback.range;
|
|
71115
|
+
effectiveTarget = fallback.target;
|
|
71116
|
+
}
|
|
70994
71117
|
}
|
|
70995
71118
|
const resolution = buildTextMutationResolution({
|
|
70996
71119
|
requestedTarget: target,
|
|
@@ -83665,18 +83788,35 @@ function parseCollaborationInput(value) {
|
|
|
83665
83788
|
if ("params" in value) {
|
|
83666
83789
|
throw new CliError("VALIDATION_ERROR", "collaboration.params is not supported in v1.");
|
|
83667
83790
|
}
|
|
83668
|
-
const allowedKeys = new Set([
|
|
83791
|
+
const allowedKeys = new Set([
|
|
83792
|
+
"providerType",
|
|
83793
|
+
"url",
|
|
83794
|
+
"documentId",
|
|
83795
|
+
"tokenEnv",
|
|
83796
|
+
"syncTimeoutMs",
|
|
83797
|
+
"onMissing",
|
|
83798
|
+
"bootstrapSettlingMs"
|
|
83799
|
+
]);
|
|
83669
83800
|
for (const key of Object.keys(value)) {
|
|
83670
83801
|
if (!allowedKeys.has(key)) {
|
|
83671
83802
|
throw new CliError("VALIDATION_ERROR", `collaboration.${key} is not supported.`);
|
|
83672
83803
|
}
|
|
83673
83804
|
}
|
|
83805
|
+
let onMissing;
|
|
83806
|
+
if (value.onMissing != null) {
|
|
83807
|
+
if (value.onMissing !== "seedFromDoc" && value.onMissing !== "blank" && value.onMissing !== "error") {
|
|
83808
|
+
throw new CliError("VALIDATION_ERROR", 'collaboration.onMissing must be "seedFromDoc", "blank", or "error".');
|
|
83809
|
+
}
|
|
83810
|
+
onMissing = value.onMissing;
|
|
83811
|
+
}
|
|
83674
83812
|
return {
|
|
83675
83813
|
providerType: normalizeProviderType(value.providerType, "collaboration.providerType"),
|
|
83676
83814
|
url: expectNonEmptyString(value.url, "collaboration.url").trim(),
|
|
83677
83815
|
documentId: value.documentId != null ? expectNonEmptyString(value.documentId, "collaboration.documentId") : undefined,
|
|
83678
83816
|
tokenEnv: expectOptionalEnvVarName(value.tokenEnv, "collaboration.tokenEnv"),
|
|
83679
|
-
syncTimeoutMs: expectOptionalPositiveNumber(value.syncTimeoutMs, "collaboration.syncTimeoutMs")
|
|
83817
|
+
syncTimeoutMs: expectOptionalPositiveNumber(value.syncTimeoutMs, "collaboration.syncTimeoutMs"),
|
|
83818
|
+
onMissing,
|
|
83819
|
+
bootstrapSettlingMs: expectOptionalPositiveNumber(value.bootstrapSettlingMs, "collaboration.bootstrapSettlingMs")
|
|
83680
83820
|
};
|
|
83681
83821
|
}
|
|
83682
83822
|
function resolveCollaborationProfile(input, sessionId) {
|
|
@@ -83686,7 +83826,9 @@ function resolveCollaborationProfile(input, sessionId) {
|
|
|
83686
83826
|
url: input.url,
|
|
83687
83827
|
documentId,
|
|
83688
83828
|
tokenEnv: input.tokenEnv,
|
|
83689
|
-
syncTimeoutMs: input.syncTimeoutMs
|
|
83829
|
+
syncTimeoutMs: input.syncTimeoutMs,
|
|
83830
|
+
onMissing: input.onMissing,
|
|
83831
|
+
bootstrapSettlingMs: input.bootstrapSettlingMs
|
|
83690
83832
|
};
|
|
83691
83833
|
}
|
|
83692
83834
|
function resolveCollaborationToken(profile) {
|
|
@@ -83786,6 +83928,119 @@ var init_collaboration = __esm(() => {
|
|
|
83786
83928
|
ENV_VAR_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
83787
83929
|
});
|
|
83788
83930
|
|
|
83931
|
+
// src/lib/bootstrap.ts
|
|
83932
|
+
function detectRoomState(ydoc) {
|
|
83933
|
+
const fragment = ydoc.getXmlFragment("supereditor");
|
|
83934
|
+
if (fragment.length > 0)
|
|
83935
|
+
return "populated";
|
|
83936
|
+
const metaMap = ydoc.getMap("meta");
|
|
83937
|
+
for (const [key, value] of metaMap.entries()) {
|
|
83938
|
+
if (key === "bootstrap") {
|
|
83939
|
+
const marker = value;
|
|
83940
|
+
if (marker && marker.source !== "pending")
|
|
83941
|
+
return "populated";
|
|
83942
|
+
continue;
|
|
83943
|
+
}
|
|
83944
|
+
return "populated";
|
|
83945
|
+
}
|
|
83946
|
+
return "empty";
|
|
83947
|
+
}
|
|
83948
|
+
function resolveBootstrapDecision(roomState, onMissing, hasDoc) {
|
|
83949
|
+
if (roomState === "populated")
|
|
83950
|
+
return { action: "join" };
|
|
83951
|
+
switch (onMissing) {
|
|
83952
|
+
case "seedFromDoc":
|
|
83953
|
+
return { action: "seed", source: hasDoc ? "doc" : "blank" };
|
|
83954
|
+
case "blank":
|
|
83955
|
+
return { action: "seed", source: "blank" };
|
|
83956
|
+
case "error":
|
|
83957
|
+
return { action: "error", reason: 'Collaboration room is empty and onMissing is set to "error".' };
|
|
83958
|
+
}
|
|
83959
|
+
}
|
|
83960
|
+
function writeBootstrapMarker(ydoc, source) {
|
|
83961
|
+
const metaMap = ydoc.getMap("meta");
|
|
83962
|
+
const marker = {
|
|
83963
|
+
version: 1,
|
|
83964
|
+
clientId: ydoc.clientID,
|
|
83965
|
+
seededAt: new Date().toISOString(),
|
|
83966
|
+
source
|
|
83967
|
+
};
|
|
83968
|
+
metaMap.set("bootstrap", marker);
|
|
83969
|
+
}
|
|
83970
|
+
function readBootstrapMarker(ydoc) {
|
|
83971
|
+
return ydoc.getMap("meta").get("bootstrap");
|
|
83972
|
+
}
|
|
83973
|
+
function snapshotCompetitor(marker) {
|
|
83974
|
+
return {
|
|
83975
|
+
observedOtherClientId: marker.clientId,
|
|
83976
|
+
observedSource: marker.source,
|
|
83977
|
+
observedAt: new Date().toISOString()
|
|
83978
|
+
};
|
|
83979
|
+
}
|
|
83980
|
+
function observeCompetitor(ydoc) {
|
|
83981
|
+
const myClientId = ydoc.clientID;
|
|
83982
|
+
const metaMap = ydoc.getMap("meta");
|
|
83983
|
+
let competitor = null;
|
|
83984
|
+
const handler2 = (event) => {
|
|
83985
|
+
if (!event.keysChanged.has("bootstrap"))
|
|
83986
|
+
return;
|
|
83987
|
+
const marker = metaMap.get("bootstrap");
|
|
83988
|
+
if (marker && marker.clientId !== myClientId && !competitor) {
|
|
83989
|
+
competitor = snapshotCompetitor(marker);
|
|
83990
|
+
}
|
|
83991
|
+
};
|
|
83992
|
+
metaMap.observe(handler2);
|
|
83993
|
+
return {
|
|
83994
|
+
getCompetitor: () => competitor,
|
|
83995
|
+
dispose: () => metaMap.unobserve(handler2)
|
|
83996
|
+
};
|
|
83997
|
+
}
|
|
83998
|
+
function sleep2(ms) {
|
|
83999
|
+
if (ms <= 0)
|
|
84000
|
+
return Promise.resolve();
|
|
84001
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
84002
|
+
}
|
|
84003
|
+
async function claimBootstrap(ydoc, settlingMs, jitterMs = DEFAULT_BOOTSTRAP_JITTER_MS) {
|
|
84004
|
+
await sleep2(Math.floor(Math.random() * jitterMs));
|
|
84005
|
+
const metaMap = ydoc.getMap("meta");
|
|
84006
|
+
metaMap.set("bootstrap", {
|
|
84007
|
+
version: 1,
|
|
84008
|
+
clientId: ydoc.clientID,
|
|
84009
|
+
seededAt: new Date().toISOString(),
|
|
84010
|
+
source: "pending"
|
|
84011
|
+
});
|
|
84012
|
+
const observer = observeCompetitor(ydoc);
|
|
84013
|
+
try {
|
|
84014
|
+
await sleep2(settlingMs);
|
|
84015
|
+
const competitor = observer.getCompetitor();
|
|
84016
|
+
if (competitor)
|
|
84017
|
+
return { granted: false, competitor };
|
|
84018
|
+
const marker = readBootstrapMarker(ydoc);
|
|
84019
|
+
if (marker?.clientId === ydoc.clientID) {
|
|
84020
|
+
return { granted: true };
|
|
84021
|
+
}
|
|
84022
|
+
return {
|
|
84023
|
+
granted: false,
|
|
84024
|
+
competitor: marker ? snapshotCompetitor(marker) : { observedOtherClientId: 0, observedSource: "unknown", observedAt: new Date().toISOString() }
|
|
84025
|
+
};
|
|
84026
|
+
} finally {
|
|
84027
|
+
observer.dispose();
|
|
84028
|
+
}
|
|
84029
|
+
}
|
|
84030
|
+
async function detectBootstrapRace(ydoc, observeMs = POST_SEED_OBSERVE_MS) {
|
|
84031
|
+
const observer = observeCompetitor(ydoc);
|
|
84032
|
+
try {
|
|
84033
|
+
await sleep2(observeMs);
|
|
84034
|
+
const competitor = observer.getCompetitor();
|
|
84035
|
+
if (competitor)
|
|
84036
|
+
return { raceSuspected: true, competitor };
|
|
84037
|
+
return { raceSuspected: false };
|
|
84038
|
+
} finally {
|
|
84039
|
+
observer.dispose();
|
|
84040
|
+
}
|
|
84041
|
+
}
|
|
84042
|
+
var DEFAULT_BOOTSTRAP_SETTLING_MS = 1500, DEFAULT_BOOTSTRAP_JITTER_MS = 150, POST_SEED_OBSERVE_MS = 200;
|
|
84043
|
+
|
|
83789
84044
|
// src/lib/document.ts
|
|
83790
84045
|
import { readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
|
|
83791
84046
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -83879,10 +84134,11 @@ async function openDocument(doc, io, options = {}) {
|
|
|
83879
84134
|
const isTest = false;
|
|
83880
84135
|
editor = await EditorRuntime.open(Buffer.from(source), {
|
|
83881
84136
|
documentId: options.documentId ?? meta.path ?? "blank.docx",
|
|
83882
|
-
user: { id: "cli", name: "CLI" },
|
|
84137
|
+
user: options.user ? { name: options.user.name, email: options.user.email, image: null } : { id: "cli", name: "CLI" },
|
|
83883
84138
|
...isTest ? { telemetry: { enabled: false } } : {},
|
|
83884
84139
|
ydoc: options.ydoc,
|
|
83885
84140
|
...options.collaborationProvider != null ? { collaborationProvider: options.collaborationProvider } : {},
|
|
84141
|
+
...options.isNewFile != null ? { isNewFile: options.isNewFile } : {},
|
|
83886
84142
|
...passThroughEditorOpts
|
|
83887
84143
|
});
|
|
83888
84144
|
} catch (error) {
|
|
@@ -83939,18 +84195,48 @@ async function openDocument(doc, io, options = {}) {
|
|
|
83939
84195
|
}
|
|
83940
84196
|
};
|
|
83941
84197
|
}
|
|
83942
|
-
async function openCollaborativeDocument(doc, io, profile) {
|
|
84198
|
+
async function openCollaborativeDocument(doc, io, profile, options = {}) {
|
|
83943
84199
|
const runtime = createCollaborationRuntime(profile);
|
|
83944
84200
|
try {
|
|
83945
84201
|
await runtime.waitForSync();
|
|
83946
|
-
const
|
|
84202
|
+
const onMissing = profile.onMissing ?? "seedFromDoc";
|
|
84203
|
+
let finalRoomState = detectRoomState(runtime.ydoc);
|
|
84204
|
+
let decision = resolveBootstrapDecision(finalRoomState, onMissing, doc != null);
|
|
84205
|
+
if (decision.action === "seed") {
|
|
84206
|
+
const claim = await claimBootstrap(runtime.ydoc, profile.bootstrapSettlingMs ?? DEFAULT_BOOTSTRAP_SETTLING_MS);
|
|
84207
|
+
if (!claim.granted) {
|
|
84208
|
+
finalRoomState = detectRoomState(runtime.ydoc);
|
|
84209
|
+
decision = { action: "join" };
|
|
84210
|
+
}
|
|
84211
|
+
}
|
|
84212
|
+
if (decision.action === "error") {
|
|
84213
|
+
throw new CliError("COLLABORATION_ROOM_EMPTY", decision.reason);
|
|
84214
|
+
}
|
|
84215
|
+
const shouldSeed = decision.action === "seed";
|
|
84216
|
+
const docForEditor = shouldSeed ? doc : undefined;
|
|
84217
|
+
const opened = await openDocument(docForEditor, io, {
|
|
83947
84218
|
documentId: profile.documentId,
|
|
83948
84219
|
ydoc: runtime.ydoc,
|
|
83949
|
-
collaborationProvider: runtime.provider
|
|
84220
|
+
collaborationProvider: runtime.provider,
|
|
84221
|
+
isNewFile: shouldSeed,
|
|
84222
|
+
user: options.user
|
|
83950
84223
|
});
|
|
84224
|
+
let raceDetection;
|
|
84225
|
+
if (shouldSeed) {
|
|
84226
|
+
writeBootstrapMarker(runtime.ydoc, decision.source);
|
|
84227
|
+
raceDetection = await detectBootstrapRace(runtime.ydoc);
|
|
84228
|
+
}
|
|
84229
|
+
const bootstrap = {
|
|
84230
|
+
roomState: finalRoomState,
|
|
84231
|
+
bootstrapApplied: shouldSeed,
|
|
84232
|
+
bootstrapSource: shouldSeed ? decision.source : undefined,
|
|
84233
|
+
raceSuspected: raceDetection?.raceSuspected,
|
|
84234
|
+
raceCompetitor: raceDetection?.raceSuspected ? raceDetection.competitor : undefined
|
|
84235
|
+
};
|
|
83951
84236
|
return {
|
|
83952
84237
|
editor: opened.editor,
|
|
83953
84238
|
meta: opened.meta,
|
|
84239
|
+
bootstrap,
|
|
83954
84240
|
dispose() {
|
|
83955
84241
|
try {
|
|
83956
84242
|
opened.dispose();
|
|
@@ -83966,7 +84252,7 @@ async function openCollaborativeDocument(doc, io, profile) {
|
|
|
83966
84252
|
}
|
|
83967
84253
|
async function openSessionDocument(doc, io, metadata, options = {}) {
|
|
83968
84254
|
if (metadata.sessionType !== "collab") {
|
|
83969
|
-
return openDocument(doc, io);
|
|
84255
|
+
return openDocument(doc, io, { user: metadata.user });
|
|
83970
84256
|
}
|
|
83971
84257
|
if (!metadata.collaboration) {
|
|
83972
84258
|
throw new CliError("COMMAND_FAILED", "Session is marked as collaborative but has no collaboration profile.");
|
|
@@ -83981,11 +84267,12 @@ async function openSessionDocument(doc, io, metadata, options = {}) {
|
|
|
83981
84267
|
sessionType: metadata.sessionType,
|
|
83982
84268
|
collaboration: metadata.collaboration,
|
|
83983
84269
|
sourcePath: metadata.sourcePath,
|
|
83984
|
-
workingDocPath: metadata.workingDocPath
|
|
84270
|
+
workingDocPath: metadata.workingDocPath,
|
|
84271
|
+
user: metadata.user
|
|
83985
84272
|
};
|
|
83986
84273
|
return options.collabSessionPool.acquire(sessionId, doc, metadataForPool, io);
|
|
83987
84274
|
}
|
|
83988
|
-
return openCollaborativeDocument(doc, io, metadata.collaboration);
|
|
84275
|
+
return openCollaborativeDocument(doc, io, metadata.collaboration, { user: metadata.user });
|
|
83989
84276
|
}
|
|
83990
84277
|
async function getFileChecksum(path2) {
|
|
83991
84278
|
let bytes;
|
|
@@ -85445,7 +85732,7 @@ async function executeReadOperation(request) {
|
|
|
85445
85732
|
opened2.dispose();
|
|
85446
85733
|
}
|
|
85447
85734
|
}
|
|
85448
|
-
const opened = await openDocument(paths.workingDocPath, context.io);
|
|
85735
|
+
const opened = await openDocument(paths.workingDocPath, context.io, { user: metadata.user });
|
|
85449
85736
|
try {
|
|
85450
85737
|
const result = invokeOperation(opened.editor, operationId, input);
|
|
85451
85738
|
const document4 = {
|
|
@@ -85635,7 +85922,7 @@ async function executeMutationOperation(request) {
|
|
|
85635
85922
|
opened2.dispose();
|
|
85636
85923
|
}
|
|
85637
85924
|
}
|
|
85638
|
-
const opened = await openDocument(paths.workingDocPath, context.io);
|
|
85925
|
+
const opened = await openDocument(paths.workingDocPath, context.io, { user: metadata.user });
|
|
85639
85926
|
try {
|
|
85640
85927
|
const result = invokeOperation2(opened.editor, operationId, input, invokeOptions);
|
|
85641
85928
|
const document4 = {
|
|
@@ -86344,7 +86631,7 @@ function deriveOptionSpecs(params3) {
|
|
|
86344
86631
|
}
|
|
86345
86632
|
return specs;
|
|
86346
86633
|
}
|
|
86347
|
-
var DOC_PARAM, SESSION_PARAM, OUT_PARAM, FORCE_PARAM, DRY_RUN_PARAM, CHANGE_MODE_PARAM, EXPECTED_REVISION_PARAM, AGENT_HIDDEN_PARAM_NAMES, OPERATION_CONSTRAINTS, PARAM_FLAG_OVERRIDES, PARAM_SCHEMA_OVERRIDES, PARAM_EXCLUSIONS, TEXT_TARGET_FLAT_PARAMS, INSERT_FLAT_PARAMS, LIST_TARGET_FLAT_PARAMS, FORMAT_OPERATION_IDS, EXTRA_CLI_PARAMS, CLI_ONLY_METADATA, CLI_OPERATION_METADATA, CLI_OPERATION_OPTION_SPECS;
|
|
86634
|
+
var DOC_PARAM, SESSION_PARAM, OUT_PARAM, FORCE_PARAM, DRY_RUN_PARAM, CHANGE_MODE_PARAM, EXPECTED_REVISION_PARAM, USER_NAME_PARAM, USER_EMAIL_PARAM, AGENT_HIDDEN_PARAM_NAMES, OPERATION_CONSTRAINTS, PARAM_FLAG_OVERRIDES, PARAM_SCHEMA_OVERRIDES, PARAM_EXCLUSIONS, TEXT_TARGET_FLAT_PARAMS, INSERT_FLAT_PARAMS, LIST_TARGET_FLAT_PARAMS, FORMAT_OPERATION_IDS, EXTRA_CLI_PARAMS, CLI_ONLY_METADATA, CLI_OPERATION_METADATA, CLI_OPERATION_OPTION_SPECS;
|
|
86348
86635
|
var init_operation_params = __esm(() => {
|
|
86349
86636
|
init_src();
|
|
86350
86637
|
init_operation_set();
|
|
@@ -86375,6 +86662,18 @@ var init_operation_params = __esm(() => {
|
|
|
86375
86662
|
type: "number",
|
|
86376
86663
|
agentVisible: false
|
|
86377
86664
|
};
|
|
86665
|
+
USER_NAME_PARAM = {
|
|
86666
|
+
name: "userName",
|
|
86667
|
+
kind: "flag",
|
|
86668
|
+
flag: "user-name",
|
|
86669
|
+
type: "string"
|
|
86670
|
+
};
|
|
86671
|
+
USER_EMAIL_PARAM = {
|
|
86672
|
+
name: "userEmail",
|
|
86673
|
+
kind: "flag",
|
|
86674
|
+
flag: "user-email",
|
|
86675
|
+
type: "string"
|
|
86676
|
+
};
|
|
86378
86677
|
AGENT_HIDDEN_PARAM_NAMES = new Set(["out", "expectedRevision", "changeMode", "dryRun"]);
|
|
86379
86678
|
OPERATION_CONSTRAINTS = {
|
|
86380
86679
|
"doc.find": {
|
|
@@ -86501,7 +86800,11 @@ var init_operation_params = __esm(() => {
|
|
|
86501
86800
|
{ name: "collabDocumentId", kind: "flag", flag: "collab-document-id", type: "string" },
|
|
86502
86801
|
{ name: "collabUrl", kind: "flag", flag: "collab-url", type: "string" },
|
|
86503
86802
|
{ name: "contentOverride", kind: "flag", flag: "content-override", type: "string" },
|
|
86504
|
-
{ name: "overrideType", kind: "flag", flag: "override-type", type: "string" }
|
|
86803
|
+
{ name: "overrideType", kind: "flag", flag: "override-type", type: "string" },
|
|
86804
|
+
{ name: "onMissing", kind: "flag", flag: "on-missing", type: "string" },
|
|
86805
|
+
{ name: "bootstrapSettlingMs", kind: "flag", flag: "bootstrap-settling-ms", type: "number" },
|
|
86806
|
+
USER_NAME_PARAM,
|
|
86807
|
+
USER_EMAIL_PARAM
|
|
86505
86808
|
],
|
|
86506
86809
|
constraints: null
|
|
86507
86810
|
},
|
|
@@ -87800,6 +88103,10 @@ async function runOpen(tokens, context) {
|
|
|
87800
88103
|
const collabDocumentId = getStringOption(parsed, "collab-document-id");
|
|
87801
88104
|
const contentOverride = getStringOption(parsed, "content-override");
|
|
87802
88105
|
const overrideType = getStringOption(parsed, "override-type");
|
|
88106
|
+
const onMissing = getStringOption(parsed, "on-missing");
|
|
88107
|
+
const bootstrapSettlingMs = getNumberOption(parsed, "bootstrap-settling-ms");
|
|
88108
|
+
const userName = getStringOption(parsed, "user-name");
|
|
88109
|
+
const userEmail = getStringOption(parsed, "user-email");
|
|
87803
88110
|
if (contentOverride != null && !overrideType) {
|
|
87804
88111
|
throw new CliError("INVALID_ARGUMENT", "open: --content-override requires --override-type.");
|
|
87805
88112
|
}
|
|
@@ -87809,6 +88116,9 @@ async function runOpen(tokens, context) {
|
|
|
87809
88116
|
if (overrideType && !VALID_OVERRIDE_TYPES.has(overrideType)) {
|
|
87810
88117
|
throw new CliError("INVALID_ARGUMENT", `open: --override-type must be one of: markdown, html, text. Got "${overrideType}".`);
|
|
87811
88118
|
}
|
|
88119
|
+
if (onMissing != null && !VALID_ON_MISSING.has(onMissing)) {
|
|
88120
|
+
throw new CliError("INVALID_ARGUMENT", `open: --on-missing must be one of: seedFromDoc, blank, error. Got "${onMissing}".`);
|
|
88121
|
+
}
|
|
87812
88122
|
if (collaborationPayload != null && (collabUrl || collabDocumentId)) {
|
|
87813
88123
|
throw new CliError("INVALID_ARGUMENT", "open: do not combine --collaboration-json with --collab-url / --collab-document-id.");
|
|
87814
88124
|
}
|
|
@@ -87817,18 +88127,32 @@ async function runOpen(tokens, context) {
|
|
|
87817
88127
|
}
|
|
87818
88128
|
let collaborationInput;
|
|
87819
88129
|
if (collaborationPayload != null) {
|
|
87820
|
-
|
|
88130
|
+
if (typeof collaborationPayload !== "object" || Array.isArray(collaborationPayload)) {
|
|
88131
|
+
throw new CliError("VALIDATION_ERROR", "open: --collaboration-json must be a JSON object.");
|
|
88132
|
+
}
|
|
88133
|
+
const payload = collaborationPayload;
|
|
88134
|
+
if (onMissing != null && !("onMissing" in payload))
|
|
88135
|
+
payload.onMissing = onMissing;
|
|
88136
|
+
if (bootstrapSettlingMs != null && !("bootstrapSettlingMs" in payload))
|
|
88137
|
+
payload.bootstrapSettlingMs = bootstrapSettlingMs;
|
|
88138
|
+
collaborationInput = parseCollaborationInput(payload);
|
|
87821
88139
|
} else if (collabUrl) {
|
|
87822
88140
|
collaborationInput = parseCollaborationInput({
|
|
87823
88141
|
providerType: "hocuspocus",
|
|
87824
88142
|
url: collabUrl,
|
|
87825
|
-
documentId: collabDocumentId
|
|
88143
|
+
documentId: collabDocumentId,
|
|
88144
|
+
...onMissing != null ? { onMissing } : {},
|
|
88145
|
+
...bootstrapSettlingMs != null ? { bootstrapSettlingMs } : {}
|
|
87826
88146
|
});
|
|
87827
88147
|
} else if (collabDocumentId) {
|
|
87828
88148
|
throw new CliError("MISSING_REQUIRED", "open: --collab-document-id requires --collab-url.");
|
|
87829
88149
|
}
|
|
87830
88150
|
const collaboration = collaborationInput ? resolveCollaborationProfile(collaborationInput, sessionId) : undefined;
|
|
87831
88151
|
const sessionType = collaboration ? "collab" : "local";
|
|
88152
|
+
if (!collaboration && (onMissing != null || bootstrapSettlingMs != null)) {
|
|
88153
|
+
throw new CliError("INVALID_ARGUMENT", "open: --on-missing and --bootstrap-settling-ms require collaboration mode (--collaboration-json or --collab-url).");
|
|
88154
|
+
}
|
|
88155
|
+
const user = userName != null || userEmail != null ? { name: userName ?? "CLI", email: userEmail ?? "" } : undefined;
|
|
87832
88156
|
const editorOpenOptions = {};
|
|
87833
88157
|
if (contentOverride != null && overrideType) {
|
|
87834
88158
|
if (overrideType === "markdown") {
|
|
@@ -87854,10 +88178,8 @@ async function runOpen(tokens, context) {
|
|
|
87854
88178
|
revision: existing.revision
|
|
87855
88179
|
});
|
|
87856
88180
|
}
|
|
87857
|
-
|
|
87858
|
-
|
|
87859
|
-
}
|
|
87860
|
-
const opened = collaboration ? await openCollaborativeDocument(doc, context.io, collaboration) : await openDocument(doc, context.io, { editorOpenOptions });
|
|
88181
|
+
const opened = collaboration ? await openCollaborativeDocument(doc, context.io, collaboration, { user }) : await openDocument(doc, context.io, { editorOpenOptions, user });
|
|
88182
|
+
const bootstrap = "bootstrap" in opened ? opened.bootstrap : undefined;
|
|
87861
88183
|
let adoptedToHostPool = false;
|
|
87862
88184
|
try {
|
|
87863
88185
|
const output = await exportToPath(opened.editor, paths.workingDocPath, true);
|
|
@@ -87868,7 +88190,8 @@ async function runOpen(tokens, context) {
|
|
|
87868
88190
|
sourcePath,
|
|
87869
88191
|
sourceSnapshot,
|
|
87870
88192
|
sessionType,
|
|
87871
|
-
collaboration
|
|
88193
|
+
collaboration,
|
|
88194
|
+
user
|
|
87872
88195
|
});
|
|
87873
88196
|
await writeContextMetadata(paths, metadata);
|
|
87874
88197
|
await setActiveSessionId(metadata.contextId);
|
|
@@ -87890,6 +88213,7 @@ async function runOpen(tokens, context) {
|
|
|
87890
88213
|
dirty: metadata.dirty,
|
|
87891
88214
|
sessionType: metadata.sessionType,
|
|
87892
88215
|
collaboration: metadata.collaboration,
|
|
88216
|
+
bootstrap,
|
|
87893
88217
|
openedAt: metadata.openedAt,
|
|
87894
88218
|
updatedAt: metadata.updatedAt
|
|
87895
88219
|
},
|
|
@@ -87902,7 +88226,7 @@ async function runOpen(tokens, context) {
|
|
|
87902
88226
|
}
|
|
87903
88227
|
}, undefined, sessionId);
|
|
87904
88228
|
}
|
|
87905
|
-
var VALID_OVERRIDE_TYPES;
|
|
88229
|
+
var VALID_OVERRIDE_TYPES, VALID_ON_MISSING;
|
|
87906
88230
|
var init_open = __esm(() => {
|
|
87907
88231
|
init_args();
|
|
87908
88232
|
init_collaboration();
|
|
@@ -87912,6 +88236,7 @@ var init_open = __esm(() => {
|
|
|
87912
88236
|
init_operation_args();
|
|
87913
88237
|
init_session();
|
|
87914
88238
|
VALID_OVERRIDE_TYPES = new Set(["markdown", "html", "text"]);
|
|
88239
|
+
VALID_ON_MISSING = new Set(["seedFromDoc", "blank", "error"]);
|
|
87915
88240
|
});
|
|
87916
88241
|
|
|
87917
88242
|
// src/commands/save.ts
|
|
@@ -94374,7 +94699,9 @@ function profileToKey(profile) {
|
|
|
94374
94699
|
url: profile.url,
|
|
94375
94700
|
documentId: profile.documentId,
|
|
94376
94701
|
tokenEnv: profile.tokenEnv ?? null,
|
|
94377
|
-
syncTimeoutMs: profile.syncTimeoutMs ?? null
|
|
94702
|
+
syncTimeoutMs: profile.syncTimeoutMs ?? null,
|
|
94703
|
+
onMissing: profile.onMissing ?? null,
|
|
94704
|
+
bootstrapSettlingMs: profile.bootstrapSettlingMs ?? null
|
|
94378
94705
|
});
|
|
94379
94706
|
}
|
|
94380
94707
|
function buildFingerprint(metadata) {
|
|
@@ -94417,7 +94744,7 @@ class InMemoryCollaborationSessionPool {
|
|
|
94417
94744
|
await this.disposeSession(sessionId);
|
|
94418
94745
|
}
|
|
94419
94746
|
const profile = metadata.collaboration;
|
|
94420
|
-
const opened = await this.openCollaborative(docPath, io, profile);
|
|
94747
|
+
const opened = await this.openCollaborative(docPath, io, profile, { user: metadata.user });
|
|
94421
94748
|
const created = {
|
|
94422
94749
|
opened,
|
|
94423
94750
|
fingerprint,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdoc-dev/cli",
|
|
3
|
-
"version": "0.2.0-next.
|
|
3
|
+
"version": "0.2.0-next.55",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"superdoc": "./dist/index.js"
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"@types/node": "22.19.2",
|
|
21
21
|
"typescript": "^5.9.2",
|
|
22
22
|
"@superdoc/document-api": "0.0.1",
|
|
23
|
-
"superdoc": "1.16.0",
|
|
24
23
|
"@superdoc/pm-adapter": "0.0.0",
|
|
24
|
+
"superdoc": "1.16.0",
|
|
25
25
|
"@superdoc/super-editor": "0.0.1"
|
|
26
26
|
},
|
|
27
27
|
"module": "src/index.ts",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"optionalDependencies": {
|
|
32
|
-
"@superdoc-dev/cli-darwin-arm64": "0.2.0-next.
|
|
33
|
-
"@superdoc-dev/cli-darwin-x64": "0.2.0-next.
|
|
34
|
-
"@superdoc-dev/cli-linux-x64": "0.2.0-next.
|
|
35
|
-
"@superdoc-dev/cli-
|
|
36
|
-
"@superdoc-dev/cli-
|
|
32
|
+
"@superdoc-dev/cli-darwin-arm64": "0.2.0-next.55",
|
|
33
|
+
"@superdoc-dev/cli-darwin-x64": "0.2.0-next.55",
|
|
34
|
+
"@superdoc-dev/cli-linux-x64": "0.2.0-next.55",
|
|
35
|
+
"@superdoc-dev/cli-linux-arm64": "0.2.0-next.55",
|
|
36
|
+
"@superdoc-dev/cli-windows-x64": "0.2.0-next.55"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"dev": "bun run src/index.ts",
|