yjs/utils/ID.js
2018-11-27 14:59:24 +01:00

95 lines
2.4 KiB
JavaScript

/**
* @module utils
*/
import { getStructReference } from './structReferences.js'
import * as decoding from '../lib/decoding.js'
import * as encoding from '../lib/encoding.js'
export class ID {
constructor (user, clock) {
this.user = user // TODO: rename to client
this.clock = clock
}
clone () {
return new ID(this.user, this.clock)
}
equals (id) {
return id !== null && id.user === this.user && id.clock === this.clock
}
lessThan (id) {
if (id.constructor === ID) {
return this.user < id.user || (this.user === id.user && this.clock < id.clock)
} else {
return false
}
}
/**
* @param {encoding.Encoder} encoder
*/
encode (encoder) {
encoding.writeVarUint(encoder, this.user)
encoding.writeVarUint(encoder, this.clock)
}
}
export const createID = (user, clock) => new ID(user, clock)
export const RootFakeUserID = 0xFFFFFF
export class RootID {
constructor (name, typeConstructor) {
this.user = RootFakeUserID
this.name = name
this.type = getStructReference(typeConstructor)
}
equals (id) {
return id !== null && id.user === this.user && id.name === this.name && id.type === this.type
}
lessThan (id) {
if (id.constructor === RootID) {
return this.user < id.user || (this.user === id.user && (this.name < id.name || (this.name === id.name && this.type < id.type)))
} else {
return true
}
}
/**
* @param {encoding.Encoder} encoder
*/
encode (encoder) {
encoding.writeVarUint(encoder, this.user)
encoding.writeVarString(encoder, this.name)
encoding.writeVarUint(encoder, this.type)
}
}
/**
* Create a new root id.
*
* @example
* y.define('name', Y.Array) // name, and typeConstructor
*
* @param {string} name
* @param {Function} typeConstructor must be defined in structReferences
*/
export const createRootID = (name, typeConstructor) => new RootID(name, typeConstructor)
/**
* Read ID.
* * If first varUint read is 0xFFFFFF a RootID is returned.
* * Otherwise an ID is returned
*
* @param {decoding.Decoder} decoder
* @return {ID|RootID}
*/
export const decode = decoder => {
const user = decoding.readVarUint(decoder)
if (user === RootFakeUserID) {
// read property name and type id
const rid = createRootID(decoding.readVarString(decoder), null)
rid.type = decoding.readVarUint(decoder)
return rid
}
return createID(user, decoding.readVarUint(decoder))
}