@stll/folio-core 0.8.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.
Files changed (168) hide show
  1. package/README.md +39 -0
  2. package/dist/ai-edits/apply.js +18 -4
  3. package/dist/ai-edits/headless.d.ts +73 -6
  4. package/dist/ai-edits/headless.js +299 -60
  5. package/dist/ai-edits/index.d.ts +3 -3
  6. package/dist/ai-edits/index.js +2 -1
  7. package/dist/ai-edits/snapshot.js +40 -3
  8. package/dist/ai-edits/types.d.ts +2 -1
  9. package/dist/compat/eigenpal.d.ts +6 -4
  10. package/dist/compat/eigenpal.js +5 -3
  11. package/dist/controller/latestRequestGate.d.ts +13 -0
  12. package/dist/controller/latestRequestGate.js +16 -0
  13. package/dist/controller/layoutPipeline.js +13 -1
  14. package/dist/document-operations.d.ts +20 -4
  15. package/dist/document-operations.js +36 -15
  16. package/dist/document-stories.d.ts +10 -0
  17. package/dist/document-stories.js +27 -0
  18. package/dist/docx/blockContentParser.js +2 -2
  19. package/dist/docx/commentParser.js +1 -1
  20. package/dist/docx/compatibility.d.ts +3 -7
  21. package/dist/docx/compatibility.js +0 -11
  22. package/dist/docx/corePropertiesParser.d.ts +8 -0
  23. package/dist/docx/corePropertiesParser.js +53 -0
  24. package/dist/docx/encryption/agileDecryption.js +1 -1
  25. package/dist/docx/encryption/encryptionInfo.js +1 -1
  26. package/dist/docx/encryption/openEncryptedDocx.js +1 -1
  27. package/dist/docx/fontTableParser.d.ts +6 -0
  28. package/dist/docx/fontTableParser.js +72 -0
  29. package/dist/docx/groupDrawingParser.js +7 -2
  30. package/dist/docx/headerFooterParser.js +1 -1
  31. package/dist/docx/index.d.ts +2 -1
  32. package/dist/docx/index.js +2 -1
  33. package/dist/docx/metadataPrivacy.d.ts +40 -0
  34. package/dist/docx/metadataPrivacy.js +131 -0
  35. package/dist/docx/normalizeBaseDirection.js +1 -1
  36. package/dist/docx/numberingParser.js +1 -0
  37. package/dist/docx/paragraphParser.js +12 -1
  38. package/dist/docx/parser.d.ts +1 -1
  39. package/dist/docx/parser.js +16 -10
  40. package/dist/docx/rezip.d.ts +5 -4
  41. package/dist/docx/rezip.js +76 -13
  42. package/dist/docx/runConsolidator.js +4 -0
  43. package/dist/docx/runParser.js +19 -1
  44. package/dist/docx/selectiveSave.js +3 -3
  45. package/dist/docx/serializer/fontTableSerializer.d.ts +6 -0
  46. package/dist/docx/serializer/fontTableSerializer.js +26 -0
  47. package/dist/docx/serializer/headerFooterSerializer.js +1 -1
  48. package/dist/docx/serializer/paragraphSerializer.js +4 -0
  49. package/dist/docx/serializer/runSerializer.js +7 -0
  50. package/dist/docx/serializer/settingsSerializer.d.ts +6 -0
  51. package/dist/docx/serializer/settingsSerializer.js +16 -0
  52. package/dist/docx/serializer/stylesSerializer.d.ts +6 -0
  53. package/dist/docx/serializer/stylesSerializer.js +56 -0
  54. package/dist/docx/serializer/tableSerializer.js +25 -26
  55. package/dist/docx/serializer/themeSerializer.d.ts +6 -0
  56. package/dist/docx/serializer/themeSerializer.js +36 -0
  57. package/dist/docx/settingsParser.js +46 -0
  58. package/dist/docx/styleParser.js +26 -1
  59. package/dist/docx/tableParser.js +11 -1
  60. package/dist/docx/vmlImageParser.js +1 -0
  61. package/dist/i18n/messages/catalogs.gen.d.ts +5916 -5916
  62. package/dist/i18n/messages/catalogs.gen.js +5910 -5910
  63. package/dist/index.d.ts +6 -4
  64. package/dist/index.js +5 -3
  65. package/dist/layout-bridge/convert/footnoteLayout.d.ts +3 -0
  66. package/dist/layout-bridge/convert/footnoteLayout.js +3 -1
  67. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +3 -0
  68. package/dist/layout-bridge/convert/headerFooterLayout.js +6 -1
  69. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +14 -2
  70. package/dist/layout-bridge/convert/toFlowBlocks.js +52 -14
  71. package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
  72. package/dist/layout-bridge/engine/measuring/index.js +2 -1
  73. package/dist/layout-engine/index.js +36 -28
  74. package/dist/layout-engine/measure/cache.js +6 -3
  75. package/dist/layout-engine/measure/effectiveLineBreakPolicy.d.ts +29 -0
  76. package/dist/layout-engine/measure/effectiveLineBreakPolicy.js +60 -0
  77. package/dist/layout-engine/measure/font-metrics.worker.js +1 -0
  78. package/dist/layout-engine/measure/index.d.ts +2 -1
  79. package/dist/layout-engine/measure/index.js +2 -1
  80. package/dist/layout-engine/measure/lineBreakProvider.d.ts +33 -0
  81. package/dist/layout-engine/measure/lineBreakProvider.js +252 -0
  82. package/dist/layout-engine/measure/lineBreaks.d.ts +7 -2
  83. package/dist/layout-engine/measure/lineBreaks.js +11 -18
  84. package/dist/layout-engine/measure/listMarkerWidth.d.ts +1 -0
  85. package/dist/layout-engine/measure/listMarkerWidth.js +12 -6
  86. package/dist/layout-engine/measure/measureBlocks.d.ts +1 -2
  87. package/dist/layout-engine/measure/measureBlocks.js +6 -36
  88. package/dist/layout-engine/measure/measureContainer.js +32 -9
  89. package/dist/layout-engine/measure/measureHelpers.js +5 -2
  90. package/dist/layout-engine/measure/measureParagraph.js +332 -73
  91. package/dist/layout-engine/measure/measureTypes.d.ts +2 -1
  92. package/dist/layout-engine/measure/measureWorker.d.ts +2 -2
  93. package/dist/layout-engine/measure/measureWorker.js +8 -19
  94. package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +3 -14
  95. package/dist/layout-engine/measure/tableCellFloating.d.ts +10 -3
  96. package/dist/layout-engine/measure/tableCellFloating.js +51 -37
  97. package/dist/layout-engine/measure/tableCellFlow.d.ts +27 -0
  98. package/dist/layout-engine/measure/tableCellFlow.js +73 -0
  99. package/dist/layout-engine/measure/tableCellGrid.js +1 -1
  100. package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +18 -0
  101. package/dist/layout-engine/measure/textMeasurementPolicy.js +24 -0
  102. package/dist/layout-engine/renderedBreakReconciliation.d.ts +6 -1
  103. package/dist/layout-engine/renderedBreakReconciliation.js +34 -11
  104. package/dist/layout-engine/tableRowBreak.d.ts +5 -2
  105. package/dist/layout-engine/tableRowBreak.js +62 -29
  106. package/dist/layout-engine/types.d.ts +43 -8
  107. package/dist/layout-painter/anchoredImagePosition.d.ts +23 -0
  108. package/dist/layout-painter/anchoredImagePosition.js +95 -0
  109. package/dist/layout-painter/borderStroke.d.ts +23 -0
  110. package/dist/layout-painter/borderStroke.js +39 -0
  111. package/dist/layout-painter/renderImage.d.ts +5 -4
  112. package/dist/layout-painter/renderImage.js +18 -4
  113. package/dist/layout-painter/renderPage.d.ts +2 -27
  114. package/dist/layout-painter/renderPage.js +13 -99
  115. package/dist/layout-painter/renderParagraph.js +41 -23
  116. package/dist/layout-painter/renderTable.d.ts +2 -0
  117. package/dist/layout-painter/renderTable.js +223 -43
  118. package/dist/managers/DocumentLoaderManager.d.ts +1 -1
  119. package/dist/managers/DocumentLoaderManager.js +2 -2
  120. package/dist/prosemirror/attrs/index.d.ts +4 -2
  121. package/dist/prosemirror/attrs/index.js +22 -2
  122. package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
  123. package/dist/prosemirror/conversion/effectiveTableCellFormatting.d.ts +62 -0
  124. package/dist/prosemirror/conversion/effectiveTableCellFormatting.js +131 -0
  125. package/dist/prosemirror/conversion/fromProseDoc.js +34 -18
  126. package/dist/prosemirror/conversion/toProseDoc.js +81 -77
  127. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  128. package/dist/prosemirror/extensions/core/ParagraphExtension.js +7 -2
  129. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +1 -1
  130. package/dist/prosemirror/extensions/features/ListExtension.js +1 -0
  131. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +1 -0
  132. package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
  133. package/dist/prosemirror/extensions/marks/LanguageExtension.d.ts +7 -0
  134. package/dist/prosemirror/extensions/marks/LanguageExtension.js +30 -0
  135. package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
  136. package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
  137. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
  138. package/dist/prosemirror/extensions/marks/markUtils.js +12 -0
  139. package/dist/prosemirror/extensions/nodes/ImageExtension.js +3 -1
  140. package/dist/prosemirror/extensions/nodes/TableExtension.js +4 -2
  141. package/dist/prosemirror/schema/index.d.ts +2 -2
  142. package/dist/prosemirror/schema/marks.d.ts +6 -1
  143. package/dist/prosemirror/schema/nodes.d.ts +15 -12
  144. package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
  145. package/dist/prosemirror/utils/tabCalculator.d.ts +3 -1
  146. package/dist/prosemirror/utils/tabCalculator.js +12 -10
  147. package/dist/prosemirror/validation.js +4 -1
  148. package/dist/redline.d.ts +26 -11
  149. package/dist/redline.js +107 -64
  150. package/dist/server.d.ts +9 -5
  151. package/dist/server.js +8 -4
  152. package/dist/style-sets/extract.d.ts +35 -0
  153. package/dist/style-sets/extract.js +123 -0
  154. package/dist/style-sets/stellaStyle.d.ts +13 -0
  155. package/dist/style-sets/stellaStyle.js +516 -0
  156. package/dist/style-sets/types.d.ts +31 -0
  157. package/dist/style-sets/types.js +5 -0
  158. package/dist/utils/createDocument.d.ts +12 -2
  159. package/dist/utils/createDocument.js +42 -31
  160. package/dist/utils/fontResolver.js +6 -6
  161. package/dist/utils/formatToStyle.js +1 -1
  162. package/dist/utils/paragraphFormattingMerge.d.ts +14 -3
  163. package/dist/utils/paragraphFormattingMerge.js +14 -4
  164. package/dist/version-comparison.d.ts +65 -11
  165. package/dist/version-comparison.js +187 -29
  166. package/package.json +5 -1
  167. package/dist/docx/capabilities.d.ts +0 -41
  168. package/dist/docx/capabilities.js +0 -322
package/README.md CHANGED
@@ -32,6 +32,45 @@ bun add @stll/folio-core
32
32
  | `@stll/folio-core/server` | DOM-free helpers for server-side use (block-id derivation, document creation, re-zip) |
33
33
  | `@stll/folio-core/*` | the source-mirrored module tree (e.g. `@stll/folio-core/types/document`, `@stll/folio-core/prosemirror/schema`) for adapters that need lower-level building blocks |
34
34
 
35
+ ## New documents and reusable style sets
36
+
37
+ Create a legal-shaped blank document with the built-in preset:
38
+
39
+ ```ts
40
+ import { createDocx, createEmptyDocument, createStellaStyleDocumentPreset } from "@stll/folio-core";
41
+
42
+ const document = createEmptyDocument({
43
+ preset: createStellaStyleDocumentPreset(),
44
+ });
45
+ const docx = await createDocx(document);
46
+ ```
47
+
48
+ Style sets are content-free JSON values. Inspect a source file before presenting
49
+ styles for selection, extract the selected dependency closure, persist the
50
+ result, and load it into any later document:
51
+
52
+ ```ts
53
+ import {
54
+ createEmptyDocument,
55
+ extractDocumentStyleSetFromDocx,
56
+ inspectDocumentStylesFromDocx,
57
+ } from "@stll/folio-core";
58
+
59
+ const catalog = await inspectDocumentStylesFromDocx(sourceDocx);
60
+ const styleSet = await extractDocumentStyleSetFromDocx(sourceDocx, {
61
+ name: "Firm contract styles",
62
+ styleIds: catalog.styles
63
+ .filter(({ role }) => role === "default" || role === "quick")
64
+ .map(({ styleId }) => styleId),
65
+ });
66
+
67
+ const document = createEmptyDocument({ styleSet });
68
+ ```
69
+
70
+ Extraction excludes document content, metadata, relationships, media, comments,
71
+ and revision data. It keeps only the selected styles and the numbering, theme,
72
+ font-table, and settings data required to reproduce their formatting.
73
+
35
74
  ## License
36
75
 
37
76
  [Apache-2.0](./LICENSE)
@@ -678,10 +678,24 @@ const resolveOperation = ({ snapshot, operation, liveBlocks, liveBlocksByParaId,
678
678
  }
679
679
  if (operation.type === "deleteBlock" || operation.type === "replaceBlock") {
680
680
  const range = getTextRangeFromCleanBlock(cleanBlock);
681
- if (!range) return {
682
- type: "skip",
683
- reason: "unsupportedBlock"
684
- };
681
+ if (!range) {
682
+ const insertionPoint = cleanBlock.offsets.at(0);
683
+ if (operation.type === "replaceBlock" && currentText.length === 0 && operation.text.length > 0 && insertionPoint !== void 0) return {
684
+ type: "resolved",
685
+ operation: {
686
+ operation,
687
+ from: insertionPoint,
688
+ to: insertionPoint,
689
+ blockFrom,
690
+ blockTo,
691
+ blockNode
692
+ }
693
+ };
694
+ return {
695
+ type: "skip",
696
+ reason: "unsupportedBlock"
697
+ };
698
+ }
685
699
  if (operation.type === "replaceBlock" && operation.text === currentText) return {
686
700
  type: "skip",
687
701
  reason: "noopOperation"
@@ -30,19 +30,61 @@ 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" | "footer";
40
+ type: "header";
37
41
  relationshipId: string;
38
42
  } | {
39
- type: "footnote" | "endnote";
43
+ type: "footer";
44
+ relationshipId: string;
45
+ } | {
46
+ type: "footnote";
47
+ noteId: number;
48
+ } | {
49
+ type: "endnote";
40
50
  noteId: number;
41
51
  };
52
+ type FolioEditableDocumentStoryHandle = FolioDocumentStoryHandle;
42
53
  type FolioDocumentStory = {
43
54
  handle: FolioDocumentStoryHandle;
44
55
  text: string;
45
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 {}
77
+ declare const FolioDocumentStoryNotFoundError_base: import("better-result").TaggedErrorClass<"FolioDocumentStoryNotFoundError", {
78
+ message: string;
79
+ story: FolioEditableDocumentStoryHandle;
80
+ }>;
81
+ declare class FolioDocumentStoryNotFoundError extends FolioDocumentStoryNotFoundError_base {}
82
+ type FolioApplyDocumentOperationsToStoryOptions = FolioApplyDocumentOperationsOptions & {
83
+ story: FolioEditableDocumentStoryHandle;
84
+ batch: FolioDocumentOperationBatch;
85
+ };
86
+ declare const isFolioReviewedView: (value: unknown) => value is FolioReviewedView;
87
+ declare const isFolioResolvedReviewedView: (value: unknown) => value is FolioResolvedReviewedView;
46
88
  /** Filter for {@link FolioDocxReviewer.getChanges}. */
47
89
  type FolioReviewChangeFilter = {
48
90
  author?: string;
@@ -97,6 +139,7 @@ declare class FolioDocxReviewer {
97
139
  private readonly baseDocument;
98
140
  private readonly originalBuffer;
99
141
  private state;
142
+ private readonly secondaryStoryStates;
100
143
  private readonly createdComments;
101
144
  private readonly documentOperationUndoEntries;
102
145
  /**
@@ -116,6 +159,17 @@ declare class FolioDocxReviewer {
116
159
  * the anchor map the apply layer resolves operations against.
117
160
  */
118
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;
164
+ /** Snapshot one editable story into stable, operation-ready blocks. */
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;
119
173
  /**
120
174
  * Apply operations against the current state. Reuses the live-editor applier
121
175
  * verbatim via a headless `{ state, dispatch }` seam; the resulting state
@@ -129,6 +183,12 @@ declare class FolioDocxReviewer {
129
183
  * edit semantics.
130
184
  */
131
185
  applyDocumentOperations(batch: FolioDocumentOperationBatch, options?: FolioApplyDocumentOperationsOptions): FolioDocumentOperationResult;
186
+ /** Apply a versioned operation batch to one editable document story. */
187
+ applyDocumentOperationsToStory({
188
+ story,
189
+ batch,
190
+ snapshot
191
+ }: FolioApplyDocumentOperationsToStoryOptions): FolioDocumentOperationResult;
132
192
  private applyDocumentOperationsInternal;
133
193
  /** Undo the latest unchanged document-operation batch and its created comments. */
134
194
  undoDocumentOperations(undoHandle: FolioDocumentOperationUndoHandle): FolioDocumentOperationUndoResult;
@@ -153,9 +213,8 @@ declare class FolioDocxReviewer {
153
213
  /**
154
214
  * Header / footer and footnote / endnote text as labeled, LLM-ready lines,
155
215
  * one per non-empty part: `[header default] …`, `[footer default] …`,
156
- * `[footnote #N] …`, `[endnote #N] …`. Read-only note bodies are outside
157
- * the reviewer's body-only apply scope, so this reflects the parsed source.
158
- * Empty parts and separator notes are omitted.
216
+ * `[footnote #N] …`, `[endnote #N] …`. Lines reflect in-memory edits. Empty
217
+ * parts and separator notes are omitted.
159
218
  */
160
219
  getNotesAsText(): string;
161
220
  /** Discover every readable document story through a typed, serializable handle. */
@@ -239,6 +298,14 @@ declare class FolioDocxReviewer {
239
298
  * is the graceful handling — no separate error surface is needed here.
240
299
  */
241
300
  private trySelectiveSave;
301
+ private getEditableStoryState;
302
+ private requireEditableStoryState;
303
+ private setEditableStoryState;
304
+ private getHeaderFooterStory;
305
+ private getNoteStory;
306
+ private getHeaderFooterStoryText;
307
+ private getNoteStoryText;
308
+ private mergeEditedSecondaryStories;
242
309
  /**
243
310
  * Count every tracked change an accept-all / reject-all sweep resolves: the
244
311
  * inline insertion / deletion groups {@link getChanges} enumerates, plus the
@@ -283,4 +350,4 @@ type ApplyFolioAIEditsToBufferResult = FolioAIEditApplyResult & {
283
350
  */
284
351
  declare const applyFolioAIEditsToBuffer: (buffer: ArrayBuffer, operations: FolioAIEditOperation[], options?: ApplyFolioAIEditsToBufferOptions) => Promise<ApplyFolioAIEditsToBufferResult>;
285
352
  //#endregion
286
- export { ApplyFolioAIEditsToBufferOptions, ApplyFolioAIEditsToBufferResult, FolioApplyDocumentOperationsOptions, FolioApplyOperationsOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocxReviewer, FolioDocxReviewerOptions, 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 };