I’d like to do the following:
- Load a document
- Encode the document as a single update
- Send the update over http to a client, when requested
What’s not working is loading the update at the other end. I originally thought this might be the browser, fetch API or http causing the trouble but after writing a simple unit test (see below) I realise it’s unclear how to encode it for transport.
I’ve tried the following:
- Using to/from Uint8 function to convert to base64 before sending (when simply recieving the data as a ArrayBuffer didn’t work)
- Encoding according to the below example code
- Only decoding (no encoding) on the assumption the encodeStateAsUpdate already does some encoding
- Using the example sync protocol from the ws server code on github
- Combinations of all 1, 2 and 3
I get either of the following everytime:
-
TypeError: contentRefs[(info & binary__namespace.BITS5)] is not a function
. -
Error: Integer out of range
. - Works without exception (in the case of base64 conversion) but applyUpdate does not work for nested maps on the document I’m trying to send.
So, what I’m wondering is - how am I meant to use encodeStateAsUpdate
when I would like to apply the update remotely? The examples mention, applying it remotely but there doesn’t appear to be any actual examples of how to achieve this over websockets or http (apologies if I’ve missed it).
Can anyone tell me where I’ve gone wrong here?
Here’s some example code of how I was testing encoding/decoding before trying over a network (it did not work):
import * as Y from 'yjs';
import fetch from 'node-fetch';
import * as decoding from 'lib0/decoding';
import { encoding } from 'lib0';
import { writeUpdate } from 'y-protocols/sync';
const encodeDocumentState = (documentToSend: Y.Doc) => {
const update = Y.encodeStateAsUpdate(documentToSend);
const encoder = encoding.createEncoder();
writeUpdate(encoder, update);
return encoding.toUint8Array(encoder);
};
const decodeDocumentState = (response: ArrayBuffer) => {
const decoder = decoding.createDecoder(new Uint8Array(response));
return decoding.readVarUint8Array(decoder);
};
// build doc one
const doc = new Y.Doc();
const board = doc.getMap('board');
board.set('foo', 'bar');
const encodedState = encodeDocumentState(doc);
const decodeState = decodeDocumentState(encodedState);
const doc2 = new Y.Doc();
Y.applyUpdate(doc2, decodeState); // this breaks. If I remove the encoding/decoding it doesn't. It doesn't work when I send data over http, regardless of whether I encode it or not.
console.log('applied doc output:', doc2.toJSON());