superdoc 2.0.0-next.26 → 2.0.0-next.28

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 (39) hide show
  1. package/dist/chunks/{create-super-doc-ui-CBs8xQUw.es.js → create-super-doc-ui-BlnUCtrx.es.js} +634 -115
  2. package/dist/chunks/{create-super-doc-ui-CHZKlLiH.cjs → create-super-doc-ui-CZBUMdjl.cjs} +634 -115
  3. package/dist/collaboration-upgrade-engine.cjs +1 -1
  4. package/dist/collaboration-upgrade-engine.es.js +1 -1
  5. package/dist/document-api/src/comments/comments.types.d.ts +9 -0
  6. package/dist/document-api/src/content-controls/content-controls.types.d.ts +13 -1
  7. package/dist/document-api/src/contract/operation-definitions.d.ts +2 -2
  8. package/dist/document-api/src/track-changes/track-changes.d.ts +6 -2
  9. package/dist/document-api/src/types/clipboard.d.ts +5 -1
  10. package/dist/document-api/src/types/table-operations.types.d.ts +6 -4
  11. package/dist/document-api/src/types/track-changes.types.d.ts +15 -0
  12. package/dist/layout-engine/contracts/src/incremental-dependency.d.ts +10 -0
  13. package/dist/layout-engine/contracts/src/index.d.ts +39 -0
  14. package/dist/layout-engine/layout-bridge/src/incrementalLayout.d.ts +23 -1
  15. package/dist/layout-engine/layout-engine/src/index.d.ts +17 -0
  16. package/dist/layout-engine/layout-engine/src/paginator.d.ts +16 -0
  17. package/dist/layout-engine/layout-engine/src/paragraph-layout-eligibility.d.ts +1 -4
  18. package/dist/layout-engine/style-engine/src/normalize/types.d.ts +1 -0
  19. package/dist/public/ui-react.cjs +1 -1
  20. package/dist/public/ui-react.es.js +1 -1
  21. package/dist/public/ui.cjs +1 -1
  22. package/dist/public/ui.es.js +1 -1
  23. package/dist/style.css +119 -100
  24. package/dist/style.layered.css +119 -100
  25. package/dist/superdoc/src/components/CommentsLayer/collect-removed-comment-ids.d.ts +1 -0
  26. package/dist/superdoc/src/components/CommentsLayer/collect-tracked-change-thread.d.ts +1 -1
  27. package/dist/superdoc/src/components/CommentsLayer/tracked-change-threading.d.ts +2 -0
  28. package/dist/superdoc/src/core/types/index.d.ts +7 -0
  29. package/dist/superdoc/src/helpers/v2-remote-review-hydration.d.ts +12 -0
  30. package/dist/superdoc/src/public/ui/reasons.d.ts +8 -0
  31. package/dist/superdoc/src/stores/comments-store.d.ts +9 -9
  32. package/dist/superdoc/src/stores/helpers/floating-comment-instances.d.ts +2 -10
  33. package/dist/superdoc/src/stores/superdoc-store.d.ts +27 -27
  34. package/dist/superdoc.cjs +286 -82
  35. package/dist/superdoc.es.js +286 -82
  36. package/dist-cdn/style.layered.css +1 -1
  37. package/dist-cdn/superdoc.min.css +1 -1
  38. package/dist-cdn/superdoc.min.js +37 -37
  39. package/package.json +3 -2
@@ -7,7 +7,7 @@ const COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
7
7
  var PRIVATE_ENGINE_INFO = (0, __superdoc_docx_engine_collaboration_upgrade_engine.getCollaborationUpgradeEngineInfo)();
8
8
  var ENGINE_INFO = Object.freeze({
9
9
  ...PRIVATE_ENGINE_INFO,
10
- superdocVersion: "2.0.0-next.26",
10
+ superdocVersion: "2.0.0-next.28",
11
11
  roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
12
12
  supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
13
13
  supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
@@ -6,7 +6,7 @@ const COLLABORATION_UPGRADE_ENGINE_MINIMUM_NODE_MAJOR = 20;
6
6
  var PRIVATE_ENGINE_INFO = getCollaborationUpgradeEngineInfo$1();
7
7
  var ENGINE_INFO = Object.freeze({
8
8
  ...PRIVATE_ENGINE_INFO,
9
- superdocVersion: "2.0.0-next.26",
9
+ superdocVersion: "2.0.0-next.28",
10
10
  roomSchemaVersion: Object.freeze({ ...PRIVATE_ENGINE_INFO.roomSchemaVersion }),
11
11
  supportedBundleVersions: SUPPORTED_COLLABORATION_UPGRADE_BUNDLE_VERSIONS,
12
12
  supportedV1ReaderContractVersions: SUPPORTED_V1_READER_CONTRACT_VERSIONS
@@ -86,6 +86,13 @@ export interface CommentInfo {
86
86
  * surviving anchor no longer maps wholly to one revision side.
87
87
  */
88
88
  trackedChangeParentId?: string;
89
+ /**
90
+ * Logical tracked-change id whose SuperDoc review conversation this
91
+ * comment explicitly belongs to. Unlike {@link trackedChangeParentId},
92
+ * this is persisted conversation provenance and is never inferred from
93
+ * anchor overlap.
94
+ */
95
+ trackedChangeThreadParentId?: string;
89
96
  /** Which side of the tracked change the anchor sits on. */
90
97
  trackedChangeSide?: CommentTrackedChangeSide;
91
98
  /**
@@ -177,6 +184,8 @@ export interface CommentDomain {
177
184
  rawOoxmlOccurrenceIndex?: number;
178
185
  /** See {@link CommentInfo.trackedChangeParentId}. */
179
186
  trackedChangeParentId?: string;
187
+ /** See {@link CommentInfo.trackedChangeThreadParentId}. */
188
+ trackedChangeThreadParentId?: string;
180
189
  /** See {@link CommentInfo.trackedChangeSide}. */
181
190
  trackedChangeSide?: CommentTrackedChangeSide;
182
191
  /** See {@link CommentInfo.trackedChangeLink}. */
@@ -1,4 +1,4 @@
1
- import { NodeKind } from '../types/base.js';
1
+ import { BlockNodeAddress, NodeKind } from '../types/base.js';
2
2
  import { SelectionTarget } from '../types/address.js';
3
3
  import { SDFragment } from '../types/fragment.js';
4
4
  import { ReceiptFailure, ReceiptInsert } from '../types/receipt.js';
@@ -119,6 +119,18 @@ export type ContentControlMoveDestination = ContentControlTarget | {
119
119
  } | {
120
120
  kind: 'after';
121
121
  target: ContentControlTarget;
122
+ }
123
+ /**
124
+ * Drop the control at an arbitrary caret inside a paragraph (SD-3779). `target`
125
+ * addresses the destination paragraph and `offset` is a text-character offset
126
+ * within it (0 = paragraph start). Mirrors `ImageCreateLocation`'s `inParagraph`
127
+ * variant so drag-and-drop can land a content control anywhere in the body, not
128
+ * just relative to another SDT. Direct-mode only.
129
+ */
130
+ | {
131
+ kind: 'inParagraph';
132
+ target: BlockNodeAddress;
133
+ offset?: number;
122
134
  };
123
135
  /**
124
136
  * Canonical content control info returned by all read/list operations.
@@ -976,7 +976,7 @@ export declare const OPERATION_DEFINITIONS: {
976
976
  };
977
977
  readonly 'trackChanges.decide': {
978
978
  readonly memberPath: "trackChanges.decide";
979
- readonly description: "Accept or reject tracked changes by logical id, by selected text range, by logical anchor range ({ anchor, relativeStart, relativeEnd }), or every active change in the document. Range targets may include overlap / side selectors and may partially resolve a change, splitting surviving content into new fragments with stable ids. Legacy `{ id, range: { kind: \"partial\", ... } }` targets are promoted only when the active adapter supports `decide()`; legacy fallback adapters fail closed with `INVALID_INPUT`. `input.expectedRevision` is accepted as a compatibility alias for mutation options.";
979
+ readonly description: "Accept or reject tracked changes by logical id, by several logical ids atomically, by selected text range, by logical anchor range ({ anchor, relativeStart, relativeEnd }), or every active change in the document. Range targets may include overlap / side selectors and may partially resolve a change, splitting surviving content into new fragments with stable ids. Legacy `{ id, range: { kind: \"partial\", ... } }` targets are promoted only when the active adapter supports `decide()`; legacy fallback adapters fail closed with `INVALID_INPUT`. `input.expectedRevision` is accepted as a compatibility alias for mutation options.";
980
980
  readonly expectedResult: "Returns a Receipt. `removed` lists retired tracked-change ids; `inserted` lists successor fragment ids produced by partial range splits; `invalidatedRefs` lists every retired tracked-change ref plus cascade-deleted comment ids; `remappedRefs` carries surviving comment anchors moved by the decision; `affectedStories` lists touched stories; `textRangeShifts` reports per-story visible-text deltas; `txId` correlates with history. Failures: SPAN_FRAGMENTED when a range crosses an indivisible boundary, CAPABILITY_UNAVAILABLE for formatting / structural / move targets (not yet supported), TARGET_NOT_FOUND for retired ids or zero overlap, STALE_REVISION for stale expectedRevision, REVISION_MISMATCH for stale range coverage, NO_OP when { kind: 'all' } resolves an empty target set.";
981
981
  readonly requiresDocumentContext: true;
982
982
  readonly metadata: CommandStaticMetadata;
@@ -2161,7 +2161,7 @@ export declare const OPERATION_DEFINITIONS: {
2161
2161
  };
2162
2162
  readonly 'contentControls.move': {
2163
2163
  readonly memberPath: "contentControls.move";
2164
- readonly description: "Move a content control to a new position. Direct moves preserve the original ID; tracked-mode authoring supports safe top-level block SDTs and remaps the destination SDT ID to avoid duplicate live anchors.";
2164
+ readonly description: "Move a content control to a new position: before or after another SDT, to the document start or end, or to an arbitrary caret inside a paragraph (the inParagraph destination) for drag-and-drop. Direct moves preserve the original ID; tracked-mode authoring supports safe top-level block SDTs (SDT-to-SDT destinations only) and remaps the destination SDT ID to avoid duplicate live anchors.";
2165
2165
  readonly expectedResult: "Returns a ContentControlMutationResult with the updated target position. Tracked-mode results include `trackedChangeRefs` pointing at the paired move review entity.";
2166
2166
  readonly requiresDocumentContext: true;
2167
2167
  readonly metadata: CommandStaticMetadata;
@@ -72,6 +72,10 @@ export type ReviewDecideTarget = {
72
72
  story?: StoryLocator;
73
73
  side?: ReviewDecideIdTargetSide;
74
74
  moveRole?: ReviewDecideTargetMoveRole;
75
+ } | {
76
+ /** Resolve several whole logical changes in one atomic history unit. */
77
+ kind: 'ids';
78
+ ids: string[];
75
79
  } | ReviewDecideTextRangeTarget | ReviewDecideLogicalRangeTarget | {
76
80
  kind: 'all';
77
81
  story?: StoryLocator | 'all';
@@ -153,7 +157,7 @@ export declare function executeTrackChangesGet(adapter: TrackChangesAdapter, inp
153
157
  * {@link RevisionGuardOptions} rather than `MutationOptions`.
154
158
  *
155
159
  * Validates the canonical discriminated target shape
156
- * (`{ kind: 'id' | 'range' | 'all' }`) and transparently promotes the
160
+ * (`{ kind: 'id' | 'ids' | 'range' | 'all' }`) and transparently promotes the
157
161
  * legacy `{ id, story? }` / `{ scope: 'all' }` shapes. Adapters that
158
162
  * implement the new {@link TrackChangesAdapter.decide} entrypoint receive
159
163
  * the normalized canonical input; older adapters that only expose
@@ -163,7 +167,7 @@ export declare function executeTrackChangesGet(adapter: TrackChangesAdapter, inp
163
167
  export declare function executeTrackChangesDecide(adapter: TrackChangesAdapter, rawInput: ReviewDecideInput, options?: RevisionGuardOptions): Receipt;
164
168
  /**
165
169
  * Validate and normalize a `trackChanges.decide` input into the canonical
166
- * `{ kind: 'id' | 'range' | 'all' }` target shape. Exposed for adapters /
170
+ * `{ kind: 'id' | 'ids' | 'range' | 'all' }` target shape. Exposed for adapters /
167
171
  * tests that need to share the same validation surface.
168
172
  */
169
173
  export declare function validateReviewDecideInput(rawInput: ReviewDecideInput): ReviewDecideRangeInput;
@@ -75,10 +75,14 @@ export interface SDPasteParagraphBlock {
75
75
  * Portable list membership intent. Without `numbering`, the kernel always
76
76
  * materializes a fresh definition. With `numbering`, the existing identity
77
77
  * is retained when the destination defines the same list kind; otherwise
78
- * this intent is the cross-document fallback. Single-level.
78
+ * this intent is the cross-document fallback. `level` is zero-based and
79
+ * bounded to OOXML's nine list levels; omitted means level 0.
79
80
  */
80
81
  listIntent?: {
81
82
  kind: 'bullet' | 'ordered';
83
+ level?: number;
84
+ /** True on the first block of a distinct adjacent portable list. */
85
+ startsNewList?: boolean;
82
86
  };
83
87
  /**
84
88
  * Pre-validated direct `<w:pPr>` properties. Same-document copy carries the
@@ -109,15 +109,17 @@ export type TableAnchorLocation = {
109
109
  */
110
110
  export type TableCreateLocation = TableAnchorLocation
111
111
  /**
112
- * Split the target paragraph at a visible-text offset and insert the table
113
- * as a standalone block between the head/tail halves (Word semantics: a
114
- * table cannot splice into a paragraph's runs). Body paragraphs only for
115
- * now; `changeMode: 'tracked'` is not supported for this location kind.
112
+ * Split the target paragraph at an offset and insert the table as a
113
+ * standalone block between the head/tail halves (Word semantics: a table
114
+ * cannot splice into a paragraph's runs). Offsets are visible-text by
115
+ * default; use `coordinateSpace: 'tracked'` for a deletion-inclusive caret
116
+ * coordinate. Body paragraphs only for now.
116
117
  */
117
118
  | {
118
119
  kind: 'inParagraph';
119
120
  target: BlockNodeAddress;
120
121
  offset: number;
122
+ coordinateSpace?: 'visible' | 'tracked';
121
123
  };
122
124
  /**
123
125
  * Generic success result for table mutation operations.
@@ -448,6 +448,17 @@ export interface TrackChangeImagePreview {
448
448
  /** Accessible label for clients that render the preview. */
449
449
  alt?: string;
450
450
  }
451
+ /**
452
+ * Authoritative block address for review navigation. Consumers use this
453
+ * instead of interpreting the shape-specific {@link TrackChangeTarget}
454
+ * union. `role` records which semantic carrier supplied the address.
455
+ */
456
+ export interface TrackChangeNavigationTarget {
457
+ kind: 'block';
458
+ story: StoryLocator;
459
+ blockId: string;
460
+ role: 'primary' | 'move-source' | 'move-destination' | 'formatting-carrier' | 'structural-carrier';
461
+ }
451
462
  export interface TrackChangeInfo {
452
463
  address: TrackedChangeAddress;
453
464
  /** Stable SuperDoc logical tracked-change id (spec §3 / §4). */
@@ -459,6 +470,8 @@ export interface TrackChangeInfo {
459
470
  state?: TrackChangeState;
460
471
  /** Logical target description. */
461
472
  target?: TrackChangeTarget;
473
+ /** Stable story/block address for focus and virtualized materialization. */
474
+ navigationTarget?: TrackChangeNavigationTarget;
462
475
  /** Semantic before-state needed to reject the change. */
463
476
  before?: TrackChangeSnapshot;
464
477
  /** Semantic after-state needed to accept the change. */
@@ -598,6 +611,8 @@ export interface TrackChangeDomain {
598
611
  state?: TrackChangeState;
599
612
  /** Logical target summary for list consumers when the compact projection can provide it safely. */
600
613
  target?: TrackChangeTarget;
614
+ /** Stable story/block address for focus and virtualized materialization. */
615
+ navigationTarget?: TrackChangeNavigationTarget;
601
616
  /** Move side metadata for paired tracked moves. */
602
617
  move?: TrackChangeMoveSides;
603
618
  /** Direction of a paired move in document order, when source/destination order is known. */
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Stable dependency classes that an incremental page checkpoint may fence.
3
+ *
4
+ * This list is proof metadata, never a feature switch. Producers must name
5
+ * every retained dependency that required the checkpoint; consumers reject
6
+ * empty, duplicate, or unknown lists instead of trusting a generic boolean.
7
+ */
8
+ export type PageCheckpointDependencyClass = 'multiple-sections' | 'furniture-page-tokens' | 'non-balanceable-multi-column-sections' | 'body-anchored-objects' | 'footnotes' | 'page-references' | 'keep-constraints' | 'tables' | 'furniture-anchored-objects';
9
+ export declare const PAGE_CHECKPOINT_DEPENDENCY_CLASSES: readonly ["multiple-sections", "furniture-page-tokens", "non-balanceable-multi-column-sections", "body-anchored-objects", "footnotes", "page-references", "keep-constraints", "tables", "furniture-anchored-objects"];
10
+ export declare function areValidPageCheckpointDependencyClasses(value: unknown): value is readonly PageCheckpointDependencyClass[];
@@ -345,6 +345,7 @@ export type TextRun = RunMarks & {
345
345
  importedId?: string;
346
346
  internal?: boolean;
347
347
  trackedChange?: boolean;
348
+ trackedChangeThreadParentId?: string;
348
349
  }>;
349
350
  /**
350
351
  * Custom data attributes propagated from ProseMirror marks (keys must be data-*).
@@ -1748,6 +1749,11 @@ export type ListBlock = {
1748
1749
  sourceAnchor?: SourceAnchor;
1749
1750
  };
1750
1751
  export type FlowBlock = ParagraphBlock | ImageBlock | DrawingBlock | ListBlock | TableBlock | SectionBreakBlock | PageBreakBlock | ColumnBreakBlock;
1752
+ export declare const isReviewableSectionBoundaryMarkerBlock: (block: FlowBlock | null | undefined) => boolean;
1753
+ /** Shared eligibility for paragraphs the layout loop deliberately omits. */
1754
+ export declare const shouldSkipParagraphDuringLayout: (blocks: FlowBlock[], index: number) => boolean;
1755
+ /** True only for block kinds that produce an addressable layout fragment. */
1756
+ export declare const doesFlowBlockProduceLayoutFragment: (blocks: FlowBlock[], index: number) => boolean;
1751
1757
  export type ColumnLayout = {
1752
1758
  count: number;
1753
1759
  gap: number;
@@ -2354,6 +2360,36 @@ export type HeaderFooterLayout = {
2354
2360
  renderHeight?: number;
2355
2361
  pages: HeaderFooterPage[];
2356
2362
  };
2363
+ /**
2364
+ * Engine-owned paginator state immediately before a top-level paragraph.
2365
+ * Incremental layout may resume from this state only after independently
2366
+ * proving that every preceding fragment on the page is stable.
2367
+ */
2368
+ export type LayoutBlockResumeCheckpoint = {
2369
+ blockId: BlockId;
2370
+ pageIndex: number;
2371
+ prefixFragmentCount: number;
2372
+ cursorY: number;
2373
+ maxCursorY: number;
2374
+ columnIndex: number;
2375
+ trailingSpacing: number;
2376
+ lastParagraphStyleId?: string;
2377
+ lastParagraphContextualSpacing: boolean;
2378
+ lastParagraphBorderHash?: string;
2379
+ constraintBoundaries: readonly {
2380
+ y: number;
2381
+ columns: ColumnLayout;
2382
+ }[];
2383
+ activeConstraintIndex: number;
2384
+ footnoteDemandThisPage: number;
2385
+ footnoteRefsThisPage: number;
2386
+ footnoteAnchorsThisPage: readonly {
2387
+ pmPos: number;
2388
+ refId: string;
2389
+ fullHeight: number;
2390
+ firstLineHeight: number;
2391
+ }[];
2392
+ };
2357
2393
  /** Final layout output ready for painting. */
2358
2394
  export type Layout = {
2359
2395
  pageSize: {
@@ -2379,6 +2415,8 @@ export type Layout = {
2379
2415
  * from DOM-derived positions back to the current ProseMirror document state.
2380
2416
  */
2381
2417
  layoutEpoch?: number;
2418
+ /** Exact paragraph-boundary resume sidecar; never inferred from painted geometry. */
2419
+ blockResumeCheckpoints?: ReadonlyMap<BlockId, LayoutBlockResumeCheckpoint>;
2382
2420
  };
2383
2421
  export type WrapTextMode = 'bothSides' | 'left' | 'right' | 'largest';
2384
2422
  export type WrapExclusion = {
@@ -2401,4 +2439,5 @@ export declare const extractHeaderFooterSpace: (margins?: PageMargins | null) =>
2401
2439
  export type { ResolvedLayout, ResolvedPage, ResolvedPaintItem, ResolvedGroupItem, ResolvedFragmentItem, ResolvedParagraphContent, ResolvedTextLineItem, ResolvedDropCapItem, ResolvedListMarkerItem, ResolvedTableItem, ResolvedImageItem, ResolvedDrawingItem, ResolvedHeaderFooterPage, ResolvedHeaderFooterLayout, } from './resolved-layout.js';
2402
2440
  export { isResolvedTableItem, isResolvedImageItem, isResolvedDrawingItem } from './resolved-layout.js';
2403
2441
  export { expandRunsForInlineNewlines, isEmptyInlineSdtPlaceholderRun, isEmptySdtPlaceholderRun, sliceRunsForLine, } from './run-helpers.js';
2442
+ export { PAGE_CHECKPOINT_DEPENDENCY_CLASSES, areValidPageCheckpointDependencyClasses, type PageCheckpointDependencyClass, } from './incremental-dependency.js';
2404
2443
  export * as Engines from './engines/index.js';
@@ -1,4 +1,4 @@
1
- import { FlowBlock, Layout, Measure, HeaderFooterLayout, ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js';
1
+ import { PageCheckpointDependencyClass, FlowBlock, Layout, Measure, HeaderFooterLayout, ParagraphBlock, ParagraphMeasure } from '../../contracts/src/index.js';
2
2
  import { FontMeasureContext } from '../../../shared/font-system/src/index.js';
3
3
  import { LayoutOptions, HeaderFooterConstraints } from '../../layout-engine/src/index.js';
4
4
  import { computeDirtyRegions } from './diff.js';
@@ -33,10 +33,18 @@ export type HeaderFooterLayoutResult = {
33
33
  */
34
34
  export type FootnoteReserveSeed = {
35
35
  reserves: number[];
36
+ /** Sparse page indexes that held a reserve, ledger, or injected note slice. */
37
+ notePageIndexes?: number[];
36
38
  separatorSpacingBefore: number | undefined;
37
39
  fontSignature: string;
38
40
  measurementWidth: number;
39
41
  measurementHeight: number;
42
+ /** Exact note block objects retained by the host's authoritative note-bundle proof. */
43
+ noteBlocksByBlockId?: Map<string, FlowBlock>;
44
+ /** Measures paired with `noteBlocksByBlockId`; object identity is revalidated before reuse. */
45
+ noteMeasuresByBlockId?: Map<string, Measure>;
46
+ noteBodyHeightById?: Map<string, number>;
47
+ noteFirstLineHeightById?: Map<string, number>;
40
48
  };
41
49
  export type IncrementalLayoutResult = {
42
50
  layout: Layout;
@@ -165,6 +173,12 @@ type IncrementalPaginationProofBase = {
165
173
  blockIdsUnchanged: true;
166
174
  blockIdsUnique: true;
167
175
  renderInputsUnchanged: true;
176
+ /** The retained dependency scan proved that no body or furniture PAGE_REF token exists. */
177
+ pageReferencesAbsent: boolean;
178
+ pageReferenceDependencyClosure?: {
179
+ referenceBlockIds: readonly string[];
180
+ targetBookmarkIds: readonly string[];
181
+ };
168
182
  };
169
183
  export type IncrementalPaginationProof = IncrementalPaginationProofBase & ({
170
184
  profile: 'single-section-local-text';
@@ -181,6 +195,12 @@ export type IncrementalPaginationProof = IncrementalPaginationProofBase & ({
181
195
  profile: 'page-checkpoint-local-text';
182
196
  globalDependenciesAbsent: false;
183
197
  globalDependenciesFencedByPageCheckpoint: true;
198
+ admittedDependencyClasses: readonly PageCheckpointDependencyClass[];
199
+ localKeepDependencyClosure?: {
200
+ checkpointPageIndex: number;
201
+ checkpointBlockId: string | null;
202
+ predecessorBlockId: string | null;
203
+ };
184
204
  /**
185
205
  * SD-3772 D1: the host proved (via the shared
186
206
  * `hasGenuinelyUnequalExplicitColumnWidths` predicate) that no
@@ -269,6 +289,8 @@ export declare function incrementalLayout(previousBlocks: FlowBlock[], _previous
269
289
  previousFontSignature?: string;
270
290
  }, warmStart?: {
271
291
  footnoteReserveSeed?: FootnoteReserveSeed | null;
292
+ /** Host proved the authoritative note projection bundle was retained exactly. */
293
+ noteMeasurePlaneRetainedExact?: true;
272
294
  }, layoutReuse?: IncrementalLayoutReuseOptions, measureReuseProof?: IncrementalMeasureReuseProof, execution?: IncrementalLayoutExecutionControl): Promise<IncrementalLayoutResult>;
273
295
  /**
274
296
  * Normalizes a margin value, using a fallback for undefined or non-finite values.
@@ -1,4 +1,5 @@
1
1
  import { ColumnLayout, FlowBlock, HeaderFooterLayout, Layout, Measure, Page, ParagraphBlock, ParagraphMeasure, SectionMetadata, FlowMode, DocumentBackground } from '../../contracts/src/index.js';
2
+ import { PageState, ConstraintBoundary } from './paginator.js';
2
3
  type PageSize = {
3
4
  w: number;
4
5
  h: number;
@@ -197,6 +198,22 @@ export type LayoutOptions = {
197
198
  };
198
199
  /** Resolved active column layout at the resumed boundary. */
199
200
  activeColumns?: ColumnLayout;
201
+ /** Engine-authored exact state for a paragraph boundary inside the first emitted page. */
202
+ initialPageState?: {
203
+ prefixFragments: readonly Page['fragments'][number][];
204
+ cursorY: number;
205
+ maxCursorY: number;
206
+ columnIndex: number;
207
+ trailingSpacing: number;
208
+ lastParagraphStyleId?: string;
209
+ lastParagraphContextualSpacing: boolean;
210
+ lastParagraphBorderHash?: string;
211
+ constraintBoundaries: readonly ConstraintBoundary[];
212
+ activeConstraintIndex: number;
213
+ footnoteDemandThisPage: number;
214
+ footnoteRefsThisPage: number;
215
+ footnoteAnchorsThisPage: readonly PageState['footnoteAnchorsThisPage'][number][];
216
+ };
200
217
  };
201
218
  /**
202
219
  * Optional page-boundary stop callback. Called after a page has completed
@@ -73,6 +73,22 @@ export type PaginatorOptions = {
73
73
  h: number;
74
74
  };
75
75
  getActiveColumns(): ColumnLayout;
76
+ /** Exact first-page state from an engine-authored paragraph checkpoint. */
77
+ initialPageState?: {
78
+ prefixFragments: readonly Page['fragments'][number][];
79
+ cursorY: number;
80
+ maxCursorY: number;
81
+ columnIndex: number;
82
+ trailingSpacing: number;
83
+ lastParagraphStyleId?: string;
84
+ lastParagraphContextualSpacing: boolean;
85
+ lastParagraphBorderHash?: string;
86
+ constraintBoundaries: readonly ConstraintBoundary[];
87
+ activeConstraintIndex: number;
88
+ footnoteDemandThisPage: number;
89
+ footnoteRefsThisPage: number;
90
+ footnoteAnchorsThisPage: readonly PageState['footnoteAnchorsThisPage'][number][];
91
+ };
76
92
  pageNumberOffset?: number;
77
93
  createPage(number: number, pageMargins: PageMargins, pageSizeOverride?: {
78
94
  w: number;
@@ -1,4 +1 @@
1
- import { FlowBlock } from '../../contracts/src/index.js';
2
- export declare const isReviewableSectionBoundaryMarkerBlock: (block: FlowBlock | null | undefined) => boolean;
3
- /** Paragraphs omitted by the main layout loop must not receive anchored objects. */
4
- export declare const shouldSkipParagraphDuringLayout: (blocks: FlowBlock[], index: number) => boolean;
1
+ export { isReviewableSectionBoundaryMarkerBlock, shouldSkipParagraphDuringLayout } from '../../contracts/src/index.js';
@@ -30,6 +30,7 @@ export interface TextRunStyleAttrs {
30
30
  vanish?: boolean;
31
31
  specVanish?: boolean;
32
32
  noProof?: boolean;
33
+ bidi?: NonNullable<TextRun['bidi']>;
33
34
  }
34
35
  /** Re-export so v2 adapter can consume one paragraph attrs type. */
35
36
  export type { ParagraphAttrs };
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("../chunks/rolldown-runtime-_dR15c8t.cjs");
3
- const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-CHZKlLiH.cjs");
3
+ const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-CZBUMdjl.cjs");
4
4
  let react = require("react");
5
5
  var SuperDocUIContext = (0, react.createContext)(null);
6
6
  function SuperDocUIProvider(props) {
@@ -1,4 +1,4 @@
1
- import { t as createSuperDocUI } from "../chunks/create-super-doc-ui-CBs8xQUw.es.js";
1
+ import { t as createSuperDocUI } from "../chunks/create-super-doc-ui-BlnUCtrx.es.js";
2
2
  import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState } from "react";
3
3
  var SuperDocUIContext = createContext(null);
4
4
  function SuperDocUIProvider(props) {
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-CHZKlLiH.cjs");
2
+ const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-CZBUMdjl.cjs");
3
3
  exports.BUILT_IN_COMMAND_IDS = require_create_super_doc_ui.BUILT_IN_COMMAND_IDS;
4
4
  exports.createSuperDocUI = require_create_super_doc_ui.createSuperDocUI;
5
5
  exports.shallowEqual = require_create_super_doc_ui.shallowEqual;
@@ -1,2 +1,2 @@
1
- import { n as BUILT_IN_COMMAND_IDS, r as shallowEqual, t as createSuperDocUI } from "../chunks/create-super-doc-ui-CBs8xQUw.es.js";
1
+ import { n as BUILT_IN_COMMAND_IDS, r as shallowEqual, t as createSuperDocUI } from "../chunks/create-super-doc-ui-BlnUCtrx.es.js";
2
2
  export { BUILT_IN_COMMAND_IDS, createSuperDocUI, shallowEqual };