@rowsncolumns/y-spreadsheet
v17.0.3
Published
[https://github.com/yjs/yjs](https://github.com/yjs/yjs)
Readme
Collaborative Spreadsheet with YJS
YJS provides a CRDT datastructure to collaborate between users
You will still need to save data in the database. YJS does not persist data in your custom MySQL or NoSQL databasesSetup
Run a yjs server locally
HOST=localhost PORT=1234 npx y-websocketimport { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";
import { useYSpreadsheet, type YjsRuntime } from "@rowsncolumns/y-spreadsheet";
import * as Y from "@y/y";
// WebsocketProvider: any collaboration provider for the @y/y 14 document
// (the hooks type it structurally, see `CollabProviderLike`).
// The package works on @y/y 14 nodes and imports no Yjs implementation: the
// host supplies its node operations. createMap / createArray / isMap /
// isArray must write and read each nested node with its Yjs 13 type reference
// (Map 1, Array 0) so Yjs 13, Yrs and pycrdt readers see maps and arrays.
const yjs: YjsRuntime = {
createMap, createArray, isMap, isArray,
getPathTo: Y.getPathTo,
Doc: Y.Doc,
applyUpdate: Y.applyUpdate,
diffUpdate: Y.diffUpdate,
encodeStateAsUpdate: Y.encodeStateAsUpdate,
encodeStateVector: Y.encodeStateVector,
};
const version = "v5";
const yDoc = new Y.Doc();
const yWebsocketProvider = new WebsocketProvider(
"ws://localhost:1234",
`y-spreadsheet-${version}`,
yDoc,
{
connect: true,
}
);
// Setup local state
const [sheets, onChangeSheets] = useState<Sheet[]>(mockSheets);
const [sheetData, onChangeSheetData] =
useState<SheetData<CellData>>(mockSheetData);
const [tables, onChangeTables] = useState<TableView[]>(mockTables);
// Setup spreadsheet hook
const { enqueueCalculation, activeSheetId, ... } = useSpreadsheetState({
onChangeHistory(patch, type) {
onBroadcastPatch(patch, type);
},
})
// Setup YJS
const { users, onBroadcastPatch } = useYSpreadsheet({
provider: yWebsocketProvider,
doc: yDoc,
// The host's node operations for yDoc (or register them once with
// setDefaultYjsRuntime(yjs)).
yjs,
onChangeSheetData,
onChangeSheets,
onChangeTables,
enqueueCalculation(operation) {
enqueueCalculation(operation);
},
sheetId: activeSheetId,
activeCell,
// User info
userId,
title: `User ${String(userId).slice(0, 5)}`,
});
return (
<CanvasGrid
userId={userId}
users={users}
>
)