implemented frontend including separate message system; started to implement backend

This commit is contained in:
User
2026-03-10 14:48:48 +01:00
committed by Jannik Luboeinski
parent 4275cbd795
commit 78d5352a48
1058 changed files with 101527 additions and 1 deletions

21
yjs-poll/node_modules/y-protocols/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 Kevin Jahns <kevin.jahns@protonmail.com>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

78
yjs-poll/node_modules/y-protocols/README.md generated vendored Normal file
View File

@@ -0,0 +1,78 @@
# Yjs Protocols
> Binary encoding protocols for *syncing*, *awareness*, and *history information*
This API is unstable and subject to change.
## API
### Awareness Protocol
```js
import * as awarenessProtocol from 'y-protocols/awareness.js'
```
The Awareness protocol implements a simple network agnostic algorithm that
manages user status (who is online?) and propagate awareness information like
cursor location, username, or email address. Each client can update its own
local state and listen to state changes of remote clients.
Each client has an awareness state. Remote awareness are stored in a Map that
maps from remote client id to remote awareness state. An *awareness state* is an
increasing clock attached to a schemaless json object.
Whenever the client changes its local state, it increases the clock and
propagates its own awareness state to all peers. When a client receives a remote
awareness state, and overwrites the clients state if the received state is newer
than the local awareness state for that client. If the state is `null`, the
client is marked as offline. If a client doesn't receive updates from a remote
peer for 30 seconds, it marks the remote client as offline. Hence each client
must broadcast its own awareness state in a regular interval to make sure that
remote clients don't mark it as offline.
#### awarenessProtocol.Awareness Class
```js
const ydoc = new Y.Doc()
const awareness = new awarenessProtocol.Awareness(ydoc)
```
<dl>
<b><code>clientID:number</code></b>
<dd>A unique identifier that identifies this client.</dd>
<b><code>getLocalState():Object&lt;string,any&gt;|null</code></b>
<dd>Get the local awareness state.</dd>
<b><code>setLocalState(Object&lt;string,any&gt;|null)</code></b>
<dd>
Set/Update the local awareness state. Set `null` to mark the local client as
offline.
</dd>
<b><code>setLocalStateField(string, any)</code></b>
<dd>
Only update a single field on the local awareness object. Does not do
anything if the local state is not set.
</dd>
<b><code>getStates():Map&lt;number,Object&lt;string,any&gt;&gt;</code></b>
<dd>
Get all client awareness states (remote and local). Maps from clientID to
awareness state.
</dd>
<b><code>
on('change', ({ added: Array&lt;number&gt;, updated: Array&lt;number&gt;
removed: Array&lt;number&gt; }, [transactionOrigin:any]) => ..)
</code></b>
<dd>
Listen to remote and local state changes on the awareness instance.
</dd>
<b><code>
on('update', ({ added: Array&lt;number&gt;, updated: Array&lt;number&gt;
removed: Array&lt;number&gt; }, [transactionOrigin:any]) => ..)
</code></b>
<dd>
Listen to remote and local awareness changes on the awareness instance.
This event is called even when the awarenes state does not change.
</dd>
</dl>
### License
[The MIT License](./LICENSE) © Kevin Jahns

8
yjs-poll/node_modules/y-protocols/auth.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
export const messagePermissionDenied: 0;
export function writePermissionDenied(encoder: encoding.Encoder, reason: string): void;
export function readAuthMessage(decoder: decoding.Decoder, y: Y.Doc, permissionDeniedHandler: PermissionDeniedHandler): void;
export type PermissionDeniedHandler = (y: any, reason: string) => any;
import * as encoding from 'lib0/encoding';
import * as decoding from 'lib0/decoding';
import * as Y from 'yjs';
//# sourceMappingURL=auth.d.ts.map

1
yjs-poll/node_modules/y-protocols/auth.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["auth.js"],"names":[],"mappings":"AAKA,wCAAwC;AAMjC,+CAHI,SAAS,OAAO,UAChB,MAAM,QAKhB;AAcM,yCAJI,SAAS,OAAO,KAChB,EAAE,GAAG,2BACL,uBAAuB,QAMjC;0CAdU,GAAG,UACH,MAAM;0BAjBS,eAAe;0BACf,eAAe;mBAFtB,KAAK"}

33
yjs-poll/node_modules/y-protocols/auth.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
import * as Y from 'yjs' // eslint-disable-line
import * as encoding from 'lib0/encoding'
import * as decoding from 'lib0/decoding'
export const messagePermissionDenied = 0
/**
* @param {encoding.Encoder} encoder
* @param {string} reason
*/
export const writePermissionDenied = (encoder, reason) => {
encoding.writeVarUint(encoder, messagePermissionDenied)
encoding.writeVarString(encoder, reason)
}
/**
* @callback PermissionDeniedHandler
* @param {any} y
* @param {string} reason
*/
/**
*
* @param {decoding.Decoder} decoder
* @param {Y.Doc} y
* @param {PermissionDeniedHandler} permissionDeniedHandler
*/
export const readAuthMessage = (decoder, y, permissionDeniedHandler) => {
switch (decoding.readVarUint(decoder)) {
case messagePermissionDenied: permissionDeniedHandler(y, decoding.readVarString(decoder))
}
}

86
yjs-poll/node_modules/y-protocols/awareness.d.ts generated vendored Normal file
View File

@@ -0,0 +1,86 @@
export const outdatedTimeout: 30000;
/**
* @typedef {Object} MetaClientState
* @property {number} MetaClientState.clock
* @property {number} MetaClientState.lastUpdated unix timestamp
*/
/**
* The Awareness class implements a simple shared state protocol that can be used for non-persistent data like awareness information
* (cursor, username, status, ..). Each client can update its own local state and listen to state changes of
* remote clients. Every client may set a state of a remote peer to `null` to mark the client as offline.
*
* Each client is identified by a unique client id (something we borrow from `doc.clientID`). A client can override
* its own state by propagating a message with an increasing timestamp (`clock`). If such a message is received, it is
* applied if the known state of that client is older than the new state (`clock < newClock`). If a client thinks that
* a remote client is offline, it may propagate a message with
* `{ clock: currentClientClock, state: null, client: remoteClient }`. If such a
* message is received, and the known clock of that client equals the received clock, it will override the state with `null`.
*
* Before a client disconnects, it should propagate a `null` state with an updated clock.
*
* Awareness states must be updated every 30 seconds. Otherwise the Awareness instance will delete the client state.
*
* @extends {Observable<string>}
*/
export class Awareness extends Observable<string> {
/**
* @param {Y.Doc} doc
*/
constructor(doc: Y.Doc);
doc: Y.Doc;
/**
* @type {number}
*/
clientID: number;
/**
* Maps from client id to client state
* @type {Map<number, Object<string, any>>}
*/
states: Map<number, {
[x: string]: any;
}>;
/**
* @type {Map<number, MetaClientState>}
*/
meta: Map<number, MetaClientState>;
_checkInterval: any;
/**
* @return {Object<string,any>|null}
*/
getLocalState(): {
[x: string]: any;
} | null;
/**
* @param {Object<string,any>|null} state
*/
setLocalState(state: {
[x: string]: any;
} | null): void;
/**
* @param {string} field
* @param {any} value
*/
setLocalStateField(field: string, value: any): void;
/**
* @return {Map<number,Object<string,any>>}
*/
getStates(): Map<number, {
[x: string]: any;
}>;
}
export function removeAwarenessStates(awareness: Awareness, clients: Array<number>, origin: any): void;
export function encodeAwarenessUpdate(awareness: Awareness, clients: Array<number>, states?: Map<number, {
[x: string]: any;
}>): Uint8Array;
export function modifyAwarenessUpdate(update: Uint8Array, modify: (arg0: any) => any): Uint8Array;
export function applyAwarenessUpdate(awareness: Awareness, update: Uint8Array, origin: any): void;
export type MetaClientState = {
clock: number;
/**
* unix timestamp
*/
lastUpdated: number;
};
import { Observable } from 'lib0/observable';
import * as Y from 'yjs';
//# sourceMappingURL=awareness.d.ts.map

1
yjs-poll/node_modules/y-protocols/awareness.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["awareness.js"],"names":[],"mappings":"AAYA,oCAAoC;AAEpC;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH;IACE;;OAEG;IACH,iBAFW,EAAE,GAAG,EAyCf;IArCC,WAAc;IACd;;OAEG;IACH,UAFU,MAAM,CAEY;IAC5B;;;OAGG;IACH,QAFU,IAAI,MAAM;YAAS,MAAM,GAAE,GAAG;MAAE,CAEnB;IACvB;;OAEG;IACH,MAFU,IAAI,MAAM,EAAE,eAAe,CAAC,CAEjB;IACrB,oBAkBqC;IAcvC;;OAEG;IACH,iBAFY;YAAO,MAAM,GAAC,GAAG;QAAE,IAAI,CAIlC;IAED;;OAEG;IACH,qBAFW;YAAO,MAAM,GAAC,GAAG;QAAE,IAAI,QAoCjC;IAED;;;OAGG;IACH,0BAHW,MAAM,SACN,GAAG,QAUb;IAED;;OAEG;IACH,aAFY,IAAI,MAAM;YAAQ,MAAM,GAAC,GAAG;MAAE,CAIzC;CACF;AAUM,iDAJI,SAAS,WACT,MAAM,MAAM,CAAC,UACb,GAAG,QAsBb;AAOM,iDAJI,SAAS,WACT,MAAM,MAAM,CAAC;;KACZ,UAAU,CAerB;AAYM,8CAJI,UAAU,iBACD,GAAG,KAAE,GAAG,GAChB,UAAU,CAiBrB;AAOM,gDAJI,SAAS,UACT,UAAU,UACV,GAAG,QAwDb;;WAtRa,MAAM;;;;iBACN,MAAM;;2BATO,iBAAiB;mBAEzB,KAAK"}

295
yjs-poll/node_modules/y-protocols/awareness.js generated vendored Normal file
View File

@@ -0,0 +1,295 @@
/**
* @module awareness-protocol
*/
import * as encoding from 'lib0/encoding'
import * as decoding from 'lib0/decoding'
import * as time from 'lib0/time'
import * as math from 'lib0/math'
import { Observable } from 'lib0/observable'
import * as f from 'lib0/function'
import * as Y from 'yjs' // eslint-disable-line
export const outdatedTimeout = 30000
/**
* @typedef {Object} MetaClientState
* @property {number} MetaClientState.clock
* @property {number} MetaClientState.lastUpdated unix timestamp
*/
/**
* The Awareness class implements a simple shared state protocol that can be used for non-persistent data like awareness information
* (cursor, username, status, ..). Each client can update its own local state and listen to state changes of
* remote clients. Every client may set a state of a remote peer to `null` to mark the client as offline.
*
* Each client is identified by a unique client id (something we borrow from `doc.clientID`). A client can override
* its own state by propagating a message with an increasing timestamp (`clock`). If such a message is received, it is
* applied if the known state of that client is older than the new state (`clock < newClock`). If a client thinks that
* a remote client is offline, it may propagate a message with
* `{ clock: currentClientClock, state: null, client: remoteClient }`. If such a
* message is received, and the known clock of that client equals the received clock, it will override the state with `null`.
*
* Before a client disconnects, it should propagate a `null` state with an updated clock.
*
* Awareness states must be updated every 30 seconds. Otherwise the Awareness instance will delete the client state.
*
* @extends {Observable<string>}
*/
export class Awareness extends Observable {
/**
* @param {Y.Doc} doc
*/
constructor (doc) {
super()
this.doc = doc
/**
* @type {number}
*/
this.clientID = doc.clientID
/**
* Maps from client id to client state
* @type {Map<number, Object<string, any>>}
*/
this.states = new Map()
/**
* @type {Map<number, MetaClientState>}
*/
this.meta = new Map()
this._checkInterval = /** @type {any} */ (setInterval(() => {
const now = time.getUnixTime()
if (this.getLocalState() !== null && (outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ (this.meta.get(this.clientID)).lastUpdated)) {
// renew local clock
this.setLocalState(this.getLocalState())
}
/**
* @type {Array<number>}
*/
const remove = []
this.meta.forEach((meta, clientid) => {
if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) {
remove.push(clientid)
}
})
if (remove.length > 0) {
removeAwarenessStates(this, remove, 'timeout')
}
}, math.floor(outdatedTimeout / 10)))
doc.on('destroy', () => {
this.destroy()
})
this.setLocalState({})
}
destroy () {
this.emit('destroy', [this])
this.setLocalState(null)
super.destroy()
clearInterval(this._checkInterval)
}
/**
* @return {Object<string,any>|null}
*/
getLocalState () {
return this.states.get(this.clientID) || null
}
/**
* @param {Object<string,any>|null} state
*/
setLocalState (state) {
const clientID = this.clientID
const currLocalMeta = this.meta.get(clientID)
const clock = currLocalMeta === undefined ? 0 : currLocalMeta.clock + 1
const prevState = this.states.get(clientID)
if (state === null) {
this.states.delete(clientID)
} else {
this.states.set(clientID, state)
}
this.meta.set(clientID, {
clock,
lastUpdated: time.getUnixTime()
})
const added = []
const updated = []
const filteredUpdated = []
const removed = []
if (state === null) {
removed.push(clientID)
} else if (prevState == null) {
if (state != null) {
added.push(clientID)
}
} else {
updated.push(clientID)
if (!f.equalityDeep(prevState, state)) {
filteredUpdated.push(clientID)
}
}
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
this.emit('change', [{ added, updated: filteredUpdated, removed }, 'local'])
}
this.emit('update', [{ added, updated, removed }, 'local'])
}
/**
* @param {string} field
* @param {any} value
*/
setLocalStateField (field, value) {
const state = this.getLocalState()
if (state !== null) {
this.setLocalState({
...state,
[field]: value
})
}
}
/**
* @return {Map<number,Object<string,any>>}
*/
getStates () {
return this.states
}
}
/**
* Mark (remote) clients as inactive and remove them from the list of active peers.
* This change will be propagated to remote clients.
*
* @param {Awareness} awareness
* @param {Array<number>} clients
* @param {any} origin
*/
export const removeAwarenessStates = (awareness, clients, origin) => {
const removed = []
for (let i = 0; i < clients.length; i++) {
const clientID = clients[i]
if (awareness.states.has(clientID)) {
awareness.states.delete(clientID)
if (clientID === awareness.clientID) {
const curMeta = /** @type {MetaClientState} */ (awareness.meta.get(clientID))
awareness.meta.set(clientID, {
clock: curMeta.clock + 1,
lastUpdated: time.getUnixTime()
})
}
removed.push(clientID)
}
}
if (removed.length > 0) {
awareness.emit('change', [{ added: [], updated: [], removed }, origin])
awareness.emit('update', [{ added: [], updated: [], removed }, origin])
}
}
/**
* @param {Awareness} awareness
* @param {Array<number>} clients
* @return {Uint8Array}
*/
export const encodeAwarenessUpdate = (awareness, clients, states = awareness.states) => {
const len = clients.length
const encoder = encoding.createEncoder()
encoding.writeVarUint(encoder, len)
for (let i = 0; i < len; i++) {
const clientID = clients[i]
const state = states.get(clientID) || null
const clock = /** @type {MetaClientState} */ (awareness.meta.get(clientID)).clock
encoding.writeVarUint(encoder, clientID)
encoding.writeVarUint(encoder, clock)
encoding.writeVarString(encoder, JSON.stringify(state))
}
return encoding.toUint8Array(encoder)
}
/**
* Modify the content of an awareness update before re-encoding it to an awareness update.
*
* This might be useful when you have a central server that wants to ensure that clients
* cant hijack somebody elses identity.
*
* @param {Uint8Array} update
* @param {function(any):any} modify
* @return {Uint8Array}
*/
export const modifyAwarenessUpdate = (update, modify) => {
const decoder = decoding.createDecoder(update)
const encoder = encoding.createEncoder()
const len = decoding.readVarUint(decoder)
encoding.writeVarUint(encoder, len)
for (let i = 0; i < len; i++) {
const clientID = decoding.readVarUint(decoder)
const clock = decoding.readVarUint(decoder)
const state = JSON.parse(decoding.readVarString(decoder))
const modifiedState = modify(state)
encoding.writeVarUint(encoder, clientID)
encoding.writeVarUint(encoder, clock)
encoding.writeVarString(encoder, JSON.stringify(modifiedState))
}
return encoding.toUint8Array(encoder)
}
/**
* @param {Awareness} awareness
* @param {Uint8Array} update
* @param {any} origin This will be added to the emitted change event
*/
export const applyAwarenessUpdate = (awareness, update, origin) => {
const decoder = decoding.createDecoder(update)
const timestamp = time.getUnixTime()
const added = []
const updated = []
const filteredUpdated = []
const removed = []
const len = decoding.readVarUint(decoder)
for (let i = 0; i < len; i++) {
const clientID = decoding.readVarUint(decoder)
let clock = decoding.readVarUint(decoder)
const state = JSON.parse(decoding.readVarString(decoder))
const clientMeta = awareness.meta.get(clientID)
const prevState = awareness.states.get(clientID)
const currClock = clientMeta === undefined ? 0 : clientMeta.clock
if (currClock < clock || (currClock === clock && state === null && awareness.states.has(clientID))) {
if (state === null) {
// never let a remote client remove this local state
if (clientID === awareness.clientID && awareness.getLocalState() != null) {
// remote client removed the local state. Do not remote state. Broadcast a message indicating
// that this client still exists by increasing the clock
clock++
} else {
awareness.states.delete(clientID)
}
} else {
awareness.states.set(clientID, state)
}
awareness.meta.set(clientID, {
clock,
lastUpdated: timestamp
})
if (clientMeta === undefined && state !== null) {
added.push(clientID)
} else if (clientMeta !== undefined && state === null) {
removed.push(clientID)
} else if (state !== null) {
if (!f.equalityDeep(state, prevState)) {
filteredUpdated.push(clientID)
}
updated.push(clientID)
}
}
}
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
awareness.emit('change', [{
added, updated: filteredUpdated, removed
}, origin])
}
if (added.length > 0 || updated.length > 0 || removed.length > 0) {
awareness.emit('update', [{
added, updated, removed
}, origin])
}
}

View File

@@ -0,0 +1,3 @@
export function testAwareness(tc: t.TestCase): void;
import * as t from 'lib0/testing';
//# sourceMappingURL=awareness.test.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"awareness.test.d.ts","sourceRoot":"","sources":["awareness.test.js"],"names":[],"mappings":"AAQO,kCAFI,EAAE,QAAQ,QA8CpB;mBAlDkB,cAAc"}

53
yjs-poll/node_modules/y-protocols/awareness.test.js generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import * as Y from 'yjs'
import * as t from 'lib0/testing'
import * as awareness from './awareness'
/**
* @param {t.TestCase} tc
*/
export const testAwareness = tc => {
const doc1 = new Y.Doc()
doc1.clientID = 0
const doc2 = new Y.Doc()
doc2.clientID = 1
const aw1 = new awareness.Awareness(doc1)
const aw2 = new awareness.Awareness(doc2)
aw1.on('update', /** @param {any} p */ ({ added, updated, removed }) => {
const enc = awareness.encodeAwarenessUpdate(aw1, added.concat(updated).concat(removed))
awareness.applyAwarenessUpdate(aw2, enc, 'custom')
})
let lastChangeLocal = /** @type {any} */ (null)
aw1.on('change', /** @param {any} change */ change => {
lastChangeLocal = change
})
let lastChange = /** @type {any} */ (null)
aw2.on('change', /** @param {any} change */ change => {
lastChange = change
})
aw1.setLocalState({ x: 3 })
t.compare(aw2.getStates().get(0), { x: 3 })
t.assert(/** @type {any} */ (aw2.meta.get(0)).clock === 1)
t.compare(lastChange.added, [0])
// When creating an Awareness instance, the the local client is already marked as available, so it is not updated.
t.compare(lastChangeLocal, { added: [], updated: [0], removed: [] })
// update state
lastChange = null
lastChangeLocal = null
aw1.setLocalState({ x: 4 })
t.compare(aw2.getStates().get(0), { x: 4 })
t.compare(lastChangeLocal, { added: [], updated: [0], removed: [] })
t.compare(lastChangeLocal, lastChange)
lastChange = null
lastChangeLocal = null
aw1.setLocalState({ x: 4 })
t.assert(lastChange === null)
t.assert(/** @type {any} */ (aw2.meta.get(0)).clock === 3)
t.compare(lastChangeLocal, lastChange)
aw1.setLocalState(null)
t.assert(lastChange.removed.length === 1)
t.compare(aw1.getStates().get(0), undefined)
t.compare(lastChangeLocal, lastChange)
}

59
yjs-poll/node_modules/y-protocols/dist/auth.cjs generated vendored Normal file
View File

@@ -0,0 +1,59 @@
'use strict';
require('yjs');
var encoding = require('lib0/dist/encoding.cjs');
var decoding = require('lib0/dist/decoding.cjs');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var encoding__namespace = /*#__PURE__*/_interopNamespaceDefault(encoding);
var decoding__namespace = /*#__PURE__*/_interopNamespaceDefault(decoding);
const messagePermissionDenied = 0;
/**
* @param {encoding.Encoder} encoder
* @param {string} reason
*/
const writePermissionDenied = (encoder, reason) => {
encoding__namespace.writeVarUint(encoder, messagePermissionDenied);
encoding__namespace.writeVarString(encoder, reason);
};
/**
* @callback PermissionDeniedHandler
* @param {any} y
* @param {string} reason
*/
/**
*
* @param {decoding.Decoder} decoder
* @param {Y.Doc} y
* @param {PermissionDeniedHandler} permissionDeniedHandler
*/
const readAuthMessage = (decoder, y, permissionDeniedHandler) => {
switch (decoding__namespace.readVarUint(decoder)) {
case messagePermissionDenied: permissionDeniedHandler(y, decoding__namespace.readVarString(decoder));
}
};
exports.messagePermissionDenied = messagePermissionDenied;
exports.readAuthMessage = readAuthMessage;
exports.writePermissionDenied = writePermissionDenied;
//# sourceMappingURL=auth.cjs.map

1
yjs-poll/node_modules/y-protocols/dist/auth.cjs.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"auth.cjs","sources":["../auth.js"],"sourcesContent":["\nimport * as Y from 'yjs' // eslint-disable-line\nimport * as encoding from 'lib0/encoding'\nimport * as decoding from 'lib0/decoding'\n\nexport const messagePermissionDenied = 0\n\n/**\n * @param {encoding.Encoder} encoder\n * @param {string} reason\n */\nexport const writePermissionDenied = (encoder, reason) => {\n encoding.writeVarUint(encoder, messagePermissionDenied)\n encoding.writeVarString(encoder, reason)\n}\n\n/**\n * @callback PermissionDeniedHandler\n * @param {any} y\n * @param {string} reason\n */\n\n/**\n *\n * @param {decoding.Decoder} decoder\n * @param {Y.Doc} y\n * @param {PermissionDeniedHandler} permissionDeniedHandler\n */\nexport const readAuthMessage = (decoder, y, permissionDeniedHandler) => {\n switch (decoding.readVarUint(decoder)) {\n case messagePermissionDenied: permissionDeniedHandler(y, decoding.readVarString(decoder))\n }\n}\n"],"names":["encoding","decoding"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAKY,MAAC,uBAAuB,GAAG,EAAC;AACxC;AACA;AACA;AACA;AACA;AACY,MAAC,qBAAqB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK;AAC1D,EAAEA,mBAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,uBAAuB,EAAC;AACzD,EAAEA,mBAAQ,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAC;AAC1C,EAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACY,MAAC,eAAe,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,uBAAuB,KAAK;AACxE,EAAE,QAAQC,mBAAQ,CAAC,WAAW,CAAC,OAAO,CAAC;AACvC,IAAI,KAAK,uBAAuB,EAAE,uBAAuB,CAAC,CAAC,EAAEA,mBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,EAAC;AAC7F,GAAG;AACH;;;;;;"}

329
yjs-poll/node_modules/y-protocols/dist/awareness.cjs generated vendored Normal file
View File

@@ -0,0 +1,329 @@
'use strict';
var encoding = require('lib0/dist/encoding.cjs');
var decoding = require('lib0/dist/decoding.cjs');
var time = require('lib0/dist/time.cjs');
var math = require('lib0/dist/math.cjs');
var observable = require('lib0/dist/observable.cjs');
var f = require('lib0/dist/function.cjs');
require('yjs');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var encoding__namespace = /*#__PURE__*/_interopNamespaceDefault(encoding);
var decoding__namespace = /*#__PURE__*/_interopNamespaceDefault(decoding);
var time__namespace = /*#__PURE__*/_interopNamespaceDefault(time);
var math__namespace = /*#__PURE__*/_interopNamespaceDefault(math);
var f__namespace = /*#__PURE__*/_interopNamespaceDefault(f);
/**
* @module awareness-protocol
*/
const outdatedTimeout = 30000;
/**
* @typedef {Object} MetaClientState
* @property {number} MetaClientState.clock
* @property {number} MetaClientState.lastUpdated unix timestamp
*/
/**
* The Awareness class implements a simple shared state protocol that can be used for non-persistent data like awareness information
* (cursor, username, status, ..). Each client can update its own local state and listen to state changes of
* remote clients. Every client may set a state of a remote peer to `null` to mark the client as offline.
*
* Each client is identified by a unique client id (something we borrow from `doc.clientID`). A client can override
* its own state by propagating a message with an increasing timestamp (`clock`). If such a message is received, it is
* applied if the known state of that client is older than the new state (`clock < newClock`). If a client thinks that
* a remote client is offline, it may propagate a message with
* `{ clock: currentClientClock, state: null, client: remoteClient }`. If such a
* message is received, and the known clock of that client equals the received clock, it will override the state with `null`.
*
* Before a client disconnects, it should propagate a `null` state with an updated clock.
*
* Awareness states must be updated every 30 seconds. Otherwise the Awareness instance will delete the client state.
*
* @extends {Observable<string>}
*/
class Awareness extends observable.Observable {
/**
* @param {Y.Doc} doc
*/
constructor (doc) {
super();
this.doc = doc;
/**
* @type {number}
*/
this.clientID = doc.clientID;
/**
* Maps from client id to client state
* @type {Map<number, Object<string, any>>}
*/
this.states = new Map();
/**
* @type {Map<number, MetaClientState>}
*/
this.meta = new Map();
this._checkInterval = /** @type {any} */ (setInterval(() => {
const now = time__namespace.getUnixTime();
if (this.getLocalState() !== null && (outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ (this.meta.get(this.clientID)).lastUpdated)) {
// renew local clock
this.setLocalState(this.getLocalState());
}
/**
* @type {Array<number>}
*/
const remove = [];
this.meta.forEach((meta, clientid) => {
if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) {
remove.push(clientid);
}
});
if (remove.length > 0) {
removeAwarenessStates(this, remove, 'timeout');
}
}, math__namespace.floor(outdatedTimeout / 10)));
doc.on('destroy', () => {
this.destroy();
});
this.setLocalState({});
}
destroy () {
this.emit('destroy', [this]);
this.setLocalState(null);
super.destroy();
clearInterval(this._checkInterval);
}
/**
* @return {Object<string,any>|null}
*/
getLocalState () {
return this.states.get(this.clientID) || null
}
/**
* @param {Object<string,any>|null} state
*/
setLocalState (state) {
const clientID = this.clientID;
const currLocalMeta = this.meta.get(clientID);
const clock = currLocalMeta === undefined ? 0 : currLocalMeta.clock + 1;
const prevState = this.states.get(clientID);
if (state === null) {
this.states.delete(clientID);
} else {
this.states.set(clientID, state);
}
this.meta.set(clientID, {
clock,
lastUpdated: time__namespace.getUnixTime()
});
const added = [];
const updated = [];
const filteredUpdated = [];
const removed = [];
if (state === null) {
removed.push(clientID);
} else if (prevState == null) {
if (state != null) {
added.push(clientID);
}
} else {
updated.push(clientID);
if (!f__namespace.equalityDeep(prevState, state)) {
filteredUpdated.push(clientID);
}
}
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
this.emit('change', [{ added, updated: filteredUpdated, removed }, 'local']);
}
this.emit('update', [{ added, updated, removed }, 'local']);
}
/**
* @param {string} field
* @param {any} value
*/
setLocalStateField (field, value) {
const state = this.getLocalState();
if (state !== null) {
this.setLocalState({
...state,
[field]: value
});
}
}
/**
* @return {Map<number,Object<string,any>>}
*/
getStates () {
return this.states
}
}
/**
* Mark (remote) clients as inactive and remove them from the list of active peers.
* This change will be propagated to remote clients.
*
* @param {Awareness} awareness
* @param {Array<number>} clients
* @param {any} origin
*/
const removeAwarenessStates = (awareness, clients, origin) => {
const removed = [];
for (let i = 0; i < clients.length; i++) {
const clientID = clients[i];
if (awareness.states.has(clientID)) {
awareness.states.delete(clientID);
if (clientID === awareness.clientID) {
const curMeta = /** @type {MetaClientState} */ (awareness.meta.get(clientID));
awareness.meta.set(clientID, {
clock: curMeta.clock + 1,
lastUpdated: time__namespace.getUnixTime()
});
}
removed.push(clientID);
}
}
if (removed.length > 0) {
awareness.emit('change', [{ added: [], updated: [], removed }, origin]);
awareness.emit('update', [{ added: [], updated: [], removed }, origin]);
}
};
/**
* @param {Awareness} awareness
* @param {Array<number>} clients
* @return {Uint8Array}
*/
const encodeAwarenessUpdate = (awareness, clients, states = awareness.states) => {
const len = clients.length;
const encoder = encoding__namespace.createEncoder();
encoding__namespace.writeVarUint(encoder, len);
for (let i = 0; i < len; i++) {
const clientID = clients[i];
const state = states.get(clientID) || null;
const clock = /** @type {MetaClientState} */ (awareness.meta.get(clientID)).clock;
encoding__namespace.writeVarUint(encoder, clientID);
encoding__namespace.writeVarUint(encoder, clock);
encoding__namespace.writeVarString(encoder, JSON.stringify(state));
}
return encoding__namespace.toUint8Array(encoder)
};
/**
* Modify the content of an awareness update before re-encoding it to an awareness update.
*
* This might be useful when you have a central server that wants to ensure that clients
* cant hijack somebody elses identity.
*
* @param {Uint8Array} update
* @param {function(any):any} modify
* @return {Uint8Array}
*/
const modifyAwarenessUpdate = (update, modify) => {
const decoder = decoding__namespace.createDecoder(update);
const encoder = encoding__namespace.createEncoder();
const len = decoding__namespace.readVarUint(decoder);
encoding__namespace.writeVarUint(encoder, len);
for (let i = 0; i < len; i++) {
const clientID = decoding__namespace.readVarUint(decoder);
const clock = decoding__namespace.readVarUint(decoder);
const state = JSON.parse(decoding__namespace.readVarString(decoder));
const modifiedState = modify(state);
encoding__namespace.writeVarUint(encoder, clientID);
encoding__namespace.writeVarUint(encoder, clock);
encoding__namespace.writeVarString(encoder, JSON.stringify(modifiedState));
}
return encoding__namespace.toUint8Array(encoder)
};
/**
* @param {Awareness} awareness
* @param {Uint8Array} update
* @param {any} origin This will be added to the emitted change event
*/
const applyAwarenessUpdate = (awareness, update, origin) => {
const decoder = decoding__namespace.createDecoder(update);
const timestamp = time__namespace.getUnixTime();
const added = [];
const updated = [];
const filteredUpdated = [];
const removed = [];
const len = decoding__namespace.readVarUint(decoder);
for (let i = 0; i < len; i++) {
const clientID = decoding__namespace.readVarUint(decoder);
let clock = decoding__namespace.readVarUint(decoder);
const state = JSON.parse(decoding__namespace.readVarString(decoder));
const clientMeta = awareness.meta.get(clientID);
const prevState = awareness.states.get(clientID);
const currClock = clientMeta === undefined ? 0 : clientMeta.clock;
if (currClock < clock || (currClock === clock && state === null && awareness.states.has(clientID))) {
if (state === null) {
// never let a remote client remove this local state
if (clientID === awareness.clientID && awareness.getLocalState() != null) {
// remote client removed the local state. Do not remote state. Broadcast a message indicating
// that this client still exists by increasing the clock
clock++;
} else {
awareness.states.delete(clientID);
}
} else {
awareness.states.set(clientID, state);
}
awareness.meta.set(clientID, {
clock,
lastUpdated: timestamp
});
if (clientMeta === undefined && state !== null) {
added.push(clientID);
} else if (clientMeta !== undefined && state === null) {
removed.push(clientID);
} else if (state !== null) {
if (!f__namespace.equalityDeep(state, prevState)) {
filteredUpdated.push(clientID);
}
updated.push(clientID);
}
}
}
if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) {
awareness.emit('change', [{
added, updated: filteredUpdated, removed
}, origin]);
}
if (added.length > 0 || updated.length > 0 || removed.length > 0) {
awareness.emit('update', [{
added, updated, removed
}, origin]);
}
};
exports.Awareness = Awareness;
exports.applyAwarenessUpdate = applyAwarenessUpdate;
exports.encodeAwarenessUpdate = encodeAwarenessUpdate;
exports.modifyAwarenessUpdate = modifyAwarenessUpdate;
exports.outdatedTimeout = outdatedTimeout;
exports.removeAwarenessStates = removeAwarenessStates;
//# sourceMappingURL=awareness.cjs.map

File diff suppressed because one or more lines are too long

170
yjs-poll/node_modules/y-protocols/dist/sync.cjs generated vendored Normal file
View File

@@ -0,0 +1,170 @@
'use strict';
var encoding = require('lib0/dist/encoding.cjs');
var decoding = require('lib0/dist/decoding.cjs');
var Y = require('yjs');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var encoding__namespace = /*#__PURE__*/_interopNamespaceDefault(encoding);
var decoding__namespace = /*#__PURE__*/_interopNamespaceDefault(decoding);
var Y__namespace = /*#__PURE__*/_interopNamespaceDefault(Y);
/**
* @module sync-protocol
*/
/**
* @typedef {Map<number, number>} StateMap
*/
/**
* Core Yjs defines two message types:
* • YjsSyncStep1: Includes the State Set of the sending client. When received, the client should reply with YjsSyncStep2.
* • YjsSyncStep2: Includes all missing structs and the complete delete set. When received, the client is assured that it
* received all information from the remote client.
*
* In a peer-to-peer network, you may want to introduce a SyncDone message type. Both parties should initiate the connection
* with SyncStep1. When a client received SyncStep2, it should reply with SyncDone. When the local client received both
* SyncStep2 and SyncDone, it is assured that it is synced to the remote client.
*
* In a client-server model, you want to handle this differently: The client should initiate the connection with SyncStep1.
* When the server receives SyncStep1, it should reply with SyncStep2 immediately followed by SyncStep1. The client replies
* with SyncStep2 when it receives SyncStep1. Optionally the server may send a SyncDone after it received SyncStep2, so the
* client knows that the sync is finished. There are two reasons for this more elaborated sync model: 1. This protocol can
* easily be implemented on top of http and websockets. 2. The server should only reply to requests, and not initiate them.
* Therefore it is necessary that the client initiates the sync.
*
* Construction of a message:
* [messageType : varUint, message definition..]
*
* Note: A message does not include information about the room name. This must to be handled by the upper layer protocol!
*
* stringify[messageType] stringifies a message definition (messageType is already read from the bufffer)
*/
const messageYjsSyncStep1 = 0;
const messageYjsSyncStep2 = 1;
const messageYjsUpdate = 2;
/**
* Create a sync step 1 message based on the state of the current shared document.
*
* @param {encoding.Encoder} encoder
* @param {Y.Doc} doc
*/
const writeSyncStep1 = (encoder, doc) => {
encoding__namespace.writeVarUint(encoder, messageYjsSyncStep1);
const sv = Y__namespace.encodeStateVector(doc);
encoding__namespace.writeVarUint8Array(encoder, sv);
};
/**
* @param {encoding.Encoder} encoder
* @param {Y.Doc} doc
* @param {Uint8Array} [encodedStateVector]
*/
const writeSyncStep2 = (encoder, doc, encodedStateVector) => {
encoding__namespace.writeVarUint(encoder, messageYjsSyncStep2);
encoding__namespace.writeVarUint8Array(encoder, Y__namespace.encodeStateAsUpdate(doc, encodedStateVector));
};
/**
* Read SyncStep1 message and reply with SyncStep2.
*
* @param {decoding.Decoder} decoder The reply to the received message
* @param {encoding.Encoder} encoder The received message
* @param {Y.Doc} doc
*/
const readSyncStep1 = (decoder, encoder, doc) =>
writeSyncStep2(encoder, doc, decoding__namespace.readVarUint8Array(decoder));
/**
* Read and apply Structs and then DeleteStore to a y instance.
*
* @param {decoding.Decoder} decoder
* @param {Y.Doc} doc
* @param {any} transactionOrigin
* @param {(error:Error)=>any} [errorHandler]
*/
const readSyncStep2 = (decoder, doc, transactionOrigin, errorHandler) => {
try {
Y__namespace.applyUpdate(doc, decoding__namespace.readVarUint8Array(decoder), transactionOrigin);
} catch (error) {
if (errorHandler != null) errorHandler(/** @type {Error} */ (error));
// This catches errors that are thrown by event handlers
console.error('Caught error while handling a Yjs update', error);
}
};
/**
* @param {encoding.Encoder} encoder
* @param {Uint8Array} update
*/
const writeUpdate = (encoder, update) => {
encoding__namespace.writeVarUint(encoder, messageYjsUpdate);
encoding__namespace.writeVarUint8Array(encoder, update);
};
/**
* Read and apply Structs and then DeleteStore to a y instance.
*
* @param {decoding.Decoder} decoder
* @param {Y.Doc} doc
* @param {any} transactionOrigin
* @param {(error:Error)=>any} [errorHandler]
*/
const readUpdate = readSyncStep2;
/**
* @param {decoding.Decoder} decoder A message received from another client
* @param {encoding.Encoder} encoder The reply message. Does not need to be sent if empty.
* @param {Y.Doc} doc
* @param {any} transactionOrigin
* @param {(error:Error)=>any} [errorHandler] Optional error handler that catches errors when reading Yjs messages.
*/
const readSyncMessage = (decoder, encoder, doc, transactionOrigin, errorHandler) => {
const messageType = decoding__namespace.readVarUint(decoder);
switch (messageType) {
case messageYjsSyncStep1:
readSyncStep1(decoder, encoder, doc);
break
case messageYjsSyncStep2:
readSyncStep2(decoder, doc, transactionOrigin, errorHandler);
break
case messageYjsUpdate:
readUpdate(decoder, doc, transactionOrigin, errorHandler);
break
default:
throw new Error('Unknown message type')
}
return messageType
};
exports.messageYjsSyncStep1 = messageYjsSyncStep1;
exports.messageYjsSyncStep2 = messageYjsSyncStep2;
exports.messageYjsUpdate = messageYjsUpdate;
exports.readSyncMessage = readSyncMessage;
exports.readSyncStep1 = readSyncStep1;
exports.readSyncStep2 = readSyncStep2;
exports.readUpdate = readUpdate;
exports.writeSyncStep1 = writeSyncStep1;
exports.writeSyncStep2 = writeSyncStep2;
exports.writeUpdate = writeUpdate;
//# sourceMappingURL=sync.cjs.map

1
yjs-poll/node_modules/y-protocols/dist/sync.cjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

103
yjs-poll/node_modules/y-protocols/dist/test.cjs generated vendored Normal file
View File

@@ -0,0 +1,103 @@
'use strict';
var t = require('lib0/dist/testing.cjs');
var log = require('lib0/dist/logging.cjs');
var Y = require('yjs');
var awareness$1 = require('./awareness.cjs');
var environment = require('lib0/dist/environment.cjs');
require('lib0/dist/encoding.cjs');
require('lib0/dist/decoding.cjs');
require('lib0/dist/time.cjs');
require('lib0/dist/math.cjs');
require('lib0/dist/observable.cjs');
require('lib0/dist/function.cjs');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var t__namespace = /*#__PURE__*/_interopNamespaceDefault(t);
var log__namespace = /*#__PURE__*/_interopNamespaceDefault(log);
var Y__namespace = /*#__PURE__*/_interopNamespaceDefault(Y);
/**
* @param {t.TestCase} tc
*/
const testAwareness = tc => {
const doc1 = new Y__namespace.Doc();
doc1.clientID = 0;
const doc2 = new Y__namespace.Doc();
doc2.clientID = 1;
const aw1 = new awareness$1.Awareness(doc1);
const aw2 = new awareness$1.Awareness(doc2);
aw1.on('update', /** @param {any} p */ ({ added, updated, removed }) => {
const enc = awareness$1.encodeAwarenessUpdate(aw1, added.concat(updated).concat(removed));
awareness$1.applyAwarenessUpdate(aw2, enc, 'custom');
});
let lastChangeLocal = /** @type {any} */ (null);
aw1.on('change', /** @param {any} change */ change => {
lastChangeLocal = change;
});
let lastChange = /** @type {any} */ (null);
aw2.on('change', /** @param {any} change */ change => {
lastChange = change;
});
aw1.setLocalState({ x: 3 });
t__namespace.compare(aw2.getStates().get(0), { x: 3 });
t__namespace.assert(/** @type {any} */ (aw2.meta.get(0)).clock === 1);
t__namespace.compare(lastChange.added, [0]);
// When creating an Awareness instance, the the local client is already marked as available, so it is not updated.
t__namespace.compare(lastChangeLocal, { added: [], updated: [0], removed: [] });
// update state
lastChange = null;
lastChangeLocal = null;
aw1.setLocalState({ x: 4 });
t__namespace.compare(aw2.getStates().get(0), { x: 4 });
t__namespace.compare(lastChangeLocal, { added: [], updated: [0], removed: [] });
t__namespace.compare(lastChangeLocal, lastChange);
lastChange = null;
lastChangeLocal = null;
aw1.setLocalState({ x: 4 });
t__namespace.assert(lastChange === null);
t__namespace.assert(/** @type {any} */ (aw2.meta.get(0)).clock === 3);
t__namespace.compare(lastChangeLocal, lastChange);
aw1.setLocalState(null);
t__namespace.assert(lastChange.removed.length === 1);
t__namespace.compare(aw1.getStates().get(0), undefined);
t__namespace.compare(lastChangeLocal, lastChange);
};
var awareness = /*#__PURE__*/Object.freeze({
__proto__: null,
testAwareness: testAwareness
});
/* istanbul ignore if */
if (environment.isBrowser) {
log__namespace.createVConsole(document.body);
}
t.runTests({
awareness
}).then(success => {
/* istanbul ignore next */
if (environment.isNode) {
process.exit(success ? 0 : 1);
}
});
//# sourceMappingURL=test.cjs.map

1
yjs-poll/node_modules/y-protocols/dist/test.cjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

9921
yjs-poll/node_modules/y-protocols/dist/test.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1
yjs-poll/node_modules/y-protocols/dist/test.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

92
yjs-poll/node_modules/y-protocols/package.json generated vendored Normal file
View File

@@ -0,0 +1,92 @@
{
"name": "y-protocols",
"version": "1.0.7",
"description": "Yjs encoding protocols",
"type": "module",
"funding": {
"type": "GitHub Sponsors ❤",
"url": "https://github.com/sponsors/dmonad"
},
"files": [
"dist/*",
"auth.*",
"sync.*",
"awareness.*"
],
"scripts": {
"clean": "rm -rf dist *.d.ts */*.d.ts *.d.ts.map */*.d.ts.map",
"dist": "rm -rf dist && rollup -c",
"test": "npm run lint && npm run dist && node dist/test.cjs",
"lint": "standard && tsc",
"types": "tsc --outDir .",
"debug": "rollup -c && concurrently 'rollup -wc' 'http-server -o test.html'",
"preversion": "npm run dist && npm run test && npm run types",
"postpublish": "npm run clean"
},
"repository": {
"type": "git",
"url": "git+https://github.com/yjs/y-protocols.git"
},
"keywords": [
"Yjs"
],
"author": "Kevin Jahns <kevin.jahns@protonmail.com>",
"license": "MIT",
"standard": {
"ignore": [
"/dist",
"/node_modules"
]
},
"bugs": {
"url": "https://github.com/yjs/y-protocols/issues"
},
"homepage": "https://github.com/yjs/y-protocols#readme",
"exports": {
"./package.json": "./package.json",
"./sync.js": "./sync.js",
"./dist/sync.cjs": "./dist/sync.cjs",
"./sync": {
"types": "./sync.d.ts",
"module": "./sync.js",
"import": "./sync.js",
"require": "./dist/sync.cjs"
},
"./awareness.js": "./awareness.js",
"./dist/awareness.cjs": "./dist/awareness.cjs",
"./awareness": {
"types": "./awareness.d.ts",
"module": "./awareness.js",
"import": "./awareness.js",
"require": "./dist/awareness.cjs"
},
"./auth.js": "./auth.js",
"./dist/auth.cjs": "./dist/auth.cjs",
"./auth": {
"types": "./auth.d.ts",
"module": "./auth.js",
"import": "./auth.js",
"require": "./dist/auth.cjs"
}
},
"dependencies": {
"lib0": "^0.2.85"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-node-resolve": "^15.2.1",
"@types/node": "^20.6.2",
"concurrently": "^5.3.0",
"rollup": "^3.29.2",
"standard": "^12.0.1",
"typescript": "^5.2.2",
"yjs": "^13.5.6"
},
"peerDependencies": {
"yjs": "^13.0.0"
},
"engines": {
"npm": ">=8.0.0",
"node": ">=16.0.0"
}
}

42
yjs-poll/node_modules/y-protocols/sync.d.ts generated vendored Normal file
View File

@@ -0,0 +1,42 @@
/**
* @typedef {Map<number, number>} StateMap
*/
/**
* Core Yjs defines two message types:
* • YjsSyncStep1: Includes the State Set of the sending client. When received, the client should reply with YjsSyncStep2.
* • YjsSyncStep2: Includes all missing structs and the complete delete set. When received, the client is assured that it
* received all information from the remote client.
*
* In a peer-to-peer network, you may want to introduce a SyncDone message type. Both parties should initiate the connection
* with SyncStep1. When a client received SyncStep2, it should reply with SyncDone. When the local client received both
* SyncStep2 and SyncDone, it is assured that it is synced to the remote client.
*
* In a client-server model, you want to handle this differently: The client should initiate the connection with SyncStep1.
* When the server receives SyncStep1, it should reply with SyncStep2 immediately followed by SyncStep1. The client replies
* with SyncStep2 when it receives SyncStep1. Optionally the server may send a SyncDone after it received SyncStep2, so the
* client knows that the sync is finished. There are two reasons for this more elaborated sync model: 1. This protocol can
* easily be implemented on top of http and websockets. 2. The server should only reply to requests, and not initiate them.
* Therefore it is necessary that the client initiates the sync.
*
* Construction of a message:
* [messageType : varUint, message definition..]
*
* Note: A message does not include information about the room name. This must to be handled by the upper layer protocol!
*
* stringify[messageType] stringifies a message definition (messageType is already read from the bufffer)
*/
export const messageYjsSyncStep1: 0;
export const messageYjsSyncStep2: 1;
export const messageYjsUpdate: 2;
export function writeSyncStep1(encoder: encoding.Encoder, doc: Y.Doc): void;
export function writeSyncStep2(encoder: encoding.Encoder, doc: Y.Doc, encodedStateVector?: Uint8Array | undefined): void;
export function readSyncStep1(decoder: decoding.Decoder, encoder: encoding.Encoder, doc: Y.Doc): void;
export function readSyncStep2(decoder: decoding.Decoder, doc: Y.Doc, transactionOrigin: any, errorHandler?: ((error: Error) => any) | undefined): void;
export function writeUpdate(encoder: encoding.Encoder, update: Uint8Array): void;
export function readUpdate(decoder: decoding.Decoder, doc: Y.Doc, transactionOrigin: any, errorHandler?: ((error: Error) => any) | undefined): void;
export function readSyncMessage(decoder: decoding.Decoder, encoder: encoding.Encoder, doc: Y.Doc, transactionOrigin: any, errorHandler?: ((error: Error) => any) | undefined): 0 | 2 | 1;
export type StateMap = Map<number, number>;
import * as encoding from 'lib0/encoding';
import * as Y from 'yjs';
import * as decoding from 'lib0/decoding';
//# sourceMappingURL=sync.d.ts.map

1
yjs-poll/node_modules/y-protocols/sync.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["sync.js"],"names":[],"mappings":"AAQA;;GAEG;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,oCAAoC;AACpC,oCAAoC;AACpC,iCAAiC;AAQ1B,wCAHI,SAAS,OAAO,OAChB,EAAE,GAAG,QAMf;AAOM,wCAJI,SAAS,OAAO,OAChB,EAAE,GAAG,qDAMf;AASM,uCAJI,SAAS,OAAO,WAChB,SAAS,OAAO,OAChB,EAAE,GAAG,QAGmD;AAU5D,uCALI,SAAS,OAAO,OAChB,EAAE,GAAG,qBACL,GAAG,0BACI,KAAK,KAAG,GAAG,qBAU5B;AAMM,qCAHI,SAAS,OAAO,UAChB,UAAU,QAKpB;AAjBM,oCALI,SAAS,OAAO,OAChB,EAAE,GAAG,qBACL,GAAG,0BACI,KAAK,KAAG,GAAG,qBAU5B;AA4BM,yCANI,SAAS,OAAO,WAChB,SAAS,OAAO,OAChB,EAAE,GAAG,qBACL,GAAG,0BACI,KAAK,KAAG,GAAG,0BAkB5B;uBA5HY,IAAI,MAAM,EAAE,MAAM,CAAC;0BALN,eAAe;mBAEtB,KAAK;0BADE,eAAe"}

134
yjs-poll/node_modules/y-protocols/sync.js generated vendored Normal file
View File

@@ -0,0 +1,134 @@
/**
* @module sync-protocol
*/
import * as encoding from 'lib0/encoding'
import * as decoding from 'lib0/decoding'
import * as Y from 'yjs'
/**
* @typedef {Map<number, number>} StateMap
*/
/**
* Core Yjs defines two message types:
* • YjsSyncStep1: Includes the State Set of the sending client. When received, the client should reply with YjsSyncStep2.
* • YjsSyncStep2: Includes all missing structs and the complete delete set. When received, the client is assured that it
* received all information from the remote client.
*
* In a peer-to-peer network, you may want to introduce a SyncDone message type. Both parties should initiate the connection
* with SyncStep1. When a client received SyncStep2, it should reply with SyncDone. When the local client received both
* SyncStep2 and SyncDone, it is assured that it is synced to the remote client.
*
* In a client-server model, you want to handle this differently: The client should initiate the connection with SyncStep1.
* When the server receives SyncStep1, it should reply with SyncStep2 immediately followed by SyncStep1. The client replies
* with SyncStep2 when it receives SyncStep1. Optionally the server may send a SyncDone after it received SyncStep2, so the
* client knows that the sync is finished. There are two reasons for this more elaborated sync model: 1. This protocol can
* easily be implemented on top of http and websockets. 2. The server should only reply to requests, and not initiate them.
* Therefore it is necessary that the client initiates the sync.
*
* Construction of a message:
* [messageType : varUint, message definition..]
*
* Note: A message does not include information about the room name. This must to be handled by the upper layer protocol!
*
* stringify[messageType] stringifies a message definition (messageType is already read from the bufffer)
*/
export const messageYjsSyncStep1 = 0
export const messageYjsSyncStep2 = 1
export const messageYjsUpdate = 2
/**
* Create a sync step 1 message based on the state of the current shared document.
*
* @param {encoding.Encoder} encoder
* @param {Y.Doc} doc
*/
export const writeSyncStep1 = (encoder, doc) => {
encoding.writeVarUint(encoder, messageYjsSyncStep1)
const sv = Y.encodeStateVector(doc)
encoding.writeVarUint8Array(encoder, sv)
}
/**
* @param {encoding.Encoder} encoder
* @param {Y.Doc} doc
* @param {Uint8Array} [encodedStateVector]
*/
export const writeSyncStep2 = (encoder, doc, encodedStateVector) => {
encoding.writeVarUint(encoder, messageYjsSyncStep2)
encoding.writeVarUint8Array(encoder, Y.encodeStateAsUpdate(doc, encodedStateVector))
}
/**
* Read SyncStep1 message and reply with SyncStep2.
*
* @param {decoding.Decoder} decoder The reply to the received message
* @param {encoding.Encoder} encoder The received message
* @param {Y.Doc} doc
*/
export const readSyncStep1 = (decoder, encoder, doc) =>
writeSyncStep2(encoder, doc, decoding.readVarUint8Array(decoder))
/**
* Read and apply Structs and then DeleteStore to a y instance.
*
* @param {decoding.Decoder} decoder
* @param {Y.Doc} doc
* @param {any} transactionOrigin
* @param {(error:Error)=>any} [errorHandler]
*/
export const readSyncStep2 = (decoder, doc, transactionOrigin, errorHandler) => {
try {
Y.applyUpdate(doc, decoding.readVarUint8Array(decoder), transactionOrigin)
} catch (error) {
if (errorHandler != null) errorHandler(/** @type {Error} */ (error))
// This catches errors that are thrown by event handlers
console.error('Caught error while handling a Yjs update', error)
}
}
/**
* @param {encoding.Encoder} encoder
* @param {Uint8Array} update
*/
export const writeUpdate = (encoder, update) => {
encoding.writeVarUint(encoder, messageYjsUpdate)
encoding.writeVarUint8Array(encoder, update)
}
/**
* Read and apply Structs and then DeleteStore to a y instance.
*
* @param {decoding.Decoder} decoder
* @param {Y.Doc} doc
* @param {any} transactionOrigin
* @param {(error:Error)=>any} [errorHandler]
*/
export const readUpdate = readSyncStep2
/**
* @param {decoding.Decoder} decoder A message received from another client
* @param {encoding.Encoder} encoder The reply message. Does not need to be sent if empty.
* @param {Y.Doc} doc
* @param {any} transactionOrigin
* @param {(error:Error)=>any} [errorHandler] Optional error handler that catches errors when reading Yjs messages.
*/
export const readSyncMessage = (decoder, encoder, doc, transactionOrigin, errorHandler) => {
const messageType = decoding.readVarUint(decoder)
switch (messageType) {
case messageYjsSyncStep1:
readSyncStep1(decoder, encoder, doc)
break
case messageYjsSyncStep2:
readSyncStep2(decoder, doc, transactionOrigin, errorHandler)
break
case messageYjsUpdate:
readUpdate(decoder, doc, transactionOrigin, errorHandler)
break
default:
throw new Error('Unknown message type')
}
return messageType
}