@stll/folio-core 0.3.1 → 0.5.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/ai-edits/apply.d.ts +3 -9
- package/dist/ai-edits/apply.js +94 -14
- package/dist/ai-edits/blockRange.d.ts +33 -0
- package/dist/ai-edits/blockRange.js +58 -0
- package/dist/ai-edits/headless.d.ts +35 -5
- package/dist/ai-edits/headless.js +92 -22
- package/dist/ai-edits/index.d.ts +5 -3
- package/dist/ai-edits/index.js +3 -2
- package/dist/ai-edits/snapshot.d.ts +14 -2
- package/dist/ai-edits/snapshot.js +12 -1
- package/dist/ai-edits/types.d.ts +42 -3
- package/dist/compat/eigenpal.d.ts +3 -2
- package/dist/compat/eigenpal.js +6 -5
- package/dist/controller/layoutPipeline.d.ts +1 -0
- package/dist/controller/layoutPipeline.js +35 -115
- package/dist/controller/layoutScheduler.d.ts +2 -1
- package/dist/controller/layoutScheduler.js +6 -0
- package/dist/document-operations.d.ts +122 -0
- package/dist/document-operations.js +575 -0
- package/dist/docx/blockContentParser.js +17 -7
- package/dist/docx/encryption/agileDecryption.d.ts +6 -0
- package/dist/docx/encryption/agileDecryption.js +209 -0
- package/dist/docx/encryption/compoundFile.d.ts +20 -0
- package/dist/docx/encryption/compoundFile.js +251 -0
- package/dist/docx/encryption/containerFormat.d.ts +15 -0
- package/dist/docx/encryption/containerFormat.js +40 -0
- package/dist/docx/encryption/cryptoBytes.d.ts +11 -0
- package/dist/docx/encryption/cryptoBytes.js +55 -0
- package/dist/docx/encryption/encryptionInfo.d.ts +32 -0
- package/dist/docx/encryption/encryptionInfo.js +128 -0
- package/dist/docx/encryption/errors.d.ts +18 -0
- package/dist/docx/encryption/errors.js +13 -0
- package/dist/docx/encryption/index.d.ts +4 -0
- package/dist/docx/encryption/index.js +4 -0
- package/dist/docx/encryption/openEncryptedDocx.d.ts +28 -0
- package/dist/docx/encryption/openEncryptedDocx.js +65 -0
- package/dist/docx/footnoteParser.d.ts +1 -17
- package/dist/docx/footnoteParser.js +1 -27
- package/dist/docx/groupDrawingParser.d.ts +8 -0
- package/dist/docx/groupDrawingParser.js +131 -0
- package/dist/docx/index.d.ts +3 -1
- package/dist/docx/index.js +3 -1
- package/dist/docx/numberingParser.d.ts +3 -1
- package/dist/docx/numberingParser.js +8 -2
- package/dist/docx/paragraphParser.js +9 -3
- package/dist/docx/parser.d.ts +4 -5
- package/dist/docx/parser.js +8 -2
- package/dist/docx/runParser.js +8 -1
- package/dist/docx/selectiveXmlPatch.js +4 -10
- package/dist/docx/serializer/numberingSerializer.js +3 -1
- package/dist/docx/settingsParser.d.ts +6 -3
- package/dist/docx/settingsParser.js +2 -0
- package/dist/docx/unzip.d.ts +7 -5
- package/dist/docx/unzip.js +8 -2
- package/dist/docx/xmlParser.js +11 -4
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -5
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +37 -1
- package/dist/layout-bridge/convert/footnoteLayout.js +138 -14
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +6 -8
- package/dist/layout-bridge/convert/headerFooterLayout.js +21 -13
- package/dist/layout-bridge/convert/toFlowBlocks.js +58 -19
- package/dist/layout-engine/index.d.ts +6 -5
- package/dist/layout-engine/index.js +116 -27
- package/dist/layout-engine/keep-together.d.ts +13 -8
- package/dist/layout-engine/keep-together.js +40 -25
- package/dist/layout-engine/layoutInstrumentation.d.ts +11 -1
- package/dist/layout-engine/layoutInstrumentation.js +10 -1
- package/dist/layout-engine/measure/measureBlocks.js +43 -19
- package/dist/layout-engine/measure/measureParagraph.js +91 -14
- package/dist/layout-engine/paginator.d.ts +2 -1
- package/dist/layout-engine/paginator.js +9 -3
- package/dist/layout-engine/textBoxGroup.d.ts +7 -0
- package/dist/layout-engine/textBoxGroup.js +8 -0
- package/dist/layout-engine/types.d.ts +33 -9
- package/dist/layout-engine/types.js +20 -2
- package/dist/layout-painter/renderPage.d.ts +15 -1
- package/dist/layout-painter/renderPage.js +29 -12
- package/dist/layout-painter/renderParagraph.js +44 -9
- package/dist/layout-painter/renderTable.js +27 -7
- package/dist/managers/DocumentLoaderManager.d.ts +3 -1
- package/dist/managers/DocumentLoaderManager.js +13 -5
- package/dist/managers/TableSelectionManager.js +1 -1
- package/dist/model.js +1 -1
- package/dist/paged-layout/pageText.d.ts +14 -0
- package/dist/paged-layout/pageText.js +21 -0
- package/dist/prosemirror/attrs/index.js +3 -0
- package/dist/prosemirror/commands/comments.js +75 -5
- package/dist/prosemirror/commands/hyperlink.js +4 -2
- package/dist/prosemirror/commands/image.js +2 -1
- package/dist/prosemirror/commands/index.js +1 -1
- package/dist/prosemirror/commands/propertyChangeScope.d.ts +68 -0
- package/dist/prosemirror/commands/propertyChangeScope.js +242 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +21 -5
- package/dist/prosemirror/conversion/toProseDoc.js +43 -15
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +3 -0
- package/dist/prosemirror/extensions/features/ListExtension.js +6 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +12 -11
- package/dist/prosemirror/findReplaceSelection.js +2 -1
- package/dist/prosemirror/index.js +1 -1
- package/dist/prosemirror/insertOperations.js +1 -1
- package/dist/prosemirror/schema/nodes.d.ts +14 -7
- package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
- package/dist/prosemirror/utils/tabCalculator.js +4 -2
- package/dist/redline.d.ts +20 -0
- package/dist/redline.js +127 -0
- package/dist/server.d.ts +7 -3
- package/dist/server.js +6 -2
- package/dist/symbols.d.ts +35 -0
- package/dist/symbols.js +512 -0
- package/dist/utils/clipboard.js +3 -3
- package/dist/utils/fontLoader.js +3 -0
- package/dist/utils/fontResolver.js +65 -1
- package/dist/utils/zoom.d.ts +21 -0
- package/dist/utils/zoom.js +21 -0
- package/dist/version-comparison.d.ts +92 -0
- package/dist/version-comparison.js +436 -0
- package/package.json +7 -3
- package/dist/paged-layout/headerFooterMargins.d.ts +0 -73
- package/dist/paged-layout/headerFooterMargins.js +0 -120
package/dist/ai-edits/apply.d.ts
CHANGED
|
@@ -23,13 +23,7 @@ type ApplyFolioAIEditOperationsOptions = {
|
|
|
23
23
|
author?: string;
|
|
24
24
|
createCommentId?: (text: string) => number;
|
|
25
25
|
};
|
|
26
|
-
declare const applyFolioAIEditOperations: (
|
|
27
|
-
|
|
28
|
-
snapshot,
|
|
29
|
-
operations,
|
|
30
|
-
mode,
|
|
31
|
-
author,
|
|
32
|
-
createCommentId
|
|
33
|
-
}: ApplyFolioAIEditOperationsOptions) => FolioAIEditApplyResult;
|
|
26
|
+
declare const applyFolioAIEditOperations: (options: ApplyFolioAIEditOperationsOptions) => FolioAIEditApplyResult;
|
|
27
|
+
declare const previewFolioAIEditOperations: (options: ApplyFolioAIEditOperationsOptions) => FolioAIEditApplyResult;
|
|
34
28
|
//#endregion
|
|
35
|
-
export { FolioAIEditView, applyFolioAIEditOperations };
|
|
29
|
+
export { FolioAIEditView, applyFolioAIEditOperations, previewFolioAIEditOperations };
|
package/dist/ai-edits/apply.js
CHANGED
|
@@ -193,7 +193,7 @@ const buildEmphasisInlineContent = (schema, text, baseMarks) => {
|
|
|
193
193
|
}
|
|
194
194
|
return nodes.length > 0 ? nodes : [schema.text(text, [...baseMarks])];
|
|
195
195
|
};
|
|
196
|
-
const
|
|
196
|
+
const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode = "tracked-changes", author = "AI", createCommentId, revisionIdSeed }) => {
|
|
197
197
|
const applied = [];
|
|
198
198
|
const skipped = [];
|
|
199
199
|
const resolved = [];
|
|
@@ -210,6 +210,13 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
210
210
|
const liveBlocks = collectLiveBlocksByHash(view.state.doc);
|
|
211
211
|
const liveBlocksByParaId = collectLiveBlocksByParaId(view.state.doc);
|
|
212
212
|
for (const [index, operation] of operations.entries()) {
|
|
213
|
+
if (mode === "tracked-changes" && operation.type === "formatRange") {
|
|
214
|
+
skipped.push({
|
|
215
|
+
id: operation.id,
|
|
216
|
+
reason: "unsupportedMode"
|
|
217
|
+
});
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
213
220
|
const commentText = getOperationCommentText(operation);
|
|
214
221
|
if (commentText !== void 0 && (!commentType || createCommentId === void 0)) {
|
|
215
222
|
skipped.push({
|
|
@@ -244,7 +251,7 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
244
251
|
skipped
|
|
245
252
|
};
|
|
246
253
|
let tr = view.state.tr;
|
|
247
|
-
let revisionSeed = nextRevisionSeed(resolved.length);
|
|
254
|
+
let revisionSeed = revisionIdSeed ?? nextRevisionSeed(resolved.length);
|
|
248
255
|
const date = (/* @__PURE__ */ new Date()).toISOString();
|
|
249
256
|
for (const item of resolved.toSorted((left, right) => {
|
|
250
257
|
if (left.from !== right.from) return right.from - left.from;
|
|
@@ -254,7 +261,8 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
254
261
|
const stepsBefore = tr.steps.length;
|
|
255
262
|
let appliedRevisionIds;
|
|
256
263
|
switch (item.operation.type) {
|
|
257
|
-
case "replaceInBlock":
|
|
264
|
+
case "replaceInBlock":
|
|
265
|
+
case "replaceRange": {
|
|
258
266
|
const revisionIdDelete = revisionSeed++;
|
|
259
267
|
const revisionIdInsert = revisionSeed++;
|
|
260
268
|
tr = applyTextReplacement({
|
|
@@ -270,6 +278,17 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
270
278
|
if (mode === "tracked-changes") appliedRevisionIds = [revisionIdDelete, revisionIdInsert];
|
|
271
279
|
break;
|
|
272
280
|
}
|
|
281
|
+
case "commentOnRange":
|
|
282
|
+
if (commentMark) tr = tr.addMark(item.from, item.to, commentMark);
|
|
283
|
+
break;
|
|
284
|
+
case "formatRange":
|
|
285
|
+
for (const [name, enabled] of Object.entries(item.operation.formatting)) {
|
|
286
|
+
const markType = view.state.schema.marks[name];
|
|
287
|
+
if (!markType) continue;
|
|
288
|
+
if (enabled) tr = tr.addMark(item.from, item.to, name === "underline" ? markType.create({ style: "single" }) : markType.create());
|
|
289
|
+
else tr = tr.removeMark(item.from, item.to, markType);
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
273
292
|
case "replaceBlock": {
|
|
274
293
|
const revisionIdDelete = revisionSeed++;
|
|
275
294
|
const revisionIdInsert = revisionSeed++;
|
|
@@ -314,7 +333,7 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
314
333
|
if (mode === "tracked-changes" && item.operation.pageBreakBefore === true && (!item.insertText || item.insertText.length === 0)) {
|
|
315
334
|
skipped.push({
|
|
316
335
|
id: item.operation.id,
|
|
317
|
-
reason: "
|
|
336
|
+
reason: "unsupportedMode"
|
|
318
337
|
});
|
|
319
338
|
continue;
|
|
320
339
|
}
|
|
@@ -338,6 +357,7 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
338
357
|
attrs["listMarker"] = null;
|
|
339
358
|
attrs["listMarkerHidden"] = null;
|
|
340
359
|
attrs["listLevelNumFmts"] = null;
|
|
360
|
+
attrs["listLevelStarts"] = null;
|
|
341
361
|
attrs["listAbstractNumId"] = null;
|
|
342
362
|
attrs["listStartOverride"] = null;
|
|
343
363
|
}
|
|
@@ -350,7 +370,7 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
350
370
|
if (mode === "tracked-changes") {
|
|
351
371
|
skipped.push({
|
|
352
372
|
id: item.operation.id,
|
|
353
|
-
reason: "
|
|
373
|
+
reason: "unsupportedMode"
|
|
354
374
|
});
|
|
355
375
|
continue;
|
|
356
376
|
}
|
|
@@ -411,15 +431,36 @@ const applyFolioAIEditOperations = ({ view, snapshot, operations, mode = "tracke
|
|
|
411
431
|
skipped
|
|
412
432
|
};
|
|
413
433
|
};
|
|
434
|
+
const applyFolioAIEditOperations = (options) => applyFolioAIEditOperationsInternal(options);
|
|
435
|
+
const previewFolioAIEditOperations = (options) => {
|
|
436
|
+
const { view, createCommentId, ...applyOptions } = options;
|
|
437
|
+
let previewCommentId = -1;
|
|
438
|
+
const previewView = {
|
|
439
|
+
state: view.state,
|
|
440
|
+
dispatch: (transaction) => {
|
|
441
|
+
previewView.state = previewView.state.apply(transaction);
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
const result = applyFolioAIEditOperationsInternal({
|
|
445
|
+
...applyOptions,
|
|
446
|
+
view: previewView,
|
|
447
|
+
...createCommentId !== void 0 && { createCommentId: () => previewCommentId-- },
|
|
448
|
+
revisionIdSeed: -1e9
|
|
449
|
+
});
|
|
450
|
+
return {
|
|
451
|
+
applied: result.applied.map(({ id }) => ({ id })),
|
|
452
|
+
skipped: result.skipped
|
|
453
|
+
};
|
|
454
|
+
};
|
|
414
455
|
const applyTextReplacement = ({ tr, item, mode, author, date, revisionIdDelete, revisionIdInsert, commentMark }) => {
|
|
415
456
|
let nextTr = tr;
|
|
416
457
|
const replacement = stripInlineEmphasisMarkers((() => {
|
|
417
|
-
if (item.operation.type === "replaceInBlock") return item.operation.replace;
|
|
458
|
+
if (item.operation.type === "replaceInBlock" || item.operation.type === "replaceRange") return item.operation.replace;
|
|
418
459
|
if (item.operation.type === "replaceBlock") return item.operation.text;
|
|
419
460
|
return "";
|
|
420
461
|
})());
|
|
421
462
|
if (mode === "direct") {
|
|
422
|
-
if (item.operation.type === "replaceInBlock" && hasInlineEmphasis(item.operation.replace)) {
|
|
463
|
+
if ((item.operation.type === "replaceInBlock" || item.operation.type === "replaceRange") && hasInlineEmphasis(item.operation.replace)) {
|
|
423
464
|
const content = buildEmphasisInlineContent(nextTr.doc.type.schema, item.operation.replace, commentMark ? [commentMark] : []);
|
|
424
465
|
return nextTr.replaceWith(item.from, item.to, content);
|
|
425
466
|
}
|
|
@@ -447,6 +488,9 @@ const applyTextReplacement = ({ tr, item, mode, author, date, revisionIdDelete,
|
|
|
447
488
|
sourceText = item.operation.find;
|
|
448
489
|
sourceCleanStart = cleanBlock.text.indexOf(item.operation.find);
|
|
449
490
|
if (sourceCleanStart === -1) sourceText = null;
|
|
491
|
+
} else if (item.operation.type === "replaceRange") {
|
|
492
|
+
sourceCleanStart = item.operation.range.startOffset;
|
|
493
|
+
sourceText = cleanBlock.text.slice(sourceCleanStart, item.operation.range.endOffset);
|
|
450
494
|
} else if (item.operation.type === "replaceBlock") {
|
|
451
495
|
sourceText = cleanBlock.text;
|
|
452
496
|
sourceCleanStart = 0;
|
|
@@ -518,12 +562,13 @@ const applyTextReplacement = ({ tr, item, mode, author, date, revisionIdDelete,
|
|
|
518
562
|
return nextTr;
|
|
519
563
|
};
|
|
520
564
|
const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId, doc }) => {
|
|
521
|
-
const
|
|
565
|
+
const blockId = operation.type === "replaceRange" || operation.type === "commentOnRange" || operation.type === "formatRange" ? operation.range.blockId : operation.blockId;
|
|
566
|
+
const anchor = snapshot.anchors[blockId];
|
|
522
567
|
if (!anchor) return {
|
|
523
568
|
type: "skip",
|
|
524
569
|
reason: "missingBlock"
|
|
525
570
|
};
|
|
526
|
-
const encodedParaId = getFolioParaIdFromBlockId(
|
|
571
|
+
const encodedParaId = getFolioParaIdFromBlockId(blockId);
|
|
527
572
|
let live;
|
|
528
573
|
if (encodedParaId !== null) {
|
|
529
574
|
live = liveBlocksByParaId.get(encodedParaId);
|
|
@@ -532,7 +577,7 @@ const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId,
|
|
|
532
577
|
reason: "missingBlock"
|
|
533
578
|
};
|
|
534
579
|
} else {
|
|
535
|
-
const ordinal = ordinalAmongSameHash(snapshot,
|
|
580
|
+
const ordinal = ordinalAmongSameHash(snapshot, blockId);
|
|
536
581
|
if (ordinal < 0) return {
|
|
537
582
|
type: "skip",
|
|
538
583
|
reason: "missingBlock"
|
|
@@ -548,10 +593,44 @@ const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId,
|
|
|
548
593
|
const blockTo = live.to;
|
|
549
594
|
const cleanBlock = buildCleanBlockText(blockNode, blockFrom);
|
|
550
595
|
const currentText = cleanBlock.text;
|
|
551
|
-
|
|
596
|
+
const currentTextHash = hashFolioAIBlockText(normalizeFolioAIBlockText(currentText));
|
|
597
|
+
if (operation.precondition !== void 0 && currentTextHash !== operation.precondition.blockTextHash) return {
|
|
598
|
+
type: "skip",
|
|
599
|
+
reason: "preconditionFailed"
|
|
600
|
+
};
|
|
601
|
+
if (currentTextHash !== anchor.textHash) return {
|
|
552
602
|
type: "skip",
|
|
553
603
|
reason: "changedBlock"
|
|
554
604
|
};
|
|
605
|
+
if (operation.type === "replaceRange" || operation.type === "commentOnRange" || operation.type === "formatRange") {
|
|
606
|
+
const { startOffset, endOffset, selectedTextHash } = operation.range;
|
|
607
|
+
const from = cleanBlock.offsets[startOffset];
|
|
608
|
+
const to = cleanBlock.offsets[endOffset];
|
|
609
|
+
if (from === void 0 || to === void 0) return {
|
|
610
|
+
type: "skip",
|
|
611
|
+
reason: "staleRange"
|
|
612
|
+
};
|
|
613
|
+
const selectedText = currentText.slice(startOffset, endOffset);
|
|
614
|
+
if (hashFolioAIBlockText(selectedText) !== selectedTextHash) return {
|
|
615
|
+
type: "skip",
|
|
616
|
+
reason: "staleRange"
|
|
617
|
+
};
|
|
618
|
+
if (operation.type === "replaceRange" && selectedText === operation.replace) return {
|
|
619
|
+
type: "skip",
|
|
620
|
+
reason: "noopOperation"
|
|
621
|
+
};
|
|
622
|
+
return {
|
|
623
|
+
type: "resolved",
|
|
624
|
+
operation: {
|
|
625
|
+
operation,
|
|
626
|
+
from,
|
|
627
|
+
to,
|
|
628
|
+
blockFrom,
|
|
629
|
+
blockTo,
|
|
630
|
+
blockNode
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
}
|
|
555
634
|
if (operation.type === "insertAfterBlock" || operation.type === "insertBeforeBlock") {
|
|
556
635
|
if (operation.text.length === 0 && operation.pageBreakBefore !== true) return {
|
|
557
636
|
type: "skip",
|
|
@@ -623,7 +702,8 @@ const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId,
|
|
|
623
702
|
type: "skip",
|
|
624
703
|
reason: "noopOperation"
|
|
625
704
|
};
|
|
626
|
-
const
|
|
705
|
+
const quote = getOperationQuote(operation);
|
|
706
|
+
const range = resolveTextInCleanBlock(cleanBlock, quote || currentText);
|
|
627
707
|
if (range.type !== "resolved") return range;
|
|
628
708
|
return {
|
|
629
709
|
type: "resolved",
|
|
@@ -674,10 +754,10 @@ const getTextRangeFromCleanBlock = (cleanBlock) => {
|
|
|
674
754
|
to
|
|
675
755
|
};
|
|
676
756
|
};
|
|
677
|
-
const getOperationCommentText = (operation) => operation.comment?.text;
|
|
757
|
+
const getOperationCommentText = (operation) => "comment" in operation ? operation.comment?.text : void 0;
|
|
678
758
|
const getOperationQuote = (operation) => {
|
|
679
759
|
if (operation.type === "replaceInBlock") return operation.find;
|
|
680
760
|
if (operation.type === "commentOnBlock") return operation.quote;
|
|
681
761
|
};
|
|
682
762
|
//#endregion
|
|
683
|
-
export { applyFolioAIEditOperations };
|
|
763
|
+
export { applyFolioAIEditOperations, previewFolioAIEditOperations };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FolioAIEditSnapshot } from "./types.js";
|
|
2
|
+
import { Node } from "prosemirror-model";
|
|
3
|
+
|
|
4
|
+
//#region src/ai-edits/blockRange.d.ts
|
|
5
|
+
type DocPositionRange = {
|
|
6
|
+
from: number;
|
|
7
|
+
to: number;
|
|
8
|
+
};
|
|
9
|
+
type ResolveFolioAIBlockRangeOptions = {
|
|
10
|
+
blockId: string;
|
|
11
|
+
doc: Node;
|
|
12
|
+
snapshot?: FolioAIEditSnapshot | null | undefined;
|
|
13
|
+
};
|
|
14
|
+
declare const resolveFolioAIBlockRange: ({
|
|
15
|
+
blockId,
|
|
16
|
+
doc,
|
|
17
|
+
snapshot
|
|
18
|
+
}: ResolveFolioAIBlockRangeOptions) => DocPositionRange | null;
|
|
19
|
+
/**
|
|
20
|
+
* Clamp a `{from, to}` pair so both endpoints fit inside a document of
|
|
21
|
+
* `docSize` (in PM content positions). Block-boundary snapshots and stale
|
|
22
|
+
* range data sometimes produce a `to` one past the last inline position;
|
|
23
|
+
* `view.state.doc.resolve(...)` rejects that with
|
|
24
|
+
* "Position … out of range", and `TextSelection.between` doesn't help — it
|
|
25
|
+
* needs *valid* resolved positions. Clamping before resolution is the cheap
|
|
26
|
+
* defensive step.
|
|
27
|
+
*
|
|
28
|
+
* Order is preserved: if both endpoints exceed `docSize`, the returned
|
|
29
|
+
* `from` may equal `to`, yielding a cursor selection at the doc end.
|
|
30
|
+
*/
|
|
31
|
+
declare function clampRangeToDocSize(docSize: number, range: DocPositionRange): DocPositionRange;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { DocPositionRange, clampRangeToDocSize, resolveFolioAIBlockRange };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getFolioParaIdFromBlockId, getSequentialFolioBlockIdIndex } from "../types/block-id.js";
|
|
2
|
+
import { createFolioAIEditSnapshot } from "./snapshot.js";
|
|
3
|
+
import { findParagraphByParaId } from "../prosemirror/utils/findParagraphByParaId.js";
|
|
4
|
+
//#region src/ai-edits/blockRange.ts
|
|
5
|
+
const resolveFolioAIBlockRange = ({ blockId, doc, snapshot }) => {
|
|
6
|
+
const paraId = getFolioParaIdFromBlockId(blockId);
|
|
7
|
+
if (paraId !== null) {
|
|
8
|
+
const liveRange = findParagraphByParaId(doc, paraId);
|
|
9
|
+
if (liveRange !== null) return {
|
|
10
|
+
from: liveRange.from,
|
|
11
|
+
to: liveRange.to
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const resolvedSnapshot = snapshot ?? createFolioAIEditSnapshot(doc);
|
|
15
|
+
const anchor = resolvedSnapshot.anchors[blockId] ?? resolveSequentialBlockAnchor(blockId, resolvedSnapshot);
|
|
16
|
+
if (!anchor) return null;
|
|
17
|
+
return clampRangeToDocSize(doc.content.size, anchor);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a `seq-NNNN` fallback id by document position.
|
|
21
|
+
*
|
|
22
|
+
* A sequential id is only minted for a paragraph the source DOCX left
|
|
23
|
+
* without a `w14:paraId`. The live editor's `ParaIdAllocator` fills
|
|
24
|
+
* that gap with a fresh random hex paraId, so a snapshot of the live
|
|
25
|
+
* document keys the block by that hex and never reproduces the
|
|
26
|
+
* server's `seq-NNNN`: the direct anchor lookup misses, and a
|
|
27
|
+
* paraId-based live lookup can't match either (no node carries a
|
|
28
|
+
* `seq-` paraId). The seq number is the block's 1-based position in
|
|
29
|
+
* the same non-empty-block walk the server extractor and
|
|
30
|
+
* `createFolioAIEditSnapshot` share, so it indexes the snapshot's
|
|
31
|
+
* ordered `blocks` directly.
|
|
32
|
+
*/
|
|
33
|
+
const resolveSequentialBlockAnchor = (blockId, snapshot) => {
|
|
34
|
+
const index = getSequentialFolioBlockIdIndex(blockId);
|
|
35
|
+
if (index === null) return;
|
|
36
|
+
const block = snapshot.blocks.at(index - 1);
|
|
37
|
+
return block ? snapshot.anchors[block.id] : void 0;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Clamp a `{from, to}` pair so both endpoints fit inside a document of
|
|
41
|
+
* `docSize` (in PM content positions). Block-boundary snapshots and stale
|
|
42
|
+
* range data sometimes produce a `to` one past the last inline position;
|
|
43
|
+
* `view.state.doc.resolve(...)` rejects that with
|
|
44
|
+
* "Position … out of range", and `TextSelection.between` doesn't help — it
|
|
45
|
+
* needs *valid* resolved positions. Clamping before resolution is the cheap
|
|
46
|
+
* defensive step.
|
|
47
|
+
*
|
|
48
|
+
* Order is preserved: if both endpoints exceed `docSize`, the returned
|
|
49
|
+
* `from` may equal `to`, yielding a cursor selection at the doc end.
|
|
50
|
+
*/
|
|
51
|
+
function clampRangeToDocSize(docSize, range) {
|
|
52
|
+
return {
|
|
53
|
+
from: Math.min(Math.max(range.from, 0), docSize),
|
|
54
|
+
to: Math.min(Math.max(range.to, 0), docSize)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { clampRangeToDocSize, resolveFolioAIBlockRange };
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { FolioAIBlock, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditSnapshot } from "./types.js";
|
|
2
2
|
import { document_d_exports } from "../types/document.js";
|
|
3
|
+
import { FolioDocumentOperationBatch, FolioDocumentOperationResult } from "../document-operations.js";
|
|
3
4
|
import { FolioReviewChange, FolioReviewChangeKind } from "./read.js";
|
|
4
5
|
|
|
5
6
|
//#region src/ai-edits/headless.d.ts
|
|
6
7
|
/** Options for {@link FolioDocxReviewer.fromBuffer}. */
|
|
7
8
|
type FolioDocxReviewerOptions = {
|
|
8
|
-
/** Default author for tracked changes and comments. (default: `"AI"`) */author?: string;
|
|
9
|
+
/** Default author for tracked changes and comments. (default: `"AI"`) */author?: string; /** Password for Agile-encrypted .docx files (Office 2010+). */
|
|
10
|
+
password?: string | undefined;
|
|
9
11
|
};
|
|
10
12
|
/** Options for {@link FolioDocxReviewer.applyOperations}. */
|
|
11
13
|
type FolioApplyOperationsOptions = {
|
|
@@ -17,6 +19,8 @@ type FolioApplyOperationsOptions = {
|
|
|
17
19
|
*/
|
|
18
20
|
snapshot?: FolioAIEditSnapshot;
|
|
19
21
|
};
|
|
22
|
+
/** Options for {@link FolioDocxReviewer.applyDocumentOperations}. */
|
|
23
|
+
type FolioApplyDocumentOperationsOptions = Omit<FolioApplyOperationsOptions, "mode">;
|
|
20
24
|
/** Options for {@link FolioDocxReviewer.getContentAsText}. */
|
|
21
25
|
type FolioGetContentAsTextOptions = {
|
|
22
26
|
/**
|
|
@@ -26,6 +30,19 @@ type FolioGetContentAsTextOptions = {
|
|
|
26
30
|
*/
|
|
27
31
|
annotated?: boolean;
|
|
28
32
|
};
|
|
33
|
+
type FolioDocumentStoryHandle = {
|
|
34
|
+
type: "main";
|
|
35
|
+
} | {
|
|
36
|
+
type: "header" | "footer";
|
|
37
|
+
relationshipId: string;
|
|
38
|
+
} | {
|
|
39
|
+
type: "footnote" | "endnote";
|
|
40
|
+
noteId: number;
|
|
41
|
+
};
|
|
42
|
+
type FolioDocumentStory = {
|
|
43
|
+
handle: FolioDocumentStoryHandle;
|
|
44
|
+
text: string;
|
|
45
|
+
};
|
|
29
46
|
/** Filter for {@link FolioDocxReviewer.getChanges}. */
|
|
30
47
|
type FolioReviewChangeFilter = {
|
|
31
48
|
author?: string;
|
|
@@ -104,6 +121,13 @@ declare class FolioDocxReviewer {
|
|
|
104
121
|
* (including any comments) is retained for {@link toBuffer}.
|
|
105
122
|
*/
|
|
106
123
|
applyOperations(operations: FolioAIEditOperation[], options?: FolioApplyOperationsOptions): FolioAIEditApplyResult;
|
|
124
|
+
/**
|
|
125
|
+
* Apply a versioned document-operation batch against the current state.
|
|
126
|
+
* This is the contract entry point for serialized callers; the legacy
|
|
127
|
+
* {@link applyOperations} method delegates here so both APIs keep identical
|
|
128
|
+
* edit semantics.
|
|
129
|
+
*/
|
|
130
|
+
applyDocumentOperations(batch: FolioDocumentOperationBatch, options?: FolioApplyDocumentOperationsOptions): FolioDocumentOperationResult;
|
|
107
131
|
/**
|
|
108
132
|
* The body blocks with their stable ids, in document order — the same
|
|
109
133
|
* `FolioAIBlock` shape {@link snapshot} builds, reused verbatim so the ids
|
|
@@ -130,6 +154,10 @@ declare class FolioDocxReviewer {
|
|
|
130
154
|
* Empty parts and separator notes are omitted.
|
|
131
155
|
*/
|
|
132
156
|
getNotesAsText(): string;
|
|
157
|
+
/** Discover every readable document story through a typed, serializable handle. */
|
|
158
|
+
listStories(): FolioDocumentStory[];
|
|
159
|
+
/** Read one discovered story; returns null when its handle is no longer present. */
|
|
160
|
+
readStory(handle: FolioDocumentStoryHandle): FolioDocumentStory | null;
|
|
133
161
|
/**
|
|
134
162
|
* The tracked changes (insertions and deletions) present in the body, read
|
|
135
163
|
* from the same `insertion` / `deletion` marks the editor renders. Each
|
|
@@ -209,9 +237,11 @@ declare class FolioDocxReviewer {
|
|
|
209
237
|
private trySelectiveSave;
|
|
210
238
|
/**
|
|
211
239
|
* Count every tracked change an accept-all / reject-all sweep resolves: the
|
|
212
|
-
* inline insertion / deletion groups {@link getChanges} enumerates, plus
|
|
213
|
-
*
|
|
214
|
-
* paragraph
|
|
240
|
+
* inline insertion / deletion groups {@link getChanges} enumerates, plus the
|
|
241
|
+
* property-change records living on node attrs rather than inline marks —
|
|
242
|
+
* paragraph-level (`pPrMark`, `_propertyChanges`, the inline sectPr's
|
|
243
|
+
* `propertyChanges`) and table-level (`tblPrChange` / `trPrChange` /
|
|
244
|
+
* `tcPrChange`).
|
|
215
245
|
*/
|
|
216
246
|
private countTrackedChanges;
|
|
217
247
|
/** Apply any {@link resolveComment} overrides recorded for these comments. */
|
|
@@ -249,4 +279,4 @@ type ApplyFolioAIEditsToBufferResult = FolioAIEditApplyResult & {
|
|
|
249
279
|
*/
|
|
250
280
|
declare const applyFolioAIEditsToBuffer: (buffer: ArrayBuffer, operations: FolioAIEditOperation[], options?: ApplyFolioAIEditsToBufferOptions) => Promise<ApplyFolioAIEditsToBufferResult>;
|
|
251
281
|
//#endregion
|
|
252
|
-
export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FolioApplyOperationsOptions, FolioDocxReviewer, FolioDocxReviewerOptions, FolioGetContentAsTextOptions, type FolioReviewChange, FolioReviewChangeFilter, type FolioReviewChangeKind, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, applyFolioAIEditsToBuffer };
|
|
282
|
+
export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FolioApplyDocumentOperationsOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocxReviewer, FolioDocxReviewerOptions, FolioGetContentAsTextOptions, type FolioReviewChange, FolioReviewChangeFilter, type FolioReviewChangeKind, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, applyFolioAIEditsToBuffer };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
2
|
+
import { createFolioAIEditSnapshot, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
3
|
+
import { applyFolioDocumentOperations } from "../document-operations.js";
|
|
1
4
|
import { getEndnoteText, getFootnoteText, isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
|
|
2
5
|
import { deterministicHexId } from "../utils/hexId.js";
|
|
3
6
|
import { repackDocx } from "../docx/rezip.js";
|
|
4
|
-
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
5
|
-
import { createFolioAIEditSnapshot, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
6
|
-
import { applyFolioAIEditOperations } from "./apply.js";
|
|
7
7
|
import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
|
|
8
8
|
import { createReply } from "../docx/replyToComment.js";
|
|
9
9
|
import { attemptSelectiveSave } from "../docx/selectiveSave.js";
|
|
@@ -181,17 +181,19 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
181
181
|
static async fromBuffer(buffer, options = {}) {
|
|
182
182
|
const baseDocument = await parseDocx(buffer, {
|
|
183
183
|
detectVariables: false,
|
|
184
|
-
preloadFonts: false
|
|
184
|
+
preloadFonts: false,
|
|
185
|
+
password: options.password
|
|
185
186
|
});
|
|
186
187
|
const plugins = singletonManager.getPlugins();
|
|
188
|
+
const state = ensureDeterministicParaIdsInState(EditorState.create({
|
|
189
|
+
schema,
|
|
190
|
+
doc: toProseDoc(baseDocument),
|
|
191
|
+
plugins
|
|
192
|
+
}));
|
|
187
193
|
return new FolioDocxReviewer({
|
|
188
194
|
baseDocument,
|
|
189
|
-
originalBuffer: buffer,
|
|
190
|
-
state
|
|
191
|
-
schema,
|
|
192
|
-
doc: toProseDoc(baseDocument),
|
|
193
|
-
plugins
|
|
194
|
-
})),
|
|
195
|
+
originalBuffer: baseDocument.originalBuffer ?? buffer,
|
|
196
|
+
state,
|
|
195
197
|
author: options.author ?? "AI"
|
|
196
198
|
});
|
|
197
199
|
}
|
|
@@ -208,18 +210,33 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
208
210
|
* (including any comments) is retained for {@link toBuffer}.
|
|
209
211
|
*/
|
|
210
212
|
applyOperations(operations, options = {}) {
|
|
211
|
-
const
|
|
213
|
+
const { applied, skipped } = this.applyDocumentOperations({
|
|
214
|
+
version: 1,
|
|
215
|
+
operations,
|
|
216
|
+
mode: options.mode ?? "tracked-changes"
|
|
217
|
+
}, { ...options.snapshot !== void 0 && { snapshot: options.snapshot } });
|
|
218
|
+
return {
|
|
219
|
+
applied,
|
|
220
|
+
skipped
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Apply a versioned document-operation batch against the current state.
|
|
225
|
+
* This is the contract entry point for serialized callers; the legacy
|
|
226
|
+
* {@link applyOperations} method delegates here so both APIs keep identical
|
|
227
|
+
* edit semantics.
|
|
228
|
+
*/
|
|
229
|
+
applyDocumentOperations(batch, options = {}) {
|
|
212
230
|
const view = {
|
|
213
231
|
state: this.state,
|
|
214
232
|
dispatch: (transaction) => {
|
|
215
233
|
view.state = view.state.apply(transaction);
|
|
216
234
|
}
|
|
217
235
|
};
|
|
218
|
-
const result =
|
|
236
|
+
const result = applyFolioDocumentOperations({
|
|
219
237
|
view,
|
|
220
|
-
snapshot,
|
|
221
|
-
|
|
222
|
-
mode: options.mode ?? "tracked-changes",
|
|
238
|
+
snapshot: options.snapshot ?? this.snapshot(),
|
|
239
|
+
batch,
|
|
223
240
|
author: this.author,
|
|
224
241
|
createCommentId: (text) => {
|
|
225
242
|
const comment = createReviewerComment(text, this.author);
|
|
@@ -257,7 +274,8 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
257
274
|
return snapshot.blocks.map((block) => {
|
|
258
275
|
const from = startById.get(block.id);
|
|
259
276
|
const node = from === void 0 ? null : this.state.doc.nodeAt(from);
|
|
260
|
-
|
|
277
|
+
const text = node ? buildAnnotatedBlockText(node) : block.text;
|
|
278
|
+
return formatBlockLine(block, text);
|
|
261
279
|
}).join("\n");
|
|
262
280
|
}
|
|
263
281
|
/**
|
|
@@ -291,6 +309,50 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
291
309
|
}
|
|
292
310
|
return lines.join("\n");
|
|
293
311
|
}
|
|
312
|
+
/** Discover every readable document story through a typed, serializable handle. */
|
|
313
|
+
listStories() {
|
|
314
|
+
const pkg = this.baseDocument.package;
|
|
315
|
+
const stories = [{
|
|
316
|
+
handle: { type: "main" },
|
|
317
|
+
text: this.getContentAsText()
|
|
318
|
+
}];
|
|
319
|
+
for (const [relationshipId, header] of pkg.headers ?? []) stories.push({
|
|
320
|
+
handle: {
|
|
321
|
+
type: "header",
|
|
322
|
+
relationshipId
|
|
323
|
+
},
|
|
324
|
+
text: normalizeFolioAIBlockText(getHeaderFooterText(header))
|
|
325
|
+
});
|
|
326
|
+
for (const [relationshipId, footer] of pkg.footers ?? []) stories.push({
|
|
327
|
+
handle: {
|
|
328
|
+
type: "footer",
|
|
329
|
+
relationshipId
|
|
330
|
+
},
|
|
331
|
+
text: normalizeFolioAIBlockText(getHeaderFooterText(footer))
|
|
332
|
+
});
|
|
333
|
+
for (const footnote of pkg.footnotes ?? []) if (!isSeparatorFootnote(footnote)) stories.push({
|
|
334
|
+
handle: {
|
|
335
|
+
type: "footnote",
|
|
336
|
+
noteId: footnote.id
|
|
337
|
+
},
|
|
338
|
+
text: normalizeFolioAIBlockText(getFootnoteText(footnote))
|
|
339
|
+
});
|
|
340
|
+
for (const endnote of pkg.endnotes ?? []) if (!isSeparatorEndnote(endnote)) stories.push({
|
|
341
|
+
handle: {
|
|
342
|
+
type: "endnote",
|
|
343
|
+
noteId: endnote.id
|
|
344
|
+
},
|
|
345
|
+
text: normalizeFolioAIBlockText(getEndnoteText(endnote))
|
|
346
|
+
});
|
|
347
|
+
return stories;
|
|
348
|
+
}
|
|
349
|
+
/** Read one discovered story; returns null when its handle is no longer present. */
|
|
350
|
+
readStory(handle) {
|
|
351
|
+
const stories = this.listStories();
|
|
352
|
+
if (handle.type === "main") return stories.at(0) ?? null;
|
|
353
|
+
if (handle.type === "header" || handle.type === "footer") return stories.find(({ handle: candidate }) => candidate.type === handle.type && candidate.relationshipId === handle.relationshipId) ?? null;
|
|
354
|
+
return stories.find(({ handle: candidate }) => (candidate.type === "footnote" || candidate.type === "endnote") && candidate.type === handle.type && candidate.noteId === handle.noteId) ?? null;
|
|
355
|
+
}
|
|
294
356
|
/**
|
|
295
357
|
* The tracked changes (insertions and deletions) present in the body, read
|
|
296
358
|
* from the same `insertion` / `deletion` marks the editor renders. Each
|
|
@@ -462,18 +524,26 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
462
524
|
}
|
|
463
525
|
/**
|
|
464
526
|
* Count every tracked change an accept-all / reject-all sweep resolves: the
|
|
465
|
-
* inline insertion / deletion groups {@link getChanges} enumerates, plus
|
|
466
|
-
*
|
|
467
|
-
* paragraph
|
|
527
|
+
* inline insertion / deletion groups {@link getChanges} enumerates, plus the
|
|
528
|
+
* property-change records living on node attrs rather than inline marks —
|
|
529
|
+
* paragraph-level (`pPrMark`, `_propertyChanges`, the inline sectPr's
|
|
530
|
+
* `propertyChanges`) and table-level (`tblPrChange` / `trPrChange` /
|
|
531
|
+
* `tcPrChange`).
|
|
468
532
|
*/
|
|
469
533
|
countTrackedChanges() {
|
|
534
|
+
const hasEntries = (value) => Array.isArray(value) && value.length > 0;
|
|
470
535
|
let count = this.getChanges().length;
|
|
471
536
|
this.state.doc.descendants((node) => {
|
|
472
|
-
|
|
537
|
+
const typeName = node.type.name;
|
|
538
|
+
if (typeName === "table" && hasEntries(node.attrs["tblPrChange"])) count += 1;
|
|
539
|
+
if (typeName === "tableRow" && hasEntries(node.attrs["trPrChange"])) count += 1;
|
|
540
|
+
if ((typeName === "tableCell" || typeName === "tableHeader") && hasEntries(node.attrs["tcPrChange"])) count += 1;
|
|
541
|
+
if (typeName !== "paragraph") return;
|
|
473
542
|
const pPrMark = node.attrs["pPrMark"];
|
|
474
543
|
if (pPrMark !== null && pPrMark !== void 0) count += 1;
|
|
475
|
-
|
|
476
|
-
|
|
544
|
+
if (hasEntries(node.attrs["_propertyChanges"])) count += 1;
|
|
545
|
+
const sectionProperties = node.attrs["_sectionProperties"];
|
|
546
|
+
if (hasEntries(sectionProperties?.propertyChanges)) count += 1;
|
|
477
547
|
return false;
|
|
478
548
|
});
|
|
479
549
|
return count;
|
package/dist/ai-edits/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAISignatureParty } from "./types.js";
|
|
1
|
+
import { FolioAIBlock, FolioAIBlockAnchor, FolioAIBlockKind, FolioAIBlockPreviewRun, FolioAIComment, FolioAIEditAppliedOperation, FolioAIEditApplyMode, FolioAIEditApplyResult, FolioAIEditOperation, FolioAIEditPrecondition, FolioAIEditReviewMeta, FolioAIEditSeverity, FolioAIEditSkipReason, FolioAIEditSkippedOperation, FolioAIEditSnapshot, FolioAIInlineFormatting, FolioAISignatureParty, FolioAITextRangeHandle } from "./types.js";
|
|
2
2
|
import { FolioAIEditView, applyFolioAIEditOperations } from "./apply.js";
|
|
3
3
|
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
4
|
+
import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationStatus, FolioDocumentOperationType, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
4
5
|
import { FolioCommentAnchor, FolioReviewChange, FolioReviewChangeKind, getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
|
|
5
|
-
import {
|
|
6
|
+
import { FolioDocumentStory, FolioDocumentStoryHandle } from "./headless.js";
|
|
7
|
+
import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
6
8
|
import { getFolioParaIdFromBlockId } from "../types/block-id.js";
|
|
7
9
|
import { WordDiffSegment, diffWordSegments } from "./word-diff.js";
|
|
8
|
-
export { type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIEditView, type FolioAISignatureParty, type FolioCommentAnchor, type FolioReviewChange, type FolioReviewChangeKind, type WordDiffSegment, applyFolioAIEditOperations, buildAnnotatedBlockText, createFolioAIEditSnapshot, diffWordSegments, getCommentAnchorsFromDoc, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, normalizeFolioAIBlockText };
|
|
10
|
+
export { type ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyResult, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIEditView, type FolioAIInlineFormatting, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioCommentAnchor, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationType, type FolioDocumentStory, type FolioDocumentStoryHandle, type FolioReviewChange, type FolioReviewChangeKind, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch };
|
package/dist/ai-edits/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getFolioParaIdFromBlockId } from "../types/block-id.js";
|
|
2
2
|
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
3
|
-
import { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
3
|
+
import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
4
4
|
import { diffWordSegments } from "./word-diff.js";
|
|
5
5
|
import { applyFolioAIEditOperations } from "./apply.js";
|
|
6
|
+
import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
6
7
|
import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
|
|
7
|
-
export { applyFolioAIEditOperations, buildAnnotatedBlockText, createFolioAIEditSnapshot, diffWordSegments, getCommentAnchorsFromDoc, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, normalizeFolioAIBlockText };
|
|
8
|
+
export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch };
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
import { FolioAIEditSnapshot } from "./types.js";
|
|
1
|
+
import { FolioAIEditSnapshot, FolioAITextRangeHandle } from "./types.js";
|
|
2
2
|
import { Node } from "prosemirror-model";
|
|
3
3
|
|
|
4
4
|
//#region src/ai-edits/snapshot.d.ts
|
|
5
5
|
declare const normalizeFolioAIBlockText: (text: string) => string;
|
|
6
6
|
declare const hashFolioAIBlockText: (text: string) => string;
|
|
7
|
+
type CreateFolioAITextRangeHandleOptions = {
|
|
8
|
+
blockId: string;
|
|
9
|
+
text: string;
|
|
10
|
+
startOffset: number;
|
|
11
|
+
endOffset: number;
|
|
12
|
+
};
|
|
13
|
+
declare const createFolioAITextRangeHandle: ({
|
|
14
|
+
blockId,
|
|
15
|
+
text,
|
|
16
|
+
startOffset,
|
|
17
|
+
endOffset
|
|
18
|
+
}: CreateFolioAITextRangeHandleOptions) => FolioAITextRangeHandle | null;
|
|
7
19
|
declare const createFolioAIEditSnapshot: (doc: Node) => FolioAIEditSnapshot;
|
|
8
20
|
//#endregion
|
|
9
|
-
export { createFolioAIEditSnapshot, hashFolioAIBlockText, normalizeFolioAIBlockText };
|
|
21
|
+
export { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, normalizeFolioAIBlockText };
|