| 66 | } |
| 67 | |
| 68 | class WSSharedDoc extends Y.Doc implements WSSharedDocInterface { |
| 69 | name: string |
| 70 | conns: Map<WebSocket.WebSocket, Set<number>> |
| 71 | awareness: awarenessProtocol.Awareness |
| 72 | subDocs: Map<string, Y.Doc> = new Map() |
| 73 | /** |
| 74 | * @param {string} name |
| 75 | */ |
| 76 | constructor(name: string, callback?: UpdateCallback) { |
| 77 | super({ gc: gcEnabled }) |
| 78 | this.name = name |
| 79 | |
| 80 | this.conns = new Map() |
| 81 | |
| 82 | this.awareness = new awarenessProtocol.Awareness(this) |
| 83 | this.awareness.setLocalState(null) |
| 84 | |
| 85 | const awarenessChangeHandler = ( |
| 86 | { added, updated, removed }: AwarenessChangeHandlerOptions, |
| 87 | conn: WebSocket.WebSocket | null, |
| 88 | ) => { |
| 89 | const changedClients = added.concat(updated, removed) |
| 90 | if (conn !== null) { |
| 91 | const connControlledIDs = this.conns.get(conn) |
| 92 | if (connControlledIDs !== undefined) { |
| 93 | added.forEach(clientID => { |
| 94 | connControlledIDs.add(clientID) |
| 95 | }) |
| 96 | removed.forEach(clientID => { |
| 97 | connControlledIDs.delete(clientID) |
| 98 | }) |
| 99 | } |
| 100 | } |
| 101 | // broadcast awareness update |
| 102 | const encoder = encoding.createEncoder() |
| 103 | encoding.writeVarUint(encoder, messageAwareness) |
| 104 | encoding.writeVarUint8Array( |
| 105 | encoder, |
| 106 | awarenessProtocol.encodeAwarenessUpdate(this.awareness, changedClients), |
| 107 | ) |
| 108 | const buff = encoding.toUint8Array(encoder) |
| 109 | this.conns.forEach((_, c) => { |
| 110 | send(this, c, buff) |
| 111 | }) |
| 112 | } |
| 113 | this.awareness.on('update', awarenessChangeHandler) |
| 114 | this.on('updateV2', updateHandler) |
| 115 | |
| 116 | const handleSubDocUpdate = (update: Uint8Array, origin: string, subDoc: Y.Doc) => { |
| 117 | updateSubDocHandler(subDoc.guid, update, origin, this) |
| 118 | } |
| 119 | |
| 120 | const _subDocsHandler = ({ |
| 121 | added, |
| 122 | removed, |
| 123 | loaded, |
| 124 | }: Record<'added' | 'removed' | 'loaded', Y.Doc[]>) => { |
| 125 | added.forEach(subDoc => { |
nothing calls this directly
no outgoing calls
no test coverage detected