@svgrid/enterprise 3.1.3 → 3.1.5
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/LICENSE +22 -17
- package/README.md +7 -7
- package/dist/advanced-filter-enable.js +2 -2
- package/dist/alerts.js +2 -2
- package/dist/board.js +2 -2
- package/dist/cdn/svgrid-enterprise.svelte-external.js +13969 -13515
- package/dist/designer/assets/GridMenus-CvcASlKv.js +8 -0
- package/dist/designer/assets/SvListBox-BlmmzYcU.js +110 -0
- package/dist/designer/assets/{index-CScGnzuX.js → index-B3WBezq_.js} +432 -370
- package/dist/designer/assets/index-KmSEY7Lb.css +1 -0
- package/dist/designer/assets/src-D4PRZJYA.js +58 -0
- package/dist/designer/assets/{validate-YxSrBF1H.js → validate-B71dE1Cs.js} +1 -1
- package/dist/designer/index.html +4 -4
- package/dist/first-party.d.ts +2 -0
- package/dist/first-party.js +11 -0
- package/dist/gantt/gantt.js +2 -2
- package/dist/install.js +2 -2
- package/dist/license-core.d.ts +1 -0
- package/dist/license-core.js +25 -23
- package/dist/license-hash.d.ts +1 -0
- package/dist/license-hash.js +6 -0
- package/dist/license.js +55 -30
- package/dist/node/studio.js +531 -136
- package/dist/pivot-enable.js +2 -2
- package/dist/scheduler.js +2 -2
- package/dist/selection-bar.js +2 -2
- package/dist/server/enable.js +2 -2
- package/dist/server/server-row-model.js +199 -26
- package/dist/sha256.d.ts +1 -0
- package/dist/sha256.js +69 -0
- package/dist/studio/emit-project.js +86 -56
- package/dist/studio/emit-schema.d.ts +3 -0
- package/dist/studio/emit-schema.js +128 -29
- package/dist/studio/index.d.ts +2 -1
- package/dist/studio/index.js +2 -1
- package/dist/studio/init-flow.d.ts +3 -0
- package/dist/studio/init-flow.js +5 -2
- package/dist/studio/project.d.ts +10 -1
- package/dist/studio/project.js +28 -15
- package/dist/studio/samples/restaurant.js +1 -1
- package/dist/studio/sveltekit3.d.ts +38 -0
- package/dist/studio/sveltekit3.js +194 -0
- package/dist/studio/ui-components.generated.js +15 -4
- package/dist/upgrade-prompt.js +3 -0
- package/dist/version.d.ts +2 -2
- package/dist/version.js +2 -2
- package/dist/watermark.js +37 -4
- package/dist/wc/{GridMenus-6_fF5jIm.js → GridMenus-fWbBUiRH.js} +121 -121
- package/dist/wc/sv-sheet-element.js +11090 -10547
- package/dist/wc/{svelte-virtualizer.svelte-Du4tjrIP.js → svelte-virtualizer.svelte-Dntdh8Ms.js} +103 -56
- package/dist/wc/{validate-JAuMsk6Z.js → validate-43C03DLP.js} +1 -1
- package/package.json +3 -3
- package/dist/designer/assets/GridMenus-DGZJKFvX.js +0 -8
- package/dist/designer/assets/SvListBox-v2jm0-vf.js +0 -110
- package/dist/designer/assets/index-l21iGkpF.css +0 -1
- package/dist/designer/assets/src-DL33yzkY.js +0 -58
package/dist/pivot-enable.js
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
import { registerPivotEngine } from '@svgrid/grid';
|
|
20
|
-
import {
|
|
20
|
+
import { hasValidLicense } from './license.js';
|
|
21
21
|
import { emitUnlicensedNudge } from './watermark.js';
|
|
22
22
|
import { createPivotModel } from './pivot.js';
|
|
23
23
|
let enabled = false;
|
|
@@ -34,6 +34,6 @@ export function enablePivot() {
|
|
|
34
34
|
return;
|
|
35
35
|
enabled = true;
|
|
36
36
|
registerPivotEngine(pivotEngine);
|
|
37
|
-
if (!
|
|
37
|
+
if (!hasValidLicense())
|
|
38
38
|
emitUnlicensedNudge();
|
|
39
39
|
}
|
package/dist/scheduler.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
import { registerSchedulerView } from '@svgrid/grid';
|
|
19
|
-
import {
|
|
19
|
+
import { hasValidLicense } from './license.js';
|
|
20
20
|
import { emitUnlicensedNudge } from './watermark.js';
|
|
21
21
|
import SvGridScheduler from './SvGridScheduler.svelte';
|
|
22
22
|
let enabled = false;
|
|
@@ -30,7 +30,7 @@ export function enableSchedulerView() {
|
|
|
30
30
|
return;
|
|
31
31
|
enabled = true;
|
|
32
32
|
registerSchedulerView(SvGridScheduler);
|
|
33
|
-
if (!
|
|
33
|
+
if (!hasValidLicense())
|
|
34
34
|
emitUnlicensedNudge();
|
|
35
35
|
}
|
|
36
36
|
export { default as SvGridScheduler } from './SvGridScheduler.svelte';
|
package/dist/selection-bar.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
import { registerSelectionBarView } from '@svgrid/grid';
|
|
25
|
-
import {
|
|
25
|
+
import { hasValidLicense } from './license.js';
|
|
26
26
|
import { emitUnlicensedNudge } from './watermark.js';
|
|
27
27
|
import SvGridSelectionBar from './SvGridSelectionBar.svelte';
|
|
28
28
|
let enabled = false;
|
|
@@ -36,7 +36,7 @@ export function enableSelectionBar() {
|
|
|
36
36
|
return;
|
|
37
37
|
enabled = true;
|
|
38
38
|
registerSelectionBarView(SvGridSelectionBar);
|
|
39
|
-
if (!
|
|
39
|
+
if (!hasValidLicense())
|
|
40
40
|
emitUnlicensedNudge();
|
|
41
41
|
}
|
|
42
42
|
export { default as SvGridSelectionBar } from './SvGridSelectionBar.svelte';
|
package/dist/server/enable.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* const ctl = createServerRowModel(source, { groupBy: ['region'], onChange })
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
import {
|
|
22
|
+
import { hasValidLicense } from '../license.js';
|
|
23
23
|
import { emitUnlicensedNudge } from '../watermark.js';
|
|
24
24
|
let enabled = false;
|
|
25
25
|
/**
|
|
@@ -34,7 +34,7 @@ export function enableServerRowModel() {
|
|
|
34
34
|
if (enabled)
|
|
35
35
|
return;
|
|
36
36
|
enabled = true;
|
|
37
|
-
if (!
|
|
37
|
+
if (!hasValidLicense())
|
|
38
38
|
emitUnlicensedNudge();
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* `createServerGroupModel` (the previous model, block-append with a "Load N
|
|
22
22
|
* more" button) is still exported for anyone on it; this one supersedes it.
|
|
23
23
|
*/
|
|
24
|
-
import { createBlockCache, createRowPlaceholder, rowPlaceholderState, toServerFilterColumns,
|
|
24
|
+
import { createBlockCache, createRowPlaceholder, createWindowedData, isWindowedData, rowPlaceholderState, toServerFilterColumns,
|
|
25
25
|
// The subpath, not the root: the root re-exports SvGrid.svelte, which
|
|
26
26
|
// would land in every bundle and test that touches this model.
|
|
27
27
|
} from '@svgrid/grid/server';
|
|
@@ -412,17 +412,80 @@ export function createServerRowModel(source, options) {
|
|
|
412
412
|
leafRuns.set(store, run);
|
|
413
413
|
return run;
|
|
414
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* A level made only of data rows maps one to one: its i-th display row is
|
|
417
|
+
* its i-th child. Such a level is not walked or copied - the flatten records
|
|
418
|
+
* it as one lazy piece and `lazyLeafAt` builds a row when the grid reads it,
|
|
419
|
+
* so a 100M-row level costs the rows on screen, not 100M. Groups, tree
|
|
420
|
+
* data, pivot, load-more, detail rows and child-row paging still walk.
|
|
421
|
+
*/
|
|
422
|
+
function isLazyLeafLevel(store) {
|
|
423
|
+
return (!treeData &&
|
|
424
|
+
!pivotMode &&
|
|
425
|
+
store.level >= groupBy.length &&
|
|
426
|
+
!store.loadMore &&
|
|
427
|
+
openDetails.size === 0 &&
|
|
428
|
+
!paging?.paginateChildRows);
|
|
429
|
+
}
|
|
430
|
+
// Replaced when a write settles (see `saving`): the grid writes a cell edit
|
|
431
|
+
// into the row object it was handed, so a row the server refused would keep
|
|
432
|
+
// showing the refused value while its child, which nothing changed, still
|
|
433
|
+
// matched the memo.
|
|
434
|
+
let lazyMemo = new WeakMap();
|
|
435
|
+
const LAZY_MEMO_CAP = 20000;
|
|
436
|
+
/** Row `index` of a lazy leaf level, built once per child object it holds. */
|
|
437
|
+
function lazyLeafAt(store, index) {
|
|
438
|
+
const child = store.cache.getRow(index);
|
|
439
|
+
const ph = rowPlaceholderState(child);
|
|
440
|
+
if (ph) {
|
|
441
|
+
const d = ph === 'failed' ? FAILED_ROW : LOADING_ROW;
|
|
442
|
+
return { child, d, g: toGridRow(d) };
|
|
443
|
+
}
|
|
444
|
+
let memo = lazyMemo.get(store);
|
|
445
|
+
if (!memo) {
|
|
446
|
+
memo = new Map();
|
|
447
|
+
lazyMemo.set(store, memo);
|
|
448
|
+
}
|
|
449
|
+
const hit = memo.get(index);
|
|
450
|
+
if (hit && hit.child === child)
|
|
451
|
+
return hit;
|
|
452
|
+
const leaf = child;
|
|
453
|
+
const d = { kind: 'leaf', id: leaf.id, level: store.level, route: store.route, data: leaf.data };
|
|
454
|
+
const entry = { child, d, g: toGridRow(d, leaf.data) };
|
|
455
|
+
memo.set(index, entry);
|
|
456
|
+
if (memo.size > LAZY_MEMO_CAP) {
|
|
457
|
+
let drop = LAZY_MEMO_CAP / 4;
|
|
458
|
+
for (const key of memo.keys()) {
|
|
459
|
+
if (drop-- <= 0)
|
|
460
|
+
break;
|
|
461
|
+
memo.delete(key);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return entry;
|
|
465
|
+
}
|
|
415
466
|
function flatten() {
|
|
416
|
-
|
|
417
|
-
let
|
|
467
|
+
const pieces = [];
|
|
468
|
+
let total = 0;
|
|
469
|
+
let open = null;
|
|
418
470
|
segments = [];
|
|
419
471
|
const pushRow = (d, data) => {
|
|
420
|
-
|
|
421
|
-
|
|
472
|
+
if (!open) {
|
|
473
|
+
open = { start: total, length: 0, display: [], grid: [] };
|
|
474
|
+
pieces.push(open);
|
|
475
|
+
}
|
|
476
|
+
open.display.push(d);
|
|
477
|
+
open.grid.push(toGridRow(d, data));
|
|
478
|
+
open.length += 1;
|
|
479
|
+
total += 1;
|
|
480
|
+
};
|
|
481
|
+
const pushPiece = (piece) => {
|
|
482
|
+
open = null;
|
|
483
|
+
pieces.push(piece);
|
|
484
|
+
total += piece.length;
|
|
422
485
|
};
|
|
423
486
|
if (grandTotalRow === 'top' && grandTotal)
|
|
424
487
|
pushRow(grandTotalDisplay(grandTotal), grandTotal);
|
|
425
|
-
const bodyStart =
|
|
488
|
+
const bodyStart = total;
|
|
426
489
|
/**
|
|
427
490
|
* A `loadMore` level shows its loaded prefix and a "more" row; rows
|
|
428
491
|
* past the first placeholder are not the grid's to scroll into.
|
|
@@ -434,32 +497,34 @@ export function createServerRowModel(source, options) {
|
|
|
434
497
|
return n;
|
|
435
498
|
};
|
|
436
499
|
const walk = (store, from = 0, to = Number.POSITIVE_INFINITY) => {
|
|
500
|
+
if (isLazyLeafLevel(store)) {
|
|
501
|
+
// A pure leaf level: one lazy piece, nothing copied.
|
|
502
|
+
const end = Math.min(store.cache.windowedRows().length, to);
|
|
503
|
+
if (end > from) {
|
|
504
|
+
segments.push({ store, displayStart: total, storeStart: from, length: end - from });
|
|
505
|
+
pushPiece({ start: total, length: end - from, store, from });
|
|
506
|
+
}
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
437
509
|
const rows = store.cache.rows();
|
|
438
510
|
const run = store.loadMore ? null : leafRun(store, rows);
|
|
439
511
|
if (run) {
|
|
440
512
|
// A level of leaves maps one to one: copy the range out of the run.
|
|
441
513
|
const end = Math.min(rows.length, to);
|
|
442
514
|
if (end > from) {
|
|
443
|
-
segments.push({ store, displayStart:
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}
|
|
451
|
-
else {
|
|
452
|
-
for (let i = from; i < end; i += 1) {
|
|
453
|
-
display.push(d[i]);
|
|
454
|
-
grid.push(g[i]);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
515
|
+
segments.push({ store, displayStart: total, storeStart: from, length: end - from });
|
|
516
|
+
pushPiece({
|
|
517
|
+
start: total,
|
|
518
|
+
length: end - from,
|
|
519
|
+
display: run.display.slice(from, end),
|
|
520
|
+
grid: run.grid.slice(from, end),
|
|
521
|
+
});
|
|
457
522
|
}
|
|
458
523
|
return;
|
|
459
524
|
}
|
|
460
525
|
const end = Math.min(rows.length, to, store.loadMore ? loadedPrefix(rows) : Number.POSITIVE_INFINITY);
|
|
461
526
|
let segStart = from;
|
|
462
|
-
let dispStart =
|
|
527
|
+
let dispStart = total;
|
|
463
528
|
const flushSegment = (upTo) => {
|
|
464
529
|
if (upTo > segStart) {
|
|
465
530
|
segments.push({ store, displayStart: dispStart, storeStart: segStart, length: upTo - segStart });
|
|
@@ -523,7 +588,7 @@ export function createServerRowModel(source, options) {
|
|
|
523
588
|
}, child.data);
|
|
524
589
|
}
|
|
525
590
|
segStart = i + 1;
|
|
526
|
-
dispStart =
|
|
591
|
+
dispStart = total;
|
|
527
592
|
}
|
|
528
593
|
}
|
|
529
594
|
flushSegment(end);
|
|
@@ -548,7 +613,7 @@ export function createServerRowModel(source, options) {
|
|
|
548
613
|
// A page of top-level rows. The root rows array is already sized to
|
|
549
614
|
// the count (placeholders for what has not loaded), so the page
|
|
550
615
|
// exists before its block does.
|
|
551
|
-
const count = root.cache.rowCount() ?? root.cache.
|
|
616
|
+
const count = root.cache.rowCount() ?? root.cache.windowedRows().length;
|
|
552
617
|
pagerRowCount = count;
|
|
553
618
|
const start = Math.min(pageIndex * pageSize, Math.max(0, count - 1));
|
|
554
619
|
walk(root, start, start + pageSize);
|
|
@@ -557,7 +622,32 @@ export function createServerRowModel(source, options) {
|
|
|
557
622
|
walk(root);
|
|
558
623
|
}
|
|
559
624
|
}
|
|
625
|
+
/** Every piece as plain arrays. Lazy pieces read through `lazyLeafAt`. */
|
|
626
|
+
const materialize = () => {
|
|
627
|
+
if (pieces.length === 1 && pieces[0].display)
|
|
628
|
+
return { display: pieces[0].display, grid: pieces[0].grid };
|
|
629
|
+
const display = [];
|
|
630
|
+
const grid = [];
|
|
631
|
+
for (const p of pieces) {
|
|
632
|
+
if (p.display) {
|
|
633
|
+
for (let i = 0; i < p.length; i += 1) {
|
|
634
|
+
display.push(p.display[i]);
|
|
635
|
+
grid.push(p.grid[i]);
|
|
636
|
+
}
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
for (let i = 0; i < p.length; i += 1) {
|
|
640
|
+
const e = lazyLeafAt(p.store, p.from + i);
|
|
641
|
+
display.push(e.d);
|
|
642
|
+
grid.push(e.g);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
return { display, grid };
|
|
646
|
+
};
|
|
560
647
|
if (paging?.paginateChildRows) {
|
|
648
|
+
// Child-row paging cuts the flattened body, so it works on plain
|
|
649
|
+
// arrays; no level is lazy in this mode (see isLazyLeafLevel).
|
|
650
|
+
const { display, grid } = materialize();
|
|
561
651
|
// A page of the flattened tree. Cut the body and re-base the segments
|
|
562
652
|
// that cross into the page; the grand total stays on every page.
|
|
563
653
|
const bodyLength = display.length - bodyStart;
|
|
@@ -582,10 +672,47 @@ export function createServerRowModel(source, options) {
|
|
|
582
672
|
});
|
|
583
673
|
}
|
|
584
674
|
segments = cut;
|
|
675
|
+
if (grandTotalRow === 'bottom' && grandTotal) {
|
|
676
|
+
const d = grandTotalDisplay(grandTotal);
|
|
677
|
+
display.push(d);
|
|
678
|
+
grid.push(toGridRow(d, grandTotal));
|
|
679
|
+
}
|
|
680
|
+
return { display, grid };
|
|
585
681
|
}
|
|
586
682
|
if (grandTotalRow === 'bottom' && grandTotal)
|
|
587
683
|
pushRow(grandTotalDisplay(grandTotal), grandTotal);
|
|
588
|
-
|
|
684
|
+
if (!pieces.some((p) => p.store))
|
|
685
|
+
return materialize();
|
|
686
|
+
// At least one lazy piece: hand out windowed arrays that find the piece
|
|
687
|
+
// holding an index by binary search on the piece starts.
|
|
688
|
+
const pieceAt = (index) => {
|
|
689
|
+
let lo = 0;
|
|
690
|
+
let hi = pieces.length - 1;
|
|
691
|
+
while (lo <= hi) {
|
|
692
|
+
const mid = (lo + hi) >> 1;
|
|
693
|
+
const p = pieces[mid];
|
|
694
|
+
if (index < p.start)
|
|
695
|
+
hi = mid - 1;
|
|
696
|
+
else if (index >= p.start + p.length)
|
|
697
|
+
lo = mid + 1;
|
|
698
|
+
else
|
|
699
|
+
return p;
|
|
700
|
+
}
|
|
701
|
+
return undefined;
|
|
702
|
+
};
|
|
703
|
+
const entryAt = (index) => {
|
|
704
|
+
const p = pieceAt(index);
|
|
705
|
+
if (!p)
|
|
706
|
+
return undefined;
|
|
707
|
+
const offset = index - p.start;
|
|
708
|
+
if (p.display)
|
|
709
|
+
return { d: p.display[offset], g: p.grid[offset] };
|
|
710
|
+
return lazyLeafAt(p.store, p.from + offset);
|
|
711
|
+
};
|
|
712
|
+
return {
|
|
713
|
+
display: createWindowedData(total, (i) => entryAt(i)?.d),
|
|
714
|
+
grid: createWindowedData(total, (i) => entryAt(i)?.g),
|
|
715
|
+
};
|
|
589
716
|
}
|
|
590
717
|
function pagination() {
|
|
591
718
|
if (!paging)
|
|
@@ -679,8 +806,38 @@ export function createServerRowModel(source, options) {
|
|
|
679
806
|
let held = false;
|
|
680
807
|
function holdRows() {
|
|
681
808
|
const ms = options.keepRowsWhileLoading ?? 0;
|
|
682
|
-
if (ms > 0 && current.displayRows.length > 0)
|
|
809
|
+
if (ms > 0 && current.displayRows.length > 0) {
|
|
683
810
|
holdUntil = Date.now() + ms;
|
|
811
|
+
freezeCurrent();
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Held rows must not change under the user, but a lazy list reads the live
|
|
816
|
+
* caches, which the sort or filter that started the hold is about to purge.
|
|
817
|
+
* Copy the rows around the last viewport into a snapshot and serve the held
|
|
818
|
+
* lists from it. Only the grid's subscription is told (so it re-reads);
|
|
819
|
+
* `onChange` still fires once, when the hold ends.
|
|
820
|
+
*/
|
|
821
|
+
function freezeCurrent() {
|
|
822
|
+
if (!isWindowedData(current.gridRows))
|
|
823
|
+
return; // plain arrays are a snapshot already
|
|
824
|
+
const n = current.gridRows.length;
|
|
825
|
+
const MARGIN = 200;
|
|
826
|
+
const from = Math.max(0, lastViewport[0] - MARGIN);
|
|
827
|
+
const to = Math.min(n - 1, lastViewport[1] + MARGIN);
|
|
828
|
+
const display = new Map();
|
|
829
|
+
const grid = new Map();
|
|
830
|
+
for (let i = from; i <= to; i += 1) {
|
|
831
|
+
display.set(i, current.displayRows[i]);
|
|
832
|
+
grid.set(i, current.gridRows[i]);
|
|
833
|
+
}
|
|
834
|
+
current = {
|
|
835
|
+
...current,
|
|
836
|
+
displayRows: createWindowedData(n, (i) => display.get(i) ?? LOADING_ROW),
|
|
837
|
+
gridRows: createWindowedData(n, (i) => grid.get(i) ?? toGridRow(LOADING_ROW)),
|
|
838
|
+
};
|
|
839
|
+
for (const notify of subscribers)
|
|
840
|
+
notify();
|
|
684
841
|
}
|
|
685
842
|
/** Whether the rows on screen should stay a little longer. */
|
|
686
843
|
function holding() {
|
|
@@ -1012,7 +1169,7 @@ export function createServerRowModel(source, options) {
|
|
|
1012
1169
|
}
|
|
1013
1170
|
if (tx.add && tx.add.length) {
|
|
1014
1171
|
const total = store.cache.rowCount();
|
|
1015
|
-
const at = tx.addIndex ?? (total ?? store.cache.
|
|
1172
|
+
const at = tx.addIndex ?? (total ?? store.cache.windowedRows().length);
|
|
1016
1173
|
const children = toChildren(route, at, tx.add);
|
|
1017
1174
|
const placed = store.cache.insert(at, children);
|
|
1018
1175
|
if (placed)
|
|
@@ -1090,6 +1247,9 @@ export function createServerRowModel(source, options) {
|
|
|
1090
1247
|
}
|
|
1091
1248
|
finally {
|
|
1092
1249
|
writesInFlight -= 1;
|
|
1250
|
+
// Rows are rebuilt from the cache on the next read, so an edit the
|
|
1251
|
+
// server refused (and the model never applied) is gone from the grid.
|
|
1252
|
+
lazyMemo = new WeakMap();
|
|
1093
1253
|
scheduleEmit();
|
|
1094
1254
|
}
|
|
1095
1255
|
}
|
|
@@ -1358,6 +1518,10 @@ export function createServerRowModel(source, options) {
|
|
|
1358
1518
|
expandAll(opts) {
|
|
1359
1519
|
autoExpand = !!opts?.includeUnloaded;
|
|
1360
1520
|
for (const store of [...stores.values()]) {
|
|
1521
|
+
// A pure leaf level holds no groups to open; reading it would walk
|
|
1522
|
+
// every row it has.
|
|
1523
|
+
if (isLazyLeafLevel(store))
|
|
1524
|
+
continue;
|
|
1361
1525
|
for (const child of store.cache.rows()) {
|
|
1362
1526
|
if (rowPlaceholderState(child) || child.kind !== 'group')
|
|
1363
1527
|
continue;
|
|
@@ -1478,6 +1642,15 @@ export function createServerRowModel(source, options) {
|
|
|
1478
1642
|
},
|
|
1479
1643
|
setViewport(startIndex, endIndex) {
|
|
1480
1644
|
lastViewport = [Math.max(0, startIndex), Math.max(startIndex, endIndex)];
|
|
1645
|
+
// The first viewport starts the model. Its first load used to come from
|
|
1646
|
+
// the grid reporting its starting sort on mount (setSort -> rebuild);
|
|
1647
|
+
// the grid no longer reports a mount as a sort change, and a model that
|
|
1648
|
+
// nothing else touched (no sort, no filter, a layout equal to the one
|
|
1649
|
+
// it was built with) then never asked for a single block.
|
|
1650
|
+
if (!disposed && !stores.has(routeKey([]))) {
|
|
1651
|
+
rebuild();
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1481
1654
|
applyViewport();
|
|
1482
1655
|
},
|
|
1483
1656
|
setPage(next) {
|
package/dist/sha256.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sha256Hex(input: string): string;
|
package/dist/sha256.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Synchronous SHA-256 for the license check. WebCrypto's digest() is async,
|
|
2
|
+
// and setLicenseKey / checkLicenseKey are synchronous on purpose (they run at
|
|
3
|
+
// module start-up and in the Node / MCP generator), so the key is hashed here.
|
|
4
|
+
// FIPS 180-4, over the UTF-8 bytes of the input; returns lowercase hex.
|
|
5
|
+
const K = new Uint32Array([
|
|
6
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
7
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
8
|
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
9
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
10
|
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
11
|
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
12
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
13
|
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
14
|
+
]);
|
|
15
|
+
const rotr = (x, n) => (x >>> n) | (x << (32 - n));
|
|
16
|
+
export function sha256Hex(input) {
|
|
17
|
+
const data = new TextEncoder().encode(input);
|
|
18
|
+
const bitLen = data.length * 8;
|
|
19
|
+
// Message + 0x80 + zero padding + 64-bit length, to a multiple of 64 bytes.
|
|
20
|
+
const total = Math.ceil((data.length + 9) / 64) * 64;
|
|
21
|
+
const buf = new Uint8Array(total);
|
|
22
|
+
buf.set(data);
|
|
23
|
+
buf[data.length] = 0x80;
|
|
24
|
+
const view = new DataView(buf.buffer);
|
|
25
|
+
view.setUint32(total - 8, Math.floor(bitLen / 0x100000000));
|
|
26
|
+
view.setUint32(total - 4, bitLen >>> 0);
|
|
27
|
+
const h = new Uint32Array([
|
|
28
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
|
29
|
+
]);
|
|
30
|
+
const w = new Uint32Array(64);
|
|
31
|
+
for (let off = 0; off < total; off += 64) {
|
|
32
|
+
for (let i = 0; i < 16; i++)
|
|
33
|
+
w[i] = view.getUint32(off + i * 4);
|
|
34
|
+
for (let i = 16; i < 64; i++) {
|
|
35
|
+
const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ (w[i - 15] >>> 3);
|
|
36
|
+
const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ (w[i - 2] >>> 10);
|
|
37
|
+
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;
|
|
38
|
+
}
|
|
39
|
+
let a = h[0], b = h[1], c = h[2], d = h[3], e = h[4], f = h[5], g = h[6], hh = h[7];
|
|
40
|
+
for (let i = 0; i < 64; i++) {
|
|
41
|
+
const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
42
|
+
const ch = (e & f) ^ (~e & g);
|
|
43
|
+
const t1 = (hh + S1 + ch + K[i] + w[i]) >>> 0;
|
|
44
|
+
const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
45
|
+
const maj = (a & b) ^ (a & c) ^ (b & c);
|
|
46
|
+
const t2 = (S0 + maj) >>> 0;
|
|
47
|
+
hh = g;
|
|
48
|
+
g = f;
|
|
49
|
+
f = e;
|
|
50
|
+
e = (d + t1) >>> 0;
|
|
51
|
+
d = c;
|
|
52
|
+
c = b;
|
|
53
|
+
b = a;
|
|
54
|
+
a = (t1 + t2) >>> 0;
|
|
55
|
+
}
|
|
56
|
+
h[0] = (h[0] + a) >>> 0;
|
|
57
|
+
h[1] = (h[1] + b) >>> 0;
|
|
58
|
+
h[2] = (h[2] + c) >>> 0;
|
|
59
|
+
h[3] = (h[3] + d) >>> 0;
|
|
60
|
+
h[4] = (h[4] + e) >>> 0;
|
|
61
|
+
h[5] = (h[5] + f) >>> 0;
|
|
62
|
+
h[6] = (h[6] + g) >>> 0;
|
|
63
|
+
h[7] = (h[7] + hh) >>> 0;
|
|
64
|
+
}
|
|
65
|
+
let out = '';
|
|
66
|
+
for (const word of h)
|
|
67
|
+
out += word.toString(16).padStart(8, '0');
|
|
68
|
+
return out;
|
|
69
|
+
}
|