@rowsncolumns/y-spreadsheet 15.0.2 → 15.0.3
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/cjs/use-yspreadsheet-v2.d.ts +13 -1
- package/dist/cjs/use-yspreadsheet-v2.d.ts.map +1 -1
- package/dist/cjs/use-yspreadsheet-v2.js +115 -54
- package/dist/esm/use-yspreadsheet-v2.d.ts +13 -1
- package/dist/esm/use-yspreadsheet-v2.d.ts.map +1 -1
- package/dist/esm/use-yspreadsheet-v2.js +74 -29
- package/package.json +1 -1
|
@@ -23,6 +23,18 @@ export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extend
|
|
|
23
23
|
* convention to remain wire-compatible.
|
|
24
24
|
*/
|
|
25
25
|
awarenessScopeId?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether this client may persist to the shared document (the host's
|
|
28
|
+
* edit permission; `false` for view-only sessions). Published on awareness
|
|
29
|
+
* as `canWrite` and consulted by the leader election: the leader is the
|
|
30
|
+
* peer that evaluates backend/agent recalc backlogs and writes the computed
|
|
31
|
+
* values back, so a client whose writes the server refuses must never win —
|
|
32
|
+
* every value it computed would be dropped. Peers whose awareness state has
|
|
33
|
+
* no `canWrite` field (older clients, REST writers) count as writers. When
|
|
34
|
+
* no writer is present there is no leader: nothing could persist the values
|
|
35
|
+
* anyway. Default: `true`.
|
|
36
|
+
*/
|
|
37
|
+
canWrite?: boolean;
|
|
26
38
|
userId: string | number;
|
|
27
39
|
title: string;
|
|
28
40
|
sheetId: number;
|
|
@@ -142,7 +154,7 @@ export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extend
|
|
|
142
154
|
};
|
|
143
155
|
export type YRowData = Y.Map<Y.Array<CellData | null>>;
|
|
144
156
|
export type YSheetData = Y.Array<YRowData | null>;
|
|
145
|
-
export declare const useYSpreadsheetV2: <T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject>({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeCitations, onAfterBroadcastPatch, recalcCellsMaxEntries, onChangeNamedRanges, onChangeProtectedRanges, onChangePivotTables, enqueueCalculation, enqueueGraphOperation, reevaluateDerivationsForCells, onChangeCellXfs, onChangeSharedStrings, calculateNow, onChangeActiveSheet, clientOnlyFunctionPattern, initialSheets, awarenessScopeId, userId, title, sheetId, activeCell, kind, agentInitiator, selections, doc, provider, useV3, sheetDataVersion, onMigrationComplete, deleteV2AfterMigration, skipInitialSync, supportLegacySharedStringsArray, }: UseYSpreadsheetPropsV2<T, S, C, O>) => {
|
|
157
|
+
export declare const useYSpreadsheetV2: <T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject>({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeCitations, onAfterBroadcastPatch, recalcCellsMaxEntries, onChangeNamedRanges, onChangeProtectedRanges, onChangePivotTables, enqueueCalculation, enqueueGraphOperation, reevaluateDerivationsForCells, onChangeCellXfs, onChangeSharedStrings, calculateNow, onChangeActiveSheet, clientOnlyFunctionPattern, initialSheets, awarenessScopeId, canWrite, userId, title, sheetId, activeCell, kind, agentInitiator, selections, doc, provider, useV3, sheetDataVersion, onMigrationComplete, deleteV2AfterMigration, skipInitialSync, supportLegacySharedStringsArray, }: UseYSpreadsheetPropsV2<T, S, C, O>) => {
|
|
146
158
|
synced: boolean;
|
|
147
159
|
users: Collaborator[];
|
|
148
160
|
onBroadcastPatch: (patches: [patch: SpreadsheetPatch<Patch>, type?: HistoryType | undefined | null][]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-yspreadsheet-v2.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet-v2.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-yspreadsheet-v2.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,10 +57,10 @@ var observables_1 = require("./observables");
|
|
|
57
57
|
// Add a single null entry to the YSheetData
|
|
58
58
|
var origin = "local";
|
|
59
59
|
var useYSpreadsheetV2 = function (_a) {
|
|
60
|
-
var onChangeSheetData = _a.onChangeSheetData, onChangeSheets = _a.onChangeSheets, onChangeTables = _a.onChangeTables, onChangeCharts = _a.onChangeCharts, onChangeEmbeds = _a.onChangeEmbeds, onChangeConditionalFormats = _a.onChangeConditionalFormats, onChangeDataValidations = _a.onChangeDataValidations, onChangeCitations = _a.onChangeCitations, onAfterBroadcastPatch = _a.onAfterBroadcastPatch, recalcCellsMaxEntries = _a.recalcCellsMaxEntries, onChangeNamedRanges = _a.onChangeNamedRanges, onChangeProtectedRanges = _a.onChangeProtectedRanges, onChangePivotTables = _a.onChangePivotTables, enqueueCalculation = _a.enqueueCalculation, enqueueGraphOperation = _a.enqueueGraphOperation, reevaluateDerivationsForCells = _a.reevaluateDerivationsForCells, onChangeCellXfs = _a.onChangeCellXfs, onChangeSharedStrings = _a.onChangeSharedStrings, calculateNow = _a.calculateNow, onChangeActiveSheet = _a.onChangeActiveSheet, clientOnlyFunctionPattern = _a.clientOnlyFunctionPattern, initialSheets = _a.initialSheets, awarenessScopeId = _a.awarenessScopeId, userId = _a.userId, title = _a.title, sheetId = _a.sheetId, activeCell = _a.activeCell, kind = _a.kind, agentInitiator = _a.agentInitiator, selections = _a.selections, doc = _a.doc, provider = _a.provider,
|
|
61
|
-
var
|
|
62
|
-
var
|
|
63
|
-
var
|
|
60
|
+
var onChangeSheetData = _a.onChangeSheetData, onChangeSheets = _a.onChangeSheets, onChangeTables = _a.onChangeTables, onChangeCharts = _a.onChangeCharts, onChangeEmbeds = _a.onChangeEmbeds, onChangeConditionalFormats = _a.onChangeConditionalFormats, onChangeDataValidations = _a.onChangeDataValidations, onChangeCitations = _a.onChangeCitations, onAfterBroadcastPatch = _a.onAfterBroadcastPatch, recalcCellsMaxEntries = _a.recalcCellsMaxEntries, onChangeNamedRanges = _a.onChangeNamedRanges, onChangeProtectedRanges = _a.onChangeProtectedRanges, onChangePivotTables = _a.onChangePivotTables, enqueueCalculation = _a.enqueueCalculation, enqueueGraphOperation = _a.enqueueGraphOperation, reevaluateDerivationsForCells = _a.reevaluateDerivationsForCells, onChangeCellXfs = _a.onChangeCellXfs, onChangeSharedStrings = _a.onChangeSharedStrings, calculateNow = _a.calculateNow, onChangeActiveSheet = _a.onChangeActiveSheet, clientOnlyFunctionPattern = _a.clientOnlyFunctionPattern, initialSheets = _a.initialSheets, awarenessScopeId = _a.awarenessScopeId, _b = _a.canWrite, canWrite = _b === void 0 ? true : _b, userId = _a.userId, title = _a.title, sheetId = _a.sheetId, activeCell = _a.activeCell, kind = _a.kind, agentInitiator = _a.agentInitiator, selections = _a.selections, doc = _a.doc, provider = _a.provider, _c = _a.useV3, useV3 = _c === void 0 ? false : _c, _d = _a.sheetDataVersion, sheetDataVersion = _d === void 0 ? "v2" : _d, onMigrationComplete = _a.onMigrationComplete, _e = _a.deleteV2AfterMigration, deleteV2AfterMigration = _e === void 0 ? false : _e, _f = _a.skipInitialSync, skipInitialSync = _f === void 0 ? false : _f, _g = _a.supportLegacySharedStringsArray, supportLegacySharedStringsArray = _g === void 0 ? false : _g;
|
|
61
|
+
var _h = tslib_1.__read((0, react_1.useState)(false), 2), synced = _h[0], setSynced = _h[1];
|
|
62
|
+
var _j = tslib_1.__read((0, react_1.useState)([]), 2), users = _j[0], setUsers = _j[1];
|
|
63
|
+
var _k = tslib_1.__read((0, react_1.useState)(false), 2), isLeader = _k[0], setIsLeader = _k[1];
|
|
64
64
|
var isLeaderRef = (0, react_1.useRef)(false);
|
|
65
65
|
var resolvedAwarenessScopeId = awarenessScopeId;
|
|
66
66
|
// Listen to awareness
|
|
@@ -76,22 +76,30 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
76
76
|
return (state === null || state === void 0 ? void 0 : state.docGuid) === resolvedAwarenessScopeId;
|
|
77
77
|
})
|
|
78
78
|
: entries;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
// Only peers that can persist may lead (see `canWrite`). A view-only
|
|
80
|
+
// client's recalc write-backs are refused by the server, so electing it
|
|
81
|
+
// silently drops every computed value. A missing field is a writer.
|
|
82
|
+
var writers = docStates
|
|
83
|
+
.filter(function (_a) {
|
|
84
|
+
var _b = tslib_1.__read(_a, 2), _ = _b[0], state = _b[1];
|
|
85
|
+
return (state === null || state === void 0 ? void 0 : state.canWrite) !== false;
|
|
86
|
+
})
|
|
87
|
+
.map(function (_a) {
|
|
84
88
|
var _b = tslib_1.__read(_a, 1), clientId = _b[0];
|
|
85
89
|
return clientId;
|
|
86
90
|
});
|
|
87
|
-
|
|
91
|
+
if (!canWrite || !writers.length) {
|
|
92
|
+
setIsLeader(false);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
var minId = Math.min.apply(Math, tslib_1.__spreadArray([], tslib_1.__read(writers), false));
|
|
88
96
|
// Always include self in the elec
|
|
89
97
|
setIsLeader(doc.clientID === minId);
|
|
90
98
|
};
|
|
91
99
|
awareness.on("change", updateLeader);
|
|
92
100
|
updateLeader(); // Initial check
|
|
93
101
|
return function () { return awareness.off("change", updateLeader); };
|
|
94
|
-
}, [awareness, doc, resolvedAwarenessScopeId]);
|
|
102
|
+
}, [awareness, doc, resolvedAwarenessScopeId, canWrite]);
|
|
95
103
|
(0, ui_1.useIsomorphicLayoutEffect)(function () {
|
|
96
104
|
isLeaderRef.current = isLeader;
|
|
97
105
|
}, [isLeader]);
|
|
@@ -243,6 +251,12 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
243
251
|
return source === "backend" || source === "agent";
|
|
244
252
|
});
|
|
245
253
|
}, [yRecalcCells]);
|
|
254
|
+
/**
|
|
255
|
+
* Set once the initial sync has built the dependency graph and replayed the
|
|
256
|
+
* backlog, so a later leadership hand-over can replay it again.
|
|
257
|
+
*/
|
|
258
|
+
var graphReadyRef = (0, react_1.useRef)(false);
|
|
259
|
+
var initialSyncTimerRef = (0, react_1.useRef)(null);
|
|
246
260
|
// Trigger cell recalcs
|
|
247
261
|
var syncRecalcCells = (0, react_1.useCallback)(function (recalcCells, origin) {
|
|
248
262
|
var e_2, _a;
|
|
@@ -460,6 +474,24 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
460
474
|
onMigrationComplete,
|
|
461
475
|
deleteV2AfterMigration,
|
|
462
476
|
]);
|
|
477
|
+
/**
|
|
478
|
+
* Replay the backend/agent recalc backlog into the local graph — and, on
|
|
479
|
+
* the leader, evaluate it. Only the leader clears the entries, and only once
|
|
480
|
+
* they sit in its calculation queue: a non-leader merely graph-enqueues
|
|
481
|
+
* (no evaluation), so if it deleted them the leader would never recompute
|
|
482
|
+
* the backlog at all.
|
|
483
|
+
*/
|
|
484
|
+
var drainBacklog = (0, react_1.useCallback)(function () {
|
|
485
|
+
var backlog = getBacklog();
|
|
486
|
+
if (!backlog.length)
|
|
487
|
+
return;
|
|
488
|
+
syncRecalcCells(backlog, "backend");
|
|
489
|
+
if (isLeaderRef.current) {
|
|
490
|
+
doc.transact(function () {
|
|
491
|
+
yRecalcCells.delete(0, yRecalcCells.length);
|
|
492
|
+
}, origin);
|
|
493
|
+
}
|
|
494
|
+
}, [getBacklog, syncRecalcCells, doc, yRecalcCells]);
|
|
463
495
|
// Synced
|
|
464
496
|
var onSynced = (0, react_1.useCallback)(function () {
|
|
465
497
|
if (!synced) {
|
|
@@ -469,42 +501,48 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
469
501
|
(0, react_dom_1.flushSync)(function () {
|
|
470
502
|
setupInitialSync();
|
|
471
503
|
});
|
|
472
|
-
// Build dependency graph, then sync backlog cells
|
|
473
|
-
|
|
474
|
-
|
|
504
|
+
// Build dependency graph, then sync backlog cells. Deferred through a
|
|
505
|
+
// timer, not `requestAnimationFrame`: rAF is paused in background tabs,
|
|
506
|
+
// which left a backgrounded leader's backlog unevaluated indefinitely.
|
|
507
|
+
initialSyncTimerRef.current = setTimeout(function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
475
508
|
return tslib_1.__generator(this, function (_a) {
|
|
476
509
|
switch (_a.label) {
|
|
477
|
-
case 0:
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
510
|
+
case 0:
|
|
511
|
+
initialSyncTimerRef.current = null;
|
|
512
|
+
return [4 /*yield*/, calculateNow({
|
|
513
|
+
disableEvaluation: true,
|
|
514
|
+
shouldResetCellDependencyGraph: true,
|
|
515
|
+
})];
|
|
481
516
|
case 1:
|
|
482
517
|
_a.sent();
|
|
483
|
-
backlog
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
// Clear processed backlog entries from yRecalcCells
|
|
487
|
-
doc.transact(function () {
|
|
488
|
-
yRecalcCells.delete(0, yRecalcCells.length);
|
|
489
|
-
}, origin);
|
|
490
|
-
}
|
|
518
|
+
// Sync backlog after graph is initialized
|
|
519
|
+
drainBacklog();
|
|
520
|
+
graphReadyRef.current = true;
|
|
491
521
|
return [2 /*return*/];
|
|
492
522
|
}
|
|
493
523
|
});
|
|
494
|
-
}); });
|
|
524
|
+
}); }, 0);
|
|
495
525
|
}
|
|
496
526
|
setSynced(true);
|
|
497
527
|
}
|
|
498
|
-
}, [
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
]);
|
|
528
|
+
}, [calculateNow, setupInitialSync, synced, drainBacklog, skipInitialSync]);
|
|
529
|
+
// A client that becomes leader after its initial sync (the previous leader
|
|
530
|
+
// left, or the election settled late) takes over whatever backlog is still
|
|
531
|
+
// in the document: as a non-leader it only mirrored those cells into its
|
|
532
|
+
// graph, so it evaluates them now — and only now clears them.
|
|
533
|
+
(0, ui_1.useIsomorphicLayoutEffect)(function () {
|
|
534
|
+
if (!isLeader || !synced || !graphReadyRef.current)
|
|
535
|
+
return;
|
|
536
|
+
drainBacklog();
|
|
537
|
+
}, [isLeader, synced, drainBacklog]);
|
|
538
|
+
(0, ui_1.useIsomorphicLayoutEffect)(function () {
|
|
539
|
+
return function () {
|
|
540
|
+
if (initialSyncTimerRef.current !== null) {
|
|
541
|
+
clearTimeout(initialSyncTimerRef.current);
|
|
542
|
+
initialSyncTimerRef.current = null;
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
}, []);
|
|
508
546
|
// Sync state
|
|
509
547
|
if ((provider === null || provider === void 0 ? void 0 : provider.synced) && !synced) {
|
|
510
548
|
onSynced();
|
|
@@ -663,24 +701,45 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
663
701
|
if (!synced) {
|
|
664
702
|
return;
|
|
665
703
|
}
|
|
704
|
+
var pending = new Set();
|
|
666
705
|
// Sync all cells that are updated in the backend
|
|
667
706
|
// // Observe recalc cells separat
|
|
668
707
|
var onRecalcCellsChange = function (event) {
|
|
669
708
|
var patches = (0, observables_1.getPatchDeltasFromEvent)(event);
|
|
670
709
|
var origin = event.transaction.origin;
|
|
671
710
|
if (origin !== "local") {
|
|
672
|
-
requestAnimationFrame
|
|
711
|
+
// A timer, not `requestAnimationFrame`: rAF is paused in background
|
|
712
|
+
// tabs, so a backgrounded leader would stop evaluating remote patches.
|
|
713
|
+
var timer_1 = setTimeout(function () {
|
|
714
|
+
pending.delete(timer_1);
|
|
673
715
|
syncRecalcCells(patches, origin);
|
|
674
|
-
});
|
|
716
|
+
}, 0);
|
|
717
|
+
pending.add(timer_1);
|
|
675
718
|
}
|
|
676
719
|
};
|
|
677
720
|
// Skip the first recalc cells change
|
|
678
721
|
var sub = (0, observables_1.createObservable)(yRecalcCells).subscribe(onRecalcCellsChange);
|
|
679
|
-
return function () {
|
|
722
|
+
return function () {
|
|
723
|
+
var e_8, _a;
|
|
724
|
+
sub.unsubscribe();
|
|
725
|
+
try {
|
|
726
|
+
for (var pending_1 = tslib_1.__values(pending), pending_1_1 = pending_1.next(); !pending_1_1.done; pending_1_1 = pending_1.next()) {
|
|
727
|
+
var timer = pending_1_1.value;
|
|
728
|
+
clearTimeout(timer);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
732
|
+
finally {
|
|
733
|
+
try {
|
|
734
|
+
if (pending_1_1 && !pending_1_1.done && (_a = pending_1.return)) _a.call(pending_1);
|
|
735
|
+
}
|
|
736
|
+
finally { if (e_8) throw e_8.error; }
|
|
737
|
+
}
|
|
738
|
+
};
|
|
680
739
|
}, [syncRecalcCells, recalcCellsMaxEntries, synced, yRecalcCells]);
|
|
681
740
|
// Broadcast patch
|
|
682
741
|
var onBroadcastPatch = (0, react_1.useCallback)(function (patches) {
|
|
683
|
-
var
|
|
742
|
+
var e_9, _a, e_10, _b;
|
|
684
743
|
var _c;
|
|
685
744
|
// Ignore push flag
|
|
686
745
|
var disableRecalc = Boolean(patches.find(function (_a) {
|
|
@@ -716,12 +775,12 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
716
775
|
}
|
|
717
776
|
}
|
|
718
777
|
}
|
|
719
|
-
catch (
|
|
778
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
720
779
|
finally {
|
|
721
780
|
try {
|
|
722
781
|
if (patches_1_1 && !patches_1_1.done && (_a = patches_1.return)) _a.call(patches_1);
|
|
723
782
|
}
|
|
724
|
-
finally { if (
|
|
783
|
+
finally { if (e_9) throw e_9.error; }
|
|
725
784
|
}
|
|
726
785
|
// Containment for this non-leader write path: an error may only
|
|
727
786
|
// fill a cell with no effective value (the blank-after-reload case)
|
|
@@ -746,12 +805,12 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
746
805
|
persistableErrorCellPatches_1.push(tslib_1.__assign(tslib_1.__assign({}, errorPatch), { value: (0, helpers_1.mergeErrorEffectiveValueIntoCellData)(currentCellData, incomingCellData) }));
|
|
747
806
|
}
|
|
748
807
|
}
|
|
749
|
-
catch (
|
|
808
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
750
809
|
finally {
|
|
751
810
|
try {
|
|
752
811
|
if (errorCellPatches_1_1 && !errorCellPatches_1_1.done && (_b = errorCellPatches_1.return)) _b.call(errorCellPatches_1);
|
|
753
812
|
}
|
|
754
|
-
finally { if (
|
|
813
|
+
finally { if (e_10) throw e_10.error; }
|
|
755
814
|
}
|
|
756
815
|
if (persistableErrorCellPatches_1.length) {
|
|
757
816
|
doc.transact(function () {
|
|
@@ -766,7 +825,7 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
766
825
|
return;
|
|
767
826
|
}
|
|
768
827
|
doc.transact(function () {
|
|
769
|
-
var
|
|
828
|
+
var e_11, _a, e_12, _b;
|
|
770
829
|
var _c, _d, _e, _f;
|
|
771
830
|
try {
|
|
772
831
|
for (var patches_2 = tslib_1.__values(patches), patches_2_1 = patches_2.next(); !patches_2_1.done; patches_2_1 = patches_2.next()) {
|
|
@@ -793,7 +852,7 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
793
852
|
(0, helpers_1.applyMapPatches)(yCellXfs, patches_4);
|
|
794
853
|
}
|
|
795
854
|
try {
|
|
796
|
-
for (var _j = (
|
|
855
|
+
for (var _j = (e_12 = void 0, tslib_1.__values(documentMap.entries())), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
797
856
|
var _l = tslib_1.__read(_k.value, 2), mappingKey = _l[0], _m = tslib_1.__read(_l[1], 1), ydoc = _m[0];
|
|
798
857
|
if (patch === null || patch === void 0 ? void 0 : patch[mappingKey]) {
|
|
799
858
|
var patches_5 = (_e = patch[mappingKey]) === null || _e === void 0 ? void 0 : _e[patchKey];
|
|
@@ -812,12 +871,12 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
812
871
|
}
|
|
813
872
|
}
|
|
814
873
|
}
|
|
815
|
-
catch (
|
|
874
|
+
catch (e_12_1) { e_12 = { error: e_12_1 }; }
|
|
816
875
|
finally {
|
|
817
876
|
try {
|
|
818
877
|
if (_k && !_k.done && (_b = _j.return)) _b.call(_j);
|
|
819
878
|
}
|
|
820
|
-
finally { if (
|
|
879
|
+
finally { if (e_12) throw e_12.error; }
|
|
821
880
|
}
|
|
822
881
|
// Recalc cells
|
|
823
882
|
if ((_f = patch.recalcCells) === null || _f === void 0 ? void 0 : _f[type]) {
|
|
@@ -834,12 +893,12 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
834
893
|
}
|
|
835
894
|
}
|
|
836
895
|
}
|
|
837
|
-
catch (
|
|
896
|
+
catch (e_11_1) { e_11 = { error: e_11_1 }; }
|
|
838
897
|
finally {
|
|
839
898
|
try {
|
|
840
899
|
if (patches_2_1 && !patches_2_1.done && (_a = patches_2.return)) _a.call(patches_2);
|
|
841
900
|
}
|
|
842
|
-
finally { if (
|
|
901
|
+
finally { if (e_11) throw e_11.error; }
|
|
843
902
|
}
|
|
844
903
|
}, origin);
|
|
845
904
|
onAfterBroadcastPatch === null || onAfterBroadcastPatch === void 0 ? void 0 : onAfterBroadcastPatch(patches, doc);
|
|
@@ -875,7 +934,7 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
875
934
|
// Awareness
|
|
876
935
|
(0, ui_1.useIsomorphicLayoutEffect)(function () {
|
|
877
936
|
var onChangeAwareness = function () {
|
|
878
|
-
var
|
|
937
|
+
var e_13, _a;
|
|
879
938
|
var _b, _c, _d, _e, _f;
|
|
880
939
|
if (awareness) {
|
|
881
940
|
var collaborators = [];
|
|
@@ -915,12 +974,12 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
915
974
|
});
|
|
916
975
|
}
|
|
917
976
|
}
|
|
918
|
-
catch (
|
|
977
|
+
catch (e_13_1) { e_13 = { error: e_13_1 }; }
|
|
919
978
|
finally {
|
|
920
979
|
try {
|
|
921
980
|
if (_h && !_h.done && (_a = _g.return)) _a.call(_g);
|
|
922
981
|
}
|
|
923
|
-
finally { if (
|
|
982
|
+
finally { if (e_13) throw e_13.error; }
|
|
924
983
|
}
|
|
925
984
|
setUsers(collaborators);
|
|
926
985
|
}
|
|
@@ -942,6 +1001,7 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
942
1001
|
awareness.setLocalStateField("userId", userId);
|
|
943
1002
|
awareness.setLocalStateField("title", title);
|
|
944
1003
|
awareness.setLocalStateField("sheetId", sheetId);
|
|
1004
|
+
awareness.setLocalStateField("canWrite", canWrite);
|
|
945
1005
|
if (resolvedAwarenessScopeId) {
|
|
946
1006
|
awareness.setLocalStateField("docGuid", resolvedAwarenessScopeId);
|
|
947
1007
|
}
|
|
@@ -963,6 +1023,7 @@ var useYSpreadsheetV2 = function (_a) {
|
|
|
963
1023
|
}, [
|
|
964
1024
|
awareness,
|
|
965
1025
|
resolvedAwarenessScopeId,
|
|
1026
|
+
canWrite,
|
|
966
1027
|
userId,
|
|
967
1028
|
title,
|
|
968
1029
|
sheetId,
|
|
@@ -23,6 +23,18 @@ export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extend
|
|
|
23
23
|
* convention to remain wire-compatible.
|
|
24
24
|
*/
|
|
25
25
|
awarenessScopeId?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether this client may persist to the shared document (the host's
|
|
28
|
+
* edit permission; `false` for view-only sessions). Published on awareness
|
|
29
|
+
* as `canWrite` and consulted by the leader election: the leader is the
|
|
30
|
+
* peer that evaluates backend/agent recalc backlogs and writes the computed
|
|
31
|
+
* values back, so a client whose writes the server refuses must never win —
|
|
32
|
+
* every value it computed would be dropped. Peers whose awareness state has
|
|
33
|
+
* no `canWrite` field (older clients, REST writers) count as writers. When
|
|
34
|
+
* no writer is present there is no leader: nothing could persist the values
|
|
35
|
+
* anyway. Default: `true`.
|
|
36
|
+
*/
|
|
37
|
+
canWrite?: boolean;
|
|
26
38
|
userId: string | number;
|
|
27
39
|
title: string;
|
|
28
40
|
sheetId: number;
|
|
@@ -142,7 +154,7 @@ export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extend
|
|
|
142
154
|
};
|
|
143
155
|
export type YRowData = Y.Map<Y.Array<CellData | null>>;
|
|
144
156
|
export type YSheetData = Y.Array<YRowData | null>;
|
|
145
|
-
export declare const useYSpreadsheetV2: <T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject>({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeCitations, onAfterBroadcastPatch, recalcCellsMaxEntries, onChangeNamedRanges, onChangeProtectedRanges, onChangePivotTables, enqueueCalculation, enqueueGraphOperation, reevaluateDerivationsForCells, onChangeCellXfs, onChangeSharedStrings, calculateNow, onChangeActiveSheet, clientOnlyFunctionPattern, initialSheets, awarenessScopeId, userId, title, sheetId, activeCell, kind, agentInitiator, selections, doc, provider, useV3, sheetDataVersion, onMigrationComplete, deleteV2AfterMigration, skipInitialSync, supportLegacySharedStringsArray, }: UseYSpreadsheetPropsV2<T, S, C, O>) => {
|
|
157
|
+
export declare const useYSpreadsheetV2: <T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject>({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeCitations, onAfterBroadcastPatch, recalcCellsMaxEntries, onChangeNamedRanges, onChangeProtectedRanges, onChangePivotTables, enqueueCalculation, enqueueGraphOperation, reevaluateDerivationsForCells, onChangeCellXfs, onChangeSharedStrings, calculateNow, onChangeActiveSheet, clientOnlyFunctionPattern, initialSheets, awarenessScopeId, canWrite, userId, title, sheetId, activeCell, kind, agentInitiator, selections, doc, provider, useV3, sheetDataVersion, onMigrationComplete, deleteV2AfterMigration, skipInitialSync, supportLegacySharedStringsArray, }: UseYSpreadsheetPropsV2<T, S, C, O>) => {
|
|
146
158
|
synced: boolean;
|
|
147
159
|
users: Collaborator[];
|
|
148
160
|
onBroadcastPatch: (patches: [patch: SpreadsheetPatch<Patch>, type?: HistoryType | undefined | null][]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-yspreadsheet-v2.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet-v2.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-yspreadsheet-v2.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,7 +52,7 @@ const getUserEnteredValueFromYDocV3 = (ySheetDataV3, sheetId, rowIndex, columnIn
|
|
|
52
52
|
import { createDeepObservable, createObservable, createSheetDataObservable, getPatchDeltasFromEvent, } from "./observables";
|
|
53
53
|
// Add a single null entry to the YSheetData
|
|
54
54
|
const origin = "local";
|
|
55
|
-
export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeCitations, onAfterBroadcastPatch, recalcCellsMaxEntries, onChangeNamedRanges, onChangeProtectedRanges, onChangePivotTables, enqueueCalculation, enqueueGraphOperation, reevaluateDerivationsForCells, onChangeCellXfs, onChangeSharedStrings, calculateNow, onChangeActiveSheet, clientOnlyFunctionPattern, initialSheets, awarenessScopeId, userId, title, sheetId, activeCell, kind, agentInitiator, selections, doc, provider, useV3 = false, sheetDataVersion = "v2", onMigrationComplete, deleteV2AfterMigration = false, skipInitialSync = false, supportLegacySharedStringsArray = false, }) => {
|
|
55
|
+
export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeCitations, onAfterBroadcastPatch, recalcCellsMaxEntries, onChangeNamedRanges, onChangeProtectedRanges, onChangePivotTables, enqueueCalculation, enqueueGraphOperation, reevaluateDerivationsForCells, onChangeCellXfs, onChangeSharedStrings, calculateNow, onChangeActiveSheet, clientOnlyFunctionPattern, initialSheets, awarenessScopeId, canWrite = true, userId, title, sheetId, activeCell, kind, agentInitiator, selections, doc, provider, useV3 = false, sheetDataVersion = "v2", onMigrationComplete, deleteV2AfterMigration = false, skipInitialSync = false, supportLegacySharedStringsArray = false, }) => {
|
|
56
56
|
const [synced, setSynced] = useState(false);
|
|
57
57
|
const [users, setUsers] = useState([]);
|
|
58
58
|
const [isLeader, setIsLeader] = useState(false);
|
|
@@ -68,19 +68,24 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
68
68
|
const docStates = resolvedAwarenessScopeId
|
|
69
69
|
? entries.filter(([_, state]) => state?.docGuid === resolvedAwarenessScopeId)
|
|
70
70
|
: entries;
|
|
71
|
-
|
|
71
|
+
// Only peers that can persist may lead (see `canWrite`). A view-only
|
|
72
|
+
// client's recalc write-backs are refused by the server, so electing it
|
|
73
|
+
// silently drops every computed value. A missing field is a writer.
|
|
74
|
+
const writers = docStates
|
|
75
|
+
.filter(([_, state]) => state?.canWrite !== false)
|
|
76
|
+
.map(([clientId]) => clientId);
|
|
77
|
+
if (!canWrite || !writers.length) {
|
|
72
78
|
setIsLeader(false);
|
|
73
79
|
return;
|
|
74
80
|
}
|
|
75
|
-
const
|
|
76
|
-
const minId = Math.min(...states);
|
|
81
|
+
const minId = Math.min(...writers);
|
|
77
82
|
// Always include self in the elec
|
|
78
83
|
setIsLeader(doc.clientID === minId);
|
|
79
84
|
};
|
|
80
85
|
awareness.on("change", updateLeader);
|
|
81
86
|
updateLeader(); // Initial check
|
|
82
87
|
return () => awareness.off("change", updateLeader);
|
|
83
|
-
}, [awareness, doc, resolvedAwarenessScopeId]);
|
|
88
|
+
}, [awareness, doc, resolvedAwarenessScopeId, canWrite]);
|
|
84
89
|
useIsomorphicLayoutEffect(() => {
|
|
85
90
|
isLeaderRef.current = isLeader;
|
|
86
91
|
}, [isLeader]);
|
|
@@ -219,6 +224,12 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
219
224
|
.flatMap((entry) => entry.patches)
|
|
220
225
|
.filter(([, , source]) => source === "backend" || source === "agent");
|
|
221
226
|
}, [yRecalcCells]);
|
|
227
|
+
/**
|
|
228
|
+
* Set once the initial sync has built the dependency graph and replayed the
|
|
229
|
+
* backlog, so a later leadership hand-over can replay it again.
|
|
230
|
+
*/
|
|
231
|
+
const graphReadyRef = useRef(false);
|
|
232
|
+
const initialSyncTimerRef = useRef(null);
|
|
222
233
|
// Trigger cell recalcs
|
|
223
234
|
const syncRecalcCells = useCallback((recalcCells, origin) => {
|
|
224
235
|
for (const [_, position, source] of recalcCells) {
|
|
@@ -389,6 +400,24 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
389
400
|
onMigrationComplete,
|
|
390
401
|
deleteV2AfterMigration,
|
|
391
402
|
]);
|
|
403
|
+
/**
|
|
404
|
+
* Replay the backend/agent recalc backlog into the local graph — and, on
|
|
405
|
+
* the leader, evaluate it. Only the leader clears the entries, and only once
|
|
406
|
+
* they sit in its calculation queue: a non-leader merely graph-enqueues
|
|
407
|
+
* (no evaluation), so if it deleted them the leader would never recompute
|
|
408
|
+
* the backlog at all.
|
|
409
|
+
*/
|
|
410
|
+
const drainBacklog = useCallback(() => {
|
|
411
|
+
const backlog = getBacklog();
|
|
412
|
+
if (!backlog.length)
|
|
413
|
+
return;
|
|
414
|
+
syncRecalcCells(backlog, "backend");
|
|
415
|
+
if (isLeaderRef.current) {
|
|
416
|
+
doc.transact(() => {
|
|
417
|
+
yRecalcCells.delete(0, yRecalcCells.length);
|
|
418
|
+
}, origin);
|
|
419
|
+
}
|
|
420
|
+
}, [getBacklog, syncRecalcCells, doc, yRecalcCells]);
|
|
392
421
|
// Synced
|
|
393
422
|
const onSynced = useCallback(() => {
|
|
394
423
|
if (!synced) {
|
|
@@ -398,35 +427,40 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
398
427
|
flushSync(() => {
|
|
399
428
|
setupInitialSync();
|
|
400
429
|
});
|
|
401
|
-
// Build dependency graph, then sync backlog cells
|
|
402
|
-
requestAnimationFrame
|
|
430
|
+
// Build dependency graph, then sync backlog cells. Deferred through a
|
|
431
|
+
// timer, not `requestAnimationFrame`: rAF is paused in background tabs,
|
|
432
|
+
// which left a backgrounded leader's backlog unevaluated indefinitely.
|
|
433
|
+
initialSyncTimerRef.current = setTimeout(async () => {
|
|
434
|
+
initialSyncTimerRef.current = null;
|
|
403
435
|
await calculateNow({
|
|
404
436
|
disableEvaluation: true,
|
|
405
437
|
shouldResetCellDependencyGraph: true,
|
|
406
438
|
});
|
|
407
439
|
// Sync backlog after graph is initialized
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
// Clear processed backlog entries from yRecalcCells
|
|
412
|
-
doc.transact(() => {
|
|
413
|
-
yRecalcCells.delete(0, yRecalcCells.length);
|
|
414
|
-
}, origin);
|
|
415
|
-
}
|
|
416
|
-
});
|
|
440
|
+
drainBacklog();
|
|
441
|
+
graphReadyRef.current = true;
|
|
442
|
+
}, 0);
|
|
417
443
|
}
|
|
418
444
|
setSynced(true);
|
|
419
445
|
}
|
|
420
|
-
}, [
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
]);
|
|
446
|
+
}, [calculateNow, setupInitialSync, synced, drainBacklog, skipInitialSync]);
|
|
447
|
+
// A client that becomes leader after its initial sync (the previous leader
|
|
448
|
+
// left, or the election settled late) takes over whatever backlog is still
|
|
449
|
+
// in the document: as a non-leader it only mirrored those cells into its
|
|
450
|
+
// graph, so it evaluates them now — and only now clears them.
|
|
451
|
+
useIsomorphicLayoutEffect(() => {
|
|
452
|
+
if (!isLeader || !synced || !graphReadyRef.current)
|
|
453
|
+
return;
|
|
454
|
+
drainBacklog();
|
|
455
|
+
}, [isLeader, synced, drainBacklog]);
|
|
456
|
+
useIsomorphicLayoutEffect(() => {
|
|
457
|
+
return () => {
|
|
458
|
+
if (initialSyncTimerRef.current !== null) {
|
|
459
|
+
clearTimeout(initialSyncTimerRef.current);
|
|
460
|
+
initialSyncTimerRef.current = null;
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
}, []);
|
|
430
464
|
// Sync state
|
|
431
465
|
if (provider?.synced && !synced) {
|
|
432
466
|
onSynced();
|
|
@@ -557,20 +591,29 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
557
591
|
if (!synced) {
|
|
558
592
|
return;
|
|
559
593
|
}
|
|
594
|
+
const pending = new Set();
|
|
560
595
|
// Sync all cells that are updated in the backend
|
|
561
596
|
// // Observe recalc cells separat
|
|
562
597
|
const onRecalcCellsChange = (event) => {
|
|
563
598
|
const patches = getPatchDeltasFromEvent(event);
|
|
564
599
|
const origin = event.transaction.origin;
|
|
565
600
|
if (origin !== "local") {
|
|
566
|
-
requestAnimationFrame
|
|
601
|
+
// A timer, not `requestAnimationFrame`: rAF is paused in background
|
|
602
|
+
// tabs, so a backgrounded leader would stop evaluating remote patches.
|
|
603
|
+
const timer = setTimeout(() => {
|
|
604
|
+
pending.delete(timer);
|
|
567
605
|
syncRecalcCells(patches, origin);
|
|
568
|
-
});
|
|
606
|
+
}, 0);
|
|
607
|
+
pending.add(timer);
|
|
569
608
|
}
|
|
570
609
|
};
|
|
571
610
|
// Skip the first recalc cells change
|
|
572
611
|
const sub = createObservable(yRecalcCells).subscribe(onRecalcCellsChange);
|
|
573
|
-
return () =>
|
|
612
|
+
return () => {
|
|
613
|
+
sub.unsubscribe();
|
|
614
|
+
for (const timer of pending)
|
|
615
|
+
clearTimeout(timer);
|
|
616
|
+
};
|
|
574
617
|
}, [syncRecalcCells, recalcCellsMaxEntries, synced, yRecalcCells]);
|
|
575
618
|
// Broadcast patch
|
|
576
619
|
const onBroadcastPatch = useCallback((patches) => {
|
|
@@ -777,6 +820,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
777
820
|
awareness.setLocalStateField("userId", userId);
|
|
778
821
|
awareness.setLocalStateField("title", title);
|
|
779
822
|
awareness.setLocalStateField("sheetId", sheetId);
|
|
823
|
+
awareness.setLocalStateField("canWrite", canWrite);
|
|
780
824
|
if (resolvedAwarenessScopeId) {
|
|
781
825
|
awareness.setLocalStateField("docGuid", resolvedAwarenessScopeId);
|
|
782
826
|
}
|
|
@@ -798,6 +842,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
798
842
|
}, [
|
|
799
843
|
awareness,
|
|
800
844
|
resolvedAwarenessScopeId,
|
|
845
|
+
canWrite,
|
|
801
846
|
userId,
|
|
802
847
|
title,
|
|
803
848
|
sheetId,
|