Skip to content

Instantly share code, notes, and snippets.

@VldMrgnn
Last active September 23, 2024 19:38
Show Gist options
  • Save VldMrgnn/a32cbb2486df5b286dd679960cb61e1e to your computer and use it in GitHub Desktop.
Save VldMrgnn/a32cbb2486df5b286dd679960cb61e1e to your computer and use it in GitHub Desktop.
persist the starfx store on remote
let pyDoc = new Y.Doc();
let provider: IndexeddbPersistence;
let wsProvider: WebsocketProvider;
const pxSync = (email, perseed) => {
return resource(function* (provide) {
if (!email) {
return;
}
const currentEmail = pxMap.get("email");
const currentPerseed = pxMap.get("perseed");
if (email === currentEmail && perseed === currentPerseed) {
console.log("no change in the params, leaving the sync as is.");
return;
}
//params are changed //
pxMap.set("email", email);
pxMap.set("perseed", perseed);
wsProvider && wsProvider.disconnect();
provider && provider.destroy();
pyDoc = new Y.Doc();
provider = new IndexeddbPersistence(`${PERSISTOR_NAME}.sync`, pyDoc);
wsProvider = new WebsocketProvider(wsUrl, "starfx-persist", pyDoc, {
params: {
email,
perseed,
},
});
wsProvider.connect();
function* stopSync() {
yield* call(() => wsProvider.disconnect());
yield* call(() => provider.destroy());
}
provider.on("synced", () => {
wsProvider.awareness.setLocalStateField("synced", true);
wsProvider.awareness.setLocalStateField("syncedAt", Date.now());
});
wsProvider.on("status", (event) => {
console.log("WSPROVIDER", event.status); // logs "connected" or "disconnected"
});
pyDoc.on("afterTransaction", async (transaction, remote) => {
const once = pxMap.get("hydrate");
if (once) {
const persisted = remote.getMap("persistor");
const data = persisted.get("data");
if (data) {
const statePersisted = persisted.get("data");
const { email: persistedEmail, perseed: persistedPerseed } =
statePersisted["persistorGuardian"] || {};
// the current login/perseed
const crtEmail = await pxMap.get("email");
const crtPerseed = await pxMap.get("perseed");
if (crtEmail !== persistedEmail || crtPerseed !== persistedPerseed) {
return;
}
// CAN WE TRANSFER THE DATA TO THE MAIN THREAD?
self.postMessage({
type: "/rehydrate",
payload: JSON.stringify(statePersisted),
});
pxMap.set("hydrate", false);
}
return;
}
});
yield* provide(stopSync);
});
};
export async function onStarfxPersistMsg(sidWithoutPrefix: string) {
if (!isValidSession(sidWithoutPrefix)) {
return;
}
const { email, perseed } = await extractNextSession(sidWithoutPrefix);
const docName = await getDocName(sidWithoutPrefix, "/starfx-persist");
if (!docName) {
dev && console.log("[dev.] DocName not found");
return;
}
// we have a session but not logged //
if (!perseed && email) {
// The next State //
// On before login, prepare already the known preserved state
await hydrateYDoc(docName); // LOAD THE NEXT BEST SHOT//
return;
}
try {
const clientDoc = wsUtils.getYDoc(docName);
const newState = Y.encodeStateAsUpdate(clientDoc);
const newBase64 = fromUint8Array(newState);
// we will use the docName as the key for the redis hash
await rasydb2.hset(docName, ["persist", newBase64]);
dev &&
console.log(
`[dev.] Persisted Yjs update ${(newBase64.length / 1024 / 1024).toFixed(
2
)}MB for ${email} to redis ${docName}`
);
} catch (error) {
console.error("Error handling persist message:", error);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment