@rtif-sdk/web 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/renderer.js CHANGED
@@ -344,90 +344,28 @@ export function reconcile(root, prevDoc, nextDoc, composingBlockId, markRenderer
344
344
  const nextBlockIds = new Set();
345
345
  // Walk next blocks in order, using a reference node cursor to minimize moves
346
346
  let referenceNode = root.firstChild;
347
+ // Skip spacer nodes (from virtual viewport) so reconcile doesn't treat them as blocks
348
+ while (referenceNode instanceof HTMLElement &&
349
+ referenceNode.hasAttribute('data-rtif-spacer')) {
350
+ referenceNode = referenceNode.nextSibling;
351
+ }
347
352
  for (const nextBlock of nextDoc.blocks) {
348
353
  nextBlockIds.add(nextBlock.id);
349
354
  let blockEl = existingElements.get(nextBlock.id) ?? null;
350
355
  if (blockEl) {
351
- // Block element already exists in the DOM
352
356
  const prevBlock = prevBlockMap.get(nextBlock.id);
353
- // Skip composing block entirely
354
- if (nextBlock.id === composingBlockId) {
355
- // Just make sure it's in the right position
356
- if (blockEl !== referenceNode) {
357
- root.insertBefore(blockEl, referenceNode);
358
- }
359
- else {
360
- referenceNode = referenceNode.nextSibling;
361
- }
357
+ // Delegate content reconciliation to reconcileBlock (single source of truth).
358
+ // reconcileBlock handles composing skip, type/attr changes, span updates.
359
+ // It may return a new element if the block was fully replaced.
360
+ const result = reconcileBlock(root, blockEl, prevBlock, nextBlock, composingBlockId, markRenderers, blockRenderers);
361
+ if (result !== blockEl) {
362
+ existingElements.set(nextBlock.id, result);
363
+ blockEl = result;
364
+ // replaceChild already placed the new element in the old position;
365
+ // advance referenceNode past it.
366
+ referenceNode = result.nextSibling;
362
367
  continue;
363
368
  }
364
- // Check if block changed by reference
365
- if (prevBlock !== nextBlock) {
366
- // If block type or attrs changed, try in-place update first
367
- if (prevBlock && (prevBlock.type !== nextBlock.type || prevBlock.attrs !== nextBlock.attrs)) {
368
- let didUpdate = false;
369
- // If same type, try updateElement() for efficient in-place attr updates
370
- if (prevBlock.type === nextBlock.type && blockRenderers) {
371
- const renderer = blockRenderers.get(nextBlock.type);
372
- if (renderer?.updateElement) {
373
- didUpdate = renderer.updateElement(blockEl, nextBlock);
374
- if (didUpdate) {
375
- // Re-apply attr renderers (alignment, indent, etc.)
376
- if (nextBlock.attrs) {
377
- for (const [key, value] of Object.entries(nextBlock.attrs)) {
378
- if (value == null)
379
- continue;
380
- const attrRenderer = blockRenderers.getAttrRenderer(key);
381
- if (attrRenderer) {
382
- attrRenderer.apply(blockEl, value);
383
- }
384
- }
385
- }
386
- // Reconcile spans separately since updateElement only handles attrs
387
- const container = getSpanContainer(blockEl, nextBlock.type, blockRenderers);
388
- reconcileBlockSpans(container, prevBlock, nextBlock, markRenderers);
389
- // Ensure correct position
390
- if (blockEl !== referenceNode) {
391
- root.insertBefore(blockEl, referenceNode);
392
- }
393
- else {
394
- referenceNode = referenceNode.nextSibling;
395
- }
396
- continue;
397
- }
398
- }
399
- }
400
- // Fall back to full replacement if updateElement doesn't exist,
401
- // returned false, or types differ
402
- const newBlockEl = createBlockElement(nextBlock, markRenderers, blockRenderers);
403
- root.replaceChild(newBlockEl, blockEl);
404
- // Update our reference so position tracking remains correct
405
- existingElements.set(nextBlock.id, newBlockEl);
406
- blockEl = newBlockEl;
407
- // replaceChild keeps position; advance referenceNode past replaced element
408
- referenceNode = newBlockEl.nextSibling;
409
- continue;
410
- }
411
- // Update block-type attribute if changed
412
- if (blockEl.getAttribute('data-block-type') !== nextBlock.type) {
413
- blockEl.setAttribute('data-block-type', nextBlock.type);
414
- }
415
- // Reconcile spans within this block (skip if spans are identical by reference)
416
- if (prevBlock && prevBlock.spans !== nextBlock.spans) {
417
- const container = getSpanContainer(blockEl, nextBlock.type, blockRenderers);
418
- reconcileBlockSpans(container, prevBlock, nextBlock, markRenderers);
419
- }
420
- else if (!prevBlock) {
421
- // No previous block data — full re-render of span content
422
- const container = getSpanContainer(blockEl, nextBlock.type, blockRenderers);
423
- while (container.firstChild) {
424
- container.removeChild(container.firstChild);
425
- }
426
- for (const span of nextBlock.spans) {
427
- container.appendChild(createSpanElement(span, markRenderers));
428
- }
429
- }
430
- }
431
369
  // Ensure correct position
432
370
  if (blockEl !== referenceNode) {
433
371
  root.insertBefore(blockEl, referenceNode);
@@ -458,4 +396,96 @@ export function reconcile(root, prevDoc, nextDoc, composingBlockId, markRenderer
458
396
  }
459
397
  }
460
398
  }
399
+ /**
400
+ * Reconcile a single block element to match a new RTIF block state.
401
+ *
402
+ * Extracted from {@link reconcile} for use by the virtual viewport, which
403
+ * needs to reconcile individual blocks without running the full document
404
+ * reconciliation loop.
405
+ *
406
+ * Returns the (possibly replaced) block element. When the block type or attrs
407
+ * change and in-place update fails, a new element is created and the caller
408
+ * must update its own references (e.g., blockElementMap).
409
+ *
410
+ * @param root - The root DOM element (used for block renderer context)
411
+ * @param blockEl - The existing block DOM element
412
+ * @param prevBlock - The previous RTIF block state, or undefined if new
413
+ * @param nextBlock - The new RTIF block state
414
+ * @param composingBlockId - Block ID currently under IME composition, or null
415
+ * @param markRenderers - Optional registry of mark renderers
416
+ * @param blockRenderers - Optional registry of block renderers
417
+ * @returns The reconciled block element (same reference or a new replacement)
418
+ *
419
+ * @example
420
+ * ```ts
421
+ * const el = reconcileBlock(root, blockEl, prevBlock, nextBlock, null, marks, blocks);
422
+ * if (el !== blockEl) {
423
+ * blockElementMap.set(nextBlock.id, el);
424
+ * }
425
+ * ```
426
+ */
427
+ export function reconcileBlock(root, blockEl, prevBlock, nextBlock, composingBlockId, markRenderers, blockRenderers) {
428
+ // Skip composing block entirely
429
+ if (nextBlock.id === composingBlockId) {
430
+ return blockEl;
431
+ }
432
+ // Check if block changed by reference
433
+ if (prevBlock === nextBlock) {
434
+ return blockEl;
435
+ }
436
+ // If block type or attrs changed, try in-place update first
437
+ if (prevBlock && (prevBlock.type !== nextBlock.type || prevBlock.attrs !== nextBlock.attrs)) {
438
+ // If same type, try updateElement() for efficient in-place attr updates
439
+ if (prevBlock.type === nextBlock.type && blockRenderers) {
440
+ const renderer = blockRenderers.get(nextBlock.type);
441
+ if (renderer?.updateElement) {
442
+ const didUpdate = renderer.updateElement(blockEl, nextBlock);
443
+ if (didUpdate) {
444
+ // Re-apply attr renderers (alignment, indent, etc.)
445
+ if (nextBlock.attrs) {
446
+ for (const [key, value] of Object.entries(nextBlock.attrs)) {
447
+ if (value == null)
448
+ continue;
449
+ const attrRenderer = blockRenderers.getAttrRenderer(key);
450
+ if (attrRenderer) {
451
+ attrRenderer.apply(blockEl, value);
452
+ }
453
+ }
454
+ }
455
+ // Reconcile spans separately since updateElement only handles attrs
456
+ const container = getSpanContainer(blockEl, nextBlock.type, blockRenderers);
457
+ reconcileBlockSpans(container, prevBlock, nextBlock, markRenderers);
458
+ return blockEl;
459
+ }
460
+ }
461
+ }
462
+ // Fall back to full replacement if updateElement doesn't exist,
463
+ // returned false, or types differ
464
+ const newBlockEl = createBlockElement(nextBlock, markRenderers, blockRenderers);
465
+ if (blockEl.parentNode) {
466
+ blockEl.parentNode.replaceChild(newBlockEl, blockEl);
467
+ }
468
+ return newBlockEl;
469
+ }
470
+ // Update block-type attribute if changed
471
+ if (blockEl.getAttribute('data-block-type') !== nextBlock.type) {
472
+ blockEl.setAttribute('data-block-type', nextBlock.type);
473
+ }
474
+ // Reconcile spans within this block (skip if spans are identical by reference)
475
+ if (prevBlock && prevBlock.spans !== nextBlock.spans) {
476
+ const container = getSpanContainer(blockEl, nextBlock.type, blockRenderers);
477
+ reconcileBlockSpans(container, prevBlock, nextBlock, markRenderers);
478
+ }
479
+ else if (!prevBlock) {
480
+ // No previous block data — full re-render of span content
481
+ const container = getSpanContainer(blockEl, nextBlock.type, blockRenderers);
482
+ while (container.firstChild) {
483
+ container.removeChild(container.firstChild);
484
+ }
485
+ for (const span of nextBlock.spans) {
486
+ container.appendChild(createSpanElement(span, markRenderers));
487
+ }
488
+ }
489
+ return blockEl;
490
+ }
461
491
  //# sourceMappingURL=renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Spatial index for viewport virtualization.
3
+ *
4
+ * A prefix-sum array of block pixel heights, mirroring
5
+ * {@link ResolveIndex} from `@rtif-sdk/core` but for layout instead of
6
+ * character offsets. Provides O(1) `blockTop` / `totalHeight` and
7
+ * O(log n) `computeVisibleRange` for efficiently determining which
8
+ * blocks are visible within a scrollable viewport.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ import type { Document } from '@rtif-sdk/core';
13
+ /**
14
+ * Default estimated pixel heights per block type.
15
+ *
16
+ * Used when no measured height is available for a block.
17
+ * Override via {@link SpatialIndexConfig.blockTypeHeights}.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * // Use defaults with a custom "callout" override
22
+ * createSpatialIndex(doc, {
23
+ * blockTypeHeights: { ...DEFAULT_BLOCK_TYPE_HEIGHTS, callout: 64 },
24
+ * });
25
+ * ```
26
+ */
27
+ export declare const DEFAULT_BLOCK_TYPE_HEIGHTS: Record<string, number>;
28
+ /**
29
+ * Configuration for creating a {@link SpatialIndex}.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const config: SpatialIndexConfig = {
34
+ * estimatedBlockHeight: 32,
35
+ * blockTypeHeights: { heading: 48, image: 250 },
36
+ * };
37
+ * ```
38
+ */
39
+ export interface SpatialIndexConfig {
40
+ /**
41
+ * Default estimated pixel height for block types not listed in
42
+ * {@link blockTypeHeights} or {@link DEFAULT_BLOCK_TYPE_HEIGHTS}.
43
+ *
44
+ * Default: `24`.
45
+ */
46
+ readonly estimatedBlockHeight?: number;
47
+ /**
48
+ * Estimated pixel heights per block type string.
49
+ *
50
+ * Merged on top of {@link DEFAULT_BLOCK_TYPE_HEIGHTS} so you only
51
+ * need to specify overrides. Pass an empty object to use only the
52
+ * built-in defaults.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * { heading: 48, 'list-item': 28 }
57
+ * ```
58
+ */
59
+ readonly blockTypeHeights?: Record<string, number>;
60
+ }
61
+ /**
62
+ * A prefix-sum spatial index for O(1) block-top queries and O(log n)
63
+ * visible-range computation.
64
+ *
65
+ * Create with {@link createSpatialIndex}. The index is mutable --
66
+ * call {@link setBlockHeight} or {@link setBlockHeights} as measured
67
+ * heights become available, and {@link rebuild} when the document
68
+ * structure changes (blocks added/removed/reordered).
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * const spatial = createSpatialIndex(doc);
73
+ * const range = spatial.computeVisibleRange(scrollTop, viewportHeight, 2);
74
+ * for (let i = range.start; i < range.end; i++) {
75
+ * renderBlock(doc.blocks[i]);
76
+ * }
77
+ * ```
78
+ */
79
+ export interface SpatialIndex {
80
+ /**
81
+ * Total height of all blocks in pixels.
82
+ *
83
+ * @returns Sum of all block heights (O(1))
84
+ */
85
+ totalHeight(): number;
86
+ /**
87
+ * Number of blocks in the index.
88
+ *
89
+ * @returns Block count (O(1))
90
+ */
91
+ blockCount(): number;
92
+ /**
93
+ * Pixel height of the block at the given index.
94
+ *
95
+ * @param index - 0-based block index
96
+ * @returns The block's height in pixels
97
+ * @throws {RangeError} If index is out of bounds
98
+ */
99
+ blockHeight(index: number): number;
100
+ /**
101
+ * The y-coordinate (top edge) of the block at the given index,
102
+ * measured from the top of the document.
103
+ *
104
+ * @param index - 0-based block index
105
+ * @returns Pixel offset from document top (O(1))
106
+ * @throws {RangeError} If index is out of bounds
107
+ */
108
+ blockTop(index: number): number;
109
+ /**
110
+ * Compute the range of block indices visible within a scrollable
111
+ * viewport, plus a configurable buffer of extra blocks on each side.
112
+ *
113
+ * Uses binary search on the prefix-sum array for O(log n) performance.
114
+ *
115
+ * @param scrollTop - The viewport's scroll offset from the top of the
116
+ * document in pixels. Clamped to `[0, totalHeight]`.
117
+ * @param viewportHeight - The viewport height in pixels. Must be >= 0.
118
+ * @param buffer - Number of extra blocks to include before and after
119
+ * the visible range (for smooth scrolling). Clamped to valid range.
120
+ * @returns An object with `start` (inclusive) and `end` (exclusive)
121
+ * block indices. When there are no blocks, returns `{ start: 0, end: 0 }`.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * const { start, end } = spatial.computeVisibleRange(200, 600, 3);
126
+ * // Render blocks [start, end)
127
+ * ```
128
+ */
129
+ computeVisibleRange(scrollTop: number, viewportHeight: number, buffer: number): {
130
+ readonly start: number;
131
+ readonly end: number;
132
+ };
133
+ /**
134
+ * Update the measured pixel height of a single block and rebuild
135
+ * prefix sums from that index onward.
136
+ *
137
+ * @param index - 0-based block index
138
+ * @param height - New measured height in pixels
139
+ * @throws {RangeError} If index is out of bounds
140
+ */
141
+ setBlockHeight(index: number, height: number): void;
142
+ /**
143
+ * Batch-update measured pixel heights for multiple blocks and rebuild
144
+ * prefix sums once.
145
+ *
146
+ * More efficient than calling {@link setBlockHeight} in a loop because
147
+ * prefix sums are only rebuilt once, starting from the lowest changed index.
148
+ *
149
+ * @param updates - Array of `{ index, height }` pairs
150
+ * @throws {RangeError} If any index is out of bounds
151
+ */
152
+ setBlockHeights(updates: ReadonlyArray<{
153
+ readonly index: number;
154
+ readonly height: number;
155
+ }>): void;
156
+ /**
157
+ * Rebuild the index from a (potentially new) document.
158
+ *
159
+ * Creates a fresh prefix-sum array sized to the document's block count.
160
+ * If `preserveHeights` is provided (keyed by block ID), those measured
161
+ * heights are used; otherwise the estimate for the block's type is used.
162
+ *
163
+ * @param doc - The RTIF document to index
164
+ * @param preserveHeights - Optional map of block ID to measured pixel
165
+ * height. Blocks whose IDs appear in this map use the measured value
166
+ * instead of the type-based estimate.
167
+ */
168
+ rebuild(doc: Document, preserveHeights?: Map<string, number>): void;
169
+ }
170
+ /**
171
+ * Create a spatial index for viewport virtualization.
172
+ *
173
+ * Builds a prefix-sum array of estimated block heights in O(n). Subsequent
174
+ * `blockTop()` calls are O(1) and `computeVisibleRange()` calls are O(log n).
175
+ *
176
+ * As blocks are rendered and measured, call {@link SpatialIndex.setBlockHeight}
177
+ * or {@link SpatialIndex.setBlockHeights} to replace estimates with actual
178
+ * measured values. When the document structure changes (blocks added, removed,
179
+ * or reordered), call {@link SpatialIndex.rebuild}.
180
+ *
181
+ * @param doc - The RTIF document to index
182
+ * @param config - Optional configuration for height estimates
183
+ * @returns A new {@link SpatialIndex} instance
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * import { createSpatialIndex } from '@rtif-sdk/web';
188
+ *
189
+ * const spatial = createSpatialIndex(doc);
190
+ * console.log(spatial.totalHeight()); // e.g. 2400
191
+ * console.log(spatial.blockTop(5)); // e.g. 120
192
+ *
193
+ * const { start, end } = spatial.computeVisibleRange(100, 600, 2);
194
+ * for (let i = start; i < end; i++) {
195
+ * renderBlock(doc.blocks[i]);
196
+ * }
197
+ *
198
+ * // After measuring a block's actual height:
199
+ * spatial.setBlockHeight(5, 36);
200
+ * ```
201
+ */
202
+ export declare function createSpatialIndex(doc: Document, config?: SpatialIndexConfig): SpatialIndex;
203
+ //# sourceMappingURL=spatial-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatial-index.d.ts","sourceRoot":"","sources":["../src/spatial-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAM/C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAQ7D,CAAC;AAMF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAEvC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,WAAW,IAAI,MAAM,CAAC;IAEtB;;;;OAIG;IACH,UAAU,IAAI,MAAM,CAAC;IAErB;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEnC;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,mBAAmB,CACjB,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAEpD;;;;;;;OAOG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpD;;;;;;;;;OASG;IACH,eAAe,CACb,OAAO,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GAC1E,IAAI,CAAC;IAER;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACrE;AA+CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,QAAQ,EACb,MAAM,CAAC,EAAE,kBAAkB,GAC1B,YAAY,CAgJd"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Spatial index for viewport virtualization.
3
+ *
4
+ * A prefix-sum array of block pixel heights, mirroring
5
+ * {@link ResolveIndex} from `@rtif-sdk/core` but for layout instead of
6
+ * character offsets. Provides O(1) `blockTop` / `totalHeight` and
7
+ * O(log n) `computeVisibleRange` for efficiently determining which
8
+ * blocks are visible within a scrollable viewport.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ // ---------------------------------------------------------------------------
13
+ // Constants
14
+ // ---------------------------------------------------------------------------
15
+ /**
16
+ * Default estimated pixel heights per block type.
17
+ *
18
+ * Used when no measured height is available for a block.
19
+ * Override via {@link SpatialIndexConfig.blockTypeHeights}.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // Use defaults with a custom "callout" override
24
+ * createSpatialIndex(doc, {
25
+ * blockTypeHeights: { ...DEFAULT_BLOCK_TYPE_HEIGHTS, callout: 64 },
26
+ * });
27
+ * ```
28
+ */
29
+ export const DEFAULT_BLOCK_TYPE_HEIGHTS = {
30
+ text: 24,
31
+ heading: 40,
32
+ code_block: 48,
33
+ blockquote: 32,
34
+ hr: 16,
35
+ image: 200,
36
+ embed: 300,
37
+ };
38
+ // ---------------------------------------------------------------------------
39
+ // Helpers
40
+ // ---------------------------------------------------------------------------
41
+ /**
42
+ * Estimate the pixel height of a block based on its type.
43
+ */
44
+ function estimateHeight(blockType, mergedHeights, fallback) {
45
+ const h = mergedHeights[blockType];
46
+ return h !== undefined ? h : fallback;
47
+ }
48
+ /**
49
+ * Rebuild prefix sums starting from `fromIndex`. Mutates `prefixSums` in place.
50
+ */
51
+ function rebuildPrefixSums(heights, prefixSums, fromIndex) {
52
+ const n = heights.length;
53
+ for (let i = fromIndex; i < n; i++) {
54
+ prefixSums[i] = i === 0 ? 0 : prefixSums[i - 1] + heights[i - 1];
55
+ }
56
+ }
57
+ /**
58
+ * Validate that `index` is in `[0, count)`.
59
+ */
60
+ function assertValidIndex(index, count) {
61
+ if (index < 0 || index >= count) {
62
+ throw new RangeError(`Block index ${index} out of range [0, ${count})`);
63
+ }
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // Factory
67
+ // ---------------------------------------------------------------------------
68
+ /**
69
+ * Create a spatial index for viewport virtualization.
70
+ *
71
+ * Builds a prefix-sum array of estimated block heights in O(n). Subsequent
72
+ * `blockTop()` calls are O(1) and `computeVisibleRange()` calls are O(log n).
73
+ *
74
+ * As blocks are rendered and measured, call {@link SpatialIndex.setBlockHeight}
75
+ * or {@link SpatialIndex.setBlockHeights} to replace estimates with actual
76
+ * measured values. When the document structure changes (blocks added, removed,
77
+ * or reordered), call {@link SpatialIndex.rebuild}.
78
+ *
79
+ * @param doc - The RTIF document to index
80
+ * @param config - Optional configuration for height estimates
81
+ * @returns A new {@link SpatialIndex} instance
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * import { createSpatialIndex } from '@rtif-sdk/web';
86
+ *
87
+ * const spatial = createSpatialIndex(doc);
88
+ * console.log(spatial.totalHeight()); // e.g. 2400
89
+ * console.log(spatial.blockTop(5)); // e.g. 120
90
+ *
91
+ * const { start, end } = spatial.computeVisibleRange(100, 600, 2);
92
+ * for (let i = start; i < end; i++) {
93
+ * renderBlock(doc.blocks[i]);
94
+ * }
95
+ *
96
+ * // After measuring a block's actual height:
97
+ * spatial.setBlockHeight(5, 36);
98
+ * ```
99
+ */
100
+ export function createSpatialIndex(doc, config) {
101
+ const fallbackHeight = config?.estimatedBlockHeight ?? 24;
102
+ const mergedHeights = {
103
+ ...DEFAULT_BLOCK_TYPE_HEIGHTS,
104
+ ...config?.blockTypeHeights,
105
+ };
106
+ // Mutable arrays — rebuilt on structural changes, updated on height changes
107
+ let heights = [];
108
+ let prefixSums = [];
109
+ let count = 0;
110
+ /**
111
+ * Build the arrays from a document, optionally preserving measured heights.
112
+ */
113
+ function buildFromDoc(d, preserveHeights) {
114
+ const n = d.blocks.length;
115
+ heights = new Array(n);
116
+ prefixSums = new Array(n);
117
+ count = n;
118
+ for (let i = 0; i < n; i++) {
119
+ const block = d.blocks[i];
120
+ const preserved = preserveHeights?.get(block.id);
121
+ heights[i] =
122
+ preserved !== undefined
123
+ ? preserved
124
+ : estimateHeight(block.type, mergedHeights, fallbackHeight);
125
+ }
126
+ rebuildPrefixSums(heights, prefixSums, 0);
127
+ }
128
+ // Initial build
129
+ buildFromDoc(doc);
130
+ const index = {
131
+ totalHeight() {
132
+ if (count === 0)
133
+ return 0;
134
+ return prefixSums[count - 1] + heights[count - 1];
135
+ },
136
+ blockCount() {
137
+ return count;
138
+ },
139
+ blockHeight(blockIndex) {
140
+ assertValidIndex(blockIndex, count);
141
+ return heights[blockIndex];
142
+ },
143
+ blockTop(blockIndex) {
144
+ assertValidIndex(blockIndex, count);
145
+ return prefixSums[blockIndex];
146
+ },
147
+ computeVisibleRange(scrollTop, viewportHeight, buffer) {
148
+ if (count === 0) {
149
+ return { start: 0, end: 0 };
150
+ }
151
+ // Clamp scrollTop to valid range
152
+ const total = index.totalHeight();
153
+ const clampedScrollTop = Math.max(0, Math.min(scrollTop, total));
154
+ const clampedViewportHeight = Math.max(0, viewportHeight);
155
+ const clampedBuffer = Math.max(0, Math.floor(buffer));
156
+ // Binary search for first block whose bottom edge > clampedScrollTop.
157
+ // A block's bottom edge = prefixSums[i] + heights[i].
158
+ // We want the smallest i such that prefixSums[i] + heights[i] > clampedScrollTop.
159
+ let lo = 0;
160
+ let hi = count - 1;
161
+ while (lo < hi) {
162
+ const mid = (lo + hi) >>> 1;
163
+ const bottomEdge = prefixSums[mid] + heights[mid];
164
+ if (bottomEdge <= clampedScrollTop) {
165
+ lo = mid + 1;
166
+ }
167
+ else {
168
+ hi = mid;
169
+ }
170
+ }
171
+ const firstVisible = lo;
172
+ // Linear scan forward to find last block within viewport.
173
+ // A block is visible if its top edge < clampedScrollTop + clampedViewportHeight.
174
+ const viewportBottom = clampedScrollTop + clampedViewportHeight;
175
+ let lastVisible = firstVisible;
176
+ for (let i = firstVisible; i < count; i++) {
177
+ if (prefixSums[i] >= viewportBottom) {
178
+ break;
179
+ }
180
+ lastVisible = i;
181
+ }
182
+ // Apply buffer, clamped to valid range
183
+ const start = Math.max(0, firstVisible - clampedBuffer);
184
+ const end = Math.min(count, lastVisible + 1 + clampedBuffer);
185
+ return { start, end };
186
+ },
187
+ setBlockHeight(blockIndex, height) {
188
+ assertValidIndex(blockIndex, count);
189
+ heights[blockIndex] = height;
190
+ rebuildPrefixSums(heights, prefixSums, blockIndex);
191
+ },
192
+ setBlockHeights(updates) {
193
+ if (updates.length === 0)
194
+ return;
195
+ let minIndex = count;
196
+ for (const { index: idx, height } of updates) {
197
+ assertValidIndex(idx, count);
198
+ heights[idx] = height;
199
+ if (idx < minIndex) {
200
+ minIndex = idx;
201
+ }
202
+ }
203
+ rebuildPrefixSums(heights, prefixSums, minIndex);
204
+ },
205
+ rebuild(d, preserveHeights) {
206
+ buildFromDoc(d, preserveHeights);
207
+ },
208
+ };
209
+ return index;
210
+ }
211
+ //# sourceMappingURL=spatial-index.js.map