@rowsncolumns/y-spreadsheet 14.0.32
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.md +100 -0
- package/Readme.md +77 -0
- package/dist/cjs/helpers.d.ts +179 -0
- package/dist/cjs/helpers.d.ts.map +1 -0
- package/dist/cjs/helpers.js +1635 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/observables.d.ts +10 -0
- package/dist/cjs/observables.d.ts.map +1 -0
- package/dist/cjs/observables.js +90 -0
- package/dist/cjs/profiling/batch-profile.spec.d.ts +2 -0
- package/dist/cjs/profiling/batch-profile.spec.d.ts.map +1 -0
- package/dist/cjs/profiling/batch-profile.spec.js +175 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/cjs/types.d.ts +62 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/use-yspreadsheet-v2.d.ts +152 -0
- package/dist/cjs/use-yspreadsheet-v2.d.ts.map +1 -0
- package/dist/cjs/use-yspreadsheet-v2.js +980 -0
- package/dist/cjs/use-yspreadsheet.d.ts +39 -0
- package/dist/cjs/use-yspreadsheet.d.ts.map +1 -0
- package/dist/cjs/use-yspreadsheet.js +430 -0
- package/dist/cjs/vitest.config.d.ts +3 -0
- package/dist/cjs/vitest.config.d.ts.map +1 -0
- package/dist/cjs/vitest.config.js +23 -0
- package/dist/esm/helpers.d.ts +179 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +1346 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/observables.d.ts +10 -0
- package/dist/esm/observables.d.ts.map +1 -0
- package/dist/esm/observables.js +51 -0
- package/dist/esm/profiling/batch-profile.spec.d.ts +2 -0
- package/dist/esm/profiling/batch-profile.spec.d.ts.map +1 -0
- package/dist/esm/profiling/batch-profile.spec.js +131 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/esm/types.d.ts +62 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/use-yspreadsheet-v2.d.ts +152 -0
- package/dist/esm/use-yspreadsheet-v2.d.ts.map +1 -0
- package/dist/esm/use-yspreadsheet-v2.js +814 -0
- package/dist/esm/use-yspreadsheet.d.ts +39 -0
- package/dist/esm/use-yspreadsheet.d.ts.map +1 -0
- package/dist/esm/use-yspreadsheet.js +304 -0
- package/dist/esm/vitest.config.d.ts +3 -0
- package/dist/esm/vitest.config.d.ts.map +1 -0
- package/dist/esm/vitest.config.js +21 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Patch } from "immer";
|
|
2
|
+
import { Observable } from "rxjs";
|
|
3
|
+
import type * as Y from "yjs";
|
|
4
|
+
import type { PatchCoordinate, PatchDocument } from "./types";
|
|
5
|
+
import type { YSheetData } from "./use-yspreadsheet-v2";
|
|
6
|
+
export declare const createSheetDataObservable: (ySheetData: Y.Map<YSheetData>) => Observable<Y.YEvent<any>[]>;
|
|
7
|
+
export declare const getPatchDeltasFromEvent: <S extends PatchCoordinate | Patch, T extends PatchDocument<S>>(event: Y.YArrayEvent<T>) => S[];
|
|
8
|
+
export declare const createObservable: <T = PatchDocument>(yArr: Y.Array<T>) => Observable<Y.YArrayEvent<T>>;
|
|
9
|
+
export declare const createDeepObservable: (yArr: Y.Array<any>) => Observable<Y.YEvent<any>[]>;
|
|
10
|
+
//# sourceMappingURL=observables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observables.d.ts","sourceRoot":"","sources":["../../observables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,KAAK,KAAK,CAAC,MAAM,KAAK,CAAC;AAE9B,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,eAAO,MAAM,yBAAyB,GAAI,YAAY,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,gCAYtE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,CAAC,SAAS,eAAe,GAAG,KAAK,EACjC,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,EAE1B,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAiBxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,aAAa,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iCAYnE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,gCAYtD,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
export const createSheetDataObservable = (ySheetData) => {
|
|
3
|
+
return new Observable((observer) => {
|
|
4
|
+
const callback = (events) => {
|
|
5
|
+
observer.next(events);
|
|
6
|
+
};
|
|
7
|
+
ySheetData.observeDeep(callback);
|
|
8
|
+
return () => {
|
|
9
|
+
ySheetData.unobserveDeep(callback);
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
export const getPatchDeltasFromEvent = (event) => {
|
|
14
|
+
const patches = [];
|
|
15
|
+
if (event.transaction.origin !== "local") {
|
|
16
|
+
for (const changes of event.changes.delta) {
|
|
17
|
+
for (const type in changes) {
|
|
18
|
+
if (type === "insert" && changes[type] !== undefined) {
|
|
19
|
+
for (const { patches: userPatches } of changes[type]) {
|
|
20
|
+
for (const patch of userPatches) {
|
|
21
|
+
patches.push(patch);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return patches;
|
|
29
|
+
};
|
|
30
|
+
export const createObservable = (yArr) => {
|
|
31
|
+
return new Observable((observer) => {
|
|
32
|
+
const callback = (event) => {
|
|
33
|
+
observer.next(event);
|
|
34
|
+
};
|
|
35
|
+
yArr.observe(callback);
|
|
36
|
+
return () => {
|
|
37
|
+
yArr.unobserve(callback);
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
export const createDeepObservable = (yArr) => {
|
|
42
|
+
return new Observable((observer) => {
|
|
43
|
+
const callback = (event) => {
|
|
44
|
+
observer.next(event);
|
|
45
|
+
};
|
|
46
|
+
yArr.observeDeep(callback);
|
|
47
|
+
return () => {
|
|
48
|
+
yArr.unobserveDeep(callback);
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-profile.spec.d.ts","sourceRoot":"","sources":["../../../profiling/batch-profile.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/* @vitest-environment jsdom */
|
|
2
|
+
import { act, renderHook } from "@testing-library/react";
|
|
3
|
+
import { describe, it, vi } from "vitest";
|
|
4
|
+
import * as Y from "yjs";
|
|
5
|
+
import { useYSpreadsheetV2 } from "../use-yspreadsheet-v2";
|
|
6
|
+
vi.mock("@rowsncolumns/utils", async (importOriginal) => {
|
|
7
|
+
const actual = await importOriginal();
|
|
8
|
+
return {
|
|
9
|
+
...actual,
|
|
10
|
+
scheduleAfterPaint: (callback) => {
|
|
11
|
+
if (typeof requestAnimationFrame === "function") {
|
|
12
|
+
const frameId = requestAnimationFrame(() => callback());
|
|
13
|
+
return () => {
|
|
14
|
+
if (typeof cancelAnimationFrame === "function") {
|
|
15
|
+
cancelAnimationFrame(frameId);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const timeoutId = setTimeout(callback, 0);
|
|
20
|
+
return () => clearTimeout(timeoutId);
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
const parseEnvNumber = (key, fallback) => {
|
|
25
|
+
const value = Number(process.env[key]);
|
|
26
|
+
return Number.isFinite(value) ? value : fallback;
|
|
27
|
+
};
|
|
28
|
+
const testTimeoutMs = parseEnvNumber("PROFILE_TEST_TIMEOUT_MS", 30000);
|
|
29
|
+
const now = () => typeof performance !== "undefined" && typeof performance.now === "function"
|
|
30
|
+
? performance.now()
|
|
31
|
+
: Date.now();
|
|
32
|
+
const createSheetDataPatchBatch = (sheetId, startRow, rows, columns) => {
|
|
33
|
+
const patches = [];
|
|
34
|
+
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
|
|
35
|
+
const absoluteRow = startRow + rowIndex;
|
|
36
|
+
const values = Array.from({ length: columns }, (_, columnIndex) => ({
|
|
37
|
+
value: `R${absoluteRow}C${columnIndex}`,
|
|
38
|
+
}));
|
|
39
|
+
patches.push([
|
|
40
|
+
{
|
|
41
|
+
sheetData: {
|
|
42
|
+
patches: [
|
|
43
|
+
{
|
|
44
|
+
op: "add",
|
|
45
|
+
path: [sheetId, absoluteRow],
|
|
46
|
+
value: { values },
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
inversePatches: [],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
undefined,
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
return patches;
|
|
56
|
+
};
|
|
57
|
+
const waitForCondition = async (condition, timeoutMs, intervalMs = 25) => {
|
|
58
|
+
const start = Date.now();
|
|
59
|
+
while (Date.now() - start < timeoutMs) {
|
|
60
|
+
if (condition()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
64
|
+
}
|
|
65
|
+
throw new Error("Profiling timed out while waiting for condition.");
|
|
66
|
+
};
|
|
67
|
+
describe("profiling: staggered broadcast patches", () => {
|
|
68
|
+
it("profiles large batch updates without data loss", async () => {
|
|
69
|
+
vi.useRealTimers();
|
|
70
|
+
const sheetId = parseEnvNumber("PROFILE_SHEET_ID", 1);
|
|
71
|
+
const rowsPerCall = parseEnvNumber("PROFILE_ROWS_PER_CALL", 150);
|
|
72
|
+
const calls = parseEnvNumber("PROFILE_CALLS", 10);
|
|
73
|
+
const columns = parseEnvNumber("PROFILE_COLUMNS", 20);
|
|
74
|
+
const timeoutMs = parseEnvNumber("PROFILE_TIMEOUT_MS", 20000);
|
|
75
|
+
const totalRows = rowsPerCall * calls;
|
|
76
|
+
const totalPatches = totalRows;
|
|
77
|
+
const doc = new Y.Doc();
|
|
78
|
+
const transactSpy = vi.spyOn(doc, "transact");
|
|
79
|
+
const { result } = renderHook(() => useYSpreadsheetV2({
|
|
80
|
+
userId: "user-1",
|
|
81
|
+
title: "Profiler",
|
|
82
|
+
sheetId,
|
|
83
|
+
doc,
|
|
84
|
+
calculateNow: vi.fn(),
|
|
85
|
+
initialSheets: [],
|
|
86
|
+
onChangeSheetData: vi.fn(),
|
|
87
|
+
onChangeSheets: vi.fn(),
|
|
88
|
+
onChangeTables: vi.fn(),
|
|
89
|
+
enqueueCalculation: vi.fn(),
|
|
90
|
+
enqueueGraphOperation: vi.fn(),
|
|
91
|
+
}));
|
|
92
|
+
const memStart = process?.memoryUsage?.().heapUsed;
|
|
93
|
+
const enqueueStart = now();
|
|
94
|
+
for (let i = 0; i < calls; i++) {
|
|
95
|
+
const batch = createSheetDataPatchBatch(sheetId, i * rowsPerCall, rowsPerCall, columns);
|
|
96
|
+
act(() => {
|
|
97
|
+
result.current.onBroadcastPatch(batch);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const enqueueMs = now() - enqueueStart;
|
|
101
|
+
const applyStart = now();
|
|
102
|
+
await waitForCondition(() => {
|
|
103
|
+
const sheetData = doc.getMap("sheetDataV2").get(String(sheetId));
|
|
104
|
+
return sheetData?.length === totalRows;
|
|
105
|
+
}, timeoutMs);
|
|
106
|
+
const applyMs = now() - applyStart;
|
|
107
|
+
const sheetData = doc.getMap("sheetDataV2").get(String(sheetId));
|
|
108
|
+
const lastRow = sheetData?.get(totalRows - 1);
|
|
109
|
+
const lastValues = lastRow?.get("values");
|
|
110
|
+
const lastCell = lastValues?.get(columns - 1);
|
|
111
|
+
if (!lastCell || lastCell.value !== `R${totalRows - 1}C${columns - 1}`) {
|
|
112
|
+
throw new Error("Data loss detected: last cell value mismatch.");
|
|
113
|
+
}
|
|
114
|
+
const memEnd = process?.memoryUsage?.().heapUsed;
|
|
115
|
+
const report = {
|
|
116
|
+
sheetId,
|
|
117
|
+
calls,
|
|
118
|
+
rowsPerCall,
|
|
119
|
+
columns,
|
|
120
|
+
totalRows,
|
|
121
|
+
totalPatches,
|
|
122
|
+
enqueueMs: Math.round(enqueueMs),
|
|
123
|
+
applyMs: Math.round(applyMs),
|
|
124
|
+
transactBatches: transactSpy.mock.calls.length,
|
|
125
|
+
heapDeltaMB: typeof memStart === "number" && typeof memEnd === "number"
|
|
126
|
+
? Math.round(((memEnd - memStart) / 1024 / 1024) * 100) / 100
|
|
127
|
+
: "n/a",
|
|
128
|
+
};
|
|
129
|
+
console.table(report);
|
|
130
|
+
}, testTimeoutMs);
|
|
131
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["../../helpers.ts","../../index.ts","../../observables.ts","../../types.ts","../../use-yspreadsheet-v2.ts","../../use-yspreadsheet.ts","../../vitest.config.ts","../../profiling/batch-profile.spec.ts"],"version":"5.8.3"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Patch } from "immer";
|
|
2
|
+
import type { RecalcCellCoordinate } from "@rowsncolumns/spreadsheet-state";
|
|
3
|
+
import type { CellData } from "@rowsncolumns/spreadsheet";
|
|
4
|
+
export type PatchDocument<T = Patch> = {
|
|
5
|
+
userId: string | number;
|
|
6
|
+
patches: T[];
|
|
7
|
+
};
|
|
8
|
+
export type PatchRecalcCells = PatchDocument<PatchCoordinate>;
|
|
9
|
+
export type PatchCoordinate = [
|
|
10
|
+
key: string,
|
|
11
|
+
position: RecalcCellCoordinate,
|
|
12
|
+
/**
|
|
13
|
+
* This is a temporary solution
|
|
14
|
+
* 1. If source is agent => Agent generates patches for cells that needs recalculation. The UI can recalculate the cells and its dependents
|
|
15
|
+
* 2. If source is backend => Agent sets effective value of a cell -> The UI recalculate its dependents | Back-end is only to update a formula result
|
|
16
|
+
* 3. If source is user => Nothing happens Business as usual
|
|
17
|
+
*/
|
|
18
|
+
source?: "agent" | "user" | "backend"
|
|
19
|
+
];
|
|
20
|
+
/**
|
|
21
|
+
* V3 Data Structure Types
|
|
22
|
+
*
|
|
23
|
+
* V3 uses a flat Map structure for sheet data storage:
|
|
24
|
+
* - Key format: `${sheetId}!${A1Address}` (e.g., "1!A1", "2!B5")
|
|
25
|
+
* - Value: CellDataV3 containing cell data and position
|
|
26
|
+
*
|
|
27
|
+
* Benefits:
|
|
28
|
+
* - O(1) cell lookups by key
|
|
29
|
+
* - Sparse storage (no null padding for empty cells)
|
|
30
|
+
* - More efficient for large spreadsheets with sparse data
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* V3 cell data structure containing value and flattened position
|
|
34
|
+
* - value: The cell data
|
|
35
|
+
* - sId: Sheet ID
|
|
36
|
+
* - r: Row index (1-based)
|
|
37
|
+
* - c: Column index (1-based)
|
|
38
|
+
*/
|
|
39
|
+
export type CellDataV3<T extends CellData = CellData> = {
|
|
40
|
+
value: T;
|
|
41
|
+
/** Sheet ID */
|
|
42
|
+
sId: number;
|
|
43
|
+
/** Row index (1-based) */
|
|
44
|
+
r: number;
|
|
45
|
+
/** Column index (1-based) */
|
|
46
|
+
c: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* V3 cell key format: `${sheetId}!${A1Address}`
|
|
50
|
+
* Examples: "1!A1", "2!B5", "1!AA100"
|
|
51
|
+
*/
|
|
52
|
+
export type CellKeyV3 = string;
|
|
53
|
+
/**
|
|
54
|
+
* Parsed cell key containing sheet ID and position information
|
|
55
|
+
*/
|
|
56
|
+
export type ParsedCellKeyV3 = {
|
|
57
|
+
sheetId: number;
|
|
58
|
+
address: string;
|
|
59
|
+
rowIndex: number;
|
|
60
|
+
columnIndex: number;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,KAAK,IAAI;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,OAAO,EAAE,CAAC,EAAE,CAAC;CACd,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;AAC9D,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM;IACX,QAAQ,EAAE,oBAAoB;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;CACtC,CAAC;AAEF;;;;;;;;;;;GAWG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAAI;IACtD,KAAK,EAAE,CAAC,CAAC;IACT,eAAe;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,0BAA0B;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,6BAA6B;IAC7B,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { HocuspocusProvider } from "@hocuspocus/provider";
|
|
2
|
+
import type { Citation } from "@rowsncolumns/common-types";
|
|
3
|
+
import type { CellInterface, SelectionArea } from "@rowsncolumns/grid";
|
|
4
|
+
import { PivotTable, type CellData, type Collaborator, type ConditionalFormatRule, type DataValidationRuleRecord, type EmbeddedChart, type EmbeddedObject, type NamedRange, type ProtectedRange, type Sheet, type TableView } from "@rowsncolumns/spreadsheet";
|
|
5
|
+
import { type CalculateNowOptions, type CalculationOperation, type CellXfs, type HistoryType, type SheetData, type SharedStrings, type SpreadsheetPatch } from "@rowsncolumns/spreadsheet-state";
|
|
6
|
+
import type { Patch } from "immer";
|
|
7
|
+
import type { WebsocketProvider } from "y-websocket";
|
|
8
|
+
import * as Y from "yjs";
|
|
9
|
+
export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject> = {
|
|
10
|
+
/**
|
|
11
|
+
* Scopes awareness updates to a single document.
|
|
12
|
+
*
|
|
13
|
+
* Multiple Athena editors (sheets, slides, docs) can share a single
|
|
14
|
+
* awareness channel by writing a `docGuid` field to their local state.
|
|
15
|
+
* When `awarenessScopeId` is set, this hook:
|
|
16
|
+
* - emits `docGuid: awarenessScopeId` on the local state
|
|
17
|
+
* - filters incoming states whose `docGuid` does not match
|
|
18
|
+
* - states with **no** `docGuid` are treated as a wildcard and accepted
|
|
19
|
+
* (so REST writers or older clients that don't set docGuid still
|
|
20
|
+
* appear as collaborators)
|
|
21
|
+
*
|
|
22
|
+
* Olympus and pptx-studio set this to the asset id; keep the same
|
|
23
|
+
* convention to remain wire-compatible.
|
|
24
|
+
*/
|
|
25
|
+
awarenessScopeId?: string;
|
|
26
|
+
userId: string | number;
|
|
27
|
+
title: string;
|
|
28
|
+
sheetId: number;
|
|
29
|
+
activeCell?: CellInterface;
|
|
30
|
+
/**
|
|
31
|
+
* Distinguishes human vs. agent presence. Surfaced on `Collaborator.kind`
|
|
32
|
+
* so renderers can style agent cursors differently.
|
|
33
|
+
*/
|
|
34
|
+
kind?: "human" | "agent";
|
|
35
|
+
/**
|
|
36
|
+
* For `kind === "agent"`, identifies the human who initiated the agent run
|
|
37
|
+
* (e.g. "Brendon"). Used to deduplicate agent cursors by initiator and to
|
|
38
|
+
* label "Athena · Brendon's run" in presence stacks.
|
|
39
|
+
*/
|
|
40
|
+
agentInitiator?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Current selection range(s). When set, collaborators rendered in the grid
|
|
43
|
+
* receive a range-shaped highlight in addition to the activeCell pin —
|
|
44
|
+
* needed so agents touching A1:E10 don't appear to be sitting on A1.
|
|
45
|
+
*/
|
|
46
|
+
selections?: SelectionArea[];
|
|
47
|
+
provider?: HocuspocusProvider | WebsocketProvider | any;
|
|
48
|
+
doc: Y.Doc;
|
|
49
|
+
calculateNow(options?: CalculateNowOptions): Promise<void>;
|
|
50
|
+
initialSheets: S[];
|
|
51
|
+
/**
|
|
52
|
+
* Enable V3 data structure (flat Map<cellKey, CellDataV3>)
|
|
53
|
+
* V3 uses a sparse map structure with keys like "1!A1" instead of nested arrays
|
|
54
|
+
* This provides better performance for sparse spreadsheets
|
|
55
|
+
*/
|
|
56
|
+
useV3?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Current data version stored in the document ("v2" or "v3")
|
|
59
|
+
* If using V3 but version is "v2" or undefined, migration will occur
|
|
60
|
+
* This should be provided by the backend/server
|
|
61
|
+
*/
|
|
62
|
+
sheetDataVersion?: "v2" | "v3";
|
|
63
|
+
/**
|
|
64
|
+
* Called after migration completes so backend can persist the new version
|
|
65
|
+
*/
|
|
66
|
+
onMigrationComplete?: (newVersion: "v3") => void;
|
|
67
|
+
/**
|
|
68
|
+
* Delete V2 data after migrating to V3
|
|
69
|
+
* Only applies when useV3 is true and migration occurs
|
|
70
|
+
* Default: false (keeps V2 data for rollback safety)
|
|
71
|
+
*/
|
|
72
|
+
deleteV2AfterMigration?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Skip the initial sync process
|
|
75
|
+
* When true, setupInitialSync will not be called on sync
|
|
76
|
+
* Useful when you want to handle initial state loading externally
|
|
77
|
+
* Default: false
|
|
78
|
+
*/
|
|
79
|
+
skipInitialSync?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Enable support for legacy shared strings stored as Y.Array.
|
|
82
|
+
* When enabled, observes both Y.Map (new format) and Y.Array (legacy format)
|
|
83
|
+
* and merges them into the shared strings state.
|
|
84
|
+
* Default: false (only observe Y.Map format)
|
|
85
|
+
*/
|
|
86
|
+
supportLegacySharedStringsArray?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Get user entered value of a cell
|
|
89
|
+
* @param sheetId
|
|
90
|
+
* @param rowIndex
|
|
91
|
+
* @param columnIndex
|
|
92
|
+
*/
|
|
93
|
+
getUserEnteredValue?(sheetId: number, rowIndex: number, columnIndex: number): string | undefined | null;
|
|
94
|
+
/**
|
|
95
|
+
* Client only functions
|
|
96
|
+
*/
|
|
97
|
+
clientOnlyFunctionPattern?: RegExp;
|
|
98
|
+
onChangeActiveSheet?(sheetId: number): void;
|
|
99
|
+
onChangeSheetData: React.Dispatch<React.SetStateAction<SheetData<T>>>;
|
|
100
|
+
onChangeTables: React.Dispatch<React.SetStateAction<TableView[]>>;
|
|
101
|
+
onChangeSheets: React.Dispatch<React.SetStateAction<S[]>>;
|
|
102
|
+
onChangeCharts?: React.Dispatch<React.SetStateAction<C[]>>;
|
|
103
|
+
onChangeEmbeds?: React.Dispatch<React.SetStateAction<O[]>>;
|
|
104
|
+
onChangeNamedRanges?: React.Dispatch<React.SetStateAction<NamedRange[]>>;
|
|
105
|
+
onChangePivotTables?: React.Dispatch<React.SetStateAction<PivotTable[]>>;
|
|
106
|
+
onChangeCellXfs?: React.Dispatch<React.SetStateAction<CellXfs | null | undefined>>;
|
|
107
|
+
onChangeSharedStrings?: React.Dispatch<React.SetStateAction<SharedStrings>>;
|
|
108
|
+
onChangeProtectedRanges?: React.Dispatch<React.SetStateAction<ProtectedRange[]>>;
|
|
109
|
+
onChangeConditionalFormats?: React.Dispatch<React.SetStateAction<ConditionalFormatRule[]>>;
|
|
110
|
+
onChangeDataValidations?: React.Dispatch<React.SetStateAction<DataValidationRuleRecord[]>>;
|
|
111
|
+
onChangeCitations?: React.Dispatch<React.SetStateAction<Citation[]>>;
|
|
112
|
+
/**
|
|
113
|
+
* Called synchronously right after a batch of local patches has been written to the
|
|
114
|
+
* shared document, inside `onBroadcastPatch` and before it returns to the caller. It
|
|
115
|
+
* receives the patches that were applied and the document. Purely observational: it
|
|
116
|
+
* does not alter the write or the patches. Useful for integrity checks, reconciliation,
|
|
117
|
+
* or telemetry that need to compare local state against the resulting document state at
|
|
118
|
+
* the moment a local edit is committed. Not called when the broadcast is skipped (e.g.
|
|
119
|
+
* a non-leader recalc patch). Default: no-op.
|
|
120
|
+
*/
|
|
121
|
+
onAfterBroadcastPatch?: (patches: [
|
|
122
|
+
patch: SpreadsheetPatch<Patch>,
|
|
123
|
+
type?: HistoryType | undefined | null
|
|
124
|
+
][], doc: Y.Doc) => void;
|
|
125
|
+
recalcCellsMaxEntries?: number;
|
|
126
|
+
enqueueCalculation: (operation: CalculationOperation) => void;
|
|
127
|
+
enqueueGraphOperation: (operation: CalculationOperation) => void;
|
|
128
|
+
/**
|
|
129
|
+
* Re-derives conditional-format / data-validation results for changed
|
|
130
|
+
* cells (`useSpreadsheetState.reevaluateDerivationsForCells`). Agent- and
|
|
131
|
+
* backend-sourced recalc patches carry PRE-COMPUTED cell values, so they
|
|
132
|
+
* only update the dependency graph (no evaluation) — but CF/DV results are
|
|
133
|
+
* client-owned and the backend never writes them, so without this the
|
|
134
|
+
* changed cells' conditional formatting stays stale until the user
|
|
135
|
+
* re-saves a rule in the dialog.
|
|
136
|
+
*/
|
|
137
|
+
reevaluateDerivationsForCells?: (cells: Array<{
|
|
138
|
+
sheetId: number;
|
|
139
|
+
rowIndex: number;
|
|
140
|
+
columnIndex: number;
|
|
141
|
+
}>) => void;
|
|
142
|
+
};
|
|
143
|
+
export type YRowData = Y.Map<Y.Array<CellData | null>>;
|
|
144
|
+
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>) => {
|
|
146
|
+
synced: boolean;
|
|
147
|
+
users: Collaborator[];
|
|
148
|
+
onBroadcastPatch: (patches: [patch: SpreadsheetPatch<Patch>, type?: HistoryType | undefined | null][]) => void;
|
|
149
|
+
isLeader: boolean;
|
|
150
|
+
setupInitialSync: () => void;
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=use-yspreadsheet-v2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-yspreadsheet-v2.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet-v2.ts"],"names":[],"mappings":"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"}
|