@stll/folio-core 0.9.0 → 0.10.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/headless.d.ts +52 -12
- package/dist/ai-edits/headless.js +181 -55
- package/dist/ai-edits/index.d.ts +2 -2
- package/dist/ai-edits/index.js +2 -2
- package/dist/controller/layoutPipeline.js +2 -1
- package/dist/document-operations.d.ts +11 -2
- package/dist/document-operations.js +7 -1
- package/dist/document-stories.d.ts +10 -0
- package/dist/document-stories.js +27 -0
- package/dist/docx/corePropertiesParser.d.ts +8 -0
- package/dist/docx/corePropertiesParser.js +53 -0
- package/dist/docx/index.d.ts +2 -1
- package/dist/docx/index.js +2 -1
- package/dist/docx/metadataPrivacy.d.ts +40 -0
- package/dist/docx/metadataPrivacy.js +131 -0
- package/dist/docx/parser.js +4 -1
- package/dist/docx/rezip.d.ts +5 -4
- package/dist/docx/rezip.js +6 -8
- package/dist/layout-bridge/convert/toFlowBlocks.js +1 -0
- package/dist/layout-engine/measure/cache.js +2 -7
- package/dist/layout-engine/measure/effectiveLineBreakPolicy.d.ts +29 -0
- package/dist/layout-engine/measure/effectiveLineBreakPolicy.js +60 -0
- package/dist/layout-engine/measure/measureParagraph.js +32 -36
- package/dist/layout-engine/measure/tableCellFloating.js +39 -33
- package/dist/layout-engine/types.d.ts +5 -3
- package/dist/prosemirror/attrs/index.js +1 -0
- package/dist/prosemirror/conversion/effectiveTableCellFormatting.d.ts +62 -0
- package/dist/prosemirror/conversion/effectiveTableCellFormatting.js +131 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +1 -0
- package/dist/prosemirror/conversion/toProseDoc.js +40 -68
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
- package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
- package/dist/prosemirror/extensions/nodes/ImageExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TableExtension.js +1 -1
- package/dist/prosemirror/schema/nodes.d.ts +2 -1
- package/dist/redline.d.ts +26 -11
- package/dist/redline.js +95 -62
- package/dist/server.d.ts +5 -4
- package/dist/server.js +5 -4
- package/dist/version-comparison.d.ts +65 -11
- package/dist/version-comparison.js +187 -29
- package/package.json +1 -1
|
@@ -30,22 +30,50 @@ type FolioGetContentAsTextOptions = {
|
|
|
30
30
|
*/
|
|
31
31
|
annotated?: boolean;
|
|
32
32
|
};
|
|
33
|
+
declare const FOLIO_REVIEWED_VIEWS: readonly ["original", "current-markup", "final"];
|
|
34
|
+
type FolioReviewedView = (typeof FOLIO_REVIEWED_VIEWS)[number];
|
|
35
|
+
declare const FOLIO_RESOLVED_REVIEWED_VIEWS: readonly ["original", "final"];
|
|
36
|
+
type FolioResolvedReviewedView = (typeof FOLIO_RESOLVED_REVIEWED_VIEWS)[number];
|
|
33
37
|
type FolioDocumentStoryHandle = {
|
|
34
38
|
type: "main";
|
|
35
39
|
} | {
|
|
36
|
-
type: "header"
|
|
40
|
+
type: "header";
|
|
37
41
|
relationshipId: string;
|
|
38
42
|
} | {
|
|
39
|
-
type: "
|
|
43
|
+
type: "footer";
|
|
44
|
+
relationshipId: string;
|
|
45
|
+
} | {
|
|
46
|
+
type: "footnote";
|
|
47
|
+
noteId: number;
|
|
48
|
+
} | {
|
|
49
|
+
type: "endnote";
|
|
40
50
|
noteId: number;
|
|
41
51
|
};
|
|
42
|
-
type FolioEditableDocumentStoryHandle =
|
|
43
|
-
type: "footnote" | "endnote";
|
|
44
|
-
}>;
|
|
52
|
+
type FolioEditableDocumentStoryHandle = FolioDocumentStoryHandle;
|
|
45
53
|
type FolioDocumentStory = {
|
|
46
54
|
handle: FolioDocumentStoryHandle;
|
|
47
55
|
text: string;
|
|
48
56
|
};
|
|
57
|
+
type FolioReadReviewedStoryOptions = {
|
|
58
|
+
story?: FolioEditableDocumentStoryHandle;
|
|
59
|
+
view?: FolioReviewedView;
|
|
60
|
+
};
|
|
61
|
+
type FolioResolveReviewedStoryOptions = {
|
|
62
|
+
story?: FolioEditableDocumentStoryHandle;
|
|
63
|
+
view: FolioResolvedReviewedView;
|
|
64
|
+
};
|
|
65
|
+
type FolioReviewedStory = {
|
|
66
|
+
story: FolioEditableDocumentStoryHandle;
|
|
67
|
+
view: FolioReviewedView;
|
|
68
|
+
snapshot: FolioAIEditSnapshot;
|
|
69
|
+
text: string;
|
|
70
|
+
changes: FolioReviewChange[];
|
|
71
|
+
};
|
|
72
|
+
declare const UnsupportedFolioReviewedViewError_base: import("better-result").TaggedErrorClass<"UnsupportedFolioReviewedViewError", {
|
|
73
|
+
message: string;
|
|
74
|
+
receivedView: unknown;
|
|
75
|
+
}>;
|
|
76
|
+
declare class UnsupportedFolioReviewedViewError extends UnsupportedFolioReviewedViewError_base {}
|
|
49
77
|
declare const FolioDocumentStoryNotFoundError_base: import("better-result").TaggedErrorClass<"FolioDocumentStoryNotFoundError", {
|
|
50
78
|
message: string;
|
|
51
79
|
story: FolioEditableDocumentStoryHandle;
|
|
@@ -55,6 +83,8 @@ type FolioApplyDocumentOperationsToStoryOptions = FolioApplyDocumentOperationsOp
|
|
|
55
83
|
story: FolioEditableDocumentStoryHandle;
|
|
56
84
|
batch: FolioDocumentOperationBatch;
|
|
57
85
|
};
|
|
86
|
+
declare const isFolioReviewedView: (value: unknown) => value is FolioReviewedView;
|
|
87
|
+
declare const isFolioResolvedReviewedView: (value: unknown) => value is FolioResolvedReviewedView;
|
|
58
88
|
/** Filter for {@link FolioDocxReviewer.getChanges}. */
|
|
59
89
|
type FolioReviewChangeFilter = {
|
|
60
90
|
author?: string;
|
|
@@ -109,7 +139,7 @@ declare class FolioDocxReviewer {
|
|
|
109
139
|
private readonly baseDocument;
|
|
110
140
|
private readonly originalBuffer;
|
|
111
141
|
private state;
|
|
112
|
-
private readonly
|
|
142
|
+
private readonly secondaryStoryStates;
|
|
113
143
|
private readonly createdComments;
|
|
114
144
|
private readonly documentOperationUndoEntries;
|
|
115
145
|
/**
|
|
@@ -129,8 +159,17 @@ declare class FolioDocxReviewer {
|
|
|
129
159
|
* the anchor map the apply layer resolves operations against.
|
|
130
160
|
*/
|
|
131
161
|
snapshot(): FolioAIEditSnapshot;
|
|
162
|
+
/** Return parsed package metadata without exposing the mutable document model. */
|
|
163
|
+
getDocumentProperties(): Readonly<NonNullable<document_d_exports.Document["package"]["properties"]>> | null;
|
|
132
164
|
/** Snapshot one editable story into stable, operation-ready blocks. */
|
|
133
165
|
snapshotStory(story: FolioEditableDocumentStoryHandle): FolioAIEditSnapshot | null;
|
|
166
|
+
/** Read one story through an immutable reviewed-view projection. */
|
|
167
|
+
readReviewedStory(options?: FolioReadReviewedStoryOptions): FolioReviewedStory | null;
|
|
168
|
+
/** Resolve one editable story to its original or final state. */
|
|
169
|
+
resolveReviewedStory({
|
|
170
|
+
story,
|
|
171
|
+
view
|
|
172
|
+
}: FolioResolveReviewedStoryOptions): boolean;
|
|
134
173
|
/**
|
|
135
174
|
* Apply operations against the current state. Reuses the live-editor applier
|
|
136
175
|
* verbatim via a headless `{ state, dispatch }` seam; the resulting state
|
|
@@ -144,7 +183,7 @@ declare class FolioDocxReviewer {
|
|
|
144
183
|
* edit semantics.
|
|
145
184
|
*/
|
|
146
185
|
applyDocumentOperations(batch: FolioDocumentOperationBatch, options?: FolioApplyDocumentOperationsOptions): FolioDocumentOperationResult;
|
|
147
|
-
/** Apply a versioned operation batch to
|
|
186
|
+
/** Apply a versioned operation batch to one editable document story. */
|
|
148
187
|
applyDocumentOperationsToStory({
|
|
149
188
|
story,
|
|
150
189
|
batch,
|
|
@@ -174,9 +213,8 @@ declare class FolioDocxReviewer {
|
|
|
174
213
|
/**
|
|
175
214
|
* Header / footer and footnote / endnote text as labeled, LLM-ready lines,
|
|
176
215
|
* one per non-empty part: `[header default] …`, `[footer default] …`,
|
|
177
|
-
* `[footnote #N] …`, `[endnote #N] …`.
|
|
178
|
-
*
|
|
179
|
-
* separator notes are omitted.
|
|
216
|
+
* `[footnote #N] …`, `[endnote #N] …`. Lines reflect in-memory edits. Empty
|
|
217
|
+
* parts and separator notes are omitted.
|
|
180
218
|
*/
|
|
181
219
|
getNotesAsText(): string;
|
|
182
220
|
/** Discover every readable document story through a typed, serializable handle. */
|
|
@@ -264,8 +302,10 @@ declare class FolioDocxReviewer {
|
|
|
264
302
|
private requireEditableStoryState;
|
|
265
303
|
private setEditableStoryState;
|
|
266
304
|
private getHeaderFooterStory;
|
|
305
|
+
private getNoteStory;
|
|
267
306
|
private getHeaderFooterStoryText;
|
|
268
|
-
private
|
|
307
|
+
private getNoteStoryText;
|
|
308
|
+
private mergeEditedSecondaryStories;
|
|
269
309
|
/**
|
|
270
310
|
* Count every tracked change an accept-all / reject-all sweep resolves: the
|
|
271
311
|
* inline insertion / deletion groups {@link getChanges} enumerates, plus the
|
|
@@ -310,4 +350,4 @@ type ApplyFolioAIEditsToBufferResult = FolioAIEditApplyResult & {
|
|
|
310
350
|
*/
|
|
311
351
|
declare const applyFolioAIEditsToBuffer: (buffer: ArrayBuffer, operations: FolioAIEditOperation[], options?: ApplyFolioAIEditsToBufferOptions) => Promise<ApplyFolioAIEditsToBufferResult>;
|
|
312
352
|
//#endregion
|
|
313
|
-
export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioGetContentAsTextOptions, type FolioReviewChange, FolioReviewChangeFilter, type FolioReviewChangeKind, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, applyFolioAIEditsToBuffer };
|
|
353
|
+
export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsOptions, FolioApplyDocumentOperationsToStoryOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioDocxReviewer, FolioDocxReviewerOptions, FolioEditableDocumentStoryHandle, FolioGetContentAsTextOptions, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, type FolioReviewChange, FolioReviewChangeFilter, type FolioReviewChangeKind, FolioReviewComment, FolioReviewCommentFilter, FolioReviewCommentReply, FolioReviewReplyInput, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView };
|
|
@@ -13,7 +13,7 @@ import { acceptAIEditRevision, acceptAllChanges, rejectAIEditRevision, rejectAll
|
|
|
13
13
|
import { proseDocToBlocks, updateDocumentContent } from "../prosemirror/conversion/fromProseDoc.js";
|
|
14
14
|
import { getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges, ignoreTrackedChanges } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
|
|
15
15
|
import { schema, singletonManager } from "../prosemirror/schema/index.js";
|
|
16
|
-
import { headerFooterToProseDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
|
|
16
|
+
import { footnoteToProseDoc, headerFooterToProseDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
|
|
17
17
|
import { TaggedError } from "better-result";
|
|
18
18
|
import { EditorState } from "prosemirror-state";
|
|
19
19
|
//#region src/ai-edits/headless.ts
|
|
@@ -34,8 +34,7 @@ import { EditorState } from "prosemirror-state";
|
|
|
34
34
|
* paragraphs in `document.xml` (leaving every untouched part byte-exact), with
|
|
35
35
|
* a full repack as the fallback for structural edits.
|
|
36
36
|
*
|
|
37
|
-
* Scope: main, header,
|
|
38
|
-
* the note serialization path separately.
|
|
37
|
+
* Scope: main, header, footer, footnote, and endnote blocks.
|
|
39
38
|
*/
|
|
40
39
|
/**
|
|
41
40
|
* Standalone comment-id allocator for the reviewer. The React editor uses
|
|
@@ -115,9 +114,43 @@ const ensureDeterministicParaIdsInState = (state) => {
|
|
|
115
114
|
tr.setMeta("addToHistory", false);
|
|
116
115
|
return state.apply(tr);
|
|
117
116
|
};
|
|
117
|
+
const FOLIO_REVIEWED_VIEWS = Object.freeze([
|
|
118
|
+
"original",
|
|
119
|
+
"current-markup",
|
|
120
|
+
"final"
|
|
121
|
+
]);
|
|
122
|
+
const FOLIO_RESOLVED_REVIEWED_VIEWS = Object.freeze(["original", "final"]);
|
|
123
|
+
var UnsupportedFolioReviewedViewError = class extends TaggedError("UnsupportedFolioReviewedViewError")() {};
|
|
118
124
|
var FolioDocumentStoryNotFoundError = class extends TaggedError("FolioDocumentStoryNotFoundError")() {};
|
|
119
125
|
const MAIN_STORY = Object.freeze({ type: "main" });
|
|
120
126
|
const headerFooterStoryKey = ({ type, relationshipId }) => `${type}:${relationshipId}`;
|
|
127
|
+
const noteStoryKey = ({ type, noteId }) => `${type}:${noteId}`;
|
|
128
|
+
const secondaryStoryKey = (story) => story.type === "header" || story.type === "footer" ? headerFooterStoryKey(story) : noteStoryKey(story);
|
|
129
|
+
const isFolioReviewedView = (value) => FOLIO_REVIEWED_VIEWS.some((view) => view === value);
|
|
130
|
+
const isFolioResolvedReviewedView = (value) => FOLIO_RESOLVED_REVIEWED_VIEWS.some((view) => view === value);
|
|
131
|
+
const applyCommandToState = (state, command) => {
|
|
132
|
+
let nextState = state;
|
|
133
|
+
command(state, (transaction) => {
|
|
134
|
+
nextState = nextState.apply(transaction);
|
|
135
|
+
});
|
|
136
|
+
return nextState;
|
|
137
|
+
};
|
|
138
|
+
const resolveReviewedState = (state, view) => {
|
|
139
|
+
if (view === "current-markup") return state;
|
|
140
|
+
return applyCommandToState(state, view === "original" ? rejectAllChanges() : acceptAllChanges());
|
|
141
|
+
};
|
|
142
|
+
const formatStoryStateForLLM = (state, annotated) => {
|
|
143
|
+
const snapshot = createFolioAIEditSnapshot(state.doc);
|
|
144
|
+
if (!annotated) return snapshot.blocks.map(formatBlockForLLM).join("\n");
|
|
145
|
+
const startById = /* @__PURE__ */ new Map();
|
|
146
|
+
for (const anchor of Object.values(snapshot.anchors)) startById.set(anchor.id, anchor.from);
|
|
147
|
+
return snapshot.blocks.map((block) => {
|
|
148
|
+
const from = startById.get(block.id);
|
|
149
|
+
const node = from === void 0 ? null : state.doc.nodeAt(from);
|
|
150
|
+
const text = node ? buildAnnotatedBlockText(node) : block.text;
|
|
151
|
+
return formatBlockLine(block, text);
|
|
152
|
+
}).join("\n");
|
|
153
|
+
};
|
|
121
154
|
/**
|
|
122
155
|
* One LLM-ready line for a block: `[<blockId>] text`, with an `(h<level>)` tag
|
|
123
156
|
* for headings and the list marker for list items, so a model can copy the
|
|
@@ -166,7 +199,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
166
199
|
baseDocument;
|
|
167
200
|
originalBuffer;
|
|
168
201
|
state;
|
|
169
|
-
|
|
202
|
+
secondaryStoryStates = /* @__PURE__ */ new Map();
|
|
170
203
|
createdComments = [];
|
|
171
204
|
documentOperationUndoEntries = [];
|
|
172
205
|
/**
|
|
@@ -211,11 +244,51 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
211
244
|
snapshot() {
|
|
212
245
|
return createFolioAIEditSnapshot(this.state.doc);
|
|
213
246
|
}
|
|
247
|
+
/** Return parsed package metadata without exposing the mutable document model. */
|
|
248
|
+
getDocumentProperties() {
|
|
249
|
+
const properties = this.baseDocument.package.properties;
|
|
250
|
+
if (!properties) return null;
|
|
251
|
+
return Object.freeze({
|
|
252
|
+
...properties,
|
|
253
|
+
...properties.created !== void 0 ? { created: new Date(properties.created.getTime()) } : {},
|
|
254
|
+
...properties.modified !== void 0 ? { modified: new Date(properties.modified.getTime()) } : {}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
214
257
|
/** Snapshot one editable story into stable, operation-ready blocks. */
|
|
215
258
|
snapshotStory(story) {
|
|
216
259
|
const state = this.getEditableStoryState(story);
|
|
217
260
|
return state ? createFolioAIEditSnapshot(state.doc) : null;
|
|
218
261
|
}
|
|
262
|
+
/** Read one story through an immutable reviewed-view projection. */
|
|
263
|
+
readReviewedStory(options = {}) {
|
|
264
|
+
const story = options.story ?? MAIN_STORY;
|
|
265
|
+
const view = options.view ?? "final";
|
|
266
|
+
if (!isFolioReviewedView(view)) throw new UnsupportedFolioReviewedViewError({
|
|
267
|
+
message: "Unsupported reviewed document view.",
|
|
268
|
+
receivedView: view
|
|
269
|
+
});
|
|
270
|
+
const sourceState = this.getEditableStoryState(story);
|
|
271
|
+
if (!sourceState) return null;
|
|
272
|
+
const state = resolveReviewedState(sourceState, view);
|
|
273
|
+
return {
|
|
274
|
+
story,
|
|
275
|
+
view,
|
|
276
|
+
snapshot: createFolioAIEditSnapshot(state.doc),
|
|
277
|
+
text: formatStoryStateForLLM(state, view === "current-markup"),
|
|
278
|
+
changes: getTrackedChangesFromDoc(state.doc)
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
/** Resolve one editable story to its original or final state. */
|
|
282
|
+
resolveReviewedStory({ story = MAIN_STORY, view }) {
|
|
283
|
+
if (!isFolioResolvedReviewedView(view)) throw new UnsupportedFolioReviewedViewError({
|
|
284
|
+
message: "Only original and final views can replace editable story state.",
|
|
285
|
+
receivedView: view
|
|
286
|
+
});
|
|
287
|
+
const sourceState = this.getEditableStoryState(story);
|
|
288
|
+
if (!sourceState) return false;
|
|
289
|
+
this.setEditableStoryState(story, resolveReviewedState(sourceState, view));
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
219
292
|
/**
|
|
220
293
|
* Apply operations against the current state. Reuses the live-editor applier
|
|
221
294
|
* verbatim via a headless `{ state, dispatch }` seam; the resulting state
|
|
@@ -251,7 +324,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
251
324
|
createUndoEntry: true
|
|
252
325
|
});
|
|
253
326
|
}
|
|
254
|
-
/** Apply a versioned operation batch to
|
|
327
|
+
/** Apply a versioned operation batch to one editable document story. */
|
|
255
328
|
applyDocumentOperationsToStory({ story, batch, snapshot }) {
|
|
256
329
|
return this.applyDocumentOperationsInternal({
|
|
257
330
|
story,
|
|
@@ -348,23 +421,13 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
348
421
|
* (clean) output flattens tracked changes and is unchanged.
|
|
349
422
|
*/
|
|
350
423
|
getContentAsText(options = {}) {
|
|
351
|
-
|
|
352
|
-
const snapshot = this.snapshot();
|
|
353
|
-
const startById = /* @__PURE__ */ new Map();
|
|
354
|
-
for (const anchor of Object.values(snapshot.anchors)) startById.set(anchor.id, anchor.from);
|
|
355
|
-
return snapshot.blocks.map((block) => {
|
|
356
|
-
const from = startById.get(block.id);
|
|
357
|
-
const node = from === void 0 ? null : this.state.doc.nodeAt(from);
|
|
358
|
-
const text = node ? buildAnnotatedBlockText(node) : block.text;
|
|
359
|
-
return formatBlockLine(block, text);
|
|
360
|
-
}).join("\n");
|
|
424
|
+
return formatStoryStateForLLM(this.state, options.annotated === true);
|
|
361
425
|
}
|
|
362
426
|
/**
|
|
363
427
|
* Header / footer and footnote / endnote text as labeled, LLM-ready lines,
|
|
364
428
|
* one per non-empty part: `[header default] …`, `[footer default] …`,
|
|
365
|
-
* `[footnote #N] …`, `[endnote #N] …`.
|
|
366
|
-
*
|
|
367
|
-
* separator notes are omitted.
|
|
429
|
+
* `[footnote #N] …`, `[endnote #N] …`. Lines reflect in-memory edits. Empty
|
|
430
|
+
* parts and separator notes are omitted.
|
|
368
431
|
*/
|
|
369
432
|
getNotesAsText() {
|
|
370
433
|
const pkg = this.baseDocument.package;
|
|
@@ -384,12 +447,20 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
384
447
|
pushHeaderFooter(pkg.footers, "footer");
|
|
385
448
|
for (const footnote of pkg.footnotes ?? []) {
|
|
386
449
|
if (isSeparatorFootnote(footnote)) continue;
|
|
387
|
-
const
|
|
450
|
+
const handle = {
|
|
451
|
+
type: "footnote",
|
|
452
|
+
noteId: footnote.id
|
|
453
|
+
};
|
|
454
|
+
const text = this.getNoteStoryText(handle, footnote);
|
|
388
455
|
if (text.length > 0) lines.push(`[footnote #${footnote.id}] ${text}`);
|
|
389
456
|
}
|
|
390
457
|
for (const endnote of pkg.endnotes ?? []) {
|
|
391
458
|
if (isSeparatorEndnote(endnote)) continue;
|
|
392
|
-
const
|
|
459
|
+
const handle = {
|
|
460
|
+
type: "endnote",
|
|
461
|
+
noteId: endnote.id
|
|
462
|
+
};
|
|
463
|
+
const text = this.getNoteStoryText(handle, endnote);
|
|
393
464
|
if (text.length > 0) lines.push(`[endnote #${endnote.id}] ${text}`);
|
|
394
465
|
}
|
|
395
466
|
return lines.join("\n");
|
|
@@ -421,20 +492,26 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
421
492
|
text: this.getHeaderFooterStoryText(handle, footer)
|
|
422
493
|
});
|
|
423
494
|
}
|
|
424
|
-
for (const footnote of pkg.footnotes ?? []) if (!isSeparatorFootnote(footnote))
|
|
425
|
-
handle
|
|
495
|
+
for (const footnote of pkg.footnotes ?? []) if (!isSeparatorFootnote(footnote)) {
|
|
496
|
+
const handle = {
|
|
426
497
|
type: "footnote",
|
|
427
498
|
noteId: footnote.id
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
499
|
+
};
|
|
500
|
+
stories.push({
|
|
501
|
+
handle,
|
|
502
|
+
text: this.getNoteStoryText(handle, footnote)
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
for (const endnote of pkg.endnotes ?? []) if (!isSeparatorEndnote(endnote)) {
|
|
506
|
+
const handle = {
|
|
433
507
|
type: "endnote",
|
|
434
508
|
noteId: endnote.id
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
|
|
509
|
+
};
|
|
510
|
+
stories.push({
|
|
511
|
+
handle,
|
|
512
|
+
text: this.getNoteStoryText(handle, endnote)
|
|
513
|
+
});
|
|
514
|
+
}
|
|
438
515
|
return stories;
|
|
439
516
|
}
|
|
440
517
|
/** Read one discovered story; returns null when its handle is no longer present. */
|
|
@@ -578,7 +655,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
578
655
|
/** The current document model with edits merged back in. */
|
|
579
656
|
toDocument() {
|
|
580
657
|
const document = updateDocumentContent(this.baseDocument, this.state.doc);
|
|
581
|
-
this.
|
|
658
|
+
this.mergeEditedSecondaryStories(document);
|
|
582
659
|
if (this.createdComments.length > 0 || this.resolvedOverrides.size > 0) document.package.document.comments = this.withResolvedOverrides([...document.package.document.comments ?? [], ...this.createdComments]);
|
|
583
660
|
return document;
|
|
584
661
|
}
|
|
@@ -604,11 +681,20 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
604
681
|
* is the graceful handling — no separate error surface is needed here.
|
|
605
682
|
*/
|
|
606
683
|
async trySelectiveSave(document) {
|
|
684
|
+
const changedParaIds = new Set(getChangedParagraphIds(this.state));
|
|
685
|
+
let structuralChange = hasStructuralChanges(this.state);
|
|
686
|
+
let untrackedChanges = hasUntrackedChanges(this.state);
|
|
687
|
+
for (const entry of this.secondaryStoryStates.values()) {
|
|
688
|
+
if (entry.handle.type !== "footnote" && entry.handle.type !== "endnote") continue;
|
|
689
|
+
for (const paraId of getChangedParagraphIds(entry.state)) changedParaIds.add(paraId);
|
|
690
|
+
structuralChange ||= hasStructuralChanges(entry.state);
|
|
691
|
+
untrackedChanges ||= hasUntrackedChanges(entry.state);
|
|
692
|
+
}
|
|
607
693
|
try {
|
|
608
694
|
return await attemptSelectiveSave(document, this.originalBuffer, {
|
|
609
|
-
changedParaIds
|
|
610
|
-
structuralChange
|
|
611
|
-
hasUntrackedChanges:
|
|
695
|
+
changedParaIds,
|
|
696
|
+
structuralChange,
|
|
697
|
+
hasUntrackedChanges: untrackedChanges
|
|
612
698
|
});
|
|
613
699
|
} catch {
|
|
614
700
|
return null;
|
|
@@ -616,20 +702,21 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
616
702
|
}
|
|
617
703
|
getEditableStoryState(story) {
|
|
618
704
|
if (story.type === "main") return this.state;
|
|
619
|
-
const key =
|
|
620
|
-
const existing = this.
|
|
705
|
+
const key = secondaryStoryKey(story);
|
|
706
|
+
const existing = this.secondaryStoryStates.get(key);
|
|
621
707
|
if (existing) return existing.state;
|
|
622
|
-
const source = this.getHeaderFooterStory(story);
|
|
708
|
+
const source = story.type === "header" || story.type === "footer" ? this.getHeaderFooterStory(story) : this.getNoteStory(story);
|
|
623
709
|
if (!source) return null;
|
|
710
|
+
const conversionOptions = {
|
|
711
|
+
...this.baseDocument.package.styles !== void 0 && { styles: this.baseDocument.package.styles },
|
|
712
|
+
...this.baseDocument.package.theme !== void 0 && { theme: this.baseDocument.package.theme }
|
|
713
|
+
};
|
|
624
714
|
const state = ensureDeterministicParaIdsInState(EditorState.create({
|
|
625
715
|
schema,
|
|
626
|
-
doc: headerFooterToProseDoc(source.content,
|
|
627
|
-
...this.baseDocument.package.styles !== void 0 && { styles: this.baseDocument.package.styles },
|
|
628
|
-
...this.baseDocument.package.theme !== void 0 && { theme: this.baseDocument.package.theme }
|
|
629
|
-
}),
|
|
716
|
+
doc: story.type === "header" || story.type === "footer" ? headerFooterToProseDoc(source.content, conversionOptions) : footnoteToProseDoc(source.content, conversionOptions),
|
|
630
717
|
plugins: singletonManager.getPlugins()
|
|
631
718
|
}));
|
|
632
|
-
this.
|
|
719
|
+
this.secondaryStoryStates.set(key, {
|
|
633
720
|
handle: story,
|
|
634
721
|
initialState: state,
|
|
635
722
|
state
|
|
@@ -649,7 +736,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
649
736
|
this.state = state;
|
|
650
737
|
return;
|
|
651
738
|
}
|
|
652
|
-
const entry = this.
|
|
739
|
+
const entry = this.secondaryStoryStates.get(secondaryStoryKey(story));
|
|
653
740
|
if (!entry) throw new FolioDocumentStoryNotFoundError({
|
|
654
741
|
message: `Document story ${JSON.stringify(story)} was not found.`,
|
|
655
742
|
story
|
|
@@ -659,31 +746,70 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
659
746
|
getHeaderFooterStory(story) {
|
|
660
747
|
return (story.type === "header" ? this.baseDocument.package.headers : this.baseDocument.package.footers)?.get(story.relationshipId);
|
|
661
748
|
}
|
|
749
|
+
getNoteStory(story) {
|
|
750
|
+
if (story.type === "footnote") return this.baseDocument.package.footnotes?.find((note) => note.id === story.noteId && !isSeparatorFootnote(note));
|
|
751
|
+
return this.baseDocument.package.endnotes?.find((note) => note.id === story.noteId && !isSeparatorEndnote(note));
|
|
752
|
+
}
|
|
662
753
|
getHeaderFooterStoryText(story, source) {
|
|
663
|
-
const state = this.
|
|
754
|
+
const state = this.secondaryStoryStates.get(headerFooterStoryKey(story))?.state;
|
|
664
755
|
return normalizeFolioAIBlockText(state?.doc.textContent ?? getHeaderFooterText(source));
|
|
665
756
|
}
|
|
666
|
-
|
|
757
|
+
getNoteStoryText(story, source) {
|
|
758
|
+
const state = this.secondaryStoryStates.get(noteStoryKey(story))?.state;
|
|
759
|
+
const sourceText = source.type === "footnote" ? getFootnoteText(source) : getEndnoteText(source);
|
|
760
|
+
return normalizeFolioAIBlockText(state?.doc.textContent ?? sourceText);
|
|
761
|
+
}
|
|
762
|
+
mergeEditedSecondaryStories(document) {
|
|
667
763
|
let headers;
|
|
668
764
|
let footers;
|
|
669
|
-
|
|
765
|
+
let footnotes;
|
|
766
|
+
let endnotes;
|
|
767
|
+
for (const entry of this.secondaryStoryStates.values()) {
|
|
670
768
|
if (entry.state === entry.initialState) continue;
|
|
671
|
-
|
|
769
|
+
if (entry.handle.type === "header" || entry.handle.type === "footer") {
|
|
770
|
+
const source = this.getHeaderFooterStory(entry.handle);
|
|
771
|
+
if (!source) continue;
|
|
772
|
+
const edited = {
|
|
773
|
+
...source,
|
|
774
|
+
content: proseDocToBlocks(entry.state.doc)
|
|
775
|
+
};
|
|
776
|
+
if (entry.handle.type === "header") {
|
|
777
|
+
headers ??= new Map(document.package.headers);
|
|
778
|
+
headers.set(entry.handle.relationshipId, edited);
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
footers ??= new Map(document.package.footers);
|
|
782
|
+
footers.set(entry.handle.relationshipId, edited);
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
if (entry.handle.type === "footnote") {
|
|
786
|
+
const { noteId } = entry.handle;
|
|
787
|
+
const source = this.baseDocument.package.footnotes?.find((note) => note.id === noteId && !isSeparatorFootnote(note));
|
|
788
|
+
if (!source) continue;
|
|
789
|
+
const edited = {
|
|
790
|
+
...source,
|
|
791
|
+
content: proseDocToBlocks(entry.state.doc)
|
|
792
|
+
};
|
|
793
|
+
footnotes ??= [...document.package.footnotes ?? []];
|
|
794
|
+
const index = footnotes.findIndex((note) => note.id === noteId);
|
|
795
|
+
if (index !== -1) footnotes[index] = edited;
|
|
796
|
+
continue;
|
|
797
|
+
}
|
|
798
|
+
const { noteId } = entry.handle;
|
|
799
|
+
const source = this.baseDocument.package.endnotes?.find((note) => note.id === noteId && !isSeparatorEndnote(note));
|
|
672
800
|
if (!source) continue;
|
|
673
801
|
const edited = {
|
|
674
802
|
...source,
|
|
675
803
|
content: proseDocToBlocks(entry.state.doc)
|
|
676
804
|
};
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
continue;
|
|
681
|
-
}
|
|
682
|
-
footers ??= new Map(document.package.footers);
|
|
683
|
-
footers.set(entry.handle.relationshipId, edited);
|
|
805
|
+
endnotes ??= [...document.package.endnotes ?? []];
|
|
806
|
+
const index = endnotes.findIndex((note) => note.id === noteId);
|
|
807
|
+
if (index !== -1) endnotes[index] = edited;
|
|
684
808
|
}
|
|
685
809
|
if (headers) document.package.headers = headers;
|
|
686
810
|
if (footers) document.package.footers = footers;
|
|
811
|
+
if (footnotes) document.package.footnotes = footnotes;
|
|
812
|
+
if (endnotes) document.package.endnotes = endnotes;
|
|
687
813
|
}
|
|
688
814
|
/**
|
|
689
815
|
* Count every tracked change an accept-all / reject-all sweep resolves: the
|
|
@@ -767,4 +893,4 @@ const applyFolioAIEditsToBuffer = async (buffer, operations, options = {}) => {
|
|
|
767
893
|
};
|
|
768
894
|
};
|
|
769
895
|
//#endregion
|
|
770
|
-
export { FolioDocumentStoryNotFoundError, FolioDocxReviewer, applyFolioAIEditsToBuffer };
|
|
896
|
+
export { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, FolioDocxReviewer, UnsupportedFolioReviewedViewError, applyFolioAIEditsToBuffer, isFolioResolvedReviewedView, isFolioReviewedView };
|
package/dist/ai-edits/index.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ import { DocPositionRange, clampRangeToDocSize, resolveFolioAIBlockRange, resolv
|
|
|
4
4
|
import { buildAnnotatedBlockText } from "./clean-text.js";
|
|
5
5
|
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, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
|
|
6
6
|
import { FolioCommentAnchor, FolioReviewChange, FolioReviewChangeKind, getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
|
|
7
|
-
import { FolioApplyDocumentOperationsToStoryOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioEditableDocumentStoryHandle } from "./headless.js";
|
|
7
|
+
import { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsToStoryOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioEditableDocumentStoryHandle, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, isFolioResolvedReviewedView, isFolioReviewedView } from "./headless.js";
|
|
8
8
|
import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, normalizeFolioAIBlockText } from "./snapshot.js";
|
|
9
9
|
import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
|
|
10
10
|
import { getFolioParaIdFromBlockId } from "../types/block-id.js";
|
|
11
11
|
import { WordDiffSegment, diffWordSegments } from "./word-diff.js";
|
|
12
|
-
export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, 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 FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReviewChange, type FolioReviewChangeKind, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange };
|
|
12
|
+
export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, 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, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, 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 FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange };
|
package/dist/ai-edits/index.js
CHANGED
|
@@ -7,5 +7,5 @@ import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT
|
|
|
7
7
|
import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange } from "./blockRange.js";
|
|
8
8
|
import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
|
|
9
9
|
import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
|
|
10
|
-
import { FolioDocumentStoryNotFoundError } from "./headless.js";
|
|
11
|
-
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, FolioDocumentStoryNotFoundError, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange };
|
|
10
|
+
import { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, UnsupportedFolioReviewedViewError, isFolioResolvedReviewedView, isFolioReviewedView } from "./headless.js";
|
|
11
|
+
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, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange };
|
|
@@ -78,7 +78,8 @@ function runLayoutPipeline(deps, state, options = {}) {
|
|
|
78
78
|
if (documentSettings?.autoHyphenation === true) flowOpts.automaticHyphenation = {
|
|
79
79
|
enabled: true,
|
|
80
80
|
...documentSettings.doNotHyphenateCaps !== void 0 ? { doNotHyphenateCaps: documentSettings.doNotHyphenateCaps } : {},
|
|
81
|
-
...documentSettings.consecutiveHyphenLimit !== void 0 ? { consecutiveLineLimit: documentSettings.consecutiveHyphenLimit } : {}
|
|
81
|
+
...documentSettings.consecutiveHyphenLimit !== void 0 ? { consecutiveLineLimit: documentSettings.consecutiveHyphenLimit } : {},
|
|
82
|
+
...documentSettings.hyphenationZoneTwips !== void 0 ? { hyphenationZoneTwips: documentSettings.hyphenationZoneTwips } : {}
|
|
82
83
|
};
|
|
83
84
|
let newBlocks = toFlowBlocks(state.doc, flowOpts);
|
|
84
85
|
const previewState = templatePreviewValuesKey.getState(state);
|
|
@@ -5,7 +5,7 @@ import { FolioAIEditView } from "./ai-edits/apply.js";
|
|
|
5
5
|
declare const FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION: 1;
|
|
6
6
|
declare const FOLIO_DOCUMENT_OPERATION_TYPES: readonly ["replaceInBlock", "replaceRange", "commentOnRange", "formatRange", "insertAfterBlock", "insertBeforeBlock", "replaceBlock", "deleteBlock", "commentOnBlock", "insertSignatureTable"];
|
|
7
7
|
declare const FOLIO_DOCUMENT_OPERATION_MODES: readonly ["direct", "tracked-changes"];
|
|
8
|
-
declare const FOLIO_DOCUMENT_OPERATION_STORIES: readonly ["main"];
|
|
8
|
+
declare const FOLIO_DOCUMENT_OPERATION_STORIES: readonly ["main", "header", "footer", "footnote", "endnote"];
|
|
9
9
|
declare const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS: readonly ["blockTextHash"];
|
|
10
10
|
declare const FOLIO_DOCUMENT_OPERATION_BATCH_MODES: readonly ["best-effort", "atomic"];
|
|
11
11
|
type FolioDocumentOperation = FolioAIEditOperation;
|
|
@@ -68,8 +68,17 @@ type FolioDocumentOperationIssue = {
|
|
|
68
68
|
recovery: FolioDocumentOperationRecovery;
|
|
69
69
|
};
|
|
70
70
|
type FolioDocumentOperationStory = "main" | {
|
|
71
|
-
type: "header"
|
|
71
|
+
type: "header";
|
|
72
72
|
relationshipId: string;
|
|
73
|
+
} | {
|
|
74
|
+
type: "footer";
|
|
75
|
+
relationshipId: string;
|
|
76
|
+
} | {
|
|
77
|
+
type: "footnote";
|
|
78
|
+
noteId: number;
|
|
79
|
+
} | {
|
|
80
|
+
type: "endnote";
|
|
81
|
+
noteId: number;
|
|
73
82
|
};
|
|
74
83
|
/** One typed target affected by a successfully applied document operation. */
|
|
75
84
|
type FolioDocumentOperationAffectedTarget = {
|
|
@@ -15,7 +15,13 @@ const FOLIO_DOCUMENT_OPERATION_TYPES = Object.freeze([
|
|
|
15
15
|
"insertSignatureTable"
|
|
16
16
|
]);
|
|
17
17
|
const FOLIO_DOCUMENT_OPERATION_MODES = Object.freeze(["direct", "tracked-changes"]);
|
|
18
|
-
const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze([
|
|
18
|
+
const FOLIO_DOCUMENT_OPERATION_STORIES = Object.freeze([
|
|
19
|
+
"main",
|
|
20
|
+
"header",
|
|
21
|
+
"footer",
|
|
22
|
+
"footnote",
|
|
23
|
+
"endnote"
|
|
24
|
+
]);
|
|
19
25
|
const FOLIO_DOCUMENT_OPERATION_PRECONDITIONS = Object.freeze(["blockTextHash"]);
|
|
20
26
|
const FOLIO_DOCUMENT_OPERATION_BATCH_MODES = Object.freeze(["best-effort", "atomic"]);
|
|
21
27
|
const DIRECT_AND_TRACKED_MODES = FOLIO_DOCUMENT_OPERATION_MODES;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FolioDocumentStoryHandle } from "./ai-edits/headless.js";
|
|
2
|
+
|
|
3
|
+
//#region src/document-stories.d.ts
|
|
4
|
+
type FolioDocumentStoryPair = {
|
|
5
|
+
baseStory: FolioDocumentStoryHandle | null;
|
|
6
|
+
revisedStory: FolioDocumentStoryHandle | null;
|
|
7
|
+
};
|
|
8
|
+
declare const pairFolioDocumentStories: (baseStories: readonly FolioDocumentStoryHandle[], revisedStories: readonly FolioDocumentStoryHandle[]) => FolioDocumentStoryPair[];
|
|
9
|
+
//#endregion
|
|
10
|
+
export { FolioDocumentStoryPair, pairFolioDocumentStories };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/document-stories.ts
|
|
2
|
+
const documentStoryKey = (story) => {
|
|
3
|
+
if (story.type === "main") return story.type;
|
|
4
|
+
if (story.type === "header" || story.type === "footer") return `${story.type}:${story.relationshipId}`;
|
|
5
|
+
return `${story.type}:${String(story.noteId)}`;
|
|
6
|
+
};
|
|
7
|
+
const pairFolioDocumentStories = (baseStories, revisedStories) => {
|
|
8
|
+
const revisedByKey = new Map(revisedStories.map((story) => [documentStoryKey(story), story]));
|
|
9
|
+
const pairedKeys = /* @__PURE__ */ new Set();
|
|
10
|
+
const pairs = [];
|
|
11
|
+
for (const baseStory of baseStories) {
|
|
12
|
+
const key = documentStoryKey(baseStory);
|
|
13
|
+
const revisedStory = revisedByKey.get(key) ?? null;
|
|
14
|
+
pairs.push({
|
|
15
|
+
baseStory,
|
|
16
|
+
revisedStory
|
|
17
|
+
});
|
|
18
|
+
if (revisedStory) pairedKeys.add(key);
|
|
19
|
+
}
|
|
20
|
+
for (const revisedStory of revisedStories) if (!pairedKeys.has(documentStoryKey(revisedStory))) pairs.push({
|
|
21
|
+
baseStory: null,
|
|
22
|
+
revisedStory
|
|
23
|
+
});
|
|
24
|
+
return pairs;
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { pairFolioDocumentStories };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
|
|
3
|
+
//#region src/docx/corePropertiesParser.d.ts
|
|
4
|
+
type DocumentProperties = NonNullable<document_d_exports.DocxPackage["properties"]>;
|
|
5
|
+
/** Parse recognized package metadata from `docProps/core.xml`. */
|
|
6
|
+
declare const parseCoreProperties: (xml: string | null) => DocumentProperties | undefined;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { parseCoreProperties };
|