added utilities to make and recover snapshots

This commit is contained in:
Kevin Jahns
2019-01-29 00:54:58 +01:00
parent 77e479c03b
commit 3a0694c35c
23 changed files with 337 additions and 109 deletions

View File

@@ -40,24 +40,22 @@ export const readUsersStateChange = (decoder, y) => {
const userID = decoding.readVarUint(decoder)
const clock = decoding.readVarUint(decoder)
const state = JSON.parse(decoding.readVarString(decoder))
if (userID !== y.userID) {
const uClock = y.awarenessClock.get(userID) || 0
y.awarenessClock.set(userID, clock)
if (state === null) {
// only write if clock increases. cannot overwrite
if (y.awareness.has(userID) && uClock < clock) {
y.awareness.delete(userID)
removed.push(userID)
}
} else if (uClock <= clock) { // allow to overwrite (e.g. when client was on, then offline)
if (y.awareness.has(userID)) {
updated.push(userID)
} else {
added.push(userID)
}
y.awareness.set(userID, state)
y.awarenessClock.set(userID, clock)
const uClock = y.awarenessClock.get(userID) || 0
y.awarenessClock.set(userID, clock)
if (state === null) {
// only write if clock increases. cannot overwrite
if (y.awareness.has(userID) && uClock < clock) {
y.awareness.delete(userID)
removed.push(userID)
}
} else if (uClock <= clock) { // allow to overwrite (e.g. when client was on, then offline)
if (y.awareness.has(userID)) {
updated.push(userID)
} else {
added.push(userID)
}
y.awareness.set(userID, state)
y.awarenessClock.set(userID, clock)
}
}
if (added.length > 0 || updated.length > 0 || removed.length > 0) {

View File

@@ -1,5 +1,4 @@
import * as encoding from '../lib/encoding.js'
import * as decoding from '../lib/decoding.js'
import { Y } from '../utils/Y.js' // eslint-disable-line
@@ -10,24 +9,38 @@ import { writeStateMap, readStateMap } from '../utils/StateStore.js'
* @typedef {Object} HistorySnapshot
* @property {DeleteStore} HistorySnapshot.ds
* @property {Map<number,number>} HistorySnapshot.sm
* @property {Map<number,string>} HistorySnapshot.userMap
*/
/**
* @param {encoding.Encoder} encoder
* @param {Y} y
* @param {Map<number, string>} userMap
*/
export const writeHistorySnapshot = (encoder, y) => {
export const writeHistorySnapshot = (encoder, y, userMap) => {
writeDeleteStore(encoder, y.ds)
writeStateMap(encoder, y.ss.state)
encoding.writeVarUint(encoder, userMap.size)
userMap.forEach((accountname, userid) => {
encoding.writeVarUint(encoder, userid)
encoding.writeVarString(encoder, accountname)
})
}
/**
*
*
* @param {decoding.Decoder} decoder
* @return {HistorySnapshot}
*/
export const readHistorySnapshot = (decoder) => {
export const readHistorySnapshot = decoder => {
const ds = readFreshDeleteStore(decoder)
const sm = readStateMap(decoder)
return { ds, sm }
}
const size = decoding.readVarUint(decoder)
const userMap = new Map()
for (let i = 0; i < size; i++) {
const userid = decoding.readVarUint(decoder)
const accountname = decoding.readVarString(decoder)
userMap.set(userid, accountname)
}
return { ds, sm, userMap }
}