superdoc 2.3.0 → 2.4.0-next.2

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 (52) hide show
  1. package/README.md +0 -1
  2. package/dist/chunks/{FindReplaceSurface-DLxnCQOB.cjs → FindReplaceSurface-Dx0llWqP.cjs} +1 -1
  3. package/dist/chunks/{PasswordPromptSurface-DMbfDvpQ.cjs → PasswordPromptSurface-BUUVC2ee.cjs} +1 -1
  4. package/dist/chunks/{PdfViewer-CoFiGAhm.cjs → PdfViewer-qpvzwYMz.cjs} +1 -1
  5. package/dist/chunks/blank-docx-DP8RUPW-.cjs +7 -0
  6. package/dist/chunks/blank-docx-XRX6Ker2.es.js +2 -0
  7. package/dist/chunks/{create-super-doc-ui-fxF2Q8Ib.es.js → create-super-doc-ui-D4kk9AjM.es.js} +331 -102
  8. package/dist/chunks/{create-super-doc-ui-CXCqHc2m.cjs → create-super-doc-ui-DXdWuTzm.cjs} +331 -102
  9. package/dist/chunks/{eventemitter3-B60Fsz-a.es.js → eventemitter3-Bt2s0X0a.es.js} +1 -1
  10. package/dist/chunks/{eventemitter3-DCfwFVNn.cjs → eventemitter3-DqY4aSMf.cjs} +1 -1
  11. package/dist/chunks/{jszip-DzmwAHr3.es.js → jszip-C8srOKAO.es.js} +2 -2
  12. package/dist/chunks/{jszip-BdUBlUeG.cjs → jszip-Cs9JBLlJ.cjs} +13 -1
  13. package/dist/chunks/{rolldown-runtime-_dR15c8t.cjs → rolldown-runtime-1Y-nnZJ3.cjs} +0 -28
  14. package/dist/chunks/{rolldown-runtime-BJVcqBbz.es.js → rolldown-runtime-D7PMmH3s.es.js} +1 -17
  15. package/dist/collaboration-upgrade-engine.cjs +1 -1
  16. package/dist/collaboration-upgrade-engine.es.js +1 -1
  17. package/dist/document-api/src/comments/comment-create-attribution.d.ts +2 -0
  18. package/dist/document-api/src/comments/comments.d.ts +13 -4
  19. package/dist/document-api/src/comments/comments.types.d.ts +39 -0
  20. package/dist/document-api/src/content-controls/content-controls.types.d.ts +2 -0
  21. package/dist/document-api/src/contract/metadata-types.d.ts +18 -0
  22. package/dist/document-api/src/contract/operation-definitions.d.ts +1 -1
  23. package/dist/document-api/src/index.d.ts +2 -2
  24. package/dist/layout-engine/painters/dom/src/_test-utils.d.ts +3 -2
  25. package/dist/layout-engine/painters/dom/src/index.d.ts +24 -19
  26. package/dist/layout-engine/painters/dom/src/page-content.d.ts +107 -39
  27. package/dist/layout-engine/painters/dom/src/persistent-page-surface.d.ts +144 -0
  28. package/dist/layout-engine/painters/dom/src/pm-position-validation.d.ts +1 -1
  29. package/dist/layout-engine/painters/dom/src/renderer.d.ts +50 -106
  30. package/dist/layout-engine/painters/dom/src/sdt/boundaries.d.ts +1 -1
  31. package/dist/public/ui-react.cjs +2 -2
  32. package/dist/public/ui-react.es.js +1 -1
  33. package/dist/public/ui.cjs +1 -1
  34. package/dist/public/ui.es.js +1 -1
  35. package/dist/style.css +97 -90
  36. package/dist/style.layered.css +97 -90
  37. package/dist/superdoc/src/core/types/index.d.ts +258 -11
  38. package/dist/superdoc/src/helpers/floor.d.ts +1 -1
  39. package/dist/superdoc/src/helpers/v2-review-mutation-impact.d.ts +4 -0
  40. package/dist/superdoc/src/internal/toolbar/built-in/constants.d.ts +0 -1
  41. package/dist/superdoc/src/public/index.d.cts +6 -0
  42. package/dist/superdoc/src/public/index.d.ts +3 -0
  43. package/dist/superdoc/src/stores/comments-store.d.ts +34 -10
  44. package/dist/superdoc/src/stores/superdoc-store.d.ts +102 -30
  45. package/dist/superdoc.cjs +4581 -608
  46. package/dist/superdoc.es.js +4581 -612
  47. package/dist-cdn/style.layered.css +1 -1
  48. package/dist-cdn/superdoc.min.css +1 -1
  49. package/dist-cdn/superdoc.min.js +37 -37
  50. package/package.json +5 -4
  51. package/dist/chunks/blank-docx-CJAXnJKp.es.js +0 -2
  52. package/dist/chunks/blank-docx-DA-G-3VB.cjs +0 -7
@@ -35,7 +35,7 @@ export type PatchPageWork = {
35
35
  fragmentsReused: number;
36
36
  };
37
37
  /**
38
- * Painter plan §4.6 (dark observability): work performed by the page-window
38
+ * Painter plan §4.6 (dark observability): work performed by the persistent-page
39
39
  * paint path, accumulated across paints until consumed. Fields the path
40
40
  * cannot attribute yet are reported as 0/null, never invented:
41
41
  * `domNodesCreated` stays null until node counting is instrumented. Since P5,
@@ -49,35 +49,26 @@ export type PatchPageWork = {
49
49
  * arrays would grow per paint on the product path.
50
50
  */
51
51
  export type PaintWorkSummary = {
52
- /** Pages newly created (no prior element for the slot). */
53
- pagesMounted: number;
54
- /** Pages removed because they left the window. */
55
- pagesUnmounted: number;
56
- /** Pages whose slot survived but whose content was patched or re-rendered. */
57
- pagesRebuilt: number;
58
- /** Pages left completely untouched (version key match, positions unchanged). */
59
- pagesUntouched: number;
60
- /**
61
- * Retained pages whose header/footer DOM was refreshed after provider
62
- * identity changed, without mounting or rebuilding the body page. May
63
- * overlap position-remapped pages; never overlaps untouched pages.
64
- */
65
- pagesDecorationsRefreshed: number;
66
- /**
67
- * Pages whose content was untouched but whose pm positions were uniformly
68
- * shifted in place (painter plan P5): the resolve stamps matched while the
69
- * packet-fresh fragment positions drifted — attribute remap, not rebuild.
70
- */
71
- pagesPositionRemapped: number;
72
- /**
73
- * Rebuilt pages whose resolve stamps MATCHED but whose position drift could
74
- * not be proven a uniform shift (`planPmReuse` demote — e.g. a page mixing
75
- * body and notes pm planes under a body edit). A demote is sound painter
76
- * behavior, not a reuse regression; the repaint oracle allows exactly these
77
- * rebuilds on relevance-UNCHANGED pages (P5x review fix). Always a subset
78
- * of the rebuilt counters/arrays.
79
- */
80
- pagesPmDemoted: number;
52
+ /** Persistent page roots newly created for a committed scaffold. */
53
+ persistentPagesCreated: number;
54
+ /** Persistent page roots reused by index whose exact geometry changed. */
55
+ persistentPagesUpdated: number;
56
+ /** Persistent page roots removed by a generation commit (never by scroll). */
57
+ persistentPagesRemoved: number;
58
+ /** Pages whose content hydrated into an existing persistent root. */
59
+ contentHydrated: number;
60
+ /** Pages whose painter-owned content descendants were removed, root kept. */
61
+ contentDehydrated: number;
62
+ /** Hydrated pages reconciled through the fragment-keyed patch. */
63
+ contentPatched: number;
64
+ /** Hydrated pages left completely untouched. */
65
+ contentUntouched: number;
66
+ /** Hydrated pages whose pm positions were uniformly shifted in place. */
67
+ contentRemapped: number;
68
+ /** Hydrated pages whose header/footer DOM refreshed without body rebuild. */
69
+ contentDecorationsRefreshed: number;
70
+ /** Hydrated pages demoted from reuse because position drift was not uniform. */
71
+ contentPmDemoted: number;
81
72
  fragmentsRendered: number;
82
73
  fragmentsReused: number;
83
74
  domNodesCreated: number | null;
@@ -87,17 +78,19 @@ export type PaintWorkSummary = {
87
78
  * `remapped ⊆ full-changed ∩ window`) need to know WHICH pages, not how
88
79
  * many. Accumulated like the counters, drained on consume.
89
80
  */
90
- mountedPageIndices: number[];
91
- unmountedPageIndices: number[];
92
- rebuiltPageIndices: number[];
93
- untouchedPageIndices: number[];
94
- decorationRefreshedPageIndices: number[];
95
- remappedPageIndices: number[];
96
- pmDemotedPageIndices: number[];
81
+ createdPersistentPageIndices: number[];
82
+ removedPersistentPageIndices: number[];
83
+ patchedContentPageIndices: number[];
84
+ untouchedContentPageIndices: number[];
85
+ decorationRefreshedContentPageIndices: number[];
86
+ remappedContentPageIndices: number[];
87
+ pmDemotedContentPageIndices: number[];
88
+ hydratedContentPageIndices: number[];
89
+ dehydratedContentPageIndices: number[];
97
90
  };
98
91
  export declare function createEmptyPaintWorkSummary(): PaintWorkSummary;
99
92
  /**
100
- * Painter plan P3a: reuse key for one exact page slot on the page-window
93
+ * Painter plan P3a: reuse key for one exact page slot on the persistent-page
101
94
  * path. Joins everything the painted page DOM depends on for a fixed page
102
95
  * index: the resolve-stage version stamp per item (the product paint-reuse
103
96
  * mechanism), fragment identity + geometry (stamps do not cover geometry),
@@ -123,7 +116,7 @@ export declare function createEmptyPaintWorkSummary(): PaintWorkSummary;
123
116
  * attribute-for-attribute — that exactness is the proof, never normalize it
124
117
  * away at the pass level (only the §7.7 unit tests use the normalized form).
125
118
  */
126
- export declare function pageWindowVersionKey(page: ResolvedPage, totalPages: number, sectionPageCount: number): string | null;
119
+ export declare function persistentPageVersionKey(page: ResolvedPage, totalPages: number, sectionPageCount: number): string | null;
127
120
  /**
128
121
  * The class state `renderPage`/`patchPage` consume, made explicit. The
129
122
  * DomPainter builds one per call (values like `totalPages`, `layoutEpoch`,
@@ -148,7 +141,49 @@ export interface PageContentContext {
148
141
  updatePositionAttributes(fragmentEl: HTMLElement, mapping: PositionMapping): void;
149
142
  updateFragmentElement(el: HTMLElement, fragment: Fragment, section?: 'body' | 'header' | 'footer', resolvedItem?: ResolvedPaintItem): void;
150
143
  }
144
+ /**
145
+ * The subset of `PageContentContext` needed to build a canonical page shell —
146
+ * the `.superdoc-page` element with exact geometry, chrome, epoch, and layout
147
+ * boundary stamps, but no content. Persistent scaffold reconciliation builds
148
+ * shells through this context and hydrates content independently.
149
+ */
150
+ export type PageShellContext = Pick<PageContentContext, 'doc' | 'layoutEpoch' | 'getEffectivePageStyles' | 'applySemanticPageOverrides'>;
151
+ /**
152
+ * The exact page box a shell derives from. `ResolvedPage` satisfies it, and
153
+ * so does a numbers-only scaffold band — the persistent page surface builds
154
+ * shells without materializing resolved packets.
155
+ */
156
+ export type PageShellGeometry = {
157
+ width: number;
158
+ height: number;
159
+ };
160
+ /** Refresh geometry and document-level presentation without replacing a page. */
161
+ export declare function refreshPageShell(ctx: PageShellContext, el: HTMLElement, page: PageShellGeometry): void;
162
+ /**
163
+ * Canonical `.superdoc-page` shell: the one place a paginated page element is
164
+ * created. The persistent scaffold mounts it bare and bounded content
165
+ * reconciliation hydrates the same element in place.
166
+ */
167
+ export declare function renderPageShell(ctx: PageShellContext, page: PageShellGeometry): HTMLElement;
168
+ /**
169
+ * Content half of page painting: resolved fragments, decorations (headers,
170
+ * footers, behind-doc sections), and column separators, appended to an
171
+ * existing page shell. Persistent hydration goes through exactly this
172
+ * function, so a hydrated page is byte-equivalent to one painted
173
+ * by the content path from scratch — same element, same append order.
174
+ */
175
+ export declare function hydratePageContent(ctx: PageContentContext, el: HTMLElement, page: ResolvedPage, pageIndex: number): FragmentDomState[];
151
176
  export declare function renderPage(ctx: PageContentContext, page: ResolvedPage, pageIndex: number): PageDomState;
177
+ /**
178
+ * Inverse of {@link hydratePageContent} (default persistent page geometry
179
+ * plan, Unit 1): remove the painter-owned content descendants from an
180
+ * existing page root, leaving root identity, root attributes, page order,
181
+ * exact geometry, and the document scroll extent untouched. The tracked
182
+ * fragment list is removed first (authoritative retained state), then any
183
+ * painter-owned straggler matched by class/attribute — a fragment orphaned
184
+ * from the retained list must not survive dehydration.
185
+ */
186
+ export declare function dehydratePageContent(el: HTMLElement, state: PageDomState): void;
152
187
  export declare function patchPage(ctx: PageContentContext, state: PageDomState, page: ResolvedPage, pageIndex: number): PatchPageWork;
153
188
  export declare function pageContextSignature(context: FragmentRenderContext): string;
154
189
  export declare function hasPageContextTokenInBlock(block: FlowBlock | undefined): boolean;
@@ -207,3 +242,36 @@ export declare function resolvedPaintCacheSignature(resolvedItem: ResolvedPaintI
207
242
  export declare const fragmentKey: (fragment: Fragment) => string;
208
243
  export declare const hasFragmentGeometryChanged: (previous: Fragment, next: Fragment) => boolean;
209
244
  export declare const isNonBodyStoryBlockId: (blockId: string | undefined) => boolean;
245
+ /** Order-insensitive equality over two SDT label key sets. */
246
+ export declare function sdtLabelSetsEqual(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean;
247
+ export type WindowPositionRemapEntry = {
248
+ fragmentState: FragmentDomState;
249
+ freshItem: ResolvedPaintItem & {
250
+ fragment: Fragment;
251
+ };
252
+ /** Fresh minus retained fragment pmStart — the exact uniform shift. */
253
+ deltaPm: number;
254
+ };
255
+ export type WindowPositionRemapPlan = {
256
+ kind: 'none' | 'remap' | 'demote';
257
+ drifted: WindowPositionRemapEntry[];
258
+ };
259
+ /**
260
+ * Painter plan P5: decide whether a version-key-matched page is reusable
261
+ * untouched (`none`), needs an in-place uniform position remap (`remap` —
262
+ * resolve stamps are pm-insensitive, so unchanged content legitimately
263
+ * drifts), or must be demoted to the fragment-keyed patch (`demote`, where
264
+ * `pmReuseUnsound` forces a REAL rebuild of the offending fragment).
265
+ *
266
+ * Fail-closed: one-sided pm, a span-LENGTH change, an interior-pm signature
267
+ * mismatch (a PM node inserted/moved inside the block emits no run, so
268
+ * stamps stay equal while interior offsets move), a missing interior key, or
269
+ * pm-bearing DOM under a fragment with no fragment-level pm all demote —
270
+ * only a PROVABLY uniform drift is shifted in place.
271
+ *
272
+ * Pairing is lockstep by index (review fix): this only runs under versionKey
273
+ * EQUALITY, and the key is an order-sensitive join of every fragment's
274
+ * key+geometry+stamp, so equal keys imply identical ordered fragment
275
+ * sequences — no per-paint key strings or Maps on the steady-state path.
276
+ */
277
+ export declare function planWindowPositionRemap(state: PageDomState, resolvedPage: ResolvedPage): WindowPositionRemapPlan;
@@ -0,0 +1,144 @@
1
+ import { DocumentBackground, ResolvedPage } from '../../../contracts/src/index.js';
2
+ import { PageContentContext, PageDomState, PaintWorkSummary } from './page-content.js';
3
+ /**
4
+ * One exact page band of the committed scaffold (numbers-only,
5
+ * serializable). Structurally compatible with the host pipeline's
6
+ * `PageScaffoldPage` so a host scaffold's `pages` array — including a lazy
7
+ * incremental one — is passed through zero-copy.
8
+ */
9
+ export type DomPainterPersistentScaffoldPage = {
10
+ index: number;
11
+ /** Prefix-sum offset of the page's top edge from the document top. */
12
+ topPx: number;
13
+ heightPx: number;
14
+ widthPx: number;
15
+ /**
16
+ * Physical page number for the shell's `data-page-number` stamp (page
17
+ * numbering can restart per section, so it is data, never `index + 1`).
18
+ * Optional: absent bands leave the stamp to content hydration — the
19
+ * painter reports, it never invents.
20
+ */
21
+ pageNumber?: number;
22
+ };
23
+ /**
24
+ * The immutable generation-scoped page scaffold. Reference identity IS the
25
+ * commit identity: the host builds one scaffold object per committed layout
26
+ * generation and passes the same object to every same-generation content
27
+ * paint, so the painter's same-generation skip is O(1).
28
+ */
29
+ export type DomPainterPersistentScaffold = {
30
+ /** Layout generation that produced this scaffold (the torn-generation fence). */
31
+ generation: number;
32
+ pageCount: number;
33
+ /**
34
+ * Uniform inter-page gap in px. The persistent surface owns the vertical
35
+ * rhythm through the mount's flex `gap`, never through spacer nodes, so
36
+ * `topPx` must equal the prefix sum of heights plus `gapPx` per boundary.
37
+ */
38
+ gapPx: number;
39
+ /** `last.topPx + last.heightPx`; `0` for an empty document. No trailing gap. */
40
+ totalHeightPx: number;
41
+ /** Ascending by `index`; `index` must equal the array position. */
42
+ pages: readonly DomPainterPersistentScaffoldPage[];
43
+ };
44
+ /**
45
+ * Read-only exact-packet lookup. A `ReadonlyMap<number, ResolvedPage>`
46
+ * satisfies it; so does a thin facade over a lazily-resolved page array —
47
+ * the painter reads only the desired content pages, so untouched document
48
+ * tails are never materialized by a paint.
49
+ */
50
+ export interface DomPainterPersistentPacketSource {
51
+ get(pageIndex: number): ResolvedPage | undefined;
52
+ }
53
+ /**
54
+ * The one paginated reconcile input (plan §Target Architecture). Shells
55
+ * always cover the whole scaffold; only the desired content set is bounded.
56
+ */
57
+ export type DomPainterPersistentPageInput = {
58
+ scaffold: DomPainterPersistentScaffold;
59
+ /** Pages whose content must be hydrated (visible window + overscan). */
60
+ desiredContentPageIndices: readonly number[];
61
+ /** Interaction pins that must stay hydrated regardless of the window. */
62
+ pinnedContentPageIndices?: readonly number[];
63
+ /**
64
+ * Exact resolved packets by page index, consumed only for desired content
65
+ * pages. A packet stamped with a different layout epoch than
66
+ * `scaffold.generation` is a torn generation and fails before DOM
67
+ * mutation; so does packet page geometry that disagrees with the band.
68
+ */
69
+ packetsByPageIndex: DomPainterPersistentPacketSource;
70
+ sectionPageCounts?: Readonly<Record<string, number>>;
71
+ documentBackground?: DocumentBackground | null;
72
+ captureSnapshot?: boolean;
73
+ };
74
+ /** Shell registry entry: the persistent page root and its geometry/style reuse key. */
75
+ export type PersistentShellEntry = {
76
+ element: HTMLElement;
77
+ shellKey: string;
78
+ };
79
+ /** Bounded content state for one hydrated page. */
80
+ export type PersistentContentEntry = {
81
+ state: PageDomState;
82
+ versionKey: string | null;
83
+ sdtLabels: ReadonlySet<string>;
84
+ };
85
+ type PersistentSurfaceIntegrity = {
86
+ dirty: boolean;
87
+ observer: MutationObserver | null;
88
+ onInvalidated: () => void;
89
+ };
90
+ /** The retained persistent-surface state the painter snapshots and restores. */
91
+ export type PersistentPageSurfaceState = {
92
+ mount: HTMLElement;
93
+ /** The committed scaffold; reference identity gates the O(1) skip. */
94
+ scaffold: DomPainterPersistentScaffold;
95
+ shells: Map<number, PersistentShellEntry>;
96
+ content: Map<number, PersistentContentEntry>;
97
+ integrity: PersistentSurfaceIntegrity;
98
+ };
99
+ /**
100
+ * The narrow renderer capabilities this module consumes. The deep
101
+ * fragment/decoration render call graph stays on the painter class and is
102
+ * reached through the `PageContentContext` it builds.
103
+ */
104
+ export interface PersistentSurfaceRenderContext {
105
+ contentContext: PageContentContext;
106
+ work: PaintWorkSummary;
107
+ recordPageWork(kind: PersistentPageWorkKind, pageIndex: number): void;
108
+ /** Read-and-consume the provider-change decorations-dirty flag. */
109
+ consumeDecorationsDirty(): boolean;
110
+ /**
111
+ * Signature of every non-geometry input to the shell's visual styles
112
+ * (document background, page-style overrides). Folded into the shell reuse
113
+ * key so a rare document-presentation change refreshes retained roots
114
+ * while steady generations skip all shell attribute writes.
115
+ */
116
+ shellStyleSignature: string;
117
+ /** Wake the host's canonical planner when foreign DOM work corrupts page roots. */
118
+ onIntegrityInvalidated: () => void;
119
+ }
120
+ export type PersistentPageWorkKind = 'createdPersistentPageIndices' | 'removedPersistentPageIndices' | 'patchedContentPageIndices' | 'untouchedContentPageIndices' | 'decorationRefreshedContentPageIndices' | 'remappedContentPageIndices' | 'pmDemotedContentPageIndices' | 'hydratedContentPageIndices' | 'dehydratedContentPageIndices';
121
+ /**
122
+ * Fail-closed scaffold validation: a scaffold is exact geometry or it is
123
+ * nothing. The prefix-sum pin also proves the flex-gap layout reproduces the
124
+ * scaffold offsets exactly, which is what lets the surface drop spacers.
125
+ */
126
+ export declare function validatePersistentScaffold(scaffold: DomPainterPersistentScaffold): void;
127
+ /** Resolve the validated, deduplicated, ascending desired content set. */
128
+ export declare function resolveDesiredContentPageIndices(input: DomPainterPersistentPageInput): number[];
129
+ /**
130
+ * Read the live shell-plane integrity without mutating page content. The host
131
+ * uses this before its zero-work skip so external child-list corruption can
132
+ * never strand the camera over a missing page until some unrelated repaint.
133
+ */
134
+ export declare function isPersistentPageSurfaceIntact(state: PersistentPageSurfaceState | null): boolean;
135
+ export declare function disposePersistentPageSurfaceState(state: PersistentPageSurfaceState | null): void;
136
+ /**
137
+ * The one persistent paginated reconcile. Same-scaffold calls skip shell
138
+ * work in O(1) (reference identity); scaffold identity changes rebuild the
139
+ * shell registry by page index; the content window reconciles every call.
140
+ */
141
+ export declare function reconcilePersistentPageSurface(ctx: PersistentSurfaceRenderContext, previous: PersistentPageSurfaceState | null, input: DomPainterPersistentPageInput, mount: HTMLElement): PersistentPageSurfaceState;
142
+ /** Deep-clone the retained planes for the painter's rollback snapshot. */
143
+ export declare function clonePersistentPageSurfaceState(state: PersistentPageSurfaceState | null, clonePageState: (pageState: PageDomState) => PageDomState): PersistentPageSurfaceState | null;
144
+ export {};
@@ -16,7 +16,7 @@ export type RunCoordinateRequirement = 'legacy-pm-required' | 'story-identity-re
16
16
  /** Console verbosity. `off` is production and the performance `--quiet` mode. */
17
17
  export type PositionValidationConsolePolicy = 'off' | 'summary' | 'verbose';
18
18
  /** Which painter produced the observation (kept isolated per painter instance). */
19
- export type PaintKind = 'surface-window' | 'dense-reference';
19
+ export type PaintKind = 'persistent-page' | 'persistent-page-oracle' | 'semantic';
20
20
  /** Execution realm, for cross-realm report comparison. */
21
21
  export type PaintRealm = 'node-headless' | 'browser-inline' | 'browser-worker' | 'product';
22
22
  export type PositionValidationSection = 'body' | 'header' | 'footer';
@@ -1,5 +1,6 @@
1
- import { FlowMode, Fragment, PageMargins, PageNumberChapterSeparator, PageNumberFormat, SourceAnchor, DocumentBackground, ResolvedLayout, ResolvedPage, ResolvedPaintItem, LayoutSourceIdentity, LayoutStoryLocator } from '../../../contracts/src/index.js';
1
+ import { FlowMode, Fragment, PageMargins, PageNumberChapterSeparator, PageNumberFormat, SourceAnchor, ResolvedLayout, ResolvedPage, ResolvedPaintItem, LayoutSourceIdentity, LayoutStoryLocator } from '../../../contracts/src/index.js';
2
2
  import { PaintWorkSummary } from './page-content.js';
3
+ import { DomPainterPersistentPageInput } from './persistent-page-surface.js';
3
4
  import { PageStyles } from './styles.js';
4
5
  import { PaintSnapshotStructuredContentBlockEntity, PaintSnapshotStructuredContentInlineEntity } from './sdt/snapshot.js';
5
6
  import { PositionValidationOptions, PositionValidationSummary } from './pm-position-validation.js';
@@ -40,56 +41,6 @@ export type RenderedLineInfo = {
40
41
  export type DomPainterInput = {
41
42
  resolvedLayout: ResolvedLayout;
42
43
  };
43
- export type DomPainterPageWindowExactness = 'exact' | 'estimated' | 'loading' | 'pending-source' | 'pending-layout' | 'degraded-unsupported' | 'failed' | 'stale';
44
- export type DomPainterPageWindowExtent = {
45
- pageIndex: number;
46
- topPx: number;
47
- heightPx: number;
48
- widthPx: number;
49
- };
50
- export type DomPainterPageWindowPacket = {
51
- pageIndex: number;
52
- exactness: DomPainterPageWindowExactness;
53
- resolvedPage?: ResolvedPage | null;
54
- diagnostic?: string | null;
55
- };
56
- export type DomPainterPageWindowInput = {
57
- pageExtents: readonly DomPainterPageWindowExtent[];
58
- documentExtent?: {
59
- pageCount: number;
60
- scrollHeightPx: number;
61
- };
62
- visibleRange: {
63
- startPageIndex: number;
64
- endPageIndexExclusive: number;
65
- };
66
- packets: readonly DomPainterPageWindowPacket[];
67
- /** Exact document-level section totals; never derive these from the mounted window. */
68
- sectionPageCounts?: Readonly<Record<string, number>>;
69
- overscan?: number;
70
- pinnedPageIndices?: readonly number[];
71
- captureSnapshot?: boolean;
72
- /**
73
- * Document-level page background (OOXML `w:background`), normally read off
74
- * `ResolvedLayout.documentBackground` by the caller. Page-window paints own
75
- * no `ResolvedLayout`, so without this scalar every windowed page silently
76
- * loses the document background dense paint applies (page-window rendering
77
- * preflight plan, failure mode 5). Omitted/null = no document background.
78
- */
79
- documentBackground?: DocumentBackground | null;
80
- /**
81
- * Layout generation the extents were derived from (painter plan P5x). When
82
- * provided, the torn-window guard is ARMED: every exact packet whose page
83
- * carries a `layoutEpoch` must match it — a mismatch means the caller mixed
84
- * packets from one layout pass with extents from another (torn window),
85
- * which paints stale geometry that no per-page version key can catch. Fail
86
- * loud instead. When omitted the guard stays dark and mixed stamps are
87
- * tolerated — the pre-integration render surface serves
88
- * stale-while-revalidate packets beside fresh ones by design; P6a arms the
89
- * guard when it wires the windowed path (plan P6a item 6).
90
- */
91
- layoutEpoch?: number;
92
- };
93
44
  export type PageDecorationPayload = {
94
45
  fragments: Fragment[];
95
46
  /** Resolved items aligned 1:1 with `fragments`. Same length, same order. */
@@ -278,15 +229,14 @@ export type PaintSnapshot = {
278
229
  pages: PaintSnapshotPage[];
279
230
  entities: PaintSnapshotEntities;
280
231
  };
281
- type PageWindowPainterTransaction = {
232
+ type PersistentPagePainterTransaction = {
282
233
  commit(): void;
283
234
  rollback(): void;
284
235
  };
285
236
  /**
286
237
  * DOM-based document painter that renders layout fragments to HTML elements.
287
- * One paint entry per mode (painter plan P7): `paintPageWindow` owns
288
- * paginated flow (windowed, page-keyed reuse; a dense paint is a full-range
289
- * window), `paint()` owns semantic flow (continuous surface).
238
+ * One paint entry per mode (painter plan P7): the persistent shell/content
239
+ * reconcile owns paginated flow, while `paint()` owns semantic flow.
290
240
  *
291
241
  * @class DomPainter
292
242
  *
@@ -304,7 +254,6 @@ export declare class DomPainter {
304
254
  private doc;
305
255
  private pageStates;
306
256
  private currentLayout;
307
- private denseProofNextPageIndex;
308
257
  private changedBlocks;
309
258
  private readonly isSemanticFlow;
310
259
  private headerProvider?;
@@ -326,22 +275,28 @@ export declare class DomPainter {
326
275
  private processedLayoutVersion;
327
276
  /** Current transaction mapping for position updates (null if no mapping or complex transaction) */
328
277
  private currentMapping;
329
- private windowPageStates;
330
- private windowMount;
278
+ /**
279
+ * Persistent paginated page surface (default persistent page geometry
280
+ * plan, Unit 1): the generation-owned shell registry plus the bounded
281
+ * content plane, retained across paints. Snapshot/restored by the private
282
+ * persistent-page transaction like every other retained plane.
283
+ */
284
+ private persistentSurface;
285
+ private persistentSurfaceInvalidationHandler;
331
286
  /**
332
287
  * Provider identity may advance every render generation even when the body
333
- * page remains reusable. Refresh header/footer DOM on the next window paint
288
+ * page remains reusable. Refresh header/footer DOM on the next content reconcile
334
289
  * without discarding the retained page element or its body fragments.
335
290
  */
336
- private windowDecorationsDirty;
291
+ private persistentDecorationsDirty;
337
292
  /**
338
293
  * Page-window analog of `currentLayout.documentBackground`: the window path
339
294
  * deliberately runs with `currentLayout = null`, so the document background
340
- * scalar from `DomPainterPageWindowInput` is retained here for
295
+ * scalar from `DomPainterPersistentPageInput` is retained here for
341
296
  * `getEffectivePageStyles()`. Reset by dense `paint()`/`resetState()`/
342
297
  * `dispose()` so a stale window value can never leak across modes/mounts.
343
298
  */
344
- private windowDocumentBackground;
299
+ private persistentDocumentBackground;
345
300
  private paintWork;
346
301
  /**
347
302
  * P5 §4.6 (review fix): per-page attribution arrays are opt-in. Counters
@@ -352,7 +307,7 @@ export declare class DomPainter {
352
307
  private readonly paintWorkAttribution;
353
308
  /**
354
309
  * Story-aware position-coverage collector, owned per painter instance so the
355
- * product surface window and the dense-reference oracle never mix counts.
310
+ * live persistent surface and fresh-state oracle never mix counts.
356
311
  * Dark unless enabled via options; when dark, `record()` is a single branch.
357
312
  */
358
313
  private readonly positionValidation;
@@ -360,12 +315,12 @@ export declare class DomPainter {
360
315
  private lastPaintSnapshot;
361
316
  private onPaintSnapshotCallback;
362
317
  /**
363
- * Private page-window transaction state. The package handle exposes this
318
+ * Private persistent-page transaction state. The package handle exposes this
364
319
  * only through a non-enumerable Symbol.for seam; it is deliberately absent
365
320
  * from the public DomPainterHandle contract.
366
321
  */
367
- private activePageWindowTransaction;
368
- private mountedPageIndices;
322
+ private activePersistentPageTransaction;
323
+ private persistentPageIndices;
369
324
  /** Resolved layout for the next-gen paint pipeline. */
370
325
  private resolvedLayout;
371
326
  private showFormattingMarks;
@@ -376,11 +331,9 @@ export declare class DomPainter {
376
331
  private applyFormattingMarksClass;
377
332
  private invalidateRenderedContent;
378
333
  /**
379
- * Forget the page-window surface so the next `paintPageWindow` rebuilds
380
- * every page from scratch (fresh-mount branch: clear + `innerHTML = ''`).
381
- * Used by invalidations whose inputs are not covered by
382
- * `pageWindowVersionKey` and require rebuilding body content (for example,
383
- * render-setting changes). Provider swaps use a decoration-only refresh.
334
+ * Forget the persistent surface so its next reconcile rebuilds content
335
+ * under the current render settings. Provider swaps use a
336
+ * decoration-only refresh.
384
337
  */
385
338
  private invalidateWindowSurface;
386
339
  /** Returns the resolved page for a given index, or null if resolved data is unavailable. */
@@ -390,15 +343,12 @@ export declare class DomPainter {
390
343
  */
391
344
  getPaintSnapshot(): PaintSnapshot | null;
392
345
  /**
393
- * Returns the page indices that are currently mounted in the DOM.
394
- *
395
- * Reflects the painter's current mounted set (page-window mounts/unmounts
396
- * included) without waiting for a full paint cycle.
346
+ * Returns the stable page-root indices owned by the current surface.
397
347
  */
398
- getMountedPageIndices(): number[];
348
+ getPersistentPageIndices(): number[];
399
349
  /**
400
350
  * Begin a rollbackable transaction around a content paint. Named for the
401
- * paginated page-window path it was minted for; the captured snapshot is
351
+ * paginated persistent-page path it was minted for; the captured snapshot is
402
352
  * the painter's COMPLETE retained/index state, so the same journal serves
403
353
  * the semantic flow's dense `paint()` entry (the v2 host's canonical
404
354
  * atomic visible commit wraps both paint kinds in one transaction).
@@ -409,41 +359,39 @@ export declare class DomPainter {
409
359
  * every painter-owned retained/index plane to references for those restored
410
360
  * last-good nodes.
411
361
  */
412
- beginPageWindowTransaction(): PageWindowPainterTransaction;
413
- private capturePageWindowPainterState;
414
- private restorePageWindowPainterState;
362
+ beginPersistentPageTransaction(): PersistentPagePainterTransaction;
363
+ private capturePersistentPagePainterState;
364
+ private restorePersistentPagePainterState;
415
365
  private createAllPageIndices;
416
- private setMountedPageIndices;
366
+ private setPersistentPageIndices;
417
367
  private emitPaintSnapshot;
418
368
  private beginPaintSnapshot;
419
369
  private finalizePaintSnapshotFromBuilder;
420
370
  private capturePaintSnapshotLine;
421
371
  private collectPaintSnapshotFromDomRoot;
422
- /**
423
- * Dense continuous paint. Mode ownership (painter plan P7): semantic flow's
424
- * ONLY paint entry, and — for paginated flow — the package-internal dense
425
- * REFERENCE implementation kept as the executable spec the equivalence
426
- * oracles and kernel tests compare `paintPageWindow` against. Consumers
427
- * reach the paginated form exclusively through `createDenseReferencePainter`;
428
- * the ordinary `createDomPainter` handle rejects paginated `paint()` calls.
429
- */
372
+ /** Semantic continuous paint. Paginated flow has only `paintPersistentPages()`. */
430
373
  paint(input: DomPainterInput, mount: HTMLElement, mapping?: PositionMapping): void;
431
374
  /**
432
- * Proof-only dense traversal. It preserves the dense painter's document
433
- * context and cross-page state while retaining DOM for only one bounded
434
- * page interval at a time.
375
+ * The persistent paginated reconcile (default persistent page geometry
376
+ * plan, Unit 1): one generation-scoped scaffold owns every page root for
377
+ * the whole layout generation, and only content descendants are
378
+ * virtualized. Same-scaffold calls skip shell work in O(1); a new scaffold
379
+ * identity reconciles page roots by index. There is no viewport-owned shell
380
+ * set and no spacer node — the scroll extent derives
381
+ * from the persistent shells plus the container gap alone.
435
382
  */
436
- paintDensePageBatch(input: DomPainterInput, mount: HTMLElement, startPageIndex: number, endPageIndexExclusive: number): void;
383
+ paintPersistentPages(input: DomPainterPersistentPageInput, mount: HTMLElement): void;
384
+ /** True only while the retained document-wide page-shell plane matches the live DOM. */
385
+ isPersistentPageSurfaceIntact(): boolean;
386
+ /** Register the host wake-up used when foreign DOM work removes/replaces page shells. */
387
+ setPersistentSurfaceInvalidationHandler(handler?: () => void): void;
437
388
  /**
438
- * Page-window runtime API. It accepts document-owned page extents and page
439
- * packets for the currently visible range, so callers can mount a lower-page
440
- * viewport without handing the painter a complete `ResolvedLayout.pages`
441
- * array. Non-exact pages are explicit pending/degraded sheets, never blank
442
- * workspace.
389
+ * Hydrated content page indices of the persistent surface, ascending.
390
+ * Page roots cover the whole scaffold; this is the bounded content set.
443
391
  */
444
- paintPageWindow(input: DomPainterPageWindowInput, mount: HTMLElement): void;
392
+ getHydratedContentPageIndices(): number[];
445
393
  /**
446
- * Painter plan §4.6 (dark observability): page-window paint work since the
394
+ * Painter plan §4.6 (dark observability): persistent-page paint work since the
447
395
  * last consume. Never invents values — fields the path cannot attribute yet
448
396
  * stay 0/null.
449
397
  */
@@ -462,10 +410,6 @@ export declare class DomPainter {
462
410
  * ever consumes the summary. Counters stay always-on and O(1).
463
411
  */
464
412
  private recordPageWork;
465
- private configureSpacerElement;
466
- private createPageWindowSpacer;
467
- private createPendingPageWindowElement;
468
- private ensurePageWindowPendingSkeletonStyles;
469
413
  private renderColumnSeparators;
470
414
  private getColumnSeparatorPositions;
471
415
  private renderDecorationsForPage;
@@ -592,8 +536,8 @@ export declare class DomPainter {
592
536
  * @param textAlign - Horizontal text alignment
593
537
  * @param textVerticalAlign - Vertical text alignment (top, center, bottom)
594
538
  * @param textInsets - Text insets in pixels (top, right, bottom, left)
595
- * @param groupScaleX - Scale factor applied by parent group (for counter-scaling)
596
- * @param groupScaleY - Scale factor applied by parent group (for counter-scaling)
539
+ * @param _groupScaleX - Reserved parent-group scale factor
540
+ * @param _groupScaleY - Reserved parent-group scale factor
597
541
  */
598
542
  private createFallbackTextElement;
599
543
  private tryCreatePresetSvg;
@@ -3,7 +3,7 @@ import { SdtBoundaryOptions } from './container.js';
3
3
  /**
4
4
  * The container-label keys a `computeSdtBoundaries` walk over `resolvedItems`
5
5
  * WOULD add to `sdtLabelsRendered`, without mutating it. This is the pure
6
- * "which labels does this page display" function the page-window reuse path
6
+ * "which labels does this page display" function the persistent-page reuse path
7
7
  * compares against recorded per-page label state: label placement is
8
8
  * cross-page prefix state that resolve stamps do not cover, so an untouched
9
9
  * reuse is only safe when the recorded labels equal this expectation.
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_rolldown_runtime = require("../chunks/rolldown-runtime-_dR15c8t.cjs");
3
- const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-CXCqHc2m.cjs");
2
+ const require_rolldown_runtime = require("../chunks/rolldown-runtime-1Y-nnZJ3.cjs");
3
+ const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-DXdWuTzm.cjs");
4
4
  let react = require("react");
5
5
  var SuperDocUIContext = (0, react.createContext)(null);
6
6
  function disposeOwnedUi(ref) {
@@ -1,4 +1,4 @@
1
- import { t as createSuperDocUI } from "../chunks/create-super-doc-ui-fxF2Q8Ib.es.js";
1
+ import { t as createSuperDocUI } from "../chunks/create-super-doc-ui-D4kk9AjM.es.js";
2
2
  import { createContext, createElement, useCallback, useContext, useEffect, useRef, useState } from "react";
3
3
  var SuperDocUIContext = createContext(null);
4
4
  function disposeOwnedUi(ref) {
@@ -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-CXCqHc2m.cjs");
2
+ const require_create_super_doc_ui = require("../chunks/create-super-doc-ui-DXdWuTzm.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 shallowEqual, r as BUILT_IN_COMMAND_IDS, t as createSuperDocUI } from "../chunks/create-super-doc-ui-fxF2Q8Ib.es.js";
1
+ import { n as shallowEqual, r as BUILT_IN_COMMAND_IDS, t as createSuperDocUI } from "../chunks/create-super-doc-ui-D4kk9AjM.es.js";
2
2
  export { BUILT_IN_COMMAND_IDS, createSuperDocUI, shallowEqual };