@rowsncolumns/y-spreadsheet 15.0.3 → 16.0.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/Readme.md +3 -0
- package/dist/cjs/helpers.d.ts +6 -6
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +22 -18
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +38 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/use-yspreadsheet-v2.d.ts +11 -4
- package/dist/cjs/use-yspreadsheet-v2.d.ts.map +1 -1
- package/dist/cjs/use-yspreadsheet-v2.js +13 -11
- package/dist/cjs/use-yspreadsheet.d.ts +9 -3
- package/dist/cjs/use-yspreadsheet.d.ts.map +1 -1
- package/dist/cjs/use-yspreadsheet.js +16 -13
- package/dist/cjs/vitest.config.d.ts.map +1 -1
- package/dist/cjs/vitest.config.js +1 -0
- package/dist/cjs/yjs-runtime.d.ts +6 -0
- package/dist/cjs/yjs-runtime.d.ts.map +1 -0
- package/dist/cjs/yjs-runtime.js +25 -0
- package/dist/esm/helpers.d.ts +6 -6
- package/dist/esm/helpers.d.ts.map +1 -1
- package/dist/esm/helpers.js +22 -18
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +38 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/use-yspreadsheet-v2.d.ts +11 -4
- package/dist/esm/use-yspreadsheet-v2.d.ts.map +1 -1
- package/dist/esm/use-yspreadsheet-v2.js +13 -11
- package/dist/esm/use-yspreadsheet.d.ts +9 -3
- package/dist/esm/use-yspreadsheet.d.ts.map +1 -1
- package/dist/esm/use-yspreadsheet.js +14 -13
- package/dist/esm/vitest.config.d.ts.map +1 -1
- package/dist/esm/vitest.config.js +1 -0
- package/dist/esm/yjs-runtime.d.ts +6 -0
- package/dist/esm/yjs-runtime.d.ts.map +1 -0
- package/dist/esm/yjs-runtime.js +20 -0
- package/package.json +6 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveYjsRuntime = exports.setDefaultYjsRuntime = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* y-spreadsheet does not import a Yjs implementation: every helper and hook
|
|
6
|
+
* takes the namespace of the implementation the document belongs to (`yjs`,
|
|
7
|
+
* or a yjs-13-compatible layer over `@y/y` 14). A host that always works with
|
|
8
|
+
* one implementation can register it once here instead of passing it on every
|
|
9
|
+
* call; a runtime passed to a call wins over the registered one.
|
|
10
|
+
*/
|
|
11
|
+
var defaultYjsRuntime;
|
|
12
|
+
/** Registers (or, with `undefined`, clears) the runtime used when a call passes none. */
|
|
13
|
+
var setDefaultYjsRuntime = function (runtime) {
|
|
14
|
+
defaultYjsRuntime = runtime;
|
|
15
|
+
};
|
|
16
|
+
exports.setDefaultYjsRuntime = setDefaultYjsRuntime;
|
|
17
|
+
/** The runtime a call works with: the one it was given, else the registered default. */
|
|
18
|
+
var resolveYjsRuntime = function (runtime) {
|
|
19
|
+
var resolved = runtime !== null && runtime !== void 0 ? runtime : defaultYjsRuntime;
|
|
20
|
+
if (!resolved) {
|
|
21
|
+
throw new Error("@rowsncolumns/y-spreadsheet: no Yjs runtime. Pass `yjs` (the namespace of the Yjs implementation the document belongs to, e.g. `import * as Y from \"yjs\"`) or register one with setDefaultYjsRuntime(Y). The package does not import yjs itself.");
|
|
22
|
+
}
|
|
23
|
+
return resolved;
|
|
24
|
+
};
|
|
25
|
+
exports.resolveYjsRuntime = resolveYjsRuntime;
|
package/dist/esm/helpers.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type CellData, type CellFormat, type Sheet } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import { type HistoryType, type SheetData, type SpreadsheetPatch } from "@rowsncolumns/spreadsheet-state";
|
|
3
3
|
import type { Patch } from "immer";
|
|
4
|
-
import * as Y from "yjs";
|
|
4
|
+
import type * as Y from "yjs";
|
|
5
5
|
import type { YRowData, YSheetData } from "./use-yspreadsheet-v2";
|
|
6
|
-
import type { CellKeyV3, CellDataV3, ParsedCellKeyV3 } from "./types";
|
|
6
|
+
import type { CellKeyV3, CellDataV3, ParsedCellKeyV3, YjsRuntime } from "./types";
|
|
7
7
|
/**
|
|
8
8
|
* Simplified structure to pass event data synchronously
|
|
9
9
|
*/
|
|
@@ -24,7 +24,7 @@ export type SheetDataEvent = {
|
|
|
24
24
|
* @param source
|
|
25
25
|
* @param sheetDataVersion - Version of sheet data format ("v2" or "v3"). Falls back to docMeta if undefined.
|
|
26
26
|
*/
|
|
27
|
-
export declare const applyPatchesToYDoc: (doc: Y.Doc, userId: string | number, patches: [patch: SpreadsheetPatch<Patch>, type?: HistoryType | undefined | null][], source?: "agent" | "user" | "backend", sheetDataVersion?: "v2" | "v3") => void;
|
|
27
|
+
export declare const applyPatchesToYDoc: (doc: Y.Doc, userId: string | number, patches: [patch: SpreadsheetPatch<Patch>, type?: HistoryType | undefined | null][], source?: "agent" | "user" | "backend", sheetDataVersion?: "v2" | "v3", yjsRuntime?: YjsRuntime) => void;
|
|
28
28
|
/**
|
|
29
29
|
* Add sheet data to a yjs map using immer patches
|
|
30
30
|
*
|
|
@@ -33,10 +33,10 @@ export declare const applyPatchesToYDoc: (doc: Y.Doc, userId: string | number, p
|
|
|
33
33
|
* 1. Deduplicating patches targeting the same cell (later patches win)
|
|
34
34
|
* 2. Grouping updates by sheet/row for efficient batch application
|
|
35
35
|
*/
|
|
36
|
-
export declare const addSheetDataPatches: (ySheetData: Y.Map<YSheetData>, patches: Patch[]) => void;
|
|
37
|
-
export declare const getSheetFromYSheetData: (ySheetData: Y.Map<YSheetData>, sheetId: string | number) => YSheetData;
|
|
36
|
+
export declare const addSheetDataPatches: (ySheetData: Y.Map<YSheetData>, patches: Patch[], yjsRuntime?: YjsRuntime) => void;
|
|
37
|
+
export declare const getSheetFromYSheetData: (ySheetData: Y.Map<YSheetData>, sheetId: string | number, yjsRuntime?: YjsRuntime) => YSheetData;
|
|
38
38
|
export declare const deleteSheetFromYSheetData: (ySheetData: Y.Map<YSheetData>, sheetId: string | number) => void;
|
|
39
|
-
export declare const getRowDataFromSheet: (ysheet: Y.Array<YRowData | null>, rowIndex: number | string) => Y.Array<CellData | null>;
|
|
39
|
+
export declare const getRowDataFromSheet: (ysheet: Y.Array<YRowData | null>, rowIndex: number | string, yjsRuntime?: YjsRuntime) => Y.Array<CellData | null>;
|
|
40
40
|
export declare const setCellDataInRowData: (rowData: Y.Array<CellData | null>, columnIndex: number | string, cellData?: CellData | null) => void;
|
|
41
41
|
export declare const removeRowData: (ysheet: Y.Array<YRowData | null>, rowIndex: number | string) => void;
|
|
42
42
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,KAAK,EAEX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACtB,MAAM,iCAAiC,CAAC;AAWzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/helpers.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { cellToAddress, getCellEffectiveValue, getCellUserEnteredValue, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, } from "@rowsncolumns/utils";
|
|
2
|
-
import * as Y from "yjs";
|
|
3
2
|
import cloneDeep from "lodash/cloneDeep";
|
|
4
3
|
import isEqual from "lodash/isEqual";
|
|
5
4
|
import set from "lodash/set";
|
|
6
5
|
import get from "lodash/get";
|
|
7
6
|
import unset from "lodash/unset";
|
|
7
|
+
import { resolveYjsRuntime } from "./yjs-runtime";
|
|
8
8
|
/**
|
|
9
9
|
* Apply patches to yjs
|
|
10
10
|
* @param doc
|
|
@@ -13,7 +13,8 @@ import unset from "lodash/unset";
|
|
|
13
13
|
* @param source
|
|
14
14
|
* @param sheetDataVersion - Version of sheet data format ("v2" or "v3"). Falls back to docMeta if undefined.
|
|
15
15
|
*/
|
|
16
|
-
export const applyPatchesToYDoc = (doc, userId, patches, source, sheetDataVersion) => {
|
|
16
|
+
export const applyPatchesToYDoc = (doc, userId, patches, source, sheetDataVersion, yjsRuntime) => {
|
|
17
|
+
const yjs = resolveYjsRuntime(yjsRuntime);
|
|
17
18
|
const ySheetDataV2 = doc.getMap("sheetDataV2");
|
|
18
19
|
const ySheetDataV3 = doc.getMap("sheetDataV3");
|
|
19
20
|
const yDocMeta = doc.getMap("docMeta");
|
|
@@ -42,7 +43,7 @@ export const applyPatchesToYDoc = (doc, userId, patches, source, sheetDataVersio
|
|
|
42
43
|
addSheetDataPatchesV3(ySheetDataV3, patches);
|
|
43
44
|
}
|
|
44
45
|
else {
|
|
45
|
-
addSheetDataPatches(ySheetDataV2, patches);
|
|
46
|
+
addSheetDataPatches(ySheetDataV2, patches, yjs);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
if (patch.sheets) {
|
|
@@ -114,7 +115,8 @@ export const applyPatchesToYDoc = (doc, userId, patches, source, sheetDataVersio
|
|
|
114
115
|
* 1. Deduplicating patches targeting the same cell (later patches win)
|
|
115
116
|
* 2. Grouping updates by sheet/row for efficient batch application
|
|
116
117
|
*/
|
|
117
|
-
export const addSheetDataPatches = (ySheetData, patches) => {
|
|
118
|
+
export const addSheetDataPatches = (ySheetData, patches, yjsRuntime) => {
|
|
119
|
+
const yjs = resolveYjsRuntime(yjsRuntime);
|
|
118
120
|
// Optimization: consecutive cell-level patches are consolidated (later
|
|
119
121
|
// patches override earlier ones for the same cell) and applied together,
|
|
120
122
|
// grouped by sheet and row so bulk operations like paste (10k+ rows) cost
|
|
@@ -138,9 +140,9 @@ export const addSheetDataPatches = (ySheetData, patches) => {
|
|
|
138
140
|
rowUpdates.get(rowIdx).set(colIdx, value);
|
|
139
141
|
}
|
|
140
142
|
for (const [sheetIdStr, rowUpdates] of sheetRowUpdates) {
|
|
141
|
-
const ysheet = getSheetFromYSheetData(ySheetData, sheetIdStr);
|
|
143
|
+
const ysheet = getSheetFromYSheetData(ySheetData, sheetIdStr, yjs);
|
|
142
144
|
for (const [rowIdx, colUpdates] of rowUpdates) {
|
|
143
|
-
const rowData = getRowDataFromSheet(ysheet, rowIdx);
|
|
145
|
+
const rowData = getRowDataFromSheet(ysheet, rowIdx, yjs);
|
|
144
146
|
for (const [colIdx, value] of colUpdates) {
|
|
145
147
|
setCellDataInRowData(rowData, colIdx, value);
|
|
146
148
|
}
|
|
@@ -169,12 +171,12 @@ export const addSheetDataPatches = (ySheetData, patches) => {
|
|
|
169
171
|
return;
|
|
170
172
|
}
|
|
171
173
|
if (op === "replace" || op === "add") {
|
|
172
|
-
const ysheet = getSheetFromYSheetData(ySheetData, sheetId);
|
|
174
|
+
const ysheet = getSheetFromYSheetData(ySheetData, sheetId, yjs);
|
|
173
175
|
// Cell-level patches (path.length === 4) are already handled above via consolidation
|
|
174
176
|
// [sheetId, rowIndex, 'values'] - Replace values array directly
|
|
175
177
|
if (path.length === 3 && path[2] === "values") {
|
|
176
178
|
const [, rowIndex] = path;
|
|
177
|
-
const rowData = getRowDataFromSheet(ysheet, rowIndex);
|
|
179
|
+
const rowData = getRowDataFromSheet(ysheet, rowIndex, yjs);
|
|
178
180
|
// Clear existing row data
|
|
179
181
|
rowData.delete(0, rowData.length);
|
|
180
182
|
if (Array.isArray(value)) {
|
|
@@ -192,7 +194,7 @@ export const addSheetDataPatches = (ySheetData, patches) => {
|
|
|
192
194
|
const [, rowIndex] = path;
|
|
193
195
|
if (value?.values) {
|
|
194
196
|
// Replace entire row with new values
|
|
195
|
-
const rowData = getRowDataFromSheet(ysheet, rowIndex);
|
|
197
|
+
const rowData = getRowDataFromSheet(ysheet, rowIndex, yjs);
|
|
196
198
|
// Clear existing row data
|
|
197
199
|
rowData.delete(0, rowData.length);
|
|
198
200
|
// Add new cell values
|
|
@@ -218,7 +220,7 @@ export const addSheetDataPatches = (ySheetData, patches) => {
|
|
|
218
220
|
.sort(([a], [b]) => Number(a) - Number(b))
|
|
219
221
|
.forEach(([rowIndex, rowData]) => {
|
|
220
222
|
if (rowData?.values) {
|
|
221
|
-
const rowDataArray = getRowDataFromSheet(ysheet, Number(rowIndex));
|
|
223
|
+
const rowDataArray = getRowDataFromSheet(ysheet, Number(rowIndex), yjs);
|
|
222
224
|
Object.entries(rowData.values)
|
|
223
225
|
.sort(([a], [b]) => Number(a) - Number(b))
|
|
224
226
|
.forEach(([columnIndex, cellData]) => {
|
|
@@ -234,7 +236,7 @@ export const addSheetDataPatches = (ySheetData, patches) => {
|
|
|
234
236
|
// [sheetId, rowIndex] - Remove entire row
|
|
235
237
|
if (path.length === 2) {
|
|
236
238
|
const [, rowIndex] = path;
|
|
237
|
-
const ysheet = getSheetFromYSheetData(ySheetData, sheetId);
|
|
239
|
+
const ysheet = getSheetFromYSheetData(ySheetData, sheetId, yjs);
|
|
238
240
|
removeRowData(ysheet, rowIndex);
|
|
239
241
|
}
|
|
240
242
|
// [sheetId] - Remove entire sheet
|
|
@@ -268,11 +270,12 @@ export const addSheetDataPatches = (ySheetData, patches) => {
|
|
|
268
270
|
}
|
|
269
271
|
flushPendingCellUpdates();
|
|
270
272
|
};
|
|
271
|
-
export const getSheetFromYSheetData = (ySheetData, sheetId) => {
|
|
273
|
+
export const getSheetFromYSheetData = (ySheetData, sheetId, yjsRuntime) => {
|
|
274
|
+
const yjs = resolveYjsRuntime(yjsRuntime);
|
|
272
275
|
const id = String(sheetId);
|
|
273
276
|
let sheet = ySheetData.get(id);
|
|
274
277
|
if (!sheet) {
|
|
275
|
-
sheet = new
|
|
278
|
+
sheet = new yjs.Array();
|
|
276
279
|
ySheetData.set(id, sheet);
|
|
277
280
|
}
|
|
278
281
|
return sheet;
|
|
@@ -281,7 +284,8 @@ export const deleteSheetFromYSheetData = (ySheetData, sheetId) => {
|
|
|
281
284
|
const id = String(sheetId);
|
|
282
285
|
ySheetData.delete(id);
|
|
283
286
|
};
|
|
284
|
-
export const getRowDataFromSheet = (ysheet, rowIndex) => {
|
|
287
|
+
export const getRowDataFromSheet = (ysheet, rowIndex, yjsRuntime) => {
|
|
288
|
+
const yjs = resolveYjsRuntime(yjsRuntime);
|
|
285
289
|
const index = Number(rowIndex);
|
|
286
290
|
if (index < 0) {
|
|
287
291
|
throw new Error("Row index cannot be negative");
|
|
@@ -292,8 +296,8 @@ export const getRowDataFromSheet = (ysheet, rowIndex) => {
|
|
|
292
296
|
ysheet.insert(ysheet.length, padding);
|
|
293
297
|
ysheet.insert(index, [null]); // Insert null first
|
|
294
298
|
// Create new row data
|
|
295
|
-
const newRowData = new
|
|
296
|
-
newRowData.set("values", new
|
|
299
|
+
const newRowData = new yjs.Map();
|
|
300
|
+
newRowData.set("values", new yjs.Array());
|
|
297
301
|
// Replace the null
|
|
298
302
|
ysheet.insert(index, [newRowData]);
|
|
299
303
|
ysheet.delete(index + 1, 1);
|
|
@@ -311,8 +315,8 @@ export const getRowDataFromSheet = (ysheet, rowIndex) => {
|
|
|
311
315
|
let rowData = ysheet.get(index);
|
|
312
316
|
if (!rowData || !rowData.get("values")) {
|
|
313
317
|
// Create new row data if it doesn't exist or is incomplete
|
|
314
|
-
const newRowData = new
|
|
315
|
-
newRowData.set("values", new
|
|
318
|
+
const newRowData = new yjs.Map();
|
|
319
|
+
newRowData.set("values", new yjs.Array());
|
|
316
320
|
// Replace the existing item
|
|
317
321
|
ysheet.insert(index, [newRowData]);
|
|
318
322
|
ysheet.delete(index + 1, 1);
|
package/dist/esm/index.d.ts
CHANGED
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
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;AACxB,cAAc,eAAe,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../../helpers.ts","../../index.ts","../../observables.ts","../../types.ts","../../use-yspreadsheet-v2.ts","../../use-yspreadsheet.ts","../../vitest.config.ts"],"version":"5.8.3"}
|
|
1
|
+
{"root":["../../helpers.ts","../../index.ts","../../observables.ts","../../types.ts","../../use-yspreadsheet-v2.ts","../../use-yspreadsheet.ts","../../vitest.config.ts","../../yjs-runtime.ts"],"version":"5.8.3"}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,6 +1,44 @@
|
|
|
1
1
|
import type { Patch } from "immer";
|
|
2
2
|
import type { RecalcCellCoordinate } from "@rowsncolumns/spreadsheet-state";
|
|
3
3
|
import type { CellData } from "@rowsncolumns/spreadsheet";
|
|
4
|
+
import type * as Y from "yjs";
|
|
5
|
+
/**
|
|
6
|
+
* The Yjs members y-spreadsheet needs as runtime values: the shared-type
|
|
7
|
+
* constructors it instantiates and `instanceof`-checks, and the update
|
|
8
|
+
* functions `useYSpreadsheet` calls on the document. The package does not
|
|
9
|
+
* import a Yjs implementation: pass the namespace of the one that created
|
|
10
|
+
* `doc` (`import * as Y from "yjs"`, or a yjs-13-compatible layer over `@y/y`
|
|
11
|
+
* 14) so the types the hooks and helpers create belong to the same
|
|
12
|
+
* implementation as the document and their `instanceof` checks see that
|
|
13
|
+
* implementation's classes, or register it once with `setDefaultYjsRuntime`.
|
|
14
|
+
* The members are typed against yjs 13 (an optional peer, used for types
|
|
15
|
+
* only), so another implementation is passed with a cast.
|
|
16
|
+
*/
|
|
17
|
+
export type YjsRuntime = {
|
|
18
|
+
Map: typeof Y.Map;
|
|
19
|
+
Array: typeof Y.Array;
|
|
20
|
+
YArrayEvent: typeof Y.YArrayEvent;
|
|
21
|
+
Doc: typeof Y.Doc;
|
|
22
|
+
applyUpdate: typeof Y.applyUpdate;
|
|
23
|
+
diffUpdate: typeof Y.diffUpdate;
|
|
24
|
+
encodeStateAsUpdate: typeof Y.encodeStateAsUpdate;
|
|
25
|
+
encodeStateVector: typeof Y.encodeStateVector;
|
|
26
|
+
};
|
|
27
|
+
/** The awareness surface the hooks use (y-protocols and @y/protocols both satisfy it). */
|
|
28
|
+
export type AwarenessLike = {
|
|
29
|
+
getStates(): Map<number, Record<string, any>>;
|
|
30
|
+
on(event: "change", callback: (...args: any[]) => void): void;
|
|
31
|
+
off(event: "change", callback: (...args: any[]) => void): void;
|
|
32
|
+
setLocalState(state: Record<string, any> | null): void;
|
|
33
|
+
setLocalStateField(field: string, value: any): void;
|
|
34
|
+
};
|
|
35
|
+
/** A collaboration provider as the hooks see it: an optional awareness plus sync/status events. */
|
|
36
|
+
export type CollabProviderLike = {
|
|
37
|
+
awareness?: AwarenessLike | null;
|
|
38
|
+
synced?: boolean;
|
|
39
|
+
on?(event: string, callback: (...args: any[]) => void): void;
|
|
40
|
+
off?(event: string, callback: (...args: any[]) => void): void;
|
|
41
|
+
};
|
|
4
42
|
export type PatchDocument<T = Patch> = {
|
|
5
43
|
userId: string | number;
|
|
6
44
|
patches: T[];
|
package/dist/esm/types.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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;AAC1D,OAAO,KAAK,KAAK,CAAC,MAAM,KAAK,CAAC;AAE9B;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC;IAClC,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC;IAChC,mBAAmB,EAAE,OAAO,CAAC,CAAC,mBAAmB,CAAC;IAClD,iBAAiB,EAAE,OAAO,CAAC,CAAC,iBAAiB,CAAC;CAC/C,CAAC;AAEF,0FAA0F;AAC1F,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9C,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC9D,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC/D,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACvD,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;CACrD,CAAC;AAEF,mGAAmG;AACnG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7D,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CAC/D,CAAC;AAEF,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"}
|
|
@@ -4,8 +4,8 @@ import type { CellInterface, SelectionArea } from "@rowsncolumns/grid";
|
|
|
4
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
5
|
import { type CalculateNowOptions, type CalculationOperation, type CellXfs, type HistoryType, type SheetData, type SharedStrings, type SpreadsheetPatch } from "@rowsncolumns/spreadsheet-state";
|
|
6
6
|
import type { Patch } from "immer";
|
|
7
|
-
import type
|
|
8
|
-
import
|
|
7
|
+
import type * as Y from "yjs";
|
|
8
|
+
import type { CollabProviderLike, YjsRuntime } from "./types";
|
|
9
9
|
export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject> = {
|
|
10
10
|
/**
|
|
11
11
|
* Scopes awareness updates to a single document.
|
|
@@ -56,8 +56,15 @@ export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extend
|
|
|
56
56
|
* needed so agents touching A1:E10 don't appear to be sitting on A1.
|
|
57
57
|
*/
|
|
58
58
|
selections?: SelectionArea[];
|
|
59
|
-
provider?: HocuspocusProvider |
|
|
59
|
+
provider?: HocuspocusProvider | CollabProviderLike | any;
|
|
60
60
|
doc: Y.Doc;
|
|
61
|
+
/**
|
|
62
|
+
* The Yjs implementation `doc` belongs to (its shared-type constructors and
|
|
63
|
+
* event classes): the namespace that created `doc`, e.g. `import * as Y
|
|
64
|
+
* from "yjs"`. Falls back to the runtime registered with
|
|
65
|
+
* `setDefaultYjsRuntime`; with neither, the hook throws (see `YjsRuntime`).
|
|
66
|
+
*/
|
|
67
|
+
yjs?: YjsRuntime;
|
|
61
68
|
calculateNow(options?: CalculateNowOptions): Promise<void>;
|
|
62
69
|
initialSheets: S[];
|
|
63
70
|
/**
|
|
@@ -154,7 +161,7 @@ export type UseYSpreadsheetPropsV2<T extends CellData, S extends Sheet, C extend
|
|
|
154
161
|
};
|
|
155
162
|
export type YRowData = Y.Map<Y.Array<CellData | null>>;
|
|
156
163
|
export type YSheetData = Y.Array<YRowData | null>;
|
|
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>) => {
|
|
164
|
+
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, yjs: yjsRuntime, useV3, sheetDataVersion, onMigrationComplete, deleteV2AfterMigration, skipInitialSync, supportLegacySharedStringsArray, }: UseYSpreadsheetPropsV2<T, S, C, O>) => {
|
|
158
165
|
synced: boolean;
|
|
159
166
|
users: Collaborator[];
|
|
160
167
|
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":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAEL,UAAU,EACV,KAAK,QAAQ,EAEb,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,SAAS,EACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACtB,MAAM,iCAAiC,CAAC;AASzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAInC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"use-yspreadsheet-v2.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet-v2.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,14 @@ import { getCellUserEnteredValue, getExtendedValueFormula, isAFormula, isNil, so
|
|
|
3
3
|
import { useIsomorphicLayoutEffect } from "@rowsncolumns/ui";
|
|
4
4
|
import { useCallback, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { flushSync } from "react-dom";
|
|
6
|
-
import * as Y from "yjs";
|
|
7
6
|
import { addSheetDataPatches, addSheetDataPatchesV3, applyMapPatches, createCellKeyV3, filterErrorCellPatches, getCellDataFromYSheetData, mergeErrorEffectiveValueIntoCellData, processSheetDataEvents, shouldPersistErrorCellPatch, processSheetDataEventsV3, sheetDataV2ToV3, sheetDataV3ToV2, updateArrayType, validateSheets, } from "./helpers";
|
|
7
|
+
import { resolveYjsRuntime } from "./yjs-runtime";
|
|
8
8
|
/**
|
|
9
9
|
* Convert Y.js events to SheetDataEvent format for incremental processing
|
|
10
10
|
*/
|
|
11
|
-
const convertToSheetDataEvents = (events) => {
|
|
11
|
+
const convertToSheetDataEvents = (events, yjs) => {
|
|
12
12
|
return events.map((event) => {
|
|
13
|
-
const isYArrayEvent = event instanceof
|
|
13
|
+
const isYArrayEvent = event instanceof yjs.YArrayEvent;
|
|
14
14
|
return {
|
|
15
15
|
path: event.path,
|
|
16
16
|
delta: isYArrayEvent
|
|
@@ -52,7 +52,8 @@ 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, canWrite = true, 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, yjs: yjsRuntime, useV3 = false, sheetDataVersion = "v2", onMigrationComplete, deleteV2AfterMigration = false, skipInitialSync = false, supportLegacySharedStringsArray = false, }) => {
|
|
56
|
+
const yjs = resolveYjsRuntime(yjsRuntime);
|
|
56
57
|
const [synced, setSynced] = useState(false);
|
|
57
58
|
const [users, setUsers] = useState([]);
|
|
58
59
|
const [isLeader, setIsLeader] = useState(false);
|
|
@@ -488,7 +489,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
488
489
|
const origin = events?.[0]?.transaction?.origin;
|
|
489
490
|
if (origin !== "local") {
|
|
490
491
|
// Convert Y.js events to SheetDataEvent format and apply incremental updates
|
|
491
|
-
const sheetDataEvents = convertToSheetDataEvents(events);
|
|
492
|
+
const sheetDataEvents = convertToSheetDataEvents(events, yjs);
|
|
492
493
|
onChangeSheetData((prevSheetData) => {
|
|
493
494
|
const result = processSheetDataEvents(sheetDataEvents, prevSheetData, ySheetDataV2);
|
|
494
495
|
// Fall back to full serialization only if incremental update fails
|
|
@@ -551,7 +552,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
551
552
|
const subs = [];
|
|
552
553
|
for (const [mappingKey, [ydoc, callback]] of documentMap.entries()) {
|
|
553
554
|
// Only observe Arrays (shared strings Map is handled separately if needed)
|
|
554
|
-
if (ydoc instanceof
|
|
555
|
+
if (ydoc instanceof yjs.Array) {
|
|
555
556
|
const subscription = createDeepObservable(ydoc).subscribe((events) => {
|
|
556
557
|
for (const event of events) {
|
|
557
558
|
if (event.transaction.origin !== "local") {
|
|
@@ -567,7 +568,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
567
568
|
});
|
|
568
569
|
subs.push(subscription);
|
|
569
570
|
}
|
|
570
|
-
else if (ydoc instanceof
|
|
571
|
+
else if (ydoc instanceof yjs.Map && mappingKey === "sharedStrings") {
|
|
571
572
|
// Handle shared strings Map observation
|
|
572
573
|
const callback_map = (event) => {
|
|
573
574
|
if (event.transaction.origin !== "local") {
|
|
@@ -671,7 +672,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
671
672
|
addSheetDataPatchesV3(ySheetDataV3, persistableErrorCellPatches);
|
|
672
673
|
}
|
|
673
674
|
else {
|
|
674
|
-
addSheetDataPatches(ySheetDataV2, persistableErrorCellPatches);
|
|
675
|
+
addSheetDataPatches(ySheetDataV2, persistableErrorCellPatches, yjs);
|
|
675
676
|
}
|
|
676
677
|
}, origin);
|
|
677
678
|
}
|
|
@@ -693,7 +694,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
693
694
|
addSheetDataPatchesV3(ySheetDataV3, patches);
|
|
694
695
|
}
|
|
695
696
|
else {
|
|
696
|
-
addSheetDataPatches(ySheetDataV2, patches);
|
|
697
|
+
addSheetDataPatches(ySheetDataV2, patches, yjs);
|
|
697
698
|
}
|
|
698
699
|
}
|
|
699
700
|
if (patch.cellXfs) {
|
|
@@ -704,10 +705,10 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
704
705
|
if (patch?.[mappingKey]) {
|
|
705
706
|
const patches = patch[mappingKey]?.[patchKey];
|
|
706
707
|
// Handle shared strings Map (always use Map now)
|
|
707
|
-
if (mappingKey === "sharedStrings" && ydoc instanceof
|
|
708
|
+
if (mappingKey === "sharedStrings" && ydoc instanceof yjs.Map) {
|
|
708
709
|
applyMapPatches(ydoc, patches);
|
|
709
710
|
}
|
|
710
|
-
else if (ydoc instanceof
|
|
711
|
+
else if (ydoc instanceof yjs.Array) {
|
|
711
712
|
// Check if we are updating sheets
|
|
712
713
|
if (mappingKey === "sheets" && ydoc.length === 0) {
|
|
713
714
|
// Add initial sheets
|
|
@@ -737,6 +738,7 @@ export const useYSpreadsheetV2 = ({ onChangeSheetData, onChangeSheets, onChangeT
|
|
|
737
738
|
onAfterBroadcastPatch,
|
|
738
739
|
documentMap,
|
|
739
740
|
yRecalcCells,
|
|
741
|
+
yjs,
|
|
740
742
|
doc,
|
|
741
743
|
userId,
|
|
742
744
|
yDisableRecalc,
|
|
@@ -3,15 +3,21 @@ import type { CellInterface } from "@rowsncolumns/grid";
|
|
|
3
3
|
import type { CellData, Collaborator, ConditionalFormatRule, DataValidationRuleRecord, EmbeddedChart, EmbeddedObject, NamedRange, ProtectedRange, Sheet, TableView } from "@rowsncolumns/spreadsheet";
|
|
4
4
|
import type { CalculateNowOptions, CalculationOperation, HistoryType, SheetData, SpreadsheetPatch } from "@rowsncolumns/spreadsheet-state";
|
|
5
5
|
import type { Patch } from "immer";
|
|
6
|
-
import type { WebsocketProvider } from "y-websocket";
|
|
7
6
|
import type * as Y from "yjs";
|
|
7
|
+
import type { CollabProviderLike, YjsRuntime } from "./types";
|
|
8
8
|
export type useYSpreadsheetProps<T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject> = {
|
|
9
9
|
userId: string | number;
|
|
10
10
|
title: string;
|
|
11
11
|
sheetId: number;
|
|
12
12
|
activeCell?: CellInterface;
|
|
13
|
-
provider?: HocuspocusProvider |
|
|
13
|
+
provider?: HocuspocusProvider | CollabProviderLike | any;
|
|
14
14
|
doc: Y.Doc;
|
|
15
|
+
/**
|
|
16
|
+
* The Yjs implementation `doc` belongs to, e.g. `import * as Y from "yjs"`.
|
|
17
|
+
* Falls back to the runtime registered with `setDefaultYjsRuntime`; with
|
|
18
|
+
* neither, the hook throws (see `YjsRuntime`).
|
|
19
|
+
*/
|
|
20
|
+
yjs?: YjsRuntime;
|
|
15
21
|
calculateNow(options?: CalculateNowOptions): void;
|
|
16
22
|
onChangeSheetData: React.Dispatch<React.SetStateAction<SheetData<T>>>;
|
|
17
23
|
onChangeTables: React.Dispatch<React.SetStateAction<TableView[]>>;
|
|
@@ -31,7 +37,7 @@ export type useYSpreadsheetProps<T extends CellData, S extends Sheet, C extends
|
|
|
31
37
|
* Does not load initial data
|
|
32
38
|
* @returns
|
|
33
39
|
*/
|
|
34
|
-
export declare const useYSpreadsheet: <T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject>({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeNamedRanges, onChangeProtectedRanges, onError, enqueueCalculation, calculateNow, userId, title, sheetId, activeCell, doc, provider, }: useYSpreadsheetProps<T, S, C, O>) => {
|
|
40
|
+
export declare const useYSpreadsheet: <T extends CellData, S extends Sheet, C extends EmbeddedChart, O extends EmbeddedObject>({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeNamedRanges, onChangeProtectedRanges, onError, enqueueCalculation, calculateNow, userId, title, sheetId, activeCell, doc, provider, yjs: yjsRuntime, }: useYSpreadsheetProps<T, S, C, O>) => {
|
|
35
41
|
onBroadcastPatch: (patches: [patch: SpreadsheetPatch<Patch>, type?: HistoryType | undefined][]) => void;
|
|
36
42
|
users: Collaborator[];
|
|
37
43
|
synced: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-yspreadsheet.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,UAAU,EACV,cAAc,EACd,KAAK,EACL,SAAS,EACV,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EAEX,SAAS,EACT,gBAAgB,EACjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAInC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"use-yspreadsheet.d.ts","sourceRoot":"","sources":["../../use-yspreadsheet.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,20 +2,21 @@ import { scheduleNormalPriorityCallback, useIsomorphicLayoutEffect, } from "@row
|
|
|
2
2
|
import { applyPatches } from "immer";
|
|
3
3
|
import uniqBy from "lodash/uniqBy";
|
|
4
4
|
import { useCallback, useMemo, useRef, useState } from "react";
|
|
5
|
-
import {
|
|
6
|
-
const getStateVector = (doc) => encodeStateVector(doc);
|
|
5
|
+
import { resolveYjsRuntime } from "./yjs-runtime";
|
|
6
|
+
const getStateVector = (doc, yjs) => yjs.encodeStateVector(doc);
|
|
7
7
|
// Function to get updates between two state vectors
|
|
8
|
-
const getUpdatesBetween = (doc, stateVector1, stateVector2) => {
|
|
9
|
-
const diff = encodeStateAsUpdate(doc, stateVector1);
|
|
10
|
-
const newDiff = encodeStateAsUpdate(doc, stateVector2);
|
|
11
|
-
return diffUpdate(diff, newDiff);
|
|
8
|
+
const getUpdatesBetween = (doc, stateVector1, stateVector2, yjs) => {
|
|
9
|
+
const diff = yjs.encodeStateAsUpdate(doc, stateVector1);
|
|
10
|
+
const newDiff = yjs.encodeStateAsUpdate(doc, stateVector2);
|
|
11
|
+
return yjs.diffUpdate(diff, newDiff);
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* Connects to a Y server and picks up the most recent change
|
|
15
15
|
* Does not load initial data
|
|
16
16
|
* @returns
|
|
17
17
|
*/
|
|
18
|
-
export const useYSpreadsheet = ({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeNamedRanges, onChangeProtectedRanges, onError, enqueueCalculation, calculateNow, userId, title, sheetId, activeCell, doc, provider, }) => {
|
|
18
|
+
export const useYSpreadsheet = ({ onChangeSheetData, onChangeSheets, onChangeTables, onChangeCharts, onChangeEmbeds, onChangeConditionalFormats, onChangeDataValidations, onChangeNamedRanges, onChangeProtectedRanges, onError, enqueueCalculation, calculateNow, userId, title, sheetId, activeCell, doc, provider, yjs: yjsRuntime, }) => {
|
|
19
|
+
const yjs = resolveYjsRuntime(yjsRuntime);
|
|
19
20
|
const [users, setUsers] = useState([]);
|
|
20
21
|
const [synced, setSynced] = useState(false);
|
|
21
22
|
const previousStateVectorRef = useRef(undefined);
|
|
@@ -89,10 +90,10 @@ export const useYSpreadsheet = ({ onChangeSheetData, onChangeSheets, onChangeTab
|
|
|
89
90
|
let syncedDoc = doc;
|
|
90
91
|
if (previousStateVectorRef.current) {
|
|
91
92
|
// Capture the current state vector on subsequent syncs
|
|
92
|
-
currentStateVectorRef.current = getStateVector(doc);
|
|
93
|
-
const updates = getUpdatesBetween(doc, previousStateVectorRef.current, currentStateVectorRef.current);
|
|
94
|
-
const newDoc = new Doc({ gc: true });
|
|
95
|
-
applyUpdate(newDoc, updates);
|
|
93
|
+
currentStateVectorRef.current = getStateVector(doc, yjs);
|
|
94
|
+
const updates = getUpdatesBetween(doc, previousStateVectorRef.current, currentStateVectorRef.current, yjs);
|
|
95
|
+
const newDoc = new yjs.Doc({ gc: true });
|
|
96
|
+
yjs.applyUpdate(newDoc, updates);
|
|
96
97
|
syncedDoc = newDoc;
|
|
97
98
|
previousStateVectorRef.current = currentStateVectorRef.current;
|
|
98
99
|
}
|
|
@@ -137,7 +138,7 @@ export const useYSpreadsheet = ({ onChangeSheetData, onChangeSheets, onChangeTab
|
|
|
137
138
|
});
|
|
138
139
|
// Set synced
|
|
139
140
|
setSynced(true);
|
|
140
|
-
}, [calculateNow, docMap, onError, doc]);
|
|
141
|
+
}, [calculateNow, docMap, onError, doc, yjs]);
|
|
141
142
|
// Sync state
|
|
142
143
|
if (provider?.synced && !synced) {
|
|
143
144
|
onSynced();
|
|
@@ -147,7 +148,7 @@ export const useYSpreadsheet = ({ onChangeSheetData, onChangeSheets, onChangeTab
|
|
|
147
148
|
provider?.on("synced", onSynced);
|
|
148
149
|
const onConnectionStatusChange = ({ status }) => {
|
|
149
150
|
if (status === "disconnected") {
|
|
150
|
-
previousStateVectorRef.current = getStateVector(doc);
|
|
151
|
+
previousStateVectorRef.current = getStateVector(doc, yjs);
|
|
151
152
|
}
|
|
152
153
|
};
|
|
153
154
|
provider?.on("status", onConnectionStatusChange);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../../vitest.config.ts"],"names":[],"mappings":";AAEA,
|
|
1
|
+
{"version":3,"file":"vitest.config.d.ts","sourceRoot":"","sources":["../../vitest.config.ts"],"names":[],"mappings":";AAEA,wBAuBG"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { YjsRuntime } from "./types";
|
|
2
|
+
/** Registers (or, with `undefined`, clears) the runtime used when a call passes none. */
|
|
3
|
+
export declare const setDefaultYjsRuntime: (runtime: YjsRuntime | undefined) => void;
|
|
4
|
+
/** The runtime a call works with: the one it was given, else the registered default. */
|
|
5
|
+
export declare const resolveYjsRuntime: (runtime?: YjsRuntime) => YjsRuntime;
|
|
6
|
+
//# sourceMappingURL=yjs-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yjs-runtime.d.ts","sourceRoot":"","sources":["../../yjs-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAW1C,yFAAyF;AACzF,eAAO,MAAM,oBAAoB,GAAI,SAAS,UAAU,GAAG,SAAS,KAAG,IAEtE,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,GAAI,UAAU,UAAU,KAAG,UAQxD,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* y-spreadsheet does not import a Yjs implementation: every helper and hook
|
|
3
|
+
* takes the namespace of the implementation the document belongs to (`yjs`,
|
|
4
|
+
* or a yjs-13-compatible layer over `@y/y` 14). A host that always works with
|
|
5
|
+
* one implementation can register it once here instead of passing it on every
|
|
6
|
+
* call; a runtime passed to a call wins over the registered one.
|
|
7
|
+
*/
|
|
8
|
+
let defaultYjsRuntime;
|
|
9
|
+
/** Registers (or, with `undefined`, clears) the runtime used when a call passes none. */
|
|
10
|
+
export const setDefaultYjsRuntime = (runtime) => {
|
|
11
|
+
defaultYjsRuntime = runtime;
|
|
12
|
+
};
|
|
13
|
+
/** The runtime a call works with: the one it was given, else the registered default. */
|
|
14
|
+
export const resolveYjsRuntime = (runtime) => {
|
|
15
|
+
const resolved = runtime ?? defaultYjsRuntime;
|
|
16
|
+
if (!resolved) {
|
|
17
|
+
throw new Error("@rowsncolumns/y-spreadsheet: no Yjs runtime. Pass `yjs` (the namespace of the Yjs implementation the document belongs to, e.g. `import * as Y from \"yjs\"`) or register one with setDefaultYjsRuntime(Y). The package does not import yjs itself.");
|
|
18
|
+
}
|
|
19
|
+
return resolved;
|
|
20
|
+
};
|