@stll/folio-core 0.47.3 → 0.47.4
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.js +46 -11
- package/package.json +1 -1
|
@@ -164,16 +164,49 @@ const FOLIO_RESOLVED_STORY_SERIALIZATION_MISMATCHES = Object.freeze({
|
|
|
164
164
|
blockProjection: "block-projection"
|
|
165
165
|
});
|
|
166
166
|
var FolioResolvedStorySerializationError = class extends TaggedError("FolioResolvedStorySerializationError") {};
|
|
167
|
+
/** Blocks whose id folio minted, because the package names no id for them. */
|
|
168
|
+
const mintedBlockOrdinals = (snapshot) => {
|
|
169
|
+
const ordinals = /* @__PURE__ */ new Set();
|
|
170
|
+
for (const [ordinal, block] of snapshot.blocks.entries()) if (block.idStability === "positional") ordinals.add(ordinal);
|
|
171
|
+
return ordinals;
|
|
172
|
+
};
|
|
167
173
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
174
|
+
* What a block looks like once the story has been through the package.
|
|
175
|
+
*
|
|
176
|
+
* `idStability` is the snapshot's own fact rather than the package's, so it
|
|
177
|
+
* goes. `minted` names the blocks whose id folio invented for a paragraph the
|
|
178
|
+
* package gives no `w14:paraId`, and each of those stands down to its position.
|
|
179
|
+
* A minted id is derived from the paragraph's text and ordinal, so resolving
|
|
180
|
+
* its text can make an id-less paragraph derive a different id when reopened.
|
|
181
|
+
* The two save paths also disagree about whether it reaches the file at all:
|
|
182
|
+
* the selective patch keeps the author's id-less convention (see
|
|
183
|
+
* `withoutMintedIds`) while a full repack writes the model's ids. Which path
|
|
184
|
+
* ran is not what this check is about, so neither the id nor the choice between
|
|
185
|
+
* them may decide it. An authored id is compared exactly as it is, and a block
|
|
186
|
+
* that moved still fails.
|
|
172
187
|
*/
|
|
173
|
-
const resolvedStoryBlockProjection = (block) => {
|
|
188
|
+
const resolvedStoryBlockProjection = (block, ordinal, minted) => {
|
|
174
189
|
const persisted = { ...block };
|
|
175
190
|
delete persisted.idStability;
|
|
176
|
-
return
|
|
191
|
+
return minted.has(ordinal) ? {
|
|
192
|
+
...persisted,
|
|
193
|
+
id: `minted-${String(ordinal)}`
|
|
194
|
+
} : persisted;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* The two halves of the expectation, from one projection.
|
|
198
|
+
*
|
|
199
|
+
* The reading text carries each block's id, so it has to be built from the
|
|
200
|
+
* same projected blocks the block comparison uses; formatting the raw snapshot
|
|
201
|
+
* instead would put a minted id back into the text and fail the check the
|
|
202
|
+
* block projection just passed.
|
|
203
|
+
*/
|
|
204
|
+
const resolvedStoryProjection = (snapshot, minted) => {
|
|
205
|
+
const blocks = snapshot.blocks.map((block, ordinal) => resolvedStoryBlockProjection(block, ordinal, minted));
|
|
206
|
+
return {
|
|
207
|
+
text: blocks.filter(isFolioAIContentBlock).map(formatBlockForLLM).join("\n"),
|
|
208
|
+
blocks
|
|
209
|
+
};
|
|
177
210
|
};
|
|
178
211
|
const numberingLevelsOf = (numbering) => {
|
|
179
212
|
if (!numbering) return [];
|
|
@@ -735,10 +768,11 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
735
768
|
const resolvedState = resolveReviewedState(sourceState, view);
|
|
736
769
|
this.setEditableStoryState(story, resolvedState);
|
|
737
770
|
const snapshot = createStateSnapshot(resolvedState);
|
|
771
|
+
const minted = mintedBlockOrdinals(snapshot);
|
|
738
772
|
this.resolvedStoryExpectations.set(editableStoryKey(story), {
|
|
739
773
|
story,
|
|
740
|
-
|
|
741
|
-
|
|
774
|
+
minted,
|
|
775
|
+
...resolvedStoryProjection(snapshot, minted)
|
|
742
776
|
});
|
|
743
777
|
return snapshot;
|
|
744
778
|
}
|
|
@@ -1356,13 +1390,14 @@ var FolioDocxReviewer = class FolioDocxReviewer {
|
|
|
1356
1390
|
async assertResolvedStoriesSerialized(buffer, expectations) {
|
|
1357
1391
|
if (expectations.length === 0) return;
|
|
1358
1392
|
const reopened = await FolioDocxReviewer.fromBuffer(buffer);
|
|
1359
|
-
for (const { story, text, blocks } of expectations) {
|
|
1393
|
+
for (const { story, text, blocks, minted } of expectations) {
|
|
1360
1394
|
const serialized = reopened.readReviewedStory({
|
|
1361
1395
|
story,
|
|
1362
1396
|
view: "current-markup"
|
|
1363
1397
|
});
|
|
1364
|
-
const
|
|
1365
|
-
const
|
|
1398
|
+
const persisted = serialized ? resolvedStoryProjection(serialized.snapshot, minted) : null;
|
|
1399
|
+
const serializedText = persisted?.text ?? null;
|
|
1400
|
+
const serializedBlocks = persisted?.blocks ?? null;
|
|
1366
1401
|
const mismatches = [];
|
|
1367
1402
|
if (!serialized) mismatches.push(FOLIO_RESOLVED_STORY_SERIALIZATION_MISMATCHES.storyMissing);
|
|
1368
1403
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.47.
|
|
3
|
+
"version": "0.47.4",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|