@mml-io/networked-dom-document 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/EditableNetworkedDOM.d.ts +1 -0
- package/build/EditableNetworkedDOM.d.ts.map +1 -0
- package/build/NetworkedDOM.d.ts +1 -0
- package/build/NetworkedDOM.d.ts.map +1 -0
- package/build/NetworkedDOMV01Connection.d.ts +1 -0
- package/build/NetworkedDOMV01Connection.d.ts.map +1 -0
- package/build/NetworkedDOMV02Connection.d.ts +1 -0
- package/build/NetworkedDOMV02Connection.d.ts.map +1 -0
- package/build/NodeManager.d.ts +1 -0
- package/build/NodeManager.d.ts.map +1 -0
- package/build/NodeWithSubjectivity.d.ts +1 -0
- package/build/NodeWithSubjectivity.d.ts.map +1 -0
- package/build/VisibilityManager.d.ts +1 -0
- package/build/VisibilityManager.d.ts.map +1 -0
- package/build/createNetworkedDOMConnectionForWebsocket.d.ts +1 -0
- package/build/createNetworkedDOMConnectionForWebsocket.d.ts.map +1 -0
- package/build/diffing/calculateStaticVirtualDOMDiff.d.ts +1 -0
- package/build/diffing/calculateStaticVirtualDOMDiff.d.ts.map +1 -0
- package/build/diffing/describeNode.d.ts +1 -0
- package/build/diffing/describeNode.d.ts.map +1 -0
- package/build/diffing/listAttributeToSet.d.ts +1 -0
- package/build/diffing/listAttributeToSet.d.ts.map +1 -0
- package/build/diffing/mergeMutations.d.ts +1 -0
- package/build/diffing/mergeMutations.d.ts.map +1 -0
- package/build/diffing/virtualDOMDiffToVirtualDOMMutationRecord.d.ts +1 -0
- package/build/diffing/virtualDOMDiffToVirtualDOMMutationRecord.d.ts.map +1 -0
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2 -0
- package/build/index.js.map +2 -2
- package/build/rfc6902/deepEqual.d.ts +1 -0
- package/build/rfc6902/deepEqual.d.ts.map +1 -0
- package/build/rfc6902/diff.d.ts +1 -0
- package/build/rfc6902/diff.d.ts.map +1 -0
- package/build/rfc6902/index.d.ts +1 -0
- package/build/rfc6902/index.d.ts.map +1 -0
- package/build/rfc6902/patch.d.ts +1 -0
- package/build/rfc6902/patch.d.ts.map +1 -0
- package/build/rfc6902/pointer.d.ts +1 -0
- package/build/rfc6902/pointer.d.ts.map +1 -0
- package/build/rfc6902/util.d.ts +1 -0
- package/build/rfc6902/util.d.ts.map +1 -0
- package/package.json +4 -4
package/build/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/createNetworkedDOMConnectionForWebsocket.ts", "../src/NetworkedDOMV01Connection.ts", "../src/NetworkedDOMV02Connection.ts", "../src/NetworkedDOM.ts", "../src/rfc6902/deepEqual.ts", "../src/rfc6902/pointer.ts", "../src/rfc6902/util.ts", "../src/rfc6902/diff.ts", "../src/rfc6902/patch.ts", "../src/diffing/calculateStaticVirtualDOMDiff.ts", "../src/NodeWithSubjectivity.ts", "../src/diffing/describeNode.ts", "../src/diffing/listAttributeToSet.ts", "../src/diffing/mergeMutations.ts", "../src/diffing/virtualDOMDiffToVirtualDOMMutationRecord.ts", "../src/NodeManager.ts", "../src/VisibilityManager.ts", "../src/EditableNetworkedDOM.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n isNetworkedDOMProtocolSubProtocol_v0_2,\n networkedDOMProtocolSubProtocol_v0_1,\n networkedDOMProtocolSubProtocol_v0_2,\n networkedDOMProtocolSubProtocol_v0_2_1,\n networkedDOMProtocolSubProtocol_v0_2_SubVersionsList,\n NetworkedDOMV02ServerMessage,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOMV01Connection } from \"./NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"./NetworkedDOMV02Connection\";\n\n// First to last in order of preference\nexport const SupportedWebsocketSubProtocolsPreferenceOrder = [\n ...networkedDOMProtocolSubProtocol_v0_2_SubVersionsList,\n networkedDOMProtocolSubProtocol_v0_1,\n] as const;\n\nexport const defaultWebsocketSubProtocol = networkedDOMProtocolSubProtocol_v0_1;\n\nfunction IsRecognizedWebsocketSubProtocol(\n protocol: string,\n): protocol is (typeof SupportedWebsocketSubProtocolsPreferenceOrder)[number] {\n return SupportedWebsocketSubProtocolsPreferenceOrder.includes(protocol as any);\n}\n\nexport function createNetworkedDOMConnectionForWebsocket(\n webSocket: WebSocket,\n): NetworkedDOMV01Connection | NetworkedDOMV02Connection | null {\n let assumedProtocol:\n | typeof networkedDOMProtocolSubProtocol_v0_1\n | typeof networkedDOMProtocolSubProtocol_v0_2\n | typeof networkedDOMProtocolSubProtocol_v0_2_1\n | null = null;\n if (webSocket.protocol) {\n if (!IsRecognizedWebsocketSubProtocol(webSocket.protocol)) {\n const errorMessageString = `Unsupported websocket subprotocol: ${webSocket.protocol}`;\n const errorMessage: Array<NetworkedDOMV02ServerMessage> = [\n {\n type: \"error\",\n message: errorMessageString,\n },\n ];\n webSocket.send(JSON.stringify(errorMessage));\n webSocket.close();\n return null;\n } else {\n assumedProtocol = webSocket.protocol;\n }\n } else {\n // Assume for now that this client is a legacy MML client that doesn't send a protocol, but send a warning to the client to encourage specifying a protocol\n const warningMessageString = `No websocket subprotocol specified. Please specify a subprotocol to ensure compatibility with networked-dom servers. Assuming subprotocol \"${defaultWebsocketSubProtocol}\" for this connection.`;\n const warningMessage: Array<NetworkedDOMV02ServerMessage> = [\n {\n type: \"warning\",\n message: warningMessageString,\n },\n ];\n webSocket.send(JSON.stringify(warningMessage));\n assumedProtocol = defaultWebsocketSubProtocol;\n }\n\n const isV02 = isNetworkedDOMProtocolSubProtocol_v0_2(assumedProtocol);\n if (isV02) {\n return new NetworkedDOMV02Connection(webSocket);\n }\n return new NetworkedDOMV01Connection(webSocket);\n}\n", "import {\n NetworkedDOMV01ClientMessage,\n NetworkedDOMV01ServerMessage,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOM } from \"./NetworkedDOM\";\n\nexport class NetworkedDOMV01Connection {\n private websocketListener: (messageEvent: MessageEvent) => void;\n\n public internalConnectionId: number | null = null;\n public internalIdToExternalId = new Map<number, number>();\n public networkedDOM: NetworkedDOM | null = null;\n\n public constructor(public readonly webSocket: WebSocket) {\n this.websocketListener = (messageEvent: MessageEvent) => {\n const string = String(messageEvent.data);\n let parsed;\n try {\n parsed = JSON.parse(string) as NetworkedDOMV01ClientMessage;\n } catch (e) {\n console.error(`Error parsing message from websocket: ${string}`, e);\n console.trace();\n return;\n }\n\n switch (parsed.type) {\n case \"pong\":\n // Ignore pongs for now\n return;\n case \"event\": {\n if (!this.networkedDOM) {\n console.error(\"NetworkedDOM not set on connection that received event\", this);\n return;\n }\n if (this.internalConnectionId === null) {\n console.error(\"Internal connection ID not set on connection that received event\", this);\n return;\n }\n this.networkedDOM.dispatchRemoteEvent(this, this.internalConnectionId, 1, {\n nodeId: parsed.nodeId,\n name: parsed.name,\n bubbles: parsed.bubbles ?? true,\n params: parsed.params,\n });\n return;\n }\n default:\n console.error(\"Unknown message type from client\", parsed);\n }\n };\n webSocket.addEventListener(\"message\", this.websocketListener);\n }\n\n public setNetworkedDOM(networkedDOM: NetworkedDOM | null) {\n this.networkedDOM = networkedDOM;\n }\n\n public initAsNewV01Connection() {\n if (!this.networkedDOM) {\n throw new Error(\"NetworkedDOM not set on connection\");\n }\n const internalConnectionIds = this.networkedDOM.connectUsers(this, new Set([1]));\n this.internalConnectionId = internalConnectionIds.entries().next().value[0] as number;\n this.internalIdToExternalId.set(this.internalConnectionId, 1);\n this.networkedDOM.announceConnectedUsers(\n new Map<number, string | null>([[this.internalConnectionId, null]]),\n );\n }\n\n public stringifyAndSendSingleMessage(message: NetworkedDOMV01ServerMessage) {\n this.webSocket.send(\"[\" + JSON.stringify(message) + \"]\");\n }\n\n public sendStringifiedJSONArray(jsonArray: string) {\n this.webSocket.send(jsonArray);\n }\n\n public dispose() {\n this.webSocket.removeEventListener(\"message\", this.websocketListener);\n }\n}\n", "import {\n BufferReader,\n BufferWriter,\n decodeClientMessages,\n encodeBatchEnd,\n encodeBatchStart,\n encodeServerMessage,\n getNetworkedDOMProtocolSubProtocol_v0_2SubversionOrThrow,\n isNetworkedDOMProtocolSubProtocol_v0_2,\n NetworkedDOMV02ClientMessage,\n NetworkedDOMV02ServerMessage,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOM } from \"./NetworkedDOM\";\n\nexport class NetworkedDOMV02Connection {\n private websocketListener: (messageEvent: MessageEvent) => void;\n\n public externalIdToInternalId = new Map<number, number>();\n public internalIdToExternalId = new Map<number, number>();\n public internalIdToToken = new Map<number, string | null>();\n\n private batchMode: boolean = false;\n private batchMessages: Array<NetworkedDOMV02ServerMessage | Uint8Array> = [];\n public externalConnectionIds = new Set<number>();\n\n public networkedDOM: NetworkedDOM | null = null;\n private messagesAwaitingNetworkedDOM: Array<NetworkedDOMV02ClientMessage> = [];\n\n public constructor(public readonly webSocket: WebSocket) {\n const protocol = webSocket.protocol;\n if (!isNetworkedDOMProtocolSubProtocol_v0_2(protocol)) {\n throw new Error(\n `WebSocket protocol ${protocol} is not a supported networked-dom-v0.2 sub-protocol`,\n );\n }\n const protocolSubversion = getNetworkedDOMProtocolSubProtocol_v0_2SubversionOrThrow(protocol);\n this.websocketListener = (messageEvent: MessageEvent) => {\n const buffer = new Uint8Array(messageEvent.data as ArrayBuffer);\n const messages = decodeClientMessages(new BufferReader(buffer), protocolSubversion);\n for (const parsed of messages) {\n if (this.networkedDOM) {\n this.handleClientMessage(parsed);\n } else {\n this.messagesAwaitingNetworkedDOM.push(parsed);\n }\n }\n };\n webSocket.addEventListener(\"message\", this.websocketListener);\n }\n\n public setNetworkedDOM(networkedDOM: NetworkedDOM | null) {\n this.networkedDOM = networkedDOM;\n }\n\n public setBatchStart() {\n this.batchMode = true;\n }\n\n public setBatchEnd() {\n this.batchMode = false;\n if (this.batchMessages.length === 0) {\n return;\n }\n const includeBatchStartAndEnd = this.batchMessages.length > 1;\n let toSendBytes: Uint8Array;\n\n if (\n this.batchMessages.length === 1 &&\n this.batchMessages[0] instanceof Uint8Array &&\n !includeBatchStartAndEnd\n ) {\n // There is only one message, it's already encoded, and we don't need to include batch start and end so we can send it directly\n toSendBytes = this.batchMessages[0];\n } else {\n const bufferWriter = new BufferWriter(256);\n if (includeBatchStartAndEnd) {\n encodeBatchStart(bufferWriter);\n }\n for (const message of this.batchMessages) {\n if (message instanceof Uint8Array) {\n bufferWriter.writeBytes(message);\n } else {\n encodeServerMessage(message, bufferWriter);\n }\n }\n if (includeBatchStartAndEnd) {\n encodeBatchEnd(bufferWriter);\n }\n toSendBytes = bufferWriter.getBuffer();\n }\n this.webSocket.send(toSendBytes);\n this.batchMessages = [];\n }\n\n public sendMessage(message: NetworkedDOMV02ServerMessage) {\n this.sendEncodedBytes(encodeServerMessage(message).getBuffer());\n }\n\n public sendMessages(messages: Array<NetworkedDOMV02ServerMessage>) {\n const bufferWriter = new BufferWriter(256);\n for (const message of messages) {\n encodeServerMessage(message, bufferWriter);\n }\n const bytes = bufferWriter.getBuffer();\n this.sendEncodedBytes(bytes);\n }\n\n public sendEncodedBytes(bytes: Uint8Array) {\n if (this.batchMode) {\n this.batchMessages.push(bytes);\n return;\n }\n // Non-batch mode - just send the bytes\n this.webSocket.send(bytes);\n }\n\n public dispose() {\n this.webSocket.removeEventListener(\"message\", this.websocketListener);\n }\n\n private handleClientMessage(parsed: NetworkedDOMV02ClientMessage) {\n switch (parsed.type) {\n case \"connectUsers\": {\n const externalIdsToToken = new Map<number, string | null>();\n const addedExternalUserIds = new Set<number>();\n for (let i = 0; i < parsed.connectionIds.length; i++) {\n const addingExternalId = parsed.connectionIds[i];\n const correspondingToken = parsed.connectionTokens[i];\n externalIdsToToken.set(addingExternalId, correspondingToken);\n\n // Check if the connection ID is a positive integer\n if (!Number.isInteger(addingExternalId) || addingExternalId < 0) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${addingExternalId} is not a positive integer.`,\n });\n console.error(\"Connection ID is not a positive integer\", addingExternalId);\n return;\n }\n\n if (this.externalConnectionIds.has(addingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${addingExternalId} already exists.`,\n });\n console.error(\"Connection ID already exists\", addingExternalId);\n return;\n }\n this.externalConnectionIds.add(addingExternalId);\n if (addedExternalUserIds.has(addingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${addingExternalId} is duplicated.`,\n });\n console.error(\"Connection ID is duplicated in connectUsers\", addingExternalId);\n return;\n }\n addedExternalUserIds.add(addingExternalId);\n }\n if (this.networkedDOM !== null) {\n const connectionIdToExternalId = this.networkedDOM.connectUsers(\n this,\n addedExternalUserIds,\n );\n const addingInternalIdsWithToken = new Map<number, string | null>();\n for (const [addingInternalId, addingExternalId] of connectionIdToExternalId) {\n const token = externalIdsToToken.get(addingExternalId) ?? null;\n addingInternalIdsWithToken.set(addingInternalId, token);\n this.externalIdToInternalId.set(addingExternalId, addingInternalId);\n this.internalIdToExternalId.set(addingInternalId, addingExternalId);\n this.internalIdToToken.set(addingInternalId, token);\n }\n this.networkedDOM.announceConnectedUsers(addingInternalIdsWithToken);\n }\n return;\n }\n case \"disconnectUsers\": {\n const removingExternalUserIds = new Set<number>();\n const removedExternalToInternalUserIds = new Map<number, number>();\n for (const removingExternalId of parsed.connectionIds) {\n if (!this.externalConnectionIds.has(removingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${removingExternalId} does not exist.`,\n });\n console.error(\"Connection ID not found\", removingExternalId);\n return;\n }\n removingExternalUserIds.add(removingExternalId);\n }\n for (const removingExternalId of removingExternalUserIds) {\n const removingInternalId = this.externalIdToInternalId.get(removingExternalId);\n if (removingInternalId === undefined) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${removingExternalId} does not exist.`,\n });\n console.error(\n \"Connection ID not found in externalIdToInternalId map\",\n removingExternalId,\n );\n return;\n }\n if (removedExternalToInternalUserIds.has(removingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${removingExternalId} is duplicated.`,\n });\n console.error(\"Connection ID is duplicated in disconnectUsers\", removingExternalId);\n return;\n }\n removedExternalToInternalUserIds.set(removingExternalId, removingInternalId);\n }\n\n if (this.networkedDOM === null) {\n for (const [removingExternalId, removingInternalId] of removedExternalToInternalUserIds) {\n this.externalConnectionIds.delete(removingExternalId);\n this.externalIdToInternalId.delete(removingExternalId);\n this.internalIdToExternalId.delete(removingInternalId);\n this.internalIdToToken.delete(removingInternalId);\n }\n } else {\n const removalDiffs = this.networkedDOM.disconnectUsers(\n this,\n removedExternalToInternalUserIds,\n );\n if (removalDiffs.length > 0) {\n this.sendMessages(removalDiffs);\n }\n }\n return;\n }\n case \"pong\":\n // Ignore pongs\n return;\n case \"event\": {\n if (!this.networkedDOM) {\n console.error(\"NetworkedDOM not set on connection that received event\", this);\n return;\n }\n const externalId = parsed.connectionId;\n const internalId = this.externalIdToInternalId.get(externalId);\n if (internalId === undefined) {\n this.sendMessage({\n type: \"error\",\n message: `Event sent with connection id ${parsed.connectionId}, but that connection id has not been connected.`,\n });\n console.error(\n \"Connection ID not found in externalIdToInternalId map\",\n parsed.connectionId,\n );\n return;\n }\n\n this.networkedDOM.dispatchRemoteEvent(this, internalId, externalId, {\n nodeId: parsed.nodeId,\n name: parsed.name,\n bubbles: parsed.bubbles ?? true,\n params: parsed.params,\n });\n return;\n }\n default:\n console.error(\"Unknown message type from client\", parsed);\n }\n }\n\n public handleBufferedMessages() {\n const awaiting = this.messagesAwaitingNetworkedDOM;\n this.messagesAwaitingNetworkedDOM = [];\n for (const message of awaiting) {\n this.handleClientMessage(message);\n }\n }\n}\n", "import {\n BufferWriter,\n encodeAttributesChanged,\n encodeChildrenAdded,\n encodeChildrenRemoved,\n encodeDocumentTime,\n encodePing,\n encodeTextChanged,\n NetworkedDOMV01AttributeChangedDiff,\n NetworkedDOMV01ChildrenChangedDiff,\n NetworkedDOMV01NodeDescription,\n NetworkedDOMV01ServerMessage,\n NetworkedDOMV01SnapshotMessage,\n NetworkedDOMV02AttributesChangedDiff,\n NetworkedDOMV02ChildrenRemovedDiff,\n NetworkedDOMV02Diff,\n NetworkedDOMV02NodeDescription,\n NetworkedDOMV02PingMessage,\n NetworkedDOMV02SnapshotMessage,\n NetworkedDOMV02TextChangedDiff,\n} from \"@mml-io/networked-dom-protocol\";\nimport {\n LogMessage,\n ObservableDOMInterface,\n ObservableDOMMessage,\n ObservableDOMParameters,\n ObservableDOMRemoteEvent,\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\n\nimport {\n createNetworkedDOMConnectionForWebsocket,\n SupportedWebsocketSubProtocolsPreferenceOrder,\n} from \"./createNetworkedDOMConnectionForWebsocket\";\nimport {\n calculateStaticVirtualDOMDiff,\n VirtualDOMDiffStruct,\n} from \"./diffing/calculateStaticVirtualDOMDiff\";\nimport {\n describeNodeWithChildrenForV01Connection,\n describeNodeWithChildrenForV02Connection,\n hiddenFromAttrName,\n visibleToAttrName,\n} from \"./diffing/describeNode\";\nimport { listAttributeToSet } from \"./diffing/listAttributeToSet\";\nimport { mergeMutations } from \"./diffing/mergeMutations\";\nimport { virtualDOMDiffToVirtualDOMMutationRecord } from \"./diffing/virtualDOMDiffToVirtualDOMMutationRecord\";\nimport { NetworkedDOMV01Connection } from \"./NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"./NetworkedDOMV02Connection\";\nimport { NodeManager } from \"./NodeManager\";\nimport {\n applySubjectivityToChildren,\n IsVisibleToAll,\n IsVisibleToAnyOneOfConnectionIds,\n NodeWithSubjectivity,\n Subjectivity,\n} from \"./NodeWithSubjectivity\";\nimport { applyPatch } from \"./rfc6902\";\nimport { VisibilityManager } from \"./VisibilityManager\";\n\nconst VisibleToMode = Symbol(\"VisibleToMode\");\nconst HiddenFromMode = Symbol(\"HiddenFromMode\");\n\nexport type ObservableDOMFactory = (\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n) => ObservableDOMInterface;\n\ntype PreVisibilityChangeRecords = {\n priorVisibleToV01Connections: Set<NetworkedDOMV01Connection>;\n priorVisibleToV02Connections: Set<NetworkedDOMV02Connection>;\n previousSubjectivity: Subjectivity;\n};\n\n/**\n * NetworkedDOM is the main class for the networked-dom-document package. It is responsible for managing the state of\n * the document and the connections to the clients.\n *\n * It is constructed with an ObservableDOMFactory, which is responsible for creating the ObservableDOMInterface\n * implementation that is used to run the document.\n */\nexport class NetworkedDOM {\n private visibilityManager = new VisibilityManager();\n private nodeManager = new NodeManager(this.visibilityManager);\n\n private currentConnectionId = 1;\n\n private connectionIdToNetworkedDOMConnection = new Map<\n number,\n NetworkedDOMV01Connection | NetworkedDOMV02Connection\n >();\n private networkedDOMV01Connections = new Set<NetworkedDOMV01Connection>();\n private networkedDOMV02Connections = new Set<NetworkedDOMV02Connection>();\n private webSocketToNetworkedDOMConnection = new Map<\n WebSocket,\n NetworkedDOMV01Connection | NetworkedDOMV02Connection\n >();\n\n private initialLoad = true;\n private readonly htmlPath: string;\n\n private ignoreTextNodes: boolean;\n\n private documentRoot!: NodeWithSubjectivity;\n\n private observableDOM: ObservableDOMInterface;\n\n private documentEffectiveStartTime = Date.now();\n private latestDocumentTime = 0;\n private pingCounter = 1;\n\n private logCallback?: (message: LogMessage) => void;\n\n private disposed = false;\n\n constructor(\n observableDOMFactory: ObservableDOMFactory,\n htmlPath: string,\n htmlContents: string,\n oldInstanceDocumentRoot: StaticVirtualDOMElement | null,\n onLoad: (domDiff: VirtualDOMDiffStruct | null, networkedDOM: NetworkedDOM) => void,\n params = {},\n ignoreTextNodes = true,\n logCallback?: (message: LogMessage) => void,\n ) {\n this.htmlPath = htmlPath;\n this.ignoreTextNodes = ignoreTextNodes;\n\n this.logCallback = logCallback || this.defaultLogCallback;\n\n this.observableDOM = observableDOMFactory(\n {\n htmlPath,\n htmlContents,\n params,\n ignoreTextNodes,\n pingIntervalMilliseconds: 5000,\n },\n (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => {\n if (this.disposed) {\n return;\n }\n this.observableDOM = observableDOM;\n if (message.documentTime) {\n this.documentEffectiveStartTime = Date.now() - message.documentTime;\n this.latestDocumentTime = message.documentTime;\n }\n if (message.snapshot) {\n const clonedSnapshot = JSON.parse(JSON.stringify(message.snapshot));\n\n if (!this.initialLoad) {\n throw new Error(\"Received snapshot after initial load\");\n }\n this.initialLoad = false;\n\n let domDiff: VirtualDOMDiffStruct | null = null;\n if (oldInstanceDocumentRoot) {\n domDiff = calculateStaticVirtualDOMDiff(\n JSON.parse(JSON.stringify(oldInstanceDocumentRoot)),\n clonedSnapshot,\n );\n for (const remapping of domDiff.nodeIdRemappings) {\n this.nodeManager.addRemappedNodeId(\n remapping.clientFacingNodeId,\n remapping.internalNodeId,\n );\n }\n /*\n Use the original document root as the starting state and the diff\n will be applied to it with the connections attached to ensure they\n get the updates\n */\n const [mappedRootNode] = this.nodeManager.addNodeFromInstance(\n JSON.parse(JSON.stringify(oldInstanceDocumentRoot)),\n null,\n );\n this.documentRoot = mappedRootNode;\n } else {\n const [mappedRootNode] = this.nodeManager.addNodeFromInstance(\n JSON.parse(JSON.stringify(message.snapshot)),\n null,\n );\n this.documentRoot = mappedRootNode;\n }\n\n onLoad(domDiff, this);\n } else if (message.mutations) {\n if (this.initialLoad) {\n throw new Error(\"Received mutation before initial load\");\n }\n\n const merged = mergeMutations(message.mutations);\n if (merged.length > 1) {\n for (const client of this.networkedDOMV02Connections) {\n client.setBatchStart();\n }\n }\n for (const mutation of merged) {\n this.handleMutation(mutation);\n }\n if (merged.length > 1) {\n for (const client of this.networkedDOMV02Connections) {\n client.setBatchEnd();\n }\n }\n } else if (message.logMessage) {\n if (this.logCallback) {\n this.logCallback(message.logMessage);\n }\n } else {\n if (message.documentTime) {\n // This is just a regular ping message to update the document time - send the document time to all connected clients\n this.sendPings();\n return;\n }\n console.error(\"Unknown message type from observableDOM\", message);\n }\n },\n );\n }\n\n public static handleWebsocketSubprotocol(protocols: Set<string> | Array<string>): string | false {\n const protocolsSet = new Set(protocols);\n // Find highest priority (first in the array) protocol that is supported\n for (const protocol of SupportedWebsocketSubProtocolsPreferenceOrder) {\n if (protocolsSet.has(protocol)) {\n return protocol;\n }\n }\n return false;\n }\n\n public addWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = createNetworkedDOMConnectionForWebsocket(webSocket);\n if (networkedDOMConnection === null) {\n // Error is handled in createNetworkedDOMConnectionForWebsocket\n return;\n }\n this.addNetworkedDOMConnection(networkedDOMConnection);\n }\n\n public removeWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = this.webSocketToNetworkedDOMConnection.get(webSocket);\n if (networkedDOMConnection === undefined) {\n throw new Error(\"Unknown websocket\");\n }\n this.removeNetworkedDOMConnection(networkedDOMConnection);\n }\n\n public hasWebSocket(webSocket: WebSocket): boolean {\n return this.webSocketToNetworkedDOMConnection.has(webSocket);\n }\n\n public addExistingNetworkedDOMConnections(\n networkedDOMConnections: Set<NetworkedDOMV01Connection | NetworkedDOMV02Connection>,\n domDiff: VirtualDOMDiffStruct | null,\n ) {\n for (const networkedDOMConnection of networkedDOMConnections) {\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n networkedDOMConnection.setNetworkedDOM(this);\n this.networkedDOMV01Connections.add(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n } else if (networkedDOMConnection instanceof NetworkedDOMV02Connection) {\n networkedDOMConnection.setNetworkedDOM(this);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n for (const connectionId of networkedDOMConnection.internalIdToExternalId.keys()) {\n this.connectionIdToNetworkedDOMConnection.set(connectionId, networkedDOMConnection);\n }\n this.networkedDOMV02Connections.add(networkedDOMConnection);\n } else {\n throw new Error(\"Unknown websocket subprotocol\");\n }\n }\n\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n for (const [connectionId, token] of networkedDOMConnection.internalIdToToken) {\n if (connectionId >= this.currentConnectionId) {\n this.currentConnectionId = connectionId + 1;\n }\n this.observableDOM.addConnectedUserId(connectionId, token);\n }\n }\n\n // Handle v0.1 connections second so that the connection IDs from v0.2 are not reused if a v0.1 connection is only initialized now\n for (const networkedDOMConnection of this.networkedDOMV01Connections) {\n if (networkedDOMConnection.internalConnectionId === null) {\n networkedDOMConnection.initAsNewV01Connection();\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.observableDOM.addConnectedUserId(networkedDOMConnection.internalConnectionId!, null);\n }\n\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n networkedDOMConnection.handleBufferedMessages();\n }\n\n if (domDiff) {\n const emptyChildrenChanged: Array<NetworkedDOMV01ServerMessage> = [\n {\n type: \"childrenChanged\",\n nodeId: this.documentRoot.nodeId,\n previousNodeId: null,\n addedNodes: [],\n removedNodes: [],\n documentTime: this.getDocumentTime(),\n },\n ];\n const encoded = JSON.stringify(emptyChildrenChanged);\n for (const networkedDOMV01Connection of this.networkedDOMV01Connections) {\n networkedDOMV01Connection.sendStringifiedJSONArray(encoded);\n }\n const encodedDocumentTime = encodeDocumentTime({\n type: \"documentTime\",\n documentTime: this.getDocumentTime(),\n }).getBuffer();\n for (const networkedDOMV02Connection of this.networkedDOMV02Connections) {\n networkedDOMV02Connection.sendEncodedBytes(encodedDocumentTime);\n }\n\n const virtualDOMDiff = domDiff.virtualDOMDiffs[0];\n if (\n domDiff.virtualDOMDiffs.length === 1 &&\n virtualDOMDiff.op === \"replace\" &&\n virtualDOMDiff.path === \"\" &&\n virtualDOMDiff.value.tag === \"div\" &&\n virtualDOMDiff.value.childNodes.length === 0\n ) {\n // The patch is effectively emptying the document. Remove all nodes from the root\n const rootChildrenIds = this.documentRoot.childNodes.map((child) => child.nodeId);\n this.handleMutation(\n {\n type: \"childList\",\n targetId: this.documentRoot.nodeId,\n addedNodes: [],\n removedNodeIds: rootChildrenIds,\n previousSiblingId: null,\n },\n false,\n );\n } else {\n for (const virtualDOMDiff of domDiff.virtualDOMDiffs) {\n // Convert the diff of the virtual dom data structure to a MutationRecord-like diff and then handle it as if it were a MutationRecord\n // The difficulty here is that the JSON diff is typed by add/remove/replace of elements of a hierarchy specified by paths, but MutationRecords are specified by type of operation and nodeIds\n const mutationRecordLikes = virtualDOMDiffToVirtualDOMMutationRecord(\n domDiff.originalState,\n virtualDOMDiff,\n );\n\n if (virtualDOMDiff.path === \"\" && virtualDOMDiff.op === \"replace\") {\n // The patch is a snapshot replacement - no need to check the patch validity\n } else {\n const patchResults = applyPatch(domDiff.originalState, [virtualDOMDiff]);\n for (const patchResult of patchResults) {\n if (patchResult !== null) {\n console.error(\"Patching virtual dom structure resulted in error\", patchResult);\n throw patchResult;\n }\n }\n }\n\n const merged = mergeMutations(mutationRecordLikes);\n for (const mutation of merged) {\n this.handleMutation(mutation, false);\n }\n }\n }\n } else {\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n for (const networkedDOMConnection of this.networkedDOMV01Connections) {\n networkedDOMConnection.stringifyAndSendSingleMessage(\n this.getInitialV01Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n }\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n networkedDOMConnection.sendMessage(\n this.getInitialV02Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n }\n }\n }\n\n public addNetworkedDOMConnection(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n ): void {\n if (this.initialLoad) {\n throw new Error(\"addWebSocket called before initial load - unsupported at this time\");\n }\n if (this.disposed) {\n throw new Error(\"This NetworkedDOM has been disposed\");\n }\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n networkedDOMConnection.setNetworkedDOM(this);\n\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n if (networkedDOMConnection.internalConnectionId === null) {\n // Create the single connection ID for the client\n networkedDOMConnection.initAsNewV01Connection();\n }\n this.networkedDOMV01Connections.add(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n networkedDOMConnection.stringifyAndSendSingleMessage(\n this.getInitialV01Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n } else {\n this.networkedDOMV02Connections.add(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n for (const [connectionId, token] of networkedDOMConnection.internalIdToToken) {\n this.observableDOM.addConnectedUserId(connectionId, token);\n }\n networkedDOMConnection.sendMessage(\n this.getInitialV02Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n }\n }\n\n public removeNetworkedDOMConnection(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n ): void {\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n if (!this.networkedDOMV01Connections.has(networkedDOMConnection)) {\n throw new Error(\"Unrecognized networkedDOMConnection\");\n }\n if (networkedDOMConnection.internalConnectionId !== null) {\n this.observableDOM.removeConnectedUserId(networkedDOMConnection.internalConnectionId);\n this.connectionIdToNetworkedDOMConnection.delete(\n networkedDOMConnection.internalConnectionId,\n );\n }\n this.networkedDOMV01Connections.delete(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.delete(networkedDOMConnection.webSocket);\n networkedDOMConnection.setNetworkedDOM(null);\n } else if (networkedDOMConnection instanceof NetworkedDOMV02Connection) {\n if (!this.networkedDOMV02Connections.has(networkedDOMConnection)) {\n throw new Error(\"Unrecognized networkedDOMConnection\");\n }\n for (const [internalConnectionId] of networkedDOMConnection.internalIdToExternalId) {\n this.observableDOM.removeConnectedUserId(internalConnectionId);\n this.connectionIdToNetworkedDOMConnection.delete(internalConnectionId);\n }\n this.networkedDOMV02Connections.delete(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.delete(networkedDOMConnection.webSocket);\n networkedDOMConnection.setNetworkedDOM(null);\n }\n }\n\n public connectUsers(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n addedExternalUserIds: Set<number>,\n ): Map<number, number> {\n const connectionIdToExternalId = new Map<number, number>();\n for (const externalId of addedExternalUserIds) {\n const internalId = this.currentConnectionId++;\n this.connectionIdToNetworkedDOMConnection.set(internalId, networkedDOMConnection);\n connectionIdToExternalId.set(internalId, externalId);\n }\n return connectionIdToExternalId;\n }\n\n // Called by the connections after storing the mapping of connected users ids\n public announceConnectedUsers(userIds: Map<number, string | null>) {\n for (const [userId, token] of userIds) {\n this.observableDOM.addConnectedUserId(userId, token);\n }\n }\n\n public disconnectUsers(\n networkedDOMConnection: NetworkedDOMV02Connection,\n removedExternalToInternalUserIds: Map<number, number>,\n ): Array<NetworkedDOMV02Diff> {\n const potentiallyAffectedNodeIds = new Set<number>();\n for (const [, removingInternalId] of removedExternalToInternalUserIds) {\n const affectedNodes = this.visibilityManager.getSpecificallyVisibleNodes(removingInternalId);\n if (affectedNodes) {\n for (const nodeId of affectedNodes) {\n potentiallyAffectedNodeIds.add(nodeId);\n }\n }\n }\n\n for (const nodeId of potentiallyAffectedNodeIds) {\n const node = this.nodeManager.getNode(nodeId);\n if (!node) {\n console.error(\"node not found\", nodeId);\n continue;\n }\n if (\n node.subjectivity != null &&\n !IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n )\n ) {\n // If the node isn't visible to this connection anyway then remove it from the map\n potentiallyAffectedNodeIds.delete(nodeId);\n }\n }\n\n for (const [removingExternalId, removingInternalId] of removedExternalToInternalUserIds) {\n this.observableDOM.removeConnectedUserId(removingInternalId);\n networkedDOMConnection.externalConnectionIds.delete(removingExternalId);\n networkedDOMConnection.externalIdToInternalId.delete(removingExternalId);\n networkedDOMConnection.internalIdToExternalId.delete(removingInternalId);\n networkedDOMConnection.internalIdToToken.delete(removingInternalId);\n this.connectionIdToNetworkedDOMConnection.delete(removingInternalId);\n }\n\n // Remove the nodes that are only visible to this connection because of\n // connection ids that are being removed - need to do a fresh\n // determination of visibility because the nodes might have other reasons\n // to be visible to this connection\n\n const removedMessagesByParent = new Map<number, NetworkedDOMV02ChildrenRemovedDiff>();\n for (const nodeId of potentiallyAffectedNodeIds) {\n const node = this.nodeManager.getNode(nodeId);\n if (!node) {\n console.error(\"node not found\", nodeId);\n continue;\n }\n if (\n node.subjectivity != null &&\n !IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n )\n ) {\n // The node is not visible to this connection anymore.\n // The issue now is whether the node might be not visible because a parent visibility was also changed.\n // We can't send removals for children after the parent has already been removed so we need to check if the parent is still visible\n if (\n node.parent != null &&\n (node.parent.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n node.parent.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n ))\n ) {\n // The parent is still visible so we can send the removal message\n let existingMessage = removedMessagesByParent.get(node.parent.nodeId);\n if (!existingMessage) {\n existingMessage = {\n type: \"childrenRemoved\",\n nodeId: node.parent.nodeId,\n removedNodes: [],\n };\n removedMessagesByParent.set(node.parent.nodeId, existingMessage);\n }\n existingMessage.removedNodes.push(nodeId);\n }\n }\n }\n\n return Array.from(removedMessagesByParent.values());\n }\n\n private defaultLogCallback(message: LogMessage) {\n const getLogFn = (level: string) => {\n switch (level) {\n case \"system\":\n return console.error;\n case \"error\":\n return console.error;\n case \"warn\":\n return console.warn;\n case \"log\":\n return console.log;\n case \"info\":\n return console.info;\n default:\n return console.log;\n }\n };\n\n const logFn = getLogFn(message.level);\n logFn(`${message.level.toUpperCase()} (${this.htmlPath}):`, ...message.content);\n }\n\n private sendPings() {\n const ping = this.pingCounter++;\n if (this.pingCounter > 1000) {\n this.pingCounter = 1;\n }\n const v01PingMessage: Array<NetworkedDOMV01ServerMessage> = [\n {\n type: \"ping\",\n ping,\n documentTime: this.getDocumentTime(),\n },\n ];\n const v01Encoded = JSON.stringify(v01PingMessage);\n const v02PingMessage: NetworkedDOMV02PingMessage = {\n type: \"ping\",\n ping,\n documentTime: this.getDocumentTime(),\n };\n const writer = new BufferWriter(8);\n encodePing(v02PingMessage, writer);\n const v02Encoded = writer.getBuffer();\n this.networkedDOMV01Connections.forEach((networkedDOMConnection) => {\n networkedDOMConnection.webSocket.send(v01Encoded);\n });\n this.networkedDOMV02Connections.forEach((networkedDOMConnection) => {\n networkedDOMConnection.webSocket.send(v02Encoded);\n });\n }\n\n private getInitialV01Snapshot(\n networkedDOMConnection: NetworkedDOMV01Connection,\n documentVirtualDOMElement: NodeWithSubjectivity,\n ): NetworkedDOMV01SnapshotMessage {\n const domSnapshot: NetworkedDOMV01NodeDescription | null =\n describeNodeWithChildrenForV01Connection(documentVirtualDOMElement, networkedDOMConnection);\n if (!domSnapshot) {\n throw new Error(`domSnapshot was not generated`);\n }\n return {\n type: \"snapshot\",\n snapshot: domSnapshot,\n documentTime: Date.now() - this.documentEffectiveStartTime,\n };\n }\n\n private getInitialV02Snapshot(\n networkedDOMConnection: NetworkedDOMV02Connection,\n documentVirtualDOMElement: NodeWithSubjectivity,\n ): NetworkedDOMV02SnapshotMessage {\n const domSnapshot: NetworkedDOMV02NodeDescription | null =\n describeNodeWithChildrenForV02Connection(documentVirtualDOMElement, networkedDOMConnection);\n if (!domSnapshot) {\n throw new Error(`domSnapshot was not generated`);\n }\n return {\n type: \"snapshot\",\n snapshot: domSnapshot,\n documentTime: Date.now() - this.documentEffectiveStartTime,\n };\n }\n\n public getDocumentTime(): number {\n return this.latestDocumentTime;\n }\n\n public dispatchRemoteEvent(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n internalConnectionId: number,\n externalConnectionId: number,\n remoteEvent: ObservableDOMRemoteEvent,\n ): void {\n if (this.disposed) {\n console.error(\"Cannot dispatch remote event after dispose\");\n throw new Error(\"This NetworkedDOM has been disposed\");\n }\n\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(\n remoteEvent.nodeId,\n );\n if (\n !node ||\n !IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n new Map<number, number>([[internalConnectionId, 1]]),\n true,\n )\n ) {\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n networkedDOMConnection.stringifyAndSendSingleMessage({\n type: \"warning\",\n message: `Node ${remoteEvent.nodeId} not found or not visible`,\n });\n } else if (networkedDOMConnection instanceof NetworkedDOMV02Connection) {\n networkedDOMConnection.sendMessage({\n type: \"warning\",\n message: `Node ${remoteEvent.nodeId} not found or not visible to connection ${externalConnectionId}`,\n });\n } else {\n console.error(\"Unknown networkedDOMConnection type. Cannot send warning.\");\n }\n return;\n }\n\n /*\n The node id sent in the remote event is the client-facing node id (and the\n one used within this class), but the node id might have been remapped from\n the underlying ObservableDOM instance so it needs mapping back\n */\n const remappedNode = this.nodeManager.getInternalRemappedNodeId(remoteEvent.nodeId);\n if (remappedNode) {\n remoteEvent.nodeId = remappedNode;\n }\n\n this.observableDOM.dispatchRemoteEventFromConnectionId(internalConnectionId, remoteEvent);\n }\n\n public getSnapshot(): StaticVirtualDOMElement {\n // Need to recreate the snapshot from the current document root because the document root has recursive parent references\n function toStaticVirtualDOMElement(node: NodeWithSubjectivity): StaticVirtualDOMElement {\n const attributes = { ...node.attributes };\n\n const hasOwnSubjectivity = node.parent && node.subjectivity !== node.parent.subjectivity;\n if (hasOwnSubjectivity) {\n if (node.subjectivity.visibleTo.size > 0) {\n attributes[visibleToAttrName] = Array.from(node.subjectivity.visibleTo).join(\" \");\n }\n if (node.subjectivity.hiddenFrom.size > 0) {\n attributes[hiddenFromAttrName] = Array.from(node.subjectivity.hiddenFrom).join(\" \");\n }\n }\n\n return {\n nodeId: node.nodeId,\n tag: node.tag,\n textContent: node.textContent,\n attributes,\n childNodes: node.childNodes.map(toStaticVirtualDOMElement),\n };\n }\n return toStaticVirtualDOMElement(this.documentRoot);\n }\n\n public dispose(): void {\n this.disposed = true;\n\n for (const networkedDOMConnection of this.networkedDOMV01Connections) {\n networkedDOMConnection.setNetworkedDOM(null);\n }\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n networkedDOMConnection.setNetworkedDOM(null);\n }\n\n // Handle all of the remaining mutations that the disconnections could have caused\n this.observableDOM.dispose();\n }\n\n private handleAddedNodes(\n targetId: number,\n previousSiblingId: number | null,\n addedNodes: Array<StaticVirtualDOMElement>,\n ) {\n const target = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!target) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n let hasSubjectiveChildren = false; // true if childrenChanged and children have visibleTo or hiddenFrom\n\n let previousNodeIdIsSubjectiveForV01 = false;\n let previousNodeIdIsSubjectiveForV02 = false;\n const parentIsSubjectiveForV01 =\n target.subjectivity != null && !IsVisibleToAll(target.subjectivity, true);\n const parentIsSubjectiveForV02 =\n target.subjectivity != null && !IsVisibleToAll(target.subjectivity, false);\n\n const addedNodesWithSubjectivity: Array<NodeWithSubjectivity> = [];\n\n let previousNode: NodeWithSubjectivity | null = null;\n let previousNodeIndex = -1;\n if (previousSiblingId != null) {\n previousNode =\n this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(previousSiblingId) ||\n null;\n if (!previousNode) {\n throw new Error(\"previous node not found: \" + previousSiblingId);\n } else {\n previousNodeIdIsSubjectiveForV01 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, true);\n previousNodeIdIsSubjectiveForV02 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, false);\n for (let i = 0; i < target.childNodes.length; i++) {\n const child = target.childNodes[i];\n if (child.nodeId === previousNode.nodeId) {\n previousNodeIndex = i;\n break;\n }\n }\n }\n }\n\n for (const addedNode of addedNodes) {\n const [addedNodeWithSubjectivity, addedNodeHasSubjectivity] =\n this.nodeManager.addNodeFromInstance(addedNode, target);\n if (addedNodeHasSubjectivity) {\n hasSubjectiveChildren = true;\n }\n if (addedNodeWithSubjectivity != null) {\n addedNodesWithSubjectivity.push(addedNodeWithSubjectivity);\n }\n }\n\n if (previousNode !== null) {\n // The previousNodeId is present, so we need to insert the addedNodes after the previousNode\n\n let index = previousNodeIndex + 1;\n for (const childVirtualDOMElement of addedNodesWithSubjectivity) {\n target.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n } else {\n // The previousNodeId is not present, so we need to prepend the addedNodes\n target.childNodes = addedNodesWithSubjectivity.concat(target.childNodes);\n }\n\n // v01 connections\n if (parentIsSubjectiveForV01 || hasSubjectiveChildren || previousNodeIdIsSubjectiveForV01) {\n // Need to go through each connection and project the children that should be visible to that connection\n\n for (const client of this.networkedDOMV01Connections) {\n const canSeeParent =\n target.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n target.subjectivity,\n client.internalIdToExternalId,\n true,\n );\n if (!canSeeParent) {\n continue;\n }\n let projectedPreviousNodeId: number | null = null;\n if (previousNode != null) {\n if (previousNodeIdIsSubjectiveForV01) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n\n for (let i = previousNodeIndex; i >= 0; i--) {\n const child = target.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n projectedPreviousNodeId = child.nodeId;\n break;\n }\n }\n } else {\n projectedPreviousNodeId = previousNode.nodeId;\n }\n }\n const projectedChildren: Array<NetworkedDOMV01NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n if (\n addedNode.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n addedNode.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n const node = describeNodeWithChildrenForV01Connection(addedNode, client);\n if (node != null) {\n projectedChildren.push(node);\n }\n }\n }\n if (projectedChildren.length > 0) {\n client.stringifyAndSendSingleMessage({\n type: \"childrenChanged\",\n nodeId: target.nodeId,\n previousNodeId: projectedPreviousNodeId,\n addedNodes: projectedChildren,\n removedNodes: [],\n });\n }\n }\n } else {\n if (this.networkedDOMV01Connections.size > 0) {\n const projectedChildren: Array<NetworkedDOMV01NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n const node = describeNodeWithChildrenForV01Connection(addedNode, null);\n if (node !== null) {\n projectedChildren.push(node);\n }\n }\n const reprojectedMsg: NetworkedDOMV01ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: target.nodeId,\n previousNodeId: previousNode ? previousNode.nodeId : null,\n addedNodes: projectedChildren,\n removedNodes: [],\n };\n const encoded = JSON.stringify([reprojectedMsg]);\n\n // forward to all clients as all clients should see this change\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n // v02 connections\n if (parentIsSubjectiveForV02 || hasSubjectiveChildren || previousNodeIdIsSubjectiveForV02) {\n // Need to go through each connection and project the children that should be visible to that connection\n\n for (const client of this.networkedDOMV02Connections) {\n const canSeeParent =\n target.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n target.subjectivity,\n client.internalIdToExternalId,\n false,\n );\n if (!canSeeParent) {\n continue;\n }\n let projectedPreviousNodeId: number | null = null;\n if (previousNode != null) {\n if (previousNodeIdIsSubjectiveForV02) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n\n for (let i = previousNodeIndex; i >= 0; i--) {\n const child = target.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n projectedPreviousNodeId = child.nodeId;\n break;\n }\n }\n } else {\n projectedPreviousNodeId = previousNode.nodeId;\n }\n }\n const projectedChildren: Array<NetworkedDOMV02NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n if (\n addedNode.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n addedNode.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n const node = describeNodeWithChildrenForV02Connection(addedNode, client);\n if (node != null) {\n projectedChildren.push(node);\n }\n }\n }\n if (projectedChildren.length > 0) {\n client.sendMessage({\n type: \"childrenAdded\",\n nodeId: target.nodeId,\n previousNodeId: projectedPreviousNodeId === null ? 0 : projectedPreviousNodeId,\n addedNodes: projectedChildren,\n });\n }\n }\n } else {\n const projectedChildren: Array<NetworkedDOMV02NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n const node = describeNodeWithChildrenForV02Connection(addedNode, null);\n if (node != null) {\n projectedChildren.push(node);\n }\n }\n const encoded = encodeChildrenAdded({\n type: \"childrenAdded\",\n nodeId: target.nodeId,\n previousNodeId: previousNode === null ? 0 : previousNode.nodeId,\n addedNodes: projectedChildren,\n }).getBuffer();\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n }\n\n private handleRemovedNodes(targetId: number, removedNodeIds: Array<number>) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const parentIsSubjectiveForV01 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, true);\n let anyChildIsSubjectiveForV01 = false;\n const parentIsSubjectiveForV02 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, false);\n let anyChildIsSubjectiveForV02 = false;\n\n const removedSet = new Set(removedNodeIds);\n\n for (let i = 0; i < node.childNodes.length; i++) {\n const child = node.childNodes[i];\n if (removedSet.has(child.nodeId)) {\n if (child.subjectivity != null && !IsVisibleToAll(child.subjectivity, true)) {\n anyChildIsSubjectiveForV01 = true;\n }\n if (child.subjectivity != null && !IsVisibleToAll(child.subjectivity, false)) {\n anyChildIsSubjectiveForV02 = true;\n }\n node.childNodes.splice(i, 1);\n break;\n }\n }\n\n // v01 connections\n if (parentIsSubjectiveForV01 || anyChildIsSubjectiveForV01) {\n // Need to go through each connection and project the children\n for (const client of this.networkedDOMV01Connections) {\n const removableChildren = [];\n for (const removedNodeId of removedNodeIds) {\n const child =\n this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(removedNodeId);\n if (!child) {\n throw new Error(\"Child not found for removed node id: \" + removedNodeId);\n }\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n removableChildren.push(removedNodeId);\n }\n }\n if (removableChildren.length > 0) {\n client.stringifyAndSendSingleMessage({\n type: \"childrenChanged\",\n nodeId: node.nodeId,\n addedNodes: [],\n previousNodeId: null,\n removedNodes: removableChildren,\n });\n }\n }\n } else {\n if (this.networkedDOMV01Connections.size > 0) {\n const msg: NetworkedDOMV01ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: node.nodeId,\n addedNodes: [],\n previousNodeId: null,\n removedNodes: removedNodeIds,\n };\n const encoded = JSON.stringify([msg]);\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n // v02 connections\n if (parentIsSubjectiveForV02 || anyChildIsSubjectiveForV02) {\n // Need to go through each connection and project the children\n for (const client of this.networkedDOMV02Connections) {\n const removableChildren = [];\n for (const removedNodeId of removedNodeIds) {\n const child =\n this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(removedNodeId);\n if (!child) {\n throw new Error(\"Child not found for removed node id: \" + removedNodeId);\n }\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n removableChildren.push(removedNodeId);\n }\n }\n if (removableChildren.length > 0) {\n client.sendMessage({\n type: \"childrenRemoved\",\n nodeId: node.nodeId,\n removedNodes: removableChildren,\n });\n }\n }\n } else {\n // forward to all clients\n const msg: NetworkedDOMV02ChildrenRemovedDiff = {\n type: \"childrenRemoved\",\n nodeId: node.nodeId,\n removedNodes: removedNodeIds,\n };\n const encoded = encodeChildrenRemoved(msg).getBuffer();\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n\n // Only delete the children from the nodeIdMap once we have finished projecting the children\n for (const removedNodeId of removedNodeIds) {\n this.removeNodeAndChildren(removedNodeId);\n }\n }\n\n private handleAttributeMutation(\n targetId: number,\n attributes: {\n [p: string]: string | null;\n },\n ) {\n const target = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!target) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const resultAttributes: { [key: string]: string | null } = {};\n for (const [key, value] of Object.entries(attributes)) {\n if (key === visibleToAttrName) {\n const hasOwnSubjectivity = target.subjectivity !== target.parent?.subjectivity;\n const previousSet = hasOwnSubjectivity ? target.subjectivity.visibleTo : new Set<number>();\n const newVisibleTo = listAttributeToSet(value);\n const added = new Set(Array.from(newVisibleTo).filter((x) => !previousSet.has(x)));\n const removed = new Set(Array.from(previousSet).filter((x) => !newVisibleTo.has(x)));\n this.handleVisibleToChange(targetId, added, removed);\n continue;\n }\n if (key === hiddenFromAttrName) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const hasOwnSubjectivity = target.subjectivity !== target.parent!.subjectivity;\n const previousSet = hasOwnSubjectivity ? target.subjectivity.hiddenFrom : new Set<number>();\n const newHiddenFrom = listAttributeToSet(value);\n const added = new Set(Array.from(newHiddenFrom).filter((x) => !previousSet.has(x)));\n const removed = new Set(Array.from(previousSet).filter((x) => !newHiddenFrom.has(x)));\n this.handleHiddenFromChange(targetId, added, removed);\n continue;\n }\n const existingAttribute = target.attributes[key];\n if (value !== null) {\n if (existingAttribute === value) {\n // Already set to this value - don't need to set again\n continue;\n }\n } else {\n if (existingAttribute === undefined) {\n // Already unset - don't need to unset again\n continue;\n }\n }\n resultAttributes[key] = value;\n }\n\n if (Object.keys(resultAttributes).length > 0) {\n // There are attribute changes other than visible-to and hidden-from\n this.handleAttributeChange(targetId, resultAttributes);\n }\n }\n\n private handleAttributeChange(targetId: number, attributes: { [key: string]: string | null }) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const nodeIsSubjectiveForV01 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, true);\n const nodeIsSubjectiveForV02 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, false);\n\n for (const [attributeName, value] of Object.entries(attributes)) {\n if (value !== null) {\n node.attributes[attributeName] = value;\n } else {\n delete node.attributes[attributeName];\n }\n }\n\n // v01 connections\n if (this.networkedDOMV01Connections.size > 0) {\n const allMessages: Array<NetworkedDOMV01ServerMessage> = [];\n\n for (const [attributeName, value] of Object.entries(attributes)) {\n const reprojectedMsg: NetworkedDOMV01AttributeChangedDiff = {\n type: \"attributeChange\",\n nodeId: node.nodeId,\n attribute: attributeName,\n newValue: value,\n };\n allMessages.push(reprojectedMsg);\n }\n const encoded = JSON.stringify(allMessages);\n if (nodeIsSubjectiveForV01) {\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n client.internalIdToExternalId,\n true,\n );\n if (canSee) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n } else {\n // forward to interested clients\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n const message: NetworkedDOMV02AttributesChangedDiff = {\n type: \"attributesChanged\",\n nodeId: node.nodeId,\n attributes: Object.entries(attributes).map(([attribute, value]) => [attribute, value]),\n };\n const encoded = encodeAttributesChanged(message).getBuffer();\n\n // v02 connections\n if (nodeIsSubjectiveForV02) {\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, false);\n if (canSee) {\n client.sendEncodedBytes(encoded);\n }\n }\n } else {\n // forward to all clients\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n }\n\n private handleVisibleToChange(targetId: number, added: Set<number>, removed: Set<number>) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n if (node.parent == null) {\n // TODO - handle/reject changeVisibleTo for root node\n return;\n }\n const previousSubjectivity = node.subjectivity;\n\n const visibilityRecords = this.calculatePreVisibilityChangeRecords(node);\n\n for (const internalConnectionId of removed) {\n this.visibilityManager.removeSpecificallyVisibleNode(internalConnectionId, node.nodeId);\n }\n const newVisibleTo = new Set<number>();\n for (const internalConnectionId of added) {\n newVisibleTo.add(internalConnectionId);\n\n this.visibilityManager.addSpecificallyVisibleNode(internalConnectionId, node.nodeId);\n }\n\n const hasNonInheritedSubjectivity =\n previousSubjectivity != null && previousSubjectivity !== node.parent.subjectivity;\n if (hasNonInheritedSubjectivity) {\n // This node had its own list of visibleTo connections, so we need to re-add the ids that are not being removed\n for (const connectionId of previousSubjectivity.visibleTo) {\n if (!removed.has(connectionId)) {\n newVisibleTo.add(connectionId);\n }\n }\n }\n\n if (hasNonInheritedSubjectivity) {\n // If the node has its own subjectivity then it is not inherited and the children already point to this node's subjectivity as their ancestor\n node.subjectivity.visibleTo = newVisibleTo;\n if (newVisibleTo.size === 0 && node.subjectivity.hiddenFrom.size === 0) {\n // This node's subjectivity has no effect so we can remove it and replace it with the parent's subjectivity\n if (!node.subjectivity.ancestorSubjectivity) {\n throw new Error(\"Expected ancestorSubjectivity to be set\");\n }\n node.subjectivity = node.subjectivity.ancestorSubjectivity;\n applySubjectivityToChildren(node, node.subjectivity, previousSubjectivity);\n }\n } else {\n // If this node uses the same subjectivity as the parent then it is inherited and needs its own which is then applied to all children\n const newSubjectivity: Subjectivity = {\n visibleTo: newVisibleTo,\n hiddenFrom: new Set<number>(),\n ancestorSubjectivity: previousSubjectivity, // The previous subjectivity is that of the parent/ancestor\n };\n node.subjectivity = newSubjectivity;\n applySubjectivityToChildren(node, newSubjectivity, previousSubjectivity);\n }\n\n this.applyVisibilityAfterChanges(node, visibilityRecords, added, removed, VisibleToMode);\n }\n\n private handleHiddenFromChange(targetId: number, added: Set<number>, removed: Set<number>) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n if (node.parent == null) {\n // TODO - handle/reject changeVisibleTo for root node\n return;\n }\n\n const previousSubjectivity = node.subjectivity;\n\n const visibilityRecords = this.calculatePreVisibilityChangeRecords(node);\n\n const newHiddenFrom = new Set<number>();\n for (const connectionId of added) {\n newHiddenFrom.add(connectionId);\n }\n\n const hasNonInheritedSubjectivity =\n previousSubjectivity !== null && previousSubjectivity !== node.parent.subjectivity;\n if (hasNonInheritedSubjectivity) {\n // This node had its own list of hiddenFrom connections, so we need to re-add the ids that are not being removed\n for (const connectionId of previousSubjectivity.hiddenFrom) {\n if (!removed.has(connectionId)) {\n newHiddenFrom.add(connectionId);\n }\n }\n }\n\n if (hasNonInheritedSubjectivity) {\n // If the node has its own subjectivity then it is not inherited and the children already point to this node's subjectivity as their ancestor\n node.subjectivity.hiddenFrom = newHiddenFrom;\n if (newHiddenFrom.size === 0 && node.subjectivity.visibleTo.size === 0) {\n // This node's subjectivity has no effect so we can remove it and replace it with the parent's subjectivity\n if (!node.subjectivity.ancestorSubjectivity) {\n throw new Error(\"Expected ancestorSubjectivity to be set\");\n }\n node.subjectivity = node.subjectivity.ancestorSubjectivity;\n applySubjectivityToChildren(node, node.subjectivity, previousSubjectivity);\n }\n } else {\n // If this node uses the same subjectivity as the parent then it is inherited and needs its own which is then applied to all children\n const newSubjectivity: Subjectivity = {\n hiddenFrom: newHiddenFrom,\n visibleTo: new Set<number>(),\n ancestorSubjectivity: previousSubjectivity, // The previous subjectivity is that of the parent/ancestor\n };\n node.subjectivity = newSubjectivity;\n applySubjectivityToChildren(node, newSubjectivity, previousSubjectivity);\n }\n\n this.applyVisibilityAfterChanges(node, visibilityRecords, added, removed, HiddenFromMode);\n }\n\n private handleCharacterData(targetId: number, textContent: string) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const nodeIsSubjectiveForV01 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, true);\n const nodeIsSubjectiveForV02 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, false);\n\n node.textContent = textContent;\n\n // v01 connections\n if (this.networkedDOMV01Connections.size > 0) {\n const allMessages: Array<NetworkedDOMV01ServerMessage> = [\n {\n type: \"textChanged\",\n nodeId: node.nodeId,\n text: textContent,\n },\n ];\n const encoded = JSON.stringify(allMessages);\n if (nodeIsSubjectiveForV01) {\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n client.internalIdToExternalId,\n true,\n );\n if (canSee) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n } else {\n // forward to interested clients\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n const message: NetworkedDOMV02TextChangedDiff = {\n type: \"textChanged\",\n nodeId: node.nodeId,\n text: textContent,\n };\n const encoded = encodeTextChanged(message).getBuffer();\n\n // v02 connections\n if (nodeIsSubjectiveForV02) {\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, false);\n if (canSee) {\n client.sendEncodedBytes(encoded);\n }\n }\n } else {\n // forward to all clients\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n }\n\n private calculatePreVisibilityChangeRecords(\n node: NodeWithSubjectivity,\n ): PreVisibilityChangeRecords {\n const priorVisibleToV01Connections = new Set<NetworkedDOMV01Connection>();\n const priorVisibleToV02Connections = new Set<NetworkedDOMV02Connection>();\n const previousSubjectivity = node.subjectivity;\n\n // Need to work out which connections can currently see this element and which ones will see it after the change\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n previousSubjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(previousSubjectivity, client.internalIdToExternalId, true);\n if (canSee) {\n priorVisibleToV01Connections.add(client);\n }\n }\n\n // Need to work out which connections can currently see this element and which ones will see it after the change\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n previousSubjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n previousSubjectivity,\n client.internalIdToExternalId,\n false,\n );\n if (canSee) {\n priorVisibleToV02Connections.add(client);\n }\n }\n\n return {\n priorVisibleToV01Connections,\n priorVisibleToV02Connections,\n previousSubjectivity,\n };\n }\n\n private applyVisibilityAfterChanges(\n node: NodeWithSubjectivity,\n preVisibilityChangeRecords: PreVisibilityChangeRecords,\n added: Set<number>,\n removed: Set<number>,\n mode: typeof VisibleToMode | typeof HiddenFromMode,\n ) {\n const priorVisibleToV01Connections = preVisibilityChangeRecords.priorVisibleToV01Connections;\n const priorVisibleToV02Connections = preVisibilityChangeRecords.priorVisibleToV02Connections;\n\n if (!node.parent) {\n throw new Error(\"Cannot apply visibility changes to root node\");\n }\n\n const nodeId = node.nodeId;\n let childIndex = -1;\n for (let i = 0; i < node.parent.childNodes.length; i++) {\n const child = node.parent.childNodes[i];\n if (child.nodeId === nodeId) {\n childIndex = i;\n break;\n }\n }\n\n let previousNodeId = 0;\n let previousNodeIndex: number | null = null;\n let previousNodeIsSubjectiveForV01 = false;\n let previousNodeIsSubjectiveForV02 = false;\n if (childIndex > 0) {\n previousNodeIndex = childIndex - 1;\n const previousNode = node.parent.childNodes[childIndex - 1];\n previousNodeId = previousNode.nodeId;\n previousNodeIsSubjectiveForV01 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, true);\n previousNodeIsSubjectiveForV02 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, false);\n }\n\n if (this.networkedDOMV01Connections.size > 0) {\n const removedMessage: NetworkedDOMV01ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: node.parent.nodeId,\n previousNodeId: null,\n removedNodes: [node.nodeId],\n addedNodes: [],\n };\n const encodedRemoved = JSON.stringify([removedMessage]);\n\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, true);\n const couldSeePreviously = priorVisibleToV01Connections.has(client);\n if (canSee && !couldSeePreviously) {\n // The client could not see the node before but can now - add it\n\n let previousNodeIdForClient = previousNodeId;\n if (previousNodeId !== 0) {\n // If the previous node is subjective then we need to determine which previousNode this connection can see\n if (previousNodeIsSubjectiveForV01) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n for (let i = previousNodeIndex!; i >= 0; i--) {\n const child = node.parent.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n previousNodeIdForClient = child.nodeId;\n break;\n }\n }\n } else {\n previousNodeIdForClient = previousNodeId;\n }\n }\n\n let previousNodeIdPointer: number | null = previousNodeIdForClient;\n if (previousNodeIdForClient === 0) {\n previousNodeIdPointer = null;\n }\n client.stringifyAndSendSingleMessage({\n type: \"childrenChanged\",\n nodeId: node.parent.nodeId,\n previousNodeId: previousNodeIdPointer,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n addedNodes: [describeNodeWithChildrenForV01Connection(node, client)!],\n removedNodes: [],\n });\n } else if (!canSee && couldSeePreviously) {\n // The client could see the node before but can't now - remove it\n client.sendStringifiedJSONArray(encodedRemoved);\n } else if (canSee && couldSeePreviously) {\n // The client could see the node before and can still see it - do nothing\n } else if (!canSee && !couldSeePreviously) {\n // The client could not see the node before and still can't - do nothing\n }\n }\n }\n\n if (this.networkedDOMV02Connections.size > 0) {\n const removedMessage: NetworkedDOMV02ChildrenRemovedDiff = {\n type: \"childrenRemoved\",\n nodeId: node.parent.nodeId,\n removedNodes: [node.nodeId],\n };\n const encodedRemoved = encodeChildrenRemoved(removedMessage).getBuffer();\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, false);\n const couldSeePreviously = priorVisibleToV02Connections.has(client);\n if (canSee && !couldSeePreviously) {\n // The client could not see the node before but can now - add it\n\n let previousNodeIdForClient = previousNodeId;\n if (previousNodeId !== 0) {\n // If the previous node is subjective then we need to determine which previousNode this connection can see\n if (previousNodeIsSubjectiveForV02) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n for (let i = previousNodeIndex!; i >= 0; i--) {\n const child = node.parent.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n previousNodeIdForClient = child.nodeId;\n break;\n }\n }\n } else {\n previousNodeIdForClient = previousNodeId;\n }\n }\n\n client.sendMessage({\n type: \"childrenAdded\",\n nodeId: node.parent.nodeId,\n previousNodeId: previousNodeIdForClient,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n addedNodes: [describeNodeWithChildrenForV02Connection(node, client)!],\n });\n } else if (!canSee && couldSeePreviously) {\n // The client could see the node before but can't now - remove it\n client.sendEncodedBytes(encodedRemoved);\n } else if (canSee && couldSeePreviously) {\n // The client could see the node before and can still see it - send a changeVisibleTo/changeHiddenFrom message with the projected ids\n\n if (mode === VisibleToMode) {\n const addVisibleTo = [];\n for (const connectionId of added) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n addVisibleTo.push(externalConnectionId);\n }\n }\n const removeVisibleTo = [];\n for (const connectionId of removed) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n removeVisibleTo.push(externalConnectionId);\n }\n }\n\n if (addVisibleTo.length > 0 || removeVisibleTo.length > 0) {\n client.sendMessage({\n type: \"changeVisibleTo\",\n nodeId: node.nodeId,\n addVisibleTo,\n removeVisibleTo,\n });\n }\n } else if (mode === HiddenFromMode) {\n const addHiddenFrom = [];\n for (const connectionId of added) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n addHiddenFrom.push(externalConnectionId);\n }\n }\n const removeHiddenFrom = [];\n for (const connectionId of removed) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n removeHiddenFrom.push(externalConnectionId);\n }\n }\n\n if (addHiddenFrom.length > 0 || removeHiddenFrom.length > 0) {\n client.sendMessage({\n type: \"changeHiddenFrom\",\n nodeId: node.nodeId,\n addHiddenFrom,\n removeHiddenFrom,\n });\n }\n }\n } else if (!canSee && !couldSeePreviously) {\n // The client could not see the node before and still can't - do nothing\n }\n }\n }\n }\n\n private reprojectStaticVirtualDOMElementWithMappings(\n staticVirtualDOMElement: StaticVirtualDOMElement,\n createIfCollided = false,\n ): StaticVirtualDOMElement {\n return {\n nodeId: this.nodeManager.getPotentiallyRemappedNode(\n staticVirtualDOMElement.nodeId,\n createIfCollided,\n ),\n tag: staticVirtualDOMElement.tag,\n attributes: staticVirtualDOMElement.attributes,\n childNodes: staticVirtualDOMElement.childNodes.map((child) =>\n this.reprojectStaticVirtualDOMElementWithMappings(child, createIfCollided),\n ),\n textContent: staticVirtualDOMElement.textContent,\n };\n }\n\n private reprojectMutationWithMappings(\n mutation: StaticVirtualDOMMutationIdsRecord,\n ): StaticVirtualDOMMutationIdsRecord {\n if (!this.nodeManager.hasAnyRemappings()) {\n // There are no mappings - nothing could be changed\n return mutation;\n }\n\n switch (mutation.type) {\n case \"attributes\": {\n return {\n type: \"attributes\",\n targetId: this.nodeManager.getPotentiallyRemappedNode(mutation.targetId),\n attributes: mutation.attributes,\n };\n }\n case \"characterData\": {\n return {\n type: \"characterData\",\n targetId: this.nodeManager.getPotentiallyRemappedNode(mutation.targetId),\n textContent: mutation.textContent,\n };\n }\n case \"childList\": {\n return {\n type: \"childList\",\n targetId: this.nodeManager.getPotentiallyRemappedNode(mutation.targetId),\n addedNodes: mutation.addedNodes.map((node) =>\n this.reprojectStaticVirtualDOMElementWithMappings(node, true),\n ),\n removedNodeIds: mutation.removedNodeIds.map((id) =>\n this.nodeManager.getPotentiallyRemappedNode(id),\n ),\n previousSiblingId: mutation.previousSiblingId\n ? this.nodeManager.getPotentiallyRemappedNode(mutation.previousSiblingId)\n : null,\n };\n }\n }\n }\n\n private handleMutation(originalMutation: StaticVirtualDOMMutationIdsRecord, reproject = true) {\n const mutation = reproject\n ? this.reprojectMutationWithMappings(originalMutation)\n : originalMutation;\n\n if (mutation.type === \"childList\") {\n if (mutation.addedNodes.length === 0 && mutation.removedNodeIds.length === 0) {\n return;\n }\n if (mutation.removedNodeIds.length > 0) {\n this.handleRemovedNodes(mutation.targetId, mutation.removedNodeIds);\n }\n if (mutation.addedNodes.length > 0) {\n this.handleAddedNodes(mutation.targetId, mutation.previousSiblingId, mutation.addedNodes);\n }\n } else if (mutation.type === \"attributes\") {\n this.handleAttributeMutation(mutation.targetId, mutation.attributes);\n } else if (mutation.type === \"characterData\") {\n this.handleCharacterData(mutation.targetId, mutation.textContent);\n }\n }\n\n private removeNodeAndChildren(nodeId: number) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(nodeId);\n\n if (node.subjectivity != null) {\n for (const connectionId of node.subjectivity.visibleTo) {\n this.visibilityManager.removeSpecificallyVisibleNode(connectionId, nodeId);\n }\n }\n\n this.nodeManager.deleteNode(node.nodeId);\n\n for (const child of node.childNodes) {\n this.removeNodeAndChildren(child.nodeId);\n }\n }\n}\n", "export function deepEqual(a: any, b: any): boolean {\n if (a === b) {\n return true;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n\n return a.every((elem, index) => {\n return deepEqual(elem, b[index]);\n });\n }\n\n if (typeof a === \"object\" && typeof b === \"object\" && a !== null && b !== null) {\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n\n const keys1 = Object.keys(a);\n const keys2 = Object.keys(b);\n if (keys1.length !== keys2.length || !keys1.every((key) => keys2.includes(key))) {\n return false;\n }\n\n for (const key in a) {\n if (!deepEqual(a[key], b[key])) {\n return false;\n }\n }\n\n if (keys1.length === 0 && a instanceof Date && b instanceof Date) {\n // Only need to check the length of 1 as they are already known to be equal\n return a.getTime() === b.getTime();\n }\n\n return true;\n }\n return false;\n}\n", "/**\nUnescape token part of a JSON Pointer string\n\n`token` should *not* contain any '/' characters.\n\n> Evaluation of each reference token begins by decoding any escaped\n> character sequence. This is performed by first transforming any\n> occurrence of the sequence '~1' to '/', and then transforming any\n> occurrence of the sequence '~0' to '~'. By performing the\n> substitutions in this order, an implementation avoids the error of\n> turning '~01' first into '~1' and then into '/', which would be\n> incorrect (the string '~01' correctly becomes '~1' after\n> transformation).\n\nHere's my take:\n\n~1 is unescaped with higher priority than ~0 because it is a lower-order escape character.\nI say \"lower order\" because '/' needs escaping due to the JSON Pointer serialization technique.\nWhereas, '~' is escaped because escaping '/' uses the '~' character.\n*/\nfunction unescape(token: string): string {\n return token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/** Escape token part of a JSON Pointer string\n\n> '~' needs to be encoded as '~0' and '/'\n> needs to be encoded as '~1' when these characters appear in a\n> reference token.\n\nThis is the exact inverse of `unescape()`, so the reverse replacements must take place in reverse order.\n*/\nfunction escape(token: string): string {\n return token.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n}\n\nexport interface PointerEvaluation {\n parent: any;\n key: string;\n value: any;\n}\n\n/**\nJSON Pointer representation\n*/\nexport class Pointer {\n constructor(public tokens = [\"\"]) {}\n /**\n `path` *must* be a properly escaped string.\n */\n static fromJSON(path: string): Pointer {\n const tokens = path.split(\"/\").map(unescape);\n if (tokens[0] !== \"\") throw new Error(`Invalid JSON Pointer: ${path}`);\n return new Pointer(tokens);\n }\n toString(): string {\n return this.tokens.map(escape).join(\"/\");\n }\n /**\n Returns an object with 'parent', 'key', and 'value' properties.\n In the special case that this Pointer's path == \"\",\n this object will be {parent: null, key: '', value: object}.\n Otherwise, parent and key will have the property such that parent[key] == value.\n */\n evaluate(object: any): PointerEvaluation {\n let parent: any = null;\n let key = \"\";\n let value = object;\n for (let i = 1, l = this.tokens.length; i < l; i++) {\n parent = value;\n key = this.tokens[i];\n if (key === \"__proto__\" || key === \"constructor\" || key === \"prototype\") {\n continue;\n }\n // not sure if this the best way to handle non-existant paths...\n value = (parent || {})[key];\n }\n return { parent, key, value };\n }\n get(object: any): any {\n return this.evaluate(object).value;\n }\n set(object: any, value: any): void {\n let cursor: any = object;\n for (let i = 1, l = this.tokens.length - 1, token = this.tokens[i]; i < l; i++) {\n // not sure if this the best way to handle non-existant paths...\n cursor = (cursor || {})[token];\n }\n if (cursor) {\n cursor[this.tokens[this.tokens.length - 1]] = value;\n }\n }\n push(token: string): void {\n // mutable\n this.tokens.push(token);\n }\n /**\n `token` should be a String. It'll be coerced to one anyway.\n\n immutable (shallowly)\n */\n add(token: string): Pointer {\n const tokens = this.tokens.concat(String(token));\n return new Pointer(tokens);\n }\n}\n", "export const hasOwnProperty = Object.prototype.hasOwnProperty;\n\nexport function objectType(object: any) {\n if (object === undefined) {\n return \"undefined\";\n }\n if (object === null) {\n return \"null\";\n }\n if (Array.isArray(object)) {\n return \"array\";\n }\n return typeof object;\n}\n\nfunction isNonPrimitive(value: any): value is object {\n // loose-equality checking for null is faster than strict checking for each of null/undefined/true/false\n // checking null first, then calling typeof, is faster than vice-versa\n return value != null && typeof value === \"object\";\n}\n\n/**\nRecursively copy a value.\n\n@param source - should be a JavaScript primitive, Array, Date, or (plain old) Object.\n@returns copy of source where every Array and Object have been recursively\n reconstructed from their constituent elements\n*/\nexport function clone<T>(source: T): T {\n if (!isNonPrimitive(source)) {\n // short-circuiting is faster than a single return\n return source;\n }\n // x.constructor == Array is the fastest way to check if x is an Array\n if (Array.isArray(source)) {\n // construction via imperative for-loop is faster than source.map(arrayVsObject)\n const length = (source as Array<any>).length;\n // setting the Array length during construction is faster than just `[]` or `new Array()`\n const arrayTarget: any = new Array(length);\n for (let i = 0; i < length; i++) {\n arrayTarget[i] = clone(source[i]);\n }\n return arrayTarget;\n }\n // Date\n if (source.constructor === Date) {\n const dateTarget: any = new Date(+source);\n return dateTarget;\n }\n // Object\n const objectTarget: any = {};\n // declaring the variable (with const) inside the loop is faster\n for (const key in source) {\n // hasOwnProperty costs a bit of performance, but it's semantically necessary\n // using a global helper is MUCH faster than calling source.hasOwnProperty(key)\n if (hasOwnProperty.call(source, key)) {\n objectTarget[key] = clone(source[key]);\n }\n }\n return objectTarget;\n}\n", "import { deepEqual } from \"./deepEqual\";\nimport { Pointer } from \"./pointer\"; // we only need this for type inference\nimport { hasOwnProperty, objectType } from \"./util\";\n\n/**\nAll diff* functions should return a list of operations, often empty.\n\nEach operation should be an object with two to four fields:\n* `op`: the name of the operation; one of \"add\", \"remove\", \"replace\", \"move\",\n \"copy\", or \"test\".\n* `path`: a JSON pointer string\n* `from`: a JSON pointer string\n* `value`: a JSON value\n\nThe different operations have different arguments.\n* \"add\": [`path`, `value`]\n* \"remove\": [`path`]\n* \"replace\": [`path`, `value`]\n* \"move\": [`from`, `path`]\n* \"copy\": [`from`, `path`]\n* \"test\": [`path`, `value`]\n\nCurrently this only really differentiates between Arrays, Objects, and\nEverything Else, which is pretty much just what JSON substantially\ndifferentiates between.\n*/\n\nexport interface AddOperation {\n op: \"add\";\n path: string;\n value: any;\n}\nexport interface RemoveOperation {\n op: \"remove\";\n path: string;\n}\nexport interface ReplaceOperation {\n op: \"replace\";\n path: string;\n value: any;\n}\nexport interface MoveOperation {\n op: \"move\";\n from: string;\n path: string;\n}\nexport interface CopyOperation {\n op: \"copy\";\n from: string;\n path: string;\n}\nexport interface TestOperation {\n op: \"test\";\n path: string;\n value: any;\n}\n\nexport type Operation =\n | AddOperation\n | RemoveOperation\n | ReplaceOperation\n | MoveOperation\n | CopyOperation\n | TestOperation;\n\nexport function isDestructive({ op }: Operation): boolean {\n return op === \"remove\" || op === \"replace\" || op === \"copy\" || op === \"move\";\n}\n\nexport type Diff = (input: any, output: any, ptr: Pointer) => Operation[];\n/**\nVoidableDiff exists to allow the user to provide a partial diff(...) function,\nfalling back to the built-in diffAny(...) function if the user-provided function\nreturns void.\n*/\nexport type VoidableDiff = (input: any, output: any, ptr: Pointer) => Operation[] | void;\n\nfunction wrapVoidableDiff(diff: VoidableDiff): Diff {\n function wrappedDiff(input: any, output: any, ptr: Pointer): Operation[] {\n const custom_patch = diff(input, output, ptr);\n // ensure an array is always returned\n return Array.isArray(custom_patch) ? custom_patch : diffAny(input, output, ptr, wrappedDiff);\n }\n return wrappedDiff;\n}\n\n/**\n Create a test operation based on `input`'s current evaluation of the JSON\n Pointer `path`; if such a pointer cannot be resolved, returns undefined.\n */\nfunction createTest(input: any, path: string): TestOperation | undefined {\n const endpoint = Pointer.fromJSON(path).evaluate(input);\n if (endpoint !== undefined) {\n return { op: \"test\", path, value: endpoint.value };\n }\n}\n\n/**\n Produce an 'application/json-patch+json'-type list of tests, to verify that\n existing values in an object are identical to the those captured at some\n checkpoint (whenever this function is called).\n\n This does not alter `input` or `output` unless they have a property getter with\n side-effects (which is not a good idea anyway).\n\n Returns list of test operations.\n */\nexport function createTests(input: any, patch: Operation[]): TestOperation[] {\n const tests = new Array<TestOperation>();\n patch.filter(isDestructive).forEach((operation) => {\n const pathTest = createTest(input, operation.path);\n if (pathTest) tests.push(pathTest);\n if (\"from\" in operation) {\n const fromTest = createTest(input, operation.from);\n if (fromTest) tests.push(fromTest);\n }\n });\n return tests;\n}\n\n/**\n Produce a 'application/json-patch+json'-type patch to get from one object to\n another.\n\n This does not alter `input` or `output` unless they have a property getter with\n side-effects (which is not a good idea anyway).\n\n `diff` is called on each pair of comparable non-primitive nodes in the\n `input`/`output` object trees, producing nested patches. Return `undefined`\n to fall back to default behaviour.\n\n Returns list of operations to perform on `input` to produce `output`.\n */\nexport function createPatch(input: any, output: any, diff?: VoidableDiff): Operation[] {\n const ptr = new Pointer();\n // a new Pointer gets a default path of [''] if not specified\n return (diff ? wrapVoidableDiff(diff) : diffAny)(input, output, ptr);\n}\n\n/**\nList the keys in `minuend` that are not in `subtrahend`.\n\nA key is only considered if it is both 1) an own-property (o.hasOwnProperty(k))\nof the object, and 2) has a value that is not undefined. This is to match JSON\nsemantics, where JSON object serialization drops keys with undefined values.\n\n@param minuend Object of interest\n@param subtrahend Object of comparison\n@returns Array of keys that are in `minuend` but not in `subtrahend`.\n*/\nexport function subtract(\n minuend: { [index: string]: any },\n subtrahend: { [index: string]: any },\n): string[] {\n // initialize empty object; we only care about the keys, the values can be anything\n const obj: { [index: string]: number } = {};\n // build up obj with all the properties of minuend\n for (const add_key in minuend) {\n if (hasOwnProperty.call(minuend, add_key) && minuend[add_key] !== undefined) {\n obj[add_key] = 1;\n }\n }\n // now delete all the properties of subtrahend from obj\n // (deleting a missing key has no effect)\n for (const del_key in subtrahend) {\n if (hasOwnProperty.call(subtrahend, del_key) && subtrahend[del_key] !== undefined) {\n delete obj[del_key];\n }\n }\n // finally, extract whatever keys remain in obj\n return Object.keys(obj);\n}\n\n/**\nList the keys that shared by all `objects`.\n\nThe semantics of what constitutes a \"key\" is described in {@link subtract}.\n\n@param objects Array of objects to compare\n@returns Array of keys that are in (\"own-properties\" of) every object in `objects`.\n*/\nexport function intersection(objects: ArrayLike<{ [index: string]: any }>): string[] {\n const length = objects.length;\n // prepare empty counter to keep track of how many objects each key occurred in\n const counter: { [index: string]: number } = {};\n // go through each object and increment the counter for each key in that object\n for (let i = 0; i < length; i++) {\n const object = objects[i];\n for (const key in object) {\n if (hasOwnProperty.call(object, key) && object[key] !== undefined) {\n counter[key] = (counter[key] || 0) + 1;\n }\n }\n }\n // now delete all keys from the counter that were not seen in every object\n for (const key in counter) {\n if (counter[key] < length) {\n delete counter[key];\n }\n }\n // finally, extract whatever keys remain in the counter\n return Object.keys(counter);\n}\n\ninterface ArrayAdd {\n op: \"add\";\n index: number;\n value: any;\n}\ninterface ArrayRemove {\n op: \"remove\";\n index: number;\n}\ninterface ArrayReplace {\n op: \"replace\";\n index: number;\n original: any;\n value: any;\n}\n/** These are not proper Operation objects, but will be converted into\nOperation objects eventually. {index} indicates the actual target position,\nnever 'end-of-array' */\ntype ArrayOperation = ArrayAdd | ArrayRemove | ArrayReplace;\nfunction isArrayAdd(array_operation: ArrayOperation): array_operation is ArrayAdd {\n return array_operation.op === \"add\";\n}\nfunction isArrayRemove(array_operation: ArrayOperation): array_operation is ArrayRemove {\n return array_operation.op === \"remove\";\n}\n\ninterface DynamicAlternative {\n /**\n * track prev key position for less memory usage\n */\n prev: string | null;\n operation: ArrayOperation | null;\n /**\n cost indicates the total cost of getting to this position.\n */\n cost: number;\n}\n\nfunction buildOperations(memo: Array<Array<DynamicAlternative>>, i: number, j: number) {\n let memoized: DynamicAlternative = memo[i][j];\n if (!memoized) {\n throw new Error(\"invalid memo\");\n }\n const operations: ArrayOperation[] = [];\n while (memoized && memoized.prev && memoized.operation) {\n operations.push(memoized.operation);\n const index = memoized.prev.split(\",\");\n memoized = memo[Number(index[0])][Number(index[1])];\n }\n return operations.reverse();\n}\n\n/**\nCalculate the shortest sequence of operations to get from `input` to `output`,\nusing a dynamic programming implementation of the Levenshtein distance algorithm.\n\nTo get from the input ABC to the output AZ we could just delete all the input\nand say \"insert A, insert Z\" and be done with it. That's what we do if the\ninput is empty. But we can be smarter.\n\n output\n A Z\n - -\n [0] 1 2\ninput A | 1 [0] 1\n B | 2 [1] 1\n C | 3 2 [2]\n\n1) start at 0,0 (+0)\n2) keep A (+0)\n3) remove B (+1)\n4) replace C with Z (+1)\n\nIf the `input` (source) is empty, they'll all be in the top row, resulting in an\narray of 'add' operations.\nIf the `output` (target) is empty, everything will be in the left column,\nresulting in an array of 'remove' operations.\n\n@returns A list of add/remove/replace operations.\n*/\nexport function diffArrays<T>(\n input: T[],\n output: T[],\n ptr: Pointer,\n diff: Diff = diffAny,\n): Operation[] {\n if (diff === void 0) {\n diff = diffAny;\n }\n // set up cost matrix (very simple initialization: just a map)\n const input_length = isNaN(input.length) || input.length <= 0 ? 0 : input.length;\n const output_length = isNaN(output.length) || output.length <= 0 ? 0 : output.length;\n let input_end = input_length;\n let output_end = output_length;\n while (input_end > 0 && output_end > 0) {\n // accelerate same arrays\n if (deepEqual(input[input_end - 1], output[output_end - 1])) {\n input_end--;\n output_end--;\n } else {\n break;\n }\n }\n const memo: Array<Array<DynamicAlternative>> = new Array(input_end + 1);\n for (let i = 0; i <= input_end; i++) {\n memo[i] = new Array(output_end + 1);\n }\n memo[0][0] = { prev: null, operation: null, cost: 0 };\n /**\n Calculate the cheapest sequence of operations required to get from\n input.slice(0, i) to output.slice(0, j).\n There may be other valid sequences with the same cost, but none cheaper.\n\n @param i The row in the layout above\n @param j The column in the layout above\n @returns An object containing a list of operations, along with the total cost\n of applying them (+1 for each add/remove/replace operation)\n */\n // handle weird objects masquerading as Arrays that don't have proper length\n // properties by using 0 for everything but positive numbers\n for (let i = 0; i <= input_end; i++) {\n for (let j = 0; j <= output_end; j++) {\n let memoized = memo[i][j];\n if (memoized) continue;\n const add_prev_key = `${i},${j - 1}`;\n const remove_prev_key = `${i - 1},${j}`;\n const replace_prev_key = `${i - 1},${j - 1}`;\n const remove_operation: ArrayRemove = {\n op: \"remove\",\n index: i - 1,\n };\n const add_operation: ArrayAdd = {\n op: \"add\",\n index: i - 1,\n value: output[j - 1],\n };\n\n if (j === 0) {\n memoized = {\n prev: remove_prev_key,\n operation: remove_operation,\n cost: memo[i - 1][j].cost + 1,\n };\n } else if (i === 0) {\n memoized = { prev: add_prev_key, operation: add_operation, cost: memo[i][j - 1].cost + 1 };\n } else {\n if (deepEqual(input[i - 1], output[j - 1])) {\n memoized = memo[i - 1][j - 1];\n } else {\n const remove_prev = memo[i - 1][j];\n const add_prev = memo[i][j - 1];\n const replace_prev = memo[i - 1][j - 1];\n const min_cost = Math.min(replace_prev.cost, add_prev.cost, remove_prev.cost);\n if (remove_prev.cost === min_cost) {\n memoized = {\n prev: remove_prev_key,\n operation: remove_operation,\n cost: memo[i - 1][j].cost + 1,\n };\n } else if (add_prev.cost === min_cost) {\n memoized = {\n prev: add_prev_key,\n operation: add_operation,\n cost: memo[i][j - 1].cost + 1,\n };\n } else {\n const replace_operation: ArrayReplace = {\n op: \"replace\",\n index: i - 1,\n original: input[i - 1],\n value: output[j - 1],\n };\n memoized = {\n prev: replace_prev_key,\n operation: replace_operation,\n cost: memo[i - 1][j - 1].cost + 1,\n };\n }\n }\n }\n memo[i][j] = memoized;\n }\n }\n const array_operations = buildOperations(memo, input_end, output_end);\n const [padded_operations] = array_operations.reduce<[Operation[], number]>(\n ([operations, padding], array_operation) => {\n if (isArrayAdd(array_operation)) {\n const padded_index = array_operation.index + 1 + padding;\n const index_token = padded_index < input_length + padding ? String(padded_index) : \"-\";\n const operation = {\n op: array_operation.op,\n path: ptr.add(index_token).toString(),\n value: array_operation.value,\n };\n // padding++ // maybe only if array_operation.index > -1 ?\n return [operations.concat(operation), padding + 1];\n } else if (isArrayRemove(array_operation)) {\n const operation = {\n op: array_operation.op,\n path: ptr.add(String(array_operation.index + padding)).toString(),\n };\n // padding--\n return [operations.concat(operation), padding - 1];\n } else {\n // replace\n const replace_ptr = ptr.add(String(array_operation.index + padding));\n const replace_operations = diff(\n array_operation.original,\n array_operation.value,\n replace_ptr,\n );\n return [operations.concat(...replace_operations), padding];\n }\n },\n [[], 0],\n );\n return padded_operations;\n}\n\nexport function diffObjects(\n input: any,\n output: any,\n ptr: Pointer,\n diff: Diff = diffAny,\n): Operation[] {\n // if a key is in input but not output -> remove it\n const operations: Operation[] = [];\n subtract(input, output).forEach((key) => {\n operations.push({ op: \"remove\", path: ptr.add(key).toString() });\n });\n // if a key is in output but not input -> add it\n subtract(output, input).forEach((key) => {\n operations.push({ op: \"add\", path: ptr.add(key).toString(), value: output[key] });\n });\n // if a key is in both, diff it recursively\n intersection([input, output]).forEach((key) => {\n operations.push(...diff(input[key], output[key], ptr.add(key)));\n });\n return operations;\n}\n\n/**\n`diffAny()` returns an empty array if `input` and `output` are materially equal\n(i.e., would produce equivalent JSON); otherwise it produces an array of patches\nthat would transform `input` into `output`.\n\n> Here, \"equal\" means that the value at the target location and the\n> value conveyed by \"value\" are of the same JSON type, and that they\n> are considered equal by the following rules for that type:\n> o strings: are considered equal if they contain the same number of\n> Unicode characters and their code points are byte-by-byte equal.\n> o numbers: are considered equal if their values are numerically\n> equal.\n> o arrays: are considered equal if they contain the same number of\n> values, and if each value can be considered equal to the value at\n> the corresponding position in the other array, using this list of\n> type-specific rules.\n> o objects: are considered equal if they contain the same number of\n> members, and if each member can be considered equal to a member in\n> the other object, by comparing their keys (as strings) and their\n> values (using this list of type-specific rules).\n> o literals (false, true, and null): are considered equal if they are\n> the same.\n*/\nexport function diffAny(input: any, output: any, ptr: Pointer, diff: Diff = diffAny): Operation[] {\n // strict equality handles literals, numbers, and strings (a sufficient but not necessary cause)\n if (input === output) {\n return [];\n }\n const input_type = objectType(input);\n const output_type = objectType(output);\n if (input_type === \"array\" && output_type === \"array\") {\n return diffArrays(input, output, ptr, diff);\n }\n if (input_type === \"object\" && output_type === \"object\") {\n return diffObjects(input, output, ptr, diff);\n }\n // at this point we know that input and output are materially different;\n // could be array -> object, object -> array, boolean -> undefined,\n // number -> string, or some other combination, but nothing that can be split\n // up into multiple patches: so `output` must replace `input` wholesale.\n return [{ op: \"replace\", path: ptr.toString(), value: output }];\n}\n", "import {\n AddOperation,\n CopyOperation,\n diffAny,\n MoveOperation,\n Operation,\n RemoveOperation,\n ReplaceOperation,\n TestOperation,\n} from \"./diff\";\nimport { Pointer } from \"./pointer\";\nimport { clone } from \"./util\";\n\nexport class MissingError extends Error {\n constructor(public path: string) {\n super(`Value required at path: ${path}`);\n this.name = \"MissingError\";\n }\n}\n\nexport class TestError extends Error {\n constructor(\n public actual: any,\n public expected: any,\n ) {\n super(`Test failed: ${actual} != ${expected}`);\n this.name = \"TestError\";\n }\n}\n\n/**\n Apply a 'application/json-patch+json'-type patch to an object.\n\n `patch` *must* be an array of operations.\n\n > Operation objects MUST have exactly one \"op\" member, whose value\n > indicates the operation to perform. Its value MUST be one of \"add\",\n > \"remove\", \"replace\", \"move\", \"copy\", or \"test\"; other values are\n > errors.\n\n This method mutates the target object in-place.\n\n @returns list of results, one for each operation: `null` indicated success,\n otherwise, the result will be an instance of one of the Error classes:\n MissingError, InvalidOperationError, or TestError.\n */\nexport function applyPatch(object: any, patch: Operation[]) {\n return patch.map((operation) => apply(object, operation));\n}\n\nfunction _add(object: any, key: string, value: any): void {\n if (Array.isArray(object)) {\n // `key` must be an index\n if (key === \"-\") {\n object.push(value);\n } else {\n const index = parseInt(key, 10);\n object.splice(index, 0, value);\n }\n } else {\n object[key] = value;\n }\n}\n\nfunction _remove(object: any, key: string): void {\n if (Array.isArray(object)) {\n // '-' syntax doesn't make sense when removing\n const index = parseInt(key, 10);\n object.splice(index, 1);\n } else {\n // not sure what the proper behavior is when path = ''\n delete object[key];\n }\n}\n\n/**\n> o If the target location specifies an array index, a new value is\n> inserted into the array at the specified index.\n> o If the target location specifies an object member that does not\n> already exist, a new member is added to the object.\n> o If the target location specifies an object member that does exist,\n> that member's value is replaced.\n*/\nexport function add(object: any, operation: AddOperation): MissingError | null {\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n // it's not exactly a \"MissingError\" in the same way that `remove` is -- more like a MissingParent, or something\n if (endpoint.parent === undefined) {\n return new MissingError(operation.path);\n }\n _add(endpoint.parent, endpoint.key, clone(operation.value));\n return null;\n}\n\n/**\n> The \"remove\" operation removes the value at the target location.\n> The target location MUST exist for the operation to be successful.\n*/\nexport function remove(object: any, operation: RemoveOperation): MissingError | null {\n // endpoint has parent, key, and value properties\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.value === undefined) {\n return new MissingError(operation.path);\n }\n // not sure what the proper behavior is when path = ''\n _remove(endpoint.parent, endpoint.key);\n return null;\n}\n\n/**\n> The \"replace\" operation replaces the value at the target location\n> with a new value. The operation object MUST contain a \"value\" member\n> whose content specifies the replacement value.\n> The target location MUST exist for the operation to be successful.\n\n> This operation is functionally identical to a \"remove\" operation for\n> a value, followed immediately by an \"add\" operation at the same\n> location with the replacement value.\n\nEven more simply, it's like the add operation with an existence check.\n*/\nexport function replace(object: any, operation: ReplaceOperation): MissingError | null {\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.parent === null) {\n return new MissingError(operation.path);\n }\n // this existence check treats arrays as a special case\n if (Array.isArray(endpoint.parent)) {\n if (parseInt(endpoint.key, 10) >= endpoint.parent.length) {\n return new MissingError(operation.path);\n }\n } else if (endpoint.value === undefined) {\n return new MissingError(operation.path);\n }\n endpoint.parent[endpoint.key] = operation.value;\n return null;\n}\n\n/**\n> The \"move\" operation removes the value at a specified location and\n> adds it to the target location.\n> The operation object MUST contain a \"from\" member, which is a string\n> containing a JSON Pointer value that references the location in the\n> target document to move the value from.\n> This operation is functionally identical to a \"remove\" operation on\n> the \"from\" location, followed immediately by an \"add\" operation at\n> the target location with the value that was just removed.\n\n> The \"from\" location MUST NOT be a proper prefix of the \"path\"\n> location; i.e., a location cannot be moved into one of its children.\n\nTODO: throw if the check described in the previous paragraph fails.\n*/\nexport function move(object: any, operation: MoveOperation): MissingError | null {\n const from_endpoint = Pointer.fromJSON(operation.from).evaluate(object);\n if (from_endpoint.value === undefined) {\n return new MissingError(operation.from);\n }\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.parent === undefined) {\n return new MissingError(operation.path);\n }\n _remove(from_endpoint.parent, from_endpoint.key);\n _add(endpoint.parent, endpoint.key, from_endpoint.value);\n return null;\n}\n\n/**\n> The \"copy\" operation copies the value at a specified location to the\n> target location.\n> The operation object MUST contain a \"from\" member, which is a string\n> containing a JSON Pointer value that references the location in the\n> target document to copy the value from.\n> The \"from\" location MUST exist for the operation to be successful.\n\n> This operation is functionally identical to an \"add\" operation at the\n> target location using the value specified in the \"from\" member.\n\nAlternatively, it's like 'move' without the 'remove'.\n*/\nexport function copy(object: any, operation: CopyOperation): MissingError | null {\n const from_endpoint = Pointer.fromJSON(operation.from).evaluate(object);\n if (from_endpoint.value === undefined) {\n return new MissingError(operation.from);\n }\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.parent === undefined) {\n return new MissingError(operation.path);\n }\n _add(endpoint.parent, endpoint.key, clone(from_endpoint.value));\n return null;\n}\n\n/**\n> The \"test\" operation tests that a value at the target location is\n> equal to a specified value.\n> The operation object MUST contain a \"value\" member that conveys the\n> value to be compared to the target location's value.\n> The target location MUST be equal to the \"value\" value for the\n> operation to be considered successful.\n*/\nexport function test(object: any, operation: TestOperation): TestError | null {\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n // TODO: this diffAny(...).length usage could/should be lazy\n if (diffAny(endpoint.value, operation.value, new Pointer()).length) {\n return new TestError(endpoint.value, operation.value);\n }\n return null;\n}\n\nexport class InvalidOperationError extends Error {\n constructor(public operation: Operation) {\n super(`Invalid operation: ${operation.op}`);\n this.name = \"InvalidOperationError\";\n }\n}\n\n/**\nSwitch on `operation.op`, applying the corresponding patch function for each\ncase to `object`.\n*/\nexport function apply(\n object: any,\n operation: Operation,\n): MissingError | InvalidOperationError | TestError | null {\n // not sure why TypeScript can't infer typesafety of:\n // {add, remove, replace, move, copy, test}[operation.op](object, operation)\n // (seems like a bug)\n switch (operation.op) {\n case \"add\":\n return add(object, operation);\n case \"remove\":\n return remove(object, operation);\n case \"replace\":\n return replace(object, operation);\n case \"move\":\n return move(object, operation);\n case \"copy\":\n return copy(object, operation);\n case \"test\":\n return test(object, operation);\n }\n return new InvalidOperationError(operation);\n}\n", "import { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport * as rfc6902 from \"../rfc6902\";\n\nexport type NodeMapping = {\n clientFacingNodeId: number;\n internalNodeId: number;\n};\n\n/**\n * VirtualDOMDiffStruct is a representation of how a VirtualDOM has changed. It contains the original state of the\n * VirtualDOM, a list of node ID remappings, and a list of RFC6902 operations that can be applied to the original state\n * to produce the new state.\n */\nexport type VirtualDOMDiffStruct = {\n originalState: StaticVirtualDOMElement;\n nodeIdRemappings: Array<NodeMapping>;\n virtualDOMDiffs: Array<rfc6902.Operation>;\n};\n\nexport function calculateStaticVirtualDOMDiff(\n originalState: StaticVirtualDOMElement,\n latestState: StaticVirtualDOMElement,\n): VirtualDOMDiffStruct {\n const jsonPatchDiffs = rfc6902.createPatch(\n originalState,\n latestState,\n (a, b, ptr: rfc6902.Pointer) => {\n if (a.tag !== b.tag) {\n return [{ op: \"replace\", path: ptr.toString(), value: b }];\n }\n return;\n },\n );\n\n const nodeIdRemappings: Array<NodeMapping> = [];\n const virtualDOMDiffs: Array<rfc6902.Operation> = [];\n for (const diff of jsonPatchDiffs) {\n if (diff.op === \"replace\" && diff.path.endsWith(\"/nodeId\")) {\n const pointer = rfc6902.Pointer.fromJSON(diff.path);\n const originalValue = pointer.get(originalState);\n nodeIdRemappings.push({\n internalNodeId: diff.value,\n clientFacingNodeId: originalValue,\n });\n } else {\n virtualDOMDiffs.push(diff);\n }\n }\n\n return remapDuplicatedNodeIdsInOperations(\n {\n originalState,\n nodeIdRemappings,\n virtualDOMDiffs,\n },\n latestState,\n );\n}\n\nfunction getHighestNodeId(node: StaticVirtualDOMElement) {\n let highest = node.nodeId;\n for (const child of node.childNodes) {\n highest = Math.max(highest, getHighestNodeId(child));\n }\n return highest;\n}\n\nfunction getRemovedNodeIds(before: StaticVirtualDOMElement, diff: rfc6902.Operation) {\n const removedIds = new Set<number>();\n function addNode(node: StaticVirtualDOMElement) {\n removedIds.add(node.nodeId);\n for (const child of node.childNodes) {\n addNode(child);\n }\n }\n if (diff.op === \"replace\" || diff.op === \"remove\") {\n const removedNode = rfc6902.Pointer.fromJSON(diff.path).get(before);\n addNode(removedNode);\n }\n return removedIds;\n}\n\nfunction getNodeIdsFromNodeAndChildren(node: StaticVirtualDOMElement) {\n const nodeIds = new Set<number>();\n function addNode(node: StaticVirtualDOMElement) {\n nodeIds.add(node.nodeId);\n for (const child of node.childNodes) {\n addNode(child);\n }\n }\n addNode(node);\n return nodeIds;\n}\n\n// To avoid duplicate node ids at any point in the sequence of operations, apply the operations and determine if any node ids are duplicated at any point. If so, remap the node ids to be unique.\nfunction remapDuplicatedNodeIdsInOperations(\n virtualDOMDiffStruct: VirtualDOMDiffStruct,\n latestState: StaticVirtualDOMElement,\n): VirtualDOMDiffStruct {\n const { originalState, nodeIdRemappings, virtualDOMDiffs } = virtualDOMDiffStruct;\n\n const highestNodeIdAcrossStartAndEnd = Math.max(\n getHighestNodeId(originalState),\n getHighestNodeId(latestState),\n );\n let nextNodeId = highestNodeIdAcrossStartAndEnd + 1;\n\n const before = JSON.parse(JSON.stringify(originalState));\n\n function checkAndReplaceNodeIdsIfAlreadyInUse(\n node: StaticVirtualDOMElement,\n addingNodeIds: Set<number>,\n removedIds: Set<number>,\n ) {\n if (existingNodeIds.has(node.nodeId) && removedIds && !removedIds.has(node.nodeId)) {\n // This node id is already present so it must be replaced\n const newNodeId = nextNodeId++;\n nodeIdRemappings.push({\n internalNodeId: node.nodeId,\n clientFacingNodeId: newNodeId,\n });\n node.nodeId = newNodeId;\n addingNodeIds.add(newNodeId);\n } else {\n addingNodeIds.add(node.nodeId);\n }\n for (const child of node.childNodes) {\n checkAndReplaceNodeIdsIfAlreadyInUse(child, addingNodeIds, removedIds);\n }\n }\n\n const existingNodeIds = getNodeIdsFromNodeAndChildren(before);\n\n for (const diff of virtualDOMDiffs) {\n const pointer = rfc6902.Pointer.fromJSON(diff.path);\n const secondLastToken = pointer.tokens[pointer.tokens.length - 2];\n if (secondLastToken !== \"childNodes\") {\n continue;\n }\n const removedIds = getRemovedNodeIds(before, diff);\n const addingNodeIds = new Set<number>();\n if (diff.op === \"replace\" || diff.op === \"add\") {\n // The added node can use removed node ids, but it must not use any node ids that are still in use.\n checkAndReplaceNodeIdsIfAlreadyInUse(diff.value, addingNodeIds, removedIds);\n }\n removedIds.forEach((removedId) => {\n existingNodeIds.delete(removedId);\n });\n addingNodeIds.forEach((addingNodeId) => {\n existingNodeIds.add(addingNodeId);\n });\n\n const patchErrors = rfc6902.applyPatch(before, [diff]);\n if (patchErrors.length !== 1 || patchErrors[0] !== null) {\n throw new Error(\"Patch failed\");\n }\n }\n\n return virtualDOMDiffStruct;\n}\n", "export type Subjectivity = {\n visibleTo: Set<number>;\n hiddenFrom: Set<number>;\n ancestorSubjectivity: Subjectivity | null;\n};\n\nexport function IsVisibleToAll(s: Subjectivity, applyV01Semantics: boolean): boolean {\n if (applyV01Semantics) {\n // In v0.1, hiddenFrom nodes should not be sent\n return (\n s.visibleTo.size === 0 &&\n s.hiddenFrom.size === 0 &&\n (s.ancestorSubjectivity == null || IsVisibleToAll(s.ancestorSubjectivity, applyV01Semantics))\n );\n }\n return (\n s.visibleTo.size === 0 &&\n (s.ancestorSubjectivity == null || IsVisibleToAll(s.ancestorSubjectivity, applyV01Semantics))\n );\n}\n\nexport function IsVisibleToAnyOneOfConnectionIds(\n s: Subjectivity,\n connectionIdsMap: Map<number, number>,\n applyV01Semantics: boolean,\n): boolean {\n if (IsVisibleToAll(s, applyV01Semantics)) {\n return true;\n }\n let visibleToDirectly = false;\n if (s.visibleTo.size > 0) {\n for (const connectionId of s.visibleTo) {\n if (connectionIdsMap.has(connectionId)) {\n visibleToDirectly = true;\n break;\n }\n }\n if (!visibleToDirectly) {\n // There is a visibleTo list and none of the connections are in it so this node is not visible\n return false;\n }\n }\n if (applyV01Semantics) {\n // In v0.1, hiddenFrom nodes should not be sent\n for (const connectionId of s.hiddenFrom) {\n if (connectionIdsMap.has(connectionId)) {\n // If the connection is in the HiddenFrom list then it should not be visible\n return false;\n }\n }\n }\n if (s.ancestorSubjectivity == null) {\n return true;\n }\n return IsVisibleToAnyOneOfConnectionIds(\n s.ancestorSubjectivity,\n connectionIdsMap,\n applyV01Semantics,\n );\n}\n\nexport type NodeWithSubjectivity = {\n nodeId: number;\n tag: string;\n textContent?: string;\n attributes: { [key: string]: string };\n childNodes: Array<NodeWithSubjectivity>;\n\n subjectivity: Subjectivity;\n parent: NodeWithSubjectivity | null;\n};\n\nexport function applySubjectivityToChildren(\n node: NodeWithSubjectivity,\n newSubjectivity: Subjectivity,\n previousSubjectivity: Subjectivity,\n) {\n for (const child of node.childNodes) {\n if (child.subjectivity === previousSubjectivity) {\n child.subjectivity = newSubjectivity;\n applySubjectivityToChildren(child, newSubjectivity, previousSubjectivity);\n } else {\n child.subjectivity.ancestorSubjectivity = newSubjectivity;\n }\n }\n}\n", "import {\n NetworkedDOMV01ElementNodeDescription,\n NetworkedDOMV01NodeDescription,\n NetworkedDOMV02ElementNodeDescription,\n NetworkedDOMV02NodeDescription,\n NetworkedDOMV02TextNodeDescription,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOMV01Connection } from \"../NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"../NetworkedDOMV02Connection\";\nimport {\n IsVisibleToAll,\n IsVisibleToAnyOneOfConnectionIds,\n NodeWithSubjectivity,\n} from \"../NodeWithSubjectivity\";\n\nexport const visibleToAttrName = \"visible-to\";\nexport const hiddenFromAttrName = \"hidden-from\";\n\nfunction filteredV01Attributes(\n attributes: { [key: string]: string },\n excludedKeys: Set<string>,\n): { [key: string]: string } {\n const filtered: { [key: string]: string } = {};\n for (const key in attributes) {\n if (!excludedKeys.has(key)) {\n filtered[key] = attributes[key];\n }\n }\n return filtered;\n}\n\nfunction filteredV02Attributes(\n attributes: { [key: string]: string },\n excludedKeys: Set<string>,\n): Array<[string, string]> {\n const filtered: Array<[string, string]> = [];\n for (const key in attributes) {\n if (!excludedKeys.has(key)) {\n filtered.push([key, attributes[key]]);\n }\n }\n return filtered;\n}\n\nconst excludedAttributes = new Set([visibleToAttrName, hiddenFromAttrName]);\n\nexport function describeNodeWithChildrenForV01Connection(\n virtualDOMElement: NodeWithSubjectivity,\n networkedDOMConnection: NetworkedDOMV01Connection | null,\n): NetworkedDOMV01NodeDescription | null {\n if (\n networkedDOMConnection\n ? !IsVisibleToAnyOneOfConnectionIds(\n virtualDOMElement.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n true,\n )\n : !IsVisibleToAll(virtualDOMElement.subjectivity, true)\n ) {\n return null;\n }\n let emittedTagName = virtualDOMElement.tag;\n if (emittedTagName === \"#DOCUMENT\") {\n emittedTagName = \"DIV\";\n }\n if (emittedTagName === \"#text\") {\n const textNode: NetworkedDOMV02TextNodeDescription = {\n type: \"text\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n return textNode;\n } else {\n const node: NetworkedDOMV01ElementNodeDescription = {\n type: \"element\",\n nodeId: virtualDOMElement.nodeId,\n tag: emittedTagName,\n attributes: filteredV01Attributes(virtualDOMElement.attributes, excludedAttributes),\n children: [],\n text: virtualDOMElement.textContent,\n };\n\n for (const child of virtualDOMElement.childNodes) {\n const childNodeDescription = describeNodeWithChildrenForV01Connection(\n child,\n networkedDOMConnection,\n );\n if (childNodeDescription) {\n node.children.push(childNodeDescription);\n }\n }\n return node;\n }\n}\n\nexport function describeNodeWithChildrenForV02Connection(\n virtualDOMElement: NodeWithSubjectivity,\n networkedDOMConnection: NetworkedDOMV02Connection | null,\n): NetworkedDOMV02NodeDescription | null {\n if (\n networkedDOMConnection\n ? !IsVisibleToAnyOneOfConnectionIds(\n virtualDOMElement.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n )\n : !IsVisibleToAll(virtualDOMElement.subjectivity, false)\n ) {\n return null;\n }\n let emittedTagName = virtualDOMElement.tag;\n if (emittedTagName === \"#DOCUMENT\") {\n emittedTagName = \"DIV\";\n }\n if (emittedTagName === \"#text\") {\n const textNode: NetworkedDOMV02TextNodeDescription = {\n type: \"text\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n return textNode;\n } else {\n const visibleTo: Array<number> = [];\n const hiddenFrom: Array<number> = [];\n const hasOwnSubjectivity =\n virtualDOMElement.parent &&\n virtualDOMElement.subjectivity !== virtualDOMElement.parent.subjectivity;\n if (networkedDOMConnection && hasOwnSubjectivity) {\n for (const id of virtualDOMElement.subjectivity.visibleTo) {\n const remapped = networkedDOMConnection.internalIdToExternalId.get(id);\n if (remapped !== undefined) {\n visibleTo.push(remapped);\n }\n }\n for (const id of virtualDOMElement.subjectivity.hiddenFrom) {\n const remapped = networkedDOMConnection.internalIdToExternalId.get(id);\n if (remapped !== undefined) {\n hiddenFrom.push(remapped);\n }\n }\n }\n\n const node: NetworkedDOMV02ElementNodeDescription = {\n type: \"element\",\n nodeId: virtualDOMElement.nodeId,\n tag: emittedTagName,\n attributes: filteredV02Attributes(virtualDOMElement.attributes, excludedAttributes),\n children: [],\n text: virtualDOMElement.textContent,\n visibleTo,\n hiddenFrom,\n };\n\n for (const child of virtualDOMElement.childNodes) {\n const childNodeDescription = describeNodeWithChildrenForV02Connection(\n child,\n networkedDOMConnection,\n );\n if (childNodeDescription) {\n node.children.push(childNodeDescription);\n }\n }\n return node;\n }\n}\n", "export function listAttributeToSet(attr?: string | null): Set<number> {\n if (attr === null || attr === undefined || attr === \"\") {\n return new Set();\n }\n let hasInvalid = false;\n const entries = attr\n .split(/[\\s,]+/)\n .map((x) => {\n // Must be an integer as a string (i.e. not 2.5 parsed as 2) or it is ignored\n // Checked with a regex to ensure it is a positive integer\n if (/^-?[0-9]\\d*$/.test(x)) {\n return parseInt(x, 10);\n }\n hasInvalid = true;\n return null;\n })\n .filter((x) => x !== null);\n if (entries.length === 0 && hasInvalid) {\n // In the case of only invalid entries, return -1 to ensure the set is not interpreted as intentionally empty\n return new Set([-1]);\n }\n return new Set(entries);\n}\n", "// TODO - there are more possible mergeable patterns\nimport { StaticVirtualDOMMutationIdsRecord } from \"@mml-io/observable-dom-common\";\n\nexport function mergeMutations(mutations: Array<StaticVirtualDOMMutationIdsRecord>) {\n if (mutations.length <= 1) {\n return mutations;\n }\n // Include the first one as the base\n const mergedMutations = [mutations[0]];\n const lastMutation = mutations[0];\n for (let i = 1; i < mutations.length; i++) {\n const currentMutation = mutations[i];\n if (\n currentMutation.type === \"childList\" &&\n lastMutation.type === \"childList\" &&\n lastMutation.targetId === currentMutation.targetId\n ) {\n const lastAddedNodeId: number | null =\n lastMutation.addedNodes.length > 0\n ? lastMutation.addedNodes[lastMutation.addedNodes.length - 1].nodeId\n : null;\n if (\n lastAddedNodeId !== null &&\n currentMutation.previousSiblingId === lastAddedNodeId &&\n currentMutation.removedNodeIds.length === 0 // Can't trivially merge if there are removed nodes because the nodes might be in the added nodes of the previous mutation\n ) {\n // Can trivially merge these as the current mutation is just adding to the end of the last mutation\n lastMutation.addedNodes.push(...currentMutation.addedNodes);\n continue;\n }\n } else if (\n currentMutation.type === \"attributes\" &&\n lastMutation.type === \"attributes\" &&\n lastMutation.targetId === currentMutation.targetId\n ) {\n // Can trivially merge these as the current mutation is just applying more attributes to the same node\n Object.assign(lastMutation.attributes, currentMutation.attributes);\n continue;\n }\n mergedMutations.push(currentMutation);\n }\n return mergedMutations;\n}\n", "import {\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\n\nimport * as rfc6902 from \"../rfc6902\";\n\nexport function virtualDOMDiffToVirtualDOMMutationRecord(\n virtualStructure: StaticVirtualDOMElement,\n domDiff: rfc6902.Operation,\n): Array<StaticVirtualDOMMutationIdsRecord> {\n const pointer = rfc6902.Pointer.fromJSON(domDiff.path);\n const grandParentTokens = pointer.tokens.slice(0, pointer.tokens.length - 2);\n const lastToken = pointer.tokens[pointer.tokens.length - 1];\n const secondLastToken = pointer.tokens[pointer.tokens.length - 2];\n\n if (lastToken === \"textContent\") {\n const nodePointer = new rfc6902.Pointer(pointer.tokens.slice(0, pointer.tokens.length - 1));\n const node = nodePointer.get(virtualStructure) as StaticVirtualDOMElement;\n if (domDiff.op === \"replace\" || domDiff.op === \"add\") {\n return [\n {\n type: \"characterData\",\n targetId: node.nodeId,\n textContent: domDiff.value as string,\n },\n ];\n } else {\n throw new Error(\"Unhandled character data diff type\");\n }\n }\n\n if (secondLastToken === \"attributes\") {\n // This handles attribute additions, changes, and removals\n const nodePointer = new rfc6902.Pointer(grandParentTokens);\n const node = nodePointer.get(virtualStructure) as StaticVirtualDOMElement;\n let value;\n if (domDiff.op === \"remove\") {\n value = null;\n } else if (domDiff.op === \"replace\" || domDiff.op === \"add\") {\n value = domDiff.value;\n } else {\n throw new Error(\"Unhandled attribute diff type\");\n }\n return [\n {\n type: \"attributes\",\n targetId: node.nodeId,\n attributes: {\n [lastToken]: value,\n },\n },\n ];\n }\n\n // Child changes\n\n if (secondLastToken === \"childNodes\") {\n const nodePointer = new rfc6902.Pointer(grandParentTokens);\n const node = nodePointer.get(virtualStructure) as StaticVirtualDOMElement;\n\n let previousSibling: StaticVirtualDOMElement | null = null;\n if (lastToken === \"-\") {\n if (node.childNodes.length > 0) {\n previousSibling = node.childNodes[node.childNodes.length - 1];\n } else {\n // There are no siblings to account for\n }\n } else {\n const index = parseInt(lastToken, 10);\n if (index === 0) {\n previousSibling = null;\n } else {\n previousSibling = node.childNodes[index - 1];\n }\n }\n const addedNodes: Array<StaticVirtualDOMElement> = [];\n const removedNodes: Array<StaticVirtualDOMElement> = [];\n switch (domDiff.op) {\n case \"add\": {\n addedNodes.push(domDiff.value as StaticVirtualDOMElement);\n return [\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes,\n removedNodeIds: [],\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n ];\n }\n case \"remove\": {\n const removedNode = pointer.get(virtualStructure) as StaticVirtualDOMElement;\n removedNodes.push(removedNode);\n return [\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes,\n removedNodeIds: removedNodes.map((node) => node.nodeId),\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n ];\n }\n case \"replace\": {\n // This is a replacement of a single node\n const removedNode = pointer.get(virtualStructure) as StaticVirtualDOMElement;\n return [\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes: [],\n removedNodeIds: [removedNode.nodeId],\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes: [domDiff.value as StaticVirtualDOMElement],\n removedNodeIds: [],\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n ];\n }\n }\n }\n\n if (domDiff.op === \"replace\" && domDiff.path === \"\") {\n throw new Error(\"Not implemented - root node is not replaceable\");\n }\n\n console.error(\"Unhandled JSON diff:\", JSON.stringify(domDiff, null, 2));\n throw new Error(\"Unhandled diff type\");\n}\n", "import { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { hiddenFromAttrName, visibleToAttrName } from \"./diffing/describeNode\";\nimport { listAttributeToSet } from \"./diffing/listAttributeToSet\";\nimport { NodeWithSubjectivity, Subjectivity } from \"./NodeWithSubjectivity\";\nimport { VisibilityManager } from \"./VisibilityManager\";\n\nexport class NodeManager {\n private nodeIdToNode = new Map<number, NodeWithSubjectivity>();\n private maximumNodeId = 0;\n\n // Map from the node ids that the DOM uses internally to the node ids that clients refer to.\n private internalNodeIdToClientNodeId = new Map<number, number>();\n\n // Map from the node ids that clients refer to to the node ids that the DOM uses internally.\n private clientNodeIdToInternalNodeId = new Map<number, number>();\n\n constructor(private visibilityManager: VisibilityManager) {}\n\n public getNode(nodeId: number): NodeWithSubjectivity | undefined {\n return this.nodeIdToNode.get(nodeId);\n }\n\n public deleteNode(nodeId: number) {\n this.nodeIdToNode.delete(nodeId);\n }\n\n public addNodeFromInstance(\n node: StaticVirtualDOMElement,\n parentNode: NodeWithSubjectivity | null,\n ): [NodeWithSubjectivity, boolean] {\n let hasSubjectivity = false;\n const nodeId = node.nodeId;\n if (this.nodeIdToNode.has(nodeId)) {\n throw new Error(\"Node already exists with id \" + nodeId);\n }\n\n const parentSubjectivity = parentNode\n ? parentNode.subjectivity\n : {\n // Root node case\n visibleTo: new Set<number>(),\n hiddenFrom: new Set<number>(),\n ancestorSubjectivity: null,\n };\n const visibleTo = listAttributeToSet(node.attributes[visibleToAttrName]);\n const hiddenFrom = listAttributeToSet(node.attributes[hiddenFromAttrName]);\n let subjectivity: Subjectivity = parentSubjectivity;\n if (visibleTo.size > 0 || hiddenFrom.size > 0) {\n hasSubjectivity = true;\n subjectivity = {\n visibleTo,\n hiddenFrom,\n ancestorSubjectivity: parentSubjectivity,\n };\n for (const connectionId of visibleTo) {\n this.visibilityManager.addSpecificallyVisibleNode(connectionId, nodeId);\n }\n }\n\n const attributes = { ...node.attributes };\n if (attributes[visibleToAttrName]) {\n delete attributes[visibleToAttrName];\n }\n if (attributes[hiddenFromAttrName]) {\n delete attributes[hiddenFromAttrName];\n }\n\n const nodeWithSubjectivity: NodeWithSubjectivity = {\n nodeId,\n tag: node.tag,\n textContent: node.textContent,\n attributes,\n childNodes: [],\n subjectivity,\n parent: parentNode,\n };\n\n this.nodeIdToNode.set(nodeId, nodeWithSubjectivity);\n this.maximumNodeId = Math.max(this.maximumNodeId, nodeId);\n\n for (const childNode of node.childNodes) {\n const [addedChild, childSubjectivity] = this.addNodeFromInstance(\n childNode,\n nodeWithSubjectivity,\n );\n if (childSubjectivity) {\n hasSubjectivity = true;\n }\n nodeWithSubjectivity.childNodes.push(addedChild);\n }\n\n return [nodeWithSubjectivity, hasSubjectivity];\n }\n\n public addRemappedNodeId(clientFacingNodeId: number, internalNodeId: number) {\n if (this.internalNodeIdToClientNodeId.has(internalNodeId)) {\n throw new Error(\"Node already exists with internal node id \" + internalNodeId);\n }\n if (this.clientNodeIdToInternalNodeId.has(clientFacingNodeId)) {\n throw new Error(\"Node already exists with client id \" + clientFacingNodeId);\n }\n this.internalNodeIdToClientNodeId.set(internalNodeId, clientFacingNodeId);\n this.clientNodeIdToInternalNodeId.set(clientFacingNodeId, internalNodeId);\n this.maximumNodeId = Math.max(this.maximumNodeId, Math.max(clientFacingNodeId, internalNodeId));\n }\n\n public hasAnyRemappings(): boolean {\n return this.internalNodeIdToClientNodeId.size > 0;\n }\n\n public getPotentiallyRemappedNode(nodeId: number, createIfCollided = false): number {\n const newId = this.internalNodeIdToClientNodeId.get(nodeId);\n if (newId !== undefined) {\n return newId;\n }\n if (createIfCollided) {\n // If a node already exists with this id, we need to create a new id and return that instead, otherwise we can use the id\n if (this.nodeIdToNode.has(nodeId) || this.clientNodeIdToInternalNodeId.has(nodeId)) {\n // Collision - need to create a new id\n const newId2 = ++this.maximumNodeId;\n this.addRemappedNodeId(newId2, nodeId);\n return newId2;\n }\n return nodeId;\n }\n return nodeId;\n }\n\n public getStaticVirtualDOMElementByInternalNodeIdOrThrow(\n internalNodeId: number,\n ): NodeWithSubjectivity {\n const node = this.nodeIdToNode.get(internalNodeId);\n if (!node) {\n throw new Error(\"Node not found with nodeId:\" + internalNodeId);\n }\n return node;\n }\n\n public getInternalRemappedNodeId(nodeId: number): number | undefined {\n return this.clientNodeIdToInternalNodeId.get(nodeId);\n }\n}\n", "export class VisibilityManager {\n private connectionIdToSpecificallyVisibleNodes = new Map<number, Set<number>>();\n\n public addSpecificallyVisibleNode(internalConnectionId: number, nodeId: number) {\n let connectionIdNodes = this.connectionIdToSpecificallyVisibleNodes.get(internalConnectionId);\n if (!connectionIdNodes) {\n connectionIdNodes = new Set<number>();\n this.connectionIdToSpecificallyVisibleNodes.set(internalConnectionId, connectionIdNodes);\n }\n connectionIdNodes.add(nodeId);\n }\n\n public removeSpecificallyVisibleNode(internalConnectionId: number, nodeId: number) {\n const connectionIdNodes = this.connectionIdToSpecificallyVisibleNodes.get(internalConnectionId);\n if (connectionIdNodes) {\n connectionIdNodes.delete(nodeId);\n if (connectionIdNodes.size === 0) {\n this.connectionIdToSpecificallyVisibleNodes.delete(internalConnectionId);\n }\n }\n }\n\n public getSpecificallyVisibleNodes(internalConnectionId: number): Set<number> | undefined {\n return this.connectionIdToSpecificallyVisibleNodes.get(internalConnectionId);\n }\n}\n", "import { LogMessage, StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { createNetworkedDOMConnectionForWebsocket } from \"./createNetworkedDOMConnectionForWebsocket\";\nimport { VirtualDOMDiffStruct } from \"./diffing/calculateStaticVirtualDOMDiff\";\nimport { NetworkedDOM, ObservableDOMFactory } from \"./NetworkedDOM\";\nimport { NetworkedDOMV01Connection } from \"./NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"./NetworkedDOMV02Connection\";\n\nenum NetworkedDOMState {\n DocumentLoading,\n DocumentLoaded,\n BeforeDocumentLoaded,\n}\n\ntype LoadedState =\n | {\n type: NetworkedDOMState.DocumentLoaded;\n htmlContents: string;\n networkedDOM: NetworkedDOM;\n }\n | {\n type: NetworkedDOMState.DocumentLoading;\n htmlContents: string;\n networkedDOM: NetworkedDOM;\n }\n | {\n type: NetworkedDOMState.BeforeDocumentLoaded;\n };\n\n/**\n * EditableNetworkedDOM wraps NetworkedDOM instances and presents them as a single document that can iterate through\n * revisions by being loaded multiple times with different contents. The connected clients receive deltas between the\n * revisions rather than a complete refresh.\n */\nexport class EditableNetworkedDOM {\n private htmlPath: string;\n private params: object = {};\n\n private websockets = new Map<WebSocket, NetworkedDOMV01Connection | NetworkedDOMV02Connection>();\n private loadedState: LoadedState = {\n type: NetworkedDOMState.BeforeDocumentLoaded,\n };\n\n private observableDOMFactory: ObservableDOMFactory;\n private ignoreTextNodes: boolean;\n\n private logCallback?: (message: LogMessage) => void;\n\n constructor(\n htmlPath: string,\n observableDOMFactory: ObservableDOMFactory,\n ignoreTextNodes = true,\n logCallback?: (message: LogMessage) => void,\n ) {\n this.htmlPath = htmlPath;\n this.observableDOMFactory = observableDOMFactory;\n this.ignoreTextNodes = ignoreTextNodes;\n this.logCallback = logCallback;\n }\n\n public isLoaded() {\n return this.loadedState !== null;\n }\n\n public load(htmlContents: string, params?: object) {\n if (params !== undefined) {\n this.params = params;\n }\n\n let oldInstanceRoot: StaticVirtualDOMElement | null = null;\n if (\n this.loadedState.type === NetworkedDOMState.DocumentLoaded ||\n this.loadedState.type === NetworkedDOMState.DocumentLoading\n ) {\n const oldInstance = this.loadedState.networkedDOM;\n oldInstance.dispose();\n oldInstanceRoot = oldInstance.getSnapshot();\n }\n let didLoad = false;\n let hasSetLoading = false;\n const networkedDOM = new NetworkedDOM(\n this.observableDOMFactory,\n this.htmlPath,\n htmlContents,\n oldInstanceRoot,\n (domDiff: VirtualDOMDiffStruct | null, networkedDOM: NetworkedDOM) => {\n didLoad = true;\n if (!hasSetLoading) {\n hasSetLoading = true;\n this.loadedState = {\n type: NetworkedDOMState.DocumentLoaded,\n htmlContents,\n networkedDOM,\n };\n } else if (\n this.loadedState &&\n this.loadedState.type === NetworkedDOMState.DocumentLoading &&\n this.loadedState.networkedDOM === networkedDOM\n ) {\n this.loadedState = {\n type: NetworkedDOMState.DocumentLoaded,\n htmlContents,\n networkedDOM,\n };\n }\n networkedDOM.addExistingNetworkedDOMConnections(new Set(this.websockets.values()), domDiff);\n },\n this.params,\n this.ignoreTextNodes,\n this.logCallback,\n );\n hasSetLoading = true;\n if (!didLoad) {\n this.loadedState = {\n type: NetworkedDOMState.DocumentLoading,\n htmlContents,\n networkedDOM,\n };\n }\n }\n\n public reload() {\n if (this.loadedState && this.loadedState.type === NetworkedDOMState.DocumentLoaded) {\n this.load(this.loadedState.htmlContents, this.params);\n } else {\n console.warn(\"EditableNetworkedDOM.reload called whilst not loaded\");\n }\n }\n\n public dispose() {\n for (const [ws, networkedDOMConnection] of this.websockets) {\n networkedDOMConnection.dispose();\n ws.close();\n }\n this.websockets.clear();\n if (\n this.loadedState.type === NetworkedDOMState.DocumentLoaded ||\n this.loadedState.type === NetworkedDOMState.DocumentLoading\n ) {\n this.loadedState.networkedDOM.dispose();\n }\n this.loadedState = {\n type: NetworkedDOMState.BeforeDocumentLoaded,\n };\n }\n\n public addWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = createNetworkedDOMConnectionForWebsocket(webSocket);\n if (networkedDOMConnection === null) {\n // Error is handled in createNetworkedDOMConnectionForWebsocket\n return;\n }\n\n this.websockets.set(webSocket, networkedDOMConnection);\n if (this.loadedState.type === NetworkedDOMState.DocumentLoaded) {\n this.loadedState.networkedDOM.addNetworkedDOMConnection(networkedDOMConnection);\n }\n }\n\n public hasWebSocket(webSocket: WebSocket): boolean {\n return this.websockets.has(webSocket);\n }\n\n public removeWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = this.websockets.get(webSocket);\n if (networkedDOMConnection === undefined) {\n throw new Error(\"Unknown websocket\");\n }\n networkedDOMConnection.dispose();\n this.websockets.delete(webSocket);\n if (this.loadedState.type === NetworkedDOMState.DocumentLoaded) {\n this.loadedState.networkedDOM.removeNetworkedDOMConnection(networkedDOMConnection);\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n isNetworkedDOMProtocolSubProtocol_v0_2,\n networkedDOMProtocolSubProtocol_v0_1,\n networkedDOMProtocolSubProtocol_v0_2,\n networkedDOMProtocolSubProtocol_v0_2_1,\n networkedDOMProtocolSubProtocol_v0_2_SubVersionsList,\n NetworkedDOMV02ServerMessage,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOMV01Connection } from \"./NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"./NetworkedDOMV02Connection\";\n\n// First to last in order of preference\nexport const SupportedWebsocketSubProtocolsPreferenceOrder = [\n ...networkedDOMProtocolSubProtocol_v0_2_SubVersionsList,\n networkedDOMProtocolSubProtocol_v0_1,\n] as const;\n\nexport const defaultWebsocketSubProtocol = networkedDOMProtocolSubProtocol_v0_1;\n\nfunction IsRecognizedWebsocketSubProtocol(\n protocol: string,\n): protocol is (typeof SupportedWebsocketSubProtocolsPreferenceOrder)[number] {\n return SupportedWebsocketSubProtocolsPreferenceOrder.includes(protocol as any);\n}\n\nexport function createNetworkedDOMConnectionForWebsocket(\n webSocket: WebSocket,\n): NetworkedDOMV01Connection | NetworkedDOMV02Connection | null {\n let assumedProtocol:\n | typeof networkedDOMProtocolSubProtocol_v0_1\n | typeof networkedDOMProtocolSubProtocol_v0_2\n | typeof networkedDOMProtocolSubProtocol_v0_2_1\n | null = null;\n if (webSocket.protocol) {\n if (!IsRecognizedWebsocketSubProtocol(webSocket.protocol)) {\n const errorMessageString = `Unsupported websocket subprotocol: ${webSocket.protocol}`;\n const errorMessage: Array<NetworkedDOMV02ServerMessage> = [\n {\n type: \"error\",\n message: errorMessageString,\n },\n ];\n webSocket.send(JSON.stringify(errorMessage));\n webSocket.close();\n return null;\n } else {\n assumedProtocol = webSocket.protocol;\n }\n } else {\n // Assume for now that this client is a legacy MML client that doesn't send a protocol, but send a warning to the client to encourage specifying a protocol\n const warningMessageString = `No websocket subprotocol specified. Please specify a subprotocol to ensure compatibility with networked-dom servers. Assuming subprotocol \"${defaultWebsocketSubProtocol}\" for this connection.`;\n const warningMessage: Array<NetworkedDOMV02ServerMessage> = [\n {\n type: \"warning\",\n message: warningMessageString,\n },\n ];\n webSocket.send(JSON.stringify(warningMessage));\n assumedProtocol = defaultWebsocketSubProtocol;\n }\n\n const isV02 = isNetworkedDOMProtocolSubProtocol_v0_2(assumedProtocol);\n if (isV02) {\n return new NetworkedDOMV02Connection(webSocket);\n }\n return new NetworkedDOMV01Connection(webSocket);\n}\n", "import {\n NetworkedDOMV01ClientMessage,\n NetworkedDOMV01ServerMessage,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOM } from \"./NetworkedDOM\";\n\nexport class NetworkedDOMV01Connection {\n private websocketListener: (messageEvent: MessageEvent) => void;\n\n public internalConnectionId: number | null = null;\n public internalIdToExternalId = new Map<number, number>();\n public networkedDOM: NetworkedDOM | null = null;\n\n public constructor(public readonly webSocket: WebSocket) {\n this.websocketListener = (messageEvent: MessageEvent) => {\n const string = String(messageEvent.data);\n let parsed;\n try {\n parsed = JSON.parse(string) as NetworkedDOMV01ClientMessage;\n } catch (e) {\n console.error(`Error parsing message from websocket: ${string}`, e);\n console.trace();\n return;\n }\n\n switch (parsed.type) {\n case \"pong\":\n // Ignore pongs for now\n return;\n case \"event\": {\n if (!this.networkedDOM) {\n console.error(\"NetworkedDOM not set on connection that received event\", this);\n return;\n }\n if (this.internalConnectionId === null) {\n console.error(\"Internal connection ID not set on connection that received event\", this);\n return;\n }\n this.networkedDOM.dispatchRemoteEvent(this, this.internalConnectionId, 1, {\n nodeId: parsed.nodeId,\n name: parsed.name,\n bubbles: parsed.bubbles ?? true,\n params: parsed.params,\n });\n return;\n }\n default:\n console.error(\"Unknown message type from client\", parsed);\n }\n };\n webSocket.addEventListener(\"message\", this.websocketListener);\n }\n\n public setNetworkedDOM(networkedDOM: NetworkedDOM | null) {\n this.networkedDOM = networkedDOM;\n }\n\n public initAsNewV01Connection() {\n if (!this.networkedDOM) {\n throw new Error(\"NetworkedDOM not set on connection\");\n }\n const internalConnectionIds = this.networkedDOM.connectUsers(this, new Set([1]));\n this.internalConnectionId = internalConnectionIds.entries().next().value[0] as number;\n this.internalIdToExternalId.set(this.internalConnectionId, 1);\n this.networkedDOM.announceConnectedUsers(\n new Map<number, string | null>([[this.internalConnectionId, null]]),\n );\n }\n\n public stringifyAndSendSingleMessage(message: NetworkedDOMV01ServerMessage) {\n this.webSocket.send(\"[\" + JSON.stringify(message) + \"]\");\n }\n\n public sendStringifiedJSONArray(jsonArray: string) {\n this.webSocket.send(jsonArray);\n }\n\n public dispose() {\n this.webSocket.removeEventListener(\"message\", this.websocketListener);\n }\n}\n", "import {\n BufferReader,\n BufferWriter,\n decodeClientMessages,\n encodeBatchEnd,\n encodeBatchStart,\n encodeServerMessage,\n getNetworkedDOMProtocolSubProtocol_v0_2SubversionOrThrow,\n isNetworkedDOMProtocolSubProtocol_v0_2,\n NetworkedDOMV02ClientMessage,\n NetworkedDOMV02ServerMessage,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOM } from \"./NetworkedDOM\";\n\nexport class NetworkedDOMV02Connection {\n private websocketListener: (messageEvent: MessageEvent) => void;\n\n public externalIdToInternalId = new Map<number, number>();\n public internalIdToExternalId = new Map<number, number>();\n public internalIdToToken = new Map<number, string | null>();\n\n private batchMode: boolean = false;\n private batchMessages: Array<NetworkedDOMV02ServerMessage | Uint8Array> = [];\n public externalConnectionIds = new Set<number>();\n\n public networkedDOM: NetworkedDOM | null = null;\n private messagesAwaitingNetworkedDOM: Array<NetworkedDOMV02ClientMessage> = [];\n\n public constructor(public readonly webSocket: WebSocket) {\n const protocol = webSocket.protocol;\n if (!isNetworkedDOMProtocolSubProtocol_v0_2(protocol)) {\n throw new Error(\n `WebSocket protocol ${protocol} is not a supported networked-dom-v0.2 sub-protocol`,\n );\n }\n const protocolSubversion = getNetworkedDOMProtocolSubProtocol_v0_2SubversionOrThrow(protocol);\n this.websocketListener = (messageEvent: MessageEvent) => {\n const buffer = new Uint8Array(messageEvent.data as ArrayBuffer);\n const messages = decodeClientMessages(new BufferReader(buffer), protocolSubversion);\n for (const parsed of messages) {\n if (this.networkedDOM) {\n this.handleClientMessage(parsed);\n } else {\n this.messagesAwaitingNetworkedDOM.push(parsed);\n }\n }\n };\n webSocket.addEventListener(\"message\", this.websocketListener);\n }\n\n public setNetworkedDOM(networkedDOM: NetworkedDOM | null) {\n this.networkedDOM = networkedDOM;\n }\n\n public setBatchStart() {\n this.batchMode = true;\n }\n\n public setBatchEnd() {\n this.batchMode = false;\n if (this.batchMessages.length === 0) {\n return;\n }\n const includeBatchStartAndEnd = this.batchMessages.length > 1;\n let toSendBytes: Uint8Array;\n\n if (\n this.batchMessages.length === 1 &&\n this.batchMessages[0] instanceof Uint8Array &&\n !includeBatchStartAndEnd\n ) {\n // There is only one message, it's already encoded, and we don't need to include batch start and end so we can send it directly\n toSendBytes = this.batchMessages[0];\n } else {\n const bufferWriter = new BufferWriter(256);\n if (includeBatchStartAndEnd) {\n encodeBatchStart(bufferWriter);\n }\n for (const message of this.batchMessages) {\n if (message instanceof Uint8Array) {\n bufferWriter.writeBytes(message);\n } else {\n encodeServerMessage(message, bufferWriter);\n }\n }\n if (includeBatchStartAndEnd) {\n encodeBatchEnd(bufferWriter);\n }\n toSendBytes = bufferWriter.getBuffer();\n }\n this.webSocket.send(toSendBytes);\n this.batchMessages = [];\n }\n\n public sendMessage(message: NetworkedDOMV02ServerMessage) {\n this.sendEncodedBytes(encodeServerMessage(message).getBuffer());\n }\n\n public sendMessages(messages: Array<NetworkedDOMV02ServerMessage>) {\n const bufferWriter = new BufferWriter(256);\n for (const message of messages) {\n encodeServerMessage(message, bufferWriter);\n }\n const bytes = bufferWriter.getBuffer();\n this.sendEncodedBytes(bytes);\n }\n\n public sendEncodedBytes(bytes: Uint8Array) {\n if (this.batchMode) {\n this.batchMessages.push(bytes);\n return;\n }\n // Non-batch mode - just send the bytes\n this.webSocket.send(bytes);\n }\n\n public dispose() {\n this.webSocket.removeEventListener(\"message\", this.websocketListener);\n }\n\n private handleClientMessage(parsed: NetworkedDOMV02ClientMessage) {\n switch (parsed.type) {\n case \"connectUsers\": {\n const externalIdsToToken = new Map<number, string | null>();\n const addedExternalUserIds = new Set<number>();\n for (let i = 0; i < parsed.connectionIds.length; i++) {\n const addingExternalId = parsed.connectionIds[i];\n const correspondingToken = parsed.connectionTokens[i];\n externalIdsToToken.set(addingExternalId, correspondingToken);\n\n // Check if the connection ID is a positive integer\n if (!Number.isInteger(addingExternalId) || addingExternalId < 0) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${addingExternalId} is not a positive integer.`,\n });\n console.error(\"Connection ID is not a positive integer\", addingExternalId);\n return;\n }\n\n if (this.externalConnectionIds.has(addingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${addingExternalId} already exists.`,\n });\n console.error(\"Connection ID already exists\", addingExternalId);\n return;\n }\n this.externalConnectionIds.add(addingExternalId);\n if (addedExternalUserIds.has(addingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${addingExternalId} is duplicated.`,\n });\n console.error(\"Connection ID is duplicated in connectUsers\", addingExternalId);\n return;\n }\n addedExternalUserIds.add(addingExternalId);\n }\n if (this.networkedDOM !== null) {\n const connectionIdToExternalId = this.networkedDOM.connectUsers(\n this,\n addedExternalUserIds,\n );\n const addingInternalIdsWithToken = new Map<number, string | null>();\n for (const [addingInternalId, addingExternalId] of connectionIdToExternalId) {\n const token = externalIdsToToken.get(addingExternalId) ?? null;\n addingInternalIdsWithToken.set(addingInternalId, token);\n this.externalIdToInternalId.set(addingExternalId, addingInternalId);\n this.internalIdToExternalId.set(addingInternalId, addingExternalId);\n this.internalIdToToken.set(addingInternalId, token);\n }\n this.networkedDOM.announceConnectedUsers(addingInternalIdsWithToken);\n }\n return;\n }\n case \"disconnectUsers\": {\n const removingExternalUserIds = new Set<number>();\n const removedExternalToInternalUserIds = new Map<number, number>();\n for (const removingExternalId of parsed.connectionIds) {\n if (!this.externalConnectionIds.has(removingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${removingExternalId} does not exist.`,\n });\n console.error(\"Connection ID not found\", removingExternalId);\n return;\n }\n removingExternalUserIds.add(removingExternalId);\n }\n for (const removingExternalId of removingExternalUserIds) {\n const removingInternalId = this.externalIdToInternalId.get(removingExternalId);\n if (removingInternalId === undefined) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${removingExternalId} does not exist.`,\n });\n console.error(\n \"Connection ID not found in externalIdToInternalId map\",\n removingExternalId,\n );\n return;\n }\n if (removedExternalToInternalUserIds.has(removingExternalId)) {\n this.sendMessage({\n type: \"error\",\n message: `Connection ID ${removingExternalId} is duplicated.`,\n });\n console.error(\"Connection ID is duplicated in disconnectUsers\", removingExternalId);\n return;\n }\n removedExternalToInternalUserIds.set(removingExternalId, removingInternalId);\n }\n\n if (this.networkedDOM === null) {\n for (const [removingExternalId, removingInternalId] of removedExternalToInternalUserIds) {\n this.externalConnectionIds.delete(removingExternalId);\n this.externalIdToInternalId.delete(removingExternalId);\n this.internalIdToExternalId.delete(removingInternalId);\n this.internalIdToToken.delete(removingInternalId);\n }\n } else {\n const removalDiffs = this.networkedDOM.disconnectUsers(\n this,\n removedExternalToInternalUserIds,\n );\n if (removalDiffs.length > 0) {\n this.sendMessages(removalDiffs);\n }\n }\n return;\n }\n case \"pong\":\n // Ignore pongs\n return;\n case \"event\": {\n if (!this.networkedDOM) {\n console.error(\"NetworkedDOM not set on connection that received event\", this);\n return;\n }\n const externalId = parsed.connectionId;\n const internalId = this.externalIdToInternalId.get(externalId);\n if (internalId === undefined) {\n this.sendMessage({\n type: \"error\",\n message: `Event sent with connection id ${parsed.connectionId}, but that connection id has not been connected.`,\n });\n console.error(\n \"Connection ID not found in externalIdToInternalId map\",\n parsed.connectionId,\n );\n return;\n }\n\n this.networkedDOM.dispatchRemoteEvent(this, internalId, externalId, {\n nodeId: parsed.nodeId,\n name: parsed.name,\n bubbles: parsed.bubbles ?? true,\n params: parsed.params,\n });\n return;\n }\n default:\n console.error(\"Unknown message type from client\", parsed);\n }\n }\n\n public handleBufferedMessages() {\n const awaiting = this.messagesAwaitingNetworkedDOM;\n this.messagesAwaitingNetworkedDOM = [];\n for (const message of awaiting) {\n this.handleClientMessage(message);\n }\n }\n}\n", "import {\n BufferWriter,\n encodeAttributesChanged,\n encodeChildrenAdded,\n encodeChildrenRemoved,\n encodeDocumentTime,\n encodePing,\n encodeTextChanged,\n NetworkedDOMV01AttributeChangedDiff,\n NetworkedDOMV01ChildrenChangedDiff,\n NetworkedDOMV01NodeDescription,\n NetworkedDOMV01ServerMessage,\n NetworkedDOMV01SnapshotMessage,\n NetworkedDOMV02AttributesChangedDiff,\n NetworkedDOMV02ChildrenRemovedDiff,\n NetworkedDOMV02Diff,\n NetworkedDOMV02NodeDescription,\n NetworkedDOMV02PingMessage,\n NetworkedDOMV02SnapshotMessage,\n NetworkedDOMV02TextChangedDiff,\n} from \"@mml-io/networked-dom-protocol\";\nimport {\n LogMessage,\n ObservableDOMInterface,\n ObservableDOMMessage,\n ObservableDOMParameters,\n ObservableDOMRemoteEvent,\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\n\nimport {\n createNetworkedDOMConnectionForWebsocket,\n SupportedWebsocketSubProtocolsPreferenceOrder,\n} from \"./createNetworkedDOMConnectionForWebsocket\";\nimport {\n calculateStaticVirtualDOMDiff,\n VirtualDOMDiffStruct,\n} from \"./diffing/calculateStaticVirtualDOMDiff\";\nimport {\n describeNodeWithChildrenForV01Connection,\n describeNodeWithChildrenForV02Connection,\n hiddenFromAttrName,\n visibleToAttrName,\n} from \"./diffing/describeNode\";\nimport { listAttributeToSet } from \"./diffing/listAttributeToSet\";\nimport { mergeMutations } from \"./diffing/mergeMutations\";\nimport { virtualDOMDiffToVirtualDOMMutationRecord } from \"./diffing/virtualDOMDiffToVirtualDOMMutationRecord\";\nimport { NetworkedDOMV01Connection } from \"./NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"./NetworkedDOMV02Connection\";\nimport { NodeManager } from \"./NodeManager\";\nimport {\n applySubjectivityToChildren,\n IsVisibleToAll,\n IsVisibleToAnyOneOfConnectionIds,\n NodeWithSubjectivity,\n Subjectivity,\n} from \"./NodeWithSubjectivity\";\nimport { applyPatch } from \"./rfc6902\";\nimport { VisibilityManager } from \"./VisibilityManager\";\n\nconst VisibleToMode = Symbol(\"VisibleToMode\");\nconst HiddenFromMode = Symbol(\"HiddenFromMode\");\n\nexport type ObservableDOMFactory = (\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n) => ObservableDOMInterface;\n\ntype PreVisibilityChangeRecords = {\n priorVisibleToV01Connections: Set<NetworkedDOMV01Connection>;\n priorVisibleToV02Connections: Set<NetworkedDOMV02Connection>;\n previousSubjectivity: Subjectivity;\n};\n\n/**\n * NetworkedDOM is the main class for the networked-dom-document package. It is responsible for managing the state of\n * the document and the connections to the clients.\n *\n * It is constructed with an ObservableDOMFactory, which is responsible for creating the ObservableDOMInterface\n * implementation that is used to run the document.\n */\nexport class NetworkedDOM {\n private visibilityManager = new VisibilityManager();\n private nodeManager = new NodeManager(this.visibilityManager);\n\n private currentConnectionId = 1;\n\n private connectionIdToNetworkedDOMConnection = new Map<\n number,\n NetworkedDOMV01Connection | NetworkedDOMV02Connection\n >();\n private networkedDOMV01Connections = new Set<NetworkedDOMV01Connection>();\n private networkedDOMV02Connections = new Set<NetworkedDOMV02Connection>();\n private webSocketToNetworkedDOMConnection = new Map<\n WebSocket,\n NetworkedDOMV01Connection | NetworkedDOMV02Connection\n >();\n\n private initialLoad = true;\n private readonly htmlPath: string;\n\n private ignoreTextNodes: boolean;\n\n private documentRoot!: NodeWithSubjectivity;\n\n private observableDOM: ObservableDOMInterface;\n\n private documentEffectiveStartTime = Date.now();\n private latestDocumentTime = 0;\n private pingCounter = 1;\n\n private logCallback?: (message: LogMessage) => void;\n\n private disposed = false;\n\n constructor(\n observableDOMFactory: ObservableDOMFactory,\n htmlPath: string,\n htmlContents: string,\n oldInstanceDocumentRoot: StaticVirtualDOMElement | null,\n onLoad: (domDiff: VirtualDOMDiffStruct | null, networkedDOM: NetworkedDOM) => void,\n params = {},\n ignoreTextNodes = true,\n logCallback?: (message: LogMessage) => void,\n ) {\n this.htmlPath = htmlPath;\n this.ignoreTextNodes = ignoreTextNodes;\n\n this.logCallback = logCallback || this.defaultLogCallback;\n\n this.observableDOM = observableDOMFactory(\n {\n htmlPath,\n htmlContents,\n params,\n ignoreTextNodes,\n pingIntervalMilliseconds: 5000,\n },\n (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => {\n if (this.disposed) {\n return;\n }\n this.observableDOM = observableDOM;\n if (message.documentTime) {\n this.documentEffectiveStartTime = Date.now() - message.documentTime;\n this.latestDocumentTime = message.documentTime;\n }\n if (message.snapshot) {\n const clonedSnapshot = JSON.parse(JSON.stringify(message.snapshot));\n\n if (!this.initialLoad) {\n throw new Error(\"Received snapshot after initial load\");\n }\n this.initialLoad = false;\n\n let domDiff: VirtualDOMDiffStruct | null = null;\n if (oldInstanceDocumentRoot) {\n domDiff = calculateStaticVirtualDOMDiff(\n JSON.parse(JSON.stringify(oldInstanceDocumentRoot)),\n clonedSnapshot,\n );\n for (const remapping of domDiff.nodeIdRemappings) {\n this.nodeManager.addRemappedNodeId(\n remapping.clientFacingNodeId,\n remapping.internalNodeId,\n );\n }\n /*\n Use the original document root as the starting state and the diff\n will be applied to it with the connections attached to ensure they\n get the updates\n */\n const [mappedRootNode] = this.nodeManager.addNodeFromInstance(\n JSON.parse(JSON.stringify(oldInstanceDocumentRoot)),\n null,\n );\n this.documentRoot = mappedRootNode;\n } else {\n const [mappedRootNode] = this.nodeManager.addNodeFromInstance(\n JSON.parse(JSON.stringify(message.snapshot)),\n null,\n );\n this.documentRoot = mappedRootNode;\n }\n\n onLoad(domDiff, this);\n } else if (message.mutations) {\n if (this.initialLoad) {\n throw new Error(\"Received mutation before initial load\");\n }\n\n const merged = mergeMutations(message.mutations);\n if (merged.length > 1) {\n for (const client of this.networkedDOMV02Connections) {\n client.setBatchStart();\n }\n }\n for (const mutation of merged) {\n this.handleMutation(mutation);\n }\n if (merged.length > 1) {\n for (const client of this.networkedDOMV02Connections) {\n client.setBatchEnd();\n }\n }\n } else if (message.logMessage) {\n if (this.logCallback) {\n this.logCallback(message.logMessage);\n }\n } else {\n if (message.documentTime) {\n // This is just a regular ping message to update the document time - send the document time to all connected clients\n this.sendPings();\n return;\n }\n console.error(\"Unknown message type from observableDOM\", message);\n }\n },\n );\n }\n\n public static handleWebsocketSubprotocol(protocols: Set<string> | Array<string>): string | false {\n const protocolsSet = new Set(protocols);\n // Find highest priority (first in the array) protocol that is supported\n for (const protocol of SupportedWebsocketSubProtocolsPreferenceOrder) {\n if (protocolsSet.has(protocol)) {\n return protocol;\n }\n }\n return false;\n }\n\n public addWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = createNetworkedDOMConnectionForWebsocket(webSocket);\n if (networkedDOMConnection === null) {\n // Error is handled in createNetworkedDOMConnectionForWebsocket\n return;\n }\n this.addNetworkedDOMConnection(networkedDOMConnection);\n }\n\n public removeWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = this.webSocketToNetworkedDOMConnection.get(webSocket);\n if (networkedDOMConnection === undefined) {\n throw new Error(\"Unknown websocket\");\n }\n this.removeNetworkedDOMConnection(networkedDOMConnection);\n }\n\n public hasWebSocket(webSocket: WebSocket): boolean {\n return this.webSocketToNetworkedDOMConnection.has(webSocket);\n }\n\n public addExistingNetworkedDOMConnections(\n networkedDOMConnections: Set<NetworkedDOMV01Connection | NetworkedDOMV02Connection>,\n domDiff: VirtualDOMDiffStruct | null,\n ) {\n for (const networkedDOMConnection of networkedDOMConnections) {\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n networkedDOMConnection.setNetworkedDOM(this);\n this.networkedDOMV01Connections.add(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n } else if (networkedDOMConnection instanceof NetworkedDOMV02Connection) {\n networkedDOMConnection.setNetworkedDOM(this);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n for (const connectionId of networkedDOMConnection.internalIdToExternalId.keys()) {\n this.connectionIdToNetworkedDOMConnection.set(connectionId, networkedDOMConnection);\n }\n this.networkedDOMV02Connections.add(networkedDOMConnection);\n } else {\n throw new Error(\"Unknown websocket subprotocol\");\n }\n }\n\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n for (const [connectionId, token] of networkedDOMConnection.internalIdToToken) {\n if (connectionId >= this.currentConnectionId) {\n this.currentConnectionId = connectionId + 1;\n }\n this.observableDOM.addConnectedUserId(connectionId, token);\n }\n }\n\n // Handle v0.1 connections second so that the connection IDs from v0.2 are not reused if a v0.1 connection is only initialized now\n for (const networkedDOMConnection of this.networkedDOMV01Connections) {\n if (networkedDOMConnection.internalConnectionId === null) {\n networkedDOMConnection.initAsNewV01Connection();\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.observableDOM.addConnectedUserId(networkedDOMConnection.internalConnectionId!, null);\n }\n\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n networkedDOMConnection.handleBufferedMessages();\n }\n\n if (domDiff) {\n const emptyChildrenChanged: Array<NetworkedDOMV01ServerMessage> = [\n {\n type: \"childrenChanged\",\n nodeId: this.documentRoot.nodeId,\n previousNodeId: null,\n addedNodes: [],\n removedNodes: [],\n documentTime: this.getDocumentTime(),\n },\n ];\n const encoded = JSON.stringify(emptyChildrenChanged);\n for (const networkedDOMV01Connection of this.networkedDOMV01Connections) {\n networkedDOMV01Connection.sendStringifiedJSONArray(encoded);\n }\n const encodedDocumentTime = encodeDocumentTime({\n type: \"documentTime\",\n documentTime: this.getDocumentTime(),\n }).getBuffer();\n for (const networkedDOMV02Connection of this.networkedDOMV02Connections) {\n networkedDOMV02Connection.sendEncodedBytes(encodedDocumentTime);\n }\n\n const virtualDOMDiff = domDiff.virtualDOMDiffs[0];\n if (\n domDiff.virtualDOMDiffs.length === 1 &&\n virtualDOMDiff.op === \"replace\" &&\n virtualDOMDiff.path === \"\" &&\n virtualDOMDiff.value.tag === \"div\" &&\n virtualDOMDiff.value.childNodes.length === 0\n ) {\n // The patch is effectively emptying the document. Remove all nodes from the root\n const rootChildrenIds = this.documentRoot.childNodes.map((child) => child.nodeId);\n this.handleMutation(\n {\n type: \"childList\",\n targetId: this.documentRoot.nodeId,\n addedNodes: [],\n removedNodeIds: rootChildrenIds,\n previousSiblingId: null,\n },\n false,\n );\n } else {\n for (const virtualDOMDiff of domDiff.virtualDOMDiffs) {\n // Convert the diff of the virtual dom data structure to a MutationRecord-like diff and then handle it as if it were a MutationRecord\n // The difficulty here is that the JSON diff is typed by add/remove/replace of elements of a hierarchy specified by paths, but MutationRecords are specified by type of operation and nodeIds\n const mutationRecordLikes = virtualDOMDiffToVirtualDOMMutationRecord(\n domDiff.originalState,\n virtualDOMDiff,\n );\n\n if (virtualDOMDiff.path === \"\" && virtualDOMDiff.op === \"replace\") {\n // The patch is a snapshot replacement - no need to check the patch validity\n } else {\n const patchResults = applyPatch(domDiff.originalState, [virtualDOMDiff]);\n for (const patchResult of patchResults) {\n if (patchResult !== null) {\n console.error(\"Patching virtual dom structure resulted in error\", patchResult);\n throw patchResult;\n }\n }\n }\n\n const merged = mergeMutations(mutationRecordLikes);\n for (const mutation of merged) {\n this.handleMutation(mutation, false);\n }\n }\n }\n } else {\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n for (const networkedDOMConnection of this.networkedDOMV01Connections) {\n networkedDOMConnection.stringifyAndSendSingleMessage(\n this.getInitialV01Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n }\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n networkedDOMConnection.sendMessage(\n this.getInitialV02Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n }\n }\n }\n\n public addNetworkedDOMConnection(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n ): void {\n if (this.initialLoad) {\n throw new Error(\"addWebSocket called before initial load - unsupported at this time\");\n }\n if (this.disposed) {\n throw new Error(\"This NetworkedDOM has been disposed\");\n }\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n networkedDOMConnection.setNetworkedDOM(this);\n\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n if (networkedDOMConnection.internalConnectionId === null) {\n // Create the single connection ID for the client\n networkedDOMConnection.initAsNewV01Connection();\n }\n this.networkedDOMV01Connections.add(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n networkedDOMConnection.stringifyAndSendSingleMessage(\n this.getInitialV01Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n } else {\n this.networkedDOMV02Connections.add(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.set(\n networkedDOMConnection.webSocket,\n networkedDOMConnection,\n );\n for (const [connectionId, token] of networkedDOMConnection.internalIdToToken) {\n this.observableDOM.addConnectedUserId(connectionId, token);\n }\n networkedDOMConnection.sendMessage(\n this.getInitialV02Snapshot(networkedDOMConnection, documentVirtualDOMElement),\n );\n }\n }\n\n public removeNetworkedDOMConnection(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n ): void {\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n if (!this.networkedDOMV01Connections.has(networkedDOMConnection)) {\n throw new Error(\"Unrecognized networkedDOMConnection\");\n }\n if (networkedDOMConnection.internalConnectionId !== null) {\n this.observableDOM.removeConnectedUserId(networkedDOMConnection.internalConnectionId);\n this.connectionIdToNetworkedDOMConnection.delete(\n networkedDOMConnection.internalConnectionId,\n );\n }\n this.networkedDOMV01Connections.delete(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.delete(networkedDOMConnection.webSocket);\n networkedDOMConnection.setNetworkedDOM(null);\n } else if (networkedDOMConnection instanceof NetworkedDOMV02Connection) {\n if (!this.networkedDOMV02Connections.has(networkedDOMConnection)) {\n throw new Error(\"Unrecognized networkedDOMConnection\");\n }\n for (const [internalConnectionId] of networkedDOMConnection.internalIdToExternalId) {\n this.observableDOM.removeConnectedUserId(internalConnectionId);\n this.connectionIdToNetworkedDOMConnection.delete(internalConnectionId);\n }\n this.networkedDOMV02Connections.delete(networkedDOMConnection);\n this.webSocketToNetworkedDOMConnection.delete(networkedDOMConnection.webSocket);\n networkedDOMConnection.setNetworkedDOM(null);\n }\n }\n\n public connectUsers(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n addedExternalUserIds: Set<number>,\n ): Map<number, number> {\n const connectionIdToExternalId = new Map<number, number>();\n for (const externalId of addedExternalUserIds) {\n const internalId = this.currentConnectionId++;\n this.connectionIdToNetworkedDOMConnection.set(internalId, networkedDOMConnection);\n connectionIdToExternalId.set(internalId, externalId);\n }\n return connectionIdToExternalId;\n }\n\n // Called by the connections after storing the mapping of connected users ids\n public announceConnectedUsers(userIds: Map<number, string | null>) {\n for (const [userId, token] of userIds) {\n this.observableDOM.addConnectedUserId(userId, token);\n }\n }\n\n public disconnectUsers(\n networkedDOMConnection: NetworkedDOMV02Connection,\n removedExternalToInternalUserIds: Map<number, number>,\n ): Array<NetworkedDOMV02Diff> {\n const potentiallyAffectedNodeIds = new Set<number>();\n for (const [, removingInternalId] of removedExternalToInternalUserIds) {\n const affectedNodes = this.visibilityManager.getSpecificallyVisibleNodes(removingInternalId);\n if (affectedNodes) {\n for (const nodeId of affectedNodes) {\n potentiallyAffectedNodeIds.add(nodeId);\n }\n }\n }\n\n for (const nodeId of potentiallyAffectedNodeIds) {\n const node = this.nodeManager.getNode(nodeId);\n if (!node) {\n console.error(\"node not found\", nodeId);\n continue;\n }\n if (\n node.subjectivity != null &&\n !IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n )\n ) {\n // If the node isn't visible to this connection anyway then remove it from the map\n potentiallyAffectedNodeIds.delete(nodeId);\n }\n }\n\n for (const [removingExternalId, removingInternalId] of removedExternalToInternalUserIds) {\n this.observableDOM.removeConnectedUserId(removingInternalId);\n networkedDOMConnection.externalConnectionIds.delete(removingExternalId);\n networkedDOMConnection.externalIdToInternalId.delete(removingExternalId);\n networkedDOMConnection.internalIdToExternalId.delete(removingInternalId);\n networkedDOMConnection.internalIdToToken.delete(removingInternalId);\n this.connectionIdToNetworkedDOMConnection.delete(removingInternalId);\n }\n\n // Remove the nodes that are only visible to this connection because of\n // connection ids that are being removed - need to do a fresh\n // determination of visibility because the nodes might have other reasons\n // to be visible to this connection\n\n const removedMessagesByParent = new Map<number, NetworkedDOMV02ChildrenRemovedDiff>();\n for (const nodeId of potentiallyAffectedNodeIds) {\n const node = this.nodeManager.getNode(nodeId);\n if (!node) {\n console.error(\"node not found\", nodeId);\n continue;\n }\n if (\n node.subjectivity != null &&\n !IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n )\n ) {\n // The node is not visible to this connection anymore.\n // The issue now is whether the node might be not visible because a parent visibility was also changed.\n // We can't send removals for children after the parent has already been removed so we need to check if the parent is still visible\n if (\n node.parent != null &&\n (node.parent.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n node.parent.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n ))\n ) {\n // The parent is still visible so we can send the removal message\n let existingMessage = removedMessagesByParent.get(node.parent.nodeId);\n if (!existingMessage) {\n existingMessage = {\n type: \"childrenRemoved\",\n nodeId: node.parent.nodeId,\n removedNodes: [],\n };\n removedMessagesByParent.set(node.parent.nodeId, existingMessage);\n }\n existingMessage.removedNodes.push(nodeId);\n }\n }\n }\n\n return Array.from(removedMessagesByParent.values());\n }\n\n private defaultLogCallback(message: LogMessage) {\n const getLogFn = (level: string) => {\n switch (level) {\n case \"system\":\n return console.error;\n case \"error\":\n return console.error;\n case \"warn\":\n return console.warn;\n case \"log\":\n return console.log;\n case \"info\":\n return console.info;\n default:\n return console.log;\n }\n };\n\n const logFn = getLogFn(message.level);\n logFn(`${message.level.toUpperCase()} (${this.htmlPath}):`, ...message.content);\n }\n\n private sendPings() {\n const ping = this.pingCounter++;\n if (this.pingCounter > 1000) {\n this.pingCounter = 1;\n }\n const v01PingMessage: Array<NetworkedDOMV01ServerMessage> = [\n {\n type: \"ping\",\n ping,\n documentTime: this.getDocumentTime(),\n },\n ];\n const v01Encoded = JSON.stringify(v01PingMessage);\n const v02PingMessage: NetworkedDOMV02PingMessage = {\n type: \"ping\",\n ping,\n documentTime: this.getDocumentTime(),\n };\n const writer = new BufferWriter(8);\n encodePing(v02PingMessage, writer);\n const v02Encoded = writer.getBuffer();\n this.networkedDOMV01Connections.forEach((networkedDOMConnection) => {\n networkedDOMConnection.webSocket.send(v01Encoded);\n });\n this.networkedDOMV02Connections.forEach((networkedDOMConnection) => {\n networkedDOMConnection.webSocket.send(v02Encoded);\n });\n }\n\n private getInitialV01Snapshot(\n networkedDOMConnection: NetworkedDOMV01Connection,\n documentVirtualDOMElement: NodeWithSubjectivity,\n ): NetworkedDOMV01SnapshotMessage {\n const domSnapshot: NetworkedDOMV01NodeDescription | null =\n describeNodeWithChildrenForV01Connection(documentVirtualDOMElement, networkedDOMConnection);\n if (!domSnapshot) {\n throw new Error(`domSnapshot was not generated`);\n }\n return {\n type: \"snapshot\",\n snapshot: domSnapshot,\n documentTime: Date.now() - this.documentEffectiveStartTime,\n };\n }\n\n private getInitialV02Snapshot(\n networkedDOMConnection: NetworkedDOMV02Connection,\n documentVirtualDOMElement: NodeWithSubjectivity,\n ): NetworkedDOMV02SnapshotMessage {\n const domSnapshot: NetworkedDOMV02NodeDescription | null =\n describeNodeWithChildrenForV02Connection(documentVirtualDOMElement, networkedDOMConnection);\n if (!domSnapshot) {\n throw new Error(`domSnapshot was not generated`);\n }\n return {\n type: \"snapshot\",\n snapshot: domSnapshot,\n documentTime: Date.now() - this.documentEffectiveStartTime,\n };\n }\n\n public getDocumentTime(): number {\n return this.latestDocumentTime;\n }\n\n public dispatchRemoteEvent(\n networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection,\n internalConnectionId: number,\n externalConnectionId: number,\n remoteEvent: ObservableDOMRemoteEvent,\n ): void {\n if (this.disposed) {\n console.error(\"Cannot dispatch remote event after dispose\");\n throw new Error(\"This NetworkedDOM has been disposed\");\n }\n\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(\n remoteEvent.nodeId,\n );\n if (\n !node ||\n !IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n new Map<number, number>([[internalConnectionId, 1]]),\n true,\n )\n ) {\n if (networkedDOMConnection instanceof NetworkedDOMV01Connection) {\n networkedDOMConnection.stringifyAndSendSingleMessage({\n type: \"warning\",\n message: `Node ${remoteEvent.nodeId} not found or not visible`,\n });\n } else if (networkedDOMConnection instanceof NetworkedDOMV02Connection) {\n networkedDOMConnection.sendMessage({\n type: \"warning\",\n message: `Node ${remoteEvent.nodeId} not found or not visible to connection ${externalConnectionId}`,\n });\n } else {\n console.error(\"Unknown networkedDOMConnection type. Cannot send warning.\");\n }\n return;\n }\n\n /*\n The node id sent in the remote event is the client-facing node id (and the\n one used within this class), but the node id might have been remapped from\n the underlying ObservableDOM instance so it needs mapping back\n */\n const remappedNode = this.nodeManager.getInternalRemappedNodeId(remoteEvent.nodeId);\n if (remappedNode) {\n remoteEvent.nodeId = remappedNode;\n }\n\n this.observableDOM.dispatchRemoteEventFromConnectionId(internalConnectionId, remoteEvent);\n }\n\n public getSnapshot(): StaticVirtualDOMElement {\n // Need to recreate the snapshot from the current document root because the document root has recursive parent references\n function toStaticVirtualDOMElement(node: NodeWithSubjectivity): StaticVirtualDOMElement {\n const attributes = { ...node.attributes };\n\n const hasOwnSubjectivity = node.parent && node.subjectivity !== node.parent.subjectivity;\n if (hasOwnSubjectivity) {\n if (node.subjectivity.visibleTo.size > 0) {\n attributes[visibleToAttrName] = Array.from(node.subjectivity.visibleTo).join(\" \");\n }\n if (node.subjectivity.hiddenFrom.size > 0) {\n attributes[hiddenFromAttrName] = Array.from(node.subjectivity.hiddenFrom).join(\" \");\n }\n }\n\n return {\n nodeId: node.nodeId,\n tag: node.tag,\n textContent: node.textContent,\n attributes,\n childNodes: node.childNodes.map(toStaticVirtualDOMElement),\n };\n }\n return toStaticVirtualDOMElement(this.documentRoot);\n }\n\n public dispose(): void {\n this.disposed = true;\n\n for (const networkedDOMConnection of this.networkedDOMV01Connections) {\n networkedDOMConnection.setNetworkedDOM(null);\n }\n for (const networkedDOMConnection of this.networkedDOMV02Connections) {\n networkedDOMConnection.setNetworkedDOM(null);\n }\n\n // Handle all of the remaining mutations that the disconnections could have caused\n this.observableDOM.dispose();\n }\n\n private handleAddedNodes(\n targetId: number,\n previousSiblingId: number | null,\n addedNodes: Array<StaticVirtualDOMElement>,\n ) {\n const target = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!target) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n let hasSubjectiveChildren = false; // true if childrenChanged and children have visibleTo or hiddenFrom\n\n let previousNodeIdIsSubjectiveForV01 = false;\n let previousNodeIdIsSubjectiveForV02 = false;\n const parentIsSubjectiveForV01 =\n target.subjectivity != null && !IsVisibleToAll(target.subjectivity, true);\n const parentIsSubjectiveForV02 =\n target.subjectivity != null && !IsVisibleToAll(target.subjectivity, false);\n\n const addedNodesWithSubjectivity: Array<NodeWithSubjectivity> = [];\n\n let previousNode: NodeWithSubjectivity | null = null;\n let previousNodeIndex = -1;\n if (previousSiblingId != null) {\n previousNode =\n this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(previousSiblingId) ||\n null;\n if (!previousNode) {\n throw new Error(\"previous node not found: \" + previousSiblingId);\n } else {\n previousNodeIdIsSubjectiveForV01 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, true);\n previousNodeIdIsSubjectiveForV02 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, false);\n for (let i = 0; i < target.childNodes.length; i++) {\n const child = target.childNodes[i];\n if (child.nodeId === previousNode.nodeId) {\n previousNodeIndex = i;\n break;\n }\n }\n }\n }\n\n for (const addedNode of addedNodes) {\n const [addedNodeWithSubjectivity, addedNodeHasSubjectivity] =\n this.nodeManager.addNodeFromInstance(addedNode, target);\n if (addedNodeHasSubjectivity) {\n hasSubjectiveChildren = true;\n }\n if (addedNodeWithSubjectivity != null) {\n addedNodesWithSubjectivity.push(addedNodeWithSubjectivity);\n }\n }\n\n if (previousNode !== null) {\n // The previousNodeId is present, so we need to insert the addedNodes after the previousNode\n\n let index = previousNodeIndex + 1;\n for (const childVirtualDOMElement of addedNodesWithSubjectivity) {\n target.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n } else {\n // The previousNodeId is not present, so we need to prepend the addedNodes\n target.childNodes = addedNodesWithSubjectivity.concat(target.childNodes);\n }\n\n // v01 connections\n if (parentIsSubjectiveForV01 || hasSubjectiveChildren || previousNodeIdIsSubjectiveForV01) {\n // Need to go through each connection and project the children that should be visible to that connection\n\n for (const client of this.networkedDOMV01Connections) {\n const canSeeParent =\n target.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n target.subjectivity,\n client.internalIdToExternalId,\n true,\n );\n if (!canSeeParent) {\n continue;\n }\n let projectedPreviousNodeId: number | null = null;\n if (previousNode != null) {\n if (previousNodeIdIsSubjectiveForV01) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n\n for (let i = previousNodeIndex; i >= 0; i--) {\n const child = target.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n projectedPreviousNodeId = child.nodeId;\n break;\n }\n }\n } else {\n projectedPreviousNodeId = previousNode.nodeId;\n }\n }\n const projectedChildren: Array<NetworkedDOMV01NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n if (\n addedNode.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n addedNode.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n const node = describeNodeWithChildrenForV01Connection(addedNode, client);\n if (node != null) {\n projectedChildren.push(node);\n }\n }\n }\n if (projectedChildren.length > 0) {\n client.stringifyAndSendSingleMessage({\n type: \"childrenChanged\",\n nodeId: target.nodeId,\n previousNodeId: projectedPreviousNodeId,\n addedNodes: projectedChildren,\n removedNodes: [],\n });\n }\n }\n } else {\n if (this.networkedDOMV01Connections.size > 0) {\n const projectedChildren: Array<NetworkedDOMV01NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n const node = describeNodeWithChildrenForV01Connection(addedNode, null);\n if (node !== null) {\n projectedChildren.push(node);\n }\n }\n const reprojectedMsg: NetworkedDOMV01ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: target.nodeId,\n previousNodeId: previousNode ? previousNode.nodeId : null,\n addedNodes: projectedChildren,\n removedNodes: [],\n };\n const encoded = JSON.stringify([reprojectedMsg]);\n\n // forward to all clients as all clients should see this change\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n // v02 connections\n if (parentIsSubjectiveForV02 || hasSubjectiveChildren || previousNodeIdIsSubjectiveForV02) {\n // Need to go through each connection and project the children that should be visible to that connection\n\n for (const client of this.networkedDOMV02Connections) {\n const canSeeParent =\n target.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n target.subjectivity,\n client.internalIdToExternalId,\n false,\n );\n if (!canSeeParent) {\n continue;\n }\n let projectedPreviousNodeId: number | null = null;\n if (previousNode != null) {\n if (previousNodeIdIsSubjectiveForV02) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n\n for (let i = previousNodeIndex; i >= 0; i--) {\n const child = target.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n projectedPreviousNodeId = child.nodeId;\n break;\n }\n }\n } else {\n projectedPreviousNodeId = previousNode.nodeId;\n }\n }\n const projectedChildren: Array<NetworkedDOMV02NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n if (\n addedNode.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n addedNode.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n const node = describeNodeWithChildrenForV02Connection(addedNode, client);\n if (node != null) {\n projectedChildren.push(node);\n }\n }\n }\n if (projectedChildren.length > 0) {\n client.sendMessage({\n type: \"childrenAdded\",\n nodeId: target.nodeId,\n previousNodeId: projectedPreviousNodeId === null ? 0 : projectedPreviousNodeId,\n addedNodes: projectedChildren,\n });\n }\n }\n } else {\n const projectedChildren: Array<NetworkedDOMV02NodeDescription> = [];\n for (const addedNode of addedNodesWithSubjectivity) {\n const node = describeNodeWithChildrenForV02Connection(addedNode, null);\n if (node != null) {\n projectedChildren.push(node);\n }\n }\n const encoded = encodeChildrenAdded({\n type: \"childrenAdded\",\n nodeId: target.nodeId,\n previousNodeId: previousNode === null ? 0 : previousNode.nodeId,\n addedNodes: projectedChildren,\n }).getBuffer();\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n }\n\n private handleRemovedNodes(targetId: number, removedNodeIds: Array<number>) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const parentIsSubjectiveForV01 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, true);\n let anyChildIsSubjectiveForV01 = false;\n const parentIsSubjectiveForV02 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, false);\n let anyChildIsSubjectiveForV02 = false;\n\n const removedSet = new Set(removedNodeIds);\n\n for (let i = 0; i < node.childNodes.length; i++) {\n const child = node.childNodes[i];\n if (removedSet.has(child.nodeId)) {\n if (child.subjectivity != null && !IsVisibleToAll(child.subjectivity, true)) {\n anyChildIsSubjectiveForV01 = true;\n }\n if (child.subjectivity != null && !IsVisibleToAll(child.subjectivity, false)) {\n anyChildIsSubjectiveForV02 = true;\n }\n node.childNodes.splice(i, 1);\n break;\n }\n }\n\n // v01 connections\n if (parentIsSubjectiveForV01 || anyChildIsSubjectiveForV01) {\n // Need to go through each connection and project the children\n for (const client of this.networkedDOMV01Connections) {\n const removableChildren = [];\n for (const removedNodeId of removedNodeIds) {\n const child =\n this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(removedNodeId);\n if (!child) {\n throw new Error(\"Child not found for removed node id: \" + removedNodeId);\n }\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n removableChildren.push(removedNodeId);\n }\n }\n if (removableChildren.length > 0) {\n client.stringifyAndSendSingleMessage({\n type: \"childrenChanged\",\n nodeId: node.nodeId,\n addedNodes: [],\n previousNodeId: null,\n removedNodes: removableChildren,\n });\n }\n }\n } else {\n if (this.networkedDOMV01Connections.size > 0) {\n const msg: NetworkedDOMV01ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: node.nodeId,\n addedNodes: [],\n previousNodeId: null,\n removedNodes: removedNodeIds,\n };\n const encoded = JSON.stringify([msg]);\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n // v02 connections\n if (parentIsSubjectiveForV02 || anyChildIsSubjectiveForV02) {\n // Need to go through each connection and project the children\n for (const client of this.networkedDOMV02Connections) {\n const removableChildren = [];\n for (const removedNodeId of removedNodeIds) {\n const child =\n this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(removedNodeId);\n if (!child) {\n throw new Error(\"Child not found for removed node id: \" + removedNodeId);\n }\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n removableChildren.push(removedNodeId);\n }\n }\n if (removableChildren.length > 0) {\n client.sendMessage({\n type: \"childrenRemoved\",\n nodeId: node.nodeId,\n removedNodes: removableChildren,\n });\n }\n }\n } else {\n // forward to all clients\n const msg: NetworkedDOMV02ChildrenRemovedDiff = {\n type: \"childrenRemoved\",\n nodeId: node.nodeId,\n removedNodes: removedNodeIds,\n };\n const encoded = encodeChildrenRemoved(msg).getBuffer();\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n\n // Only delete the children from the nodeIdMap once we have finished projecting the children\n for (const removedNodeId of removedNodeIds) {\n this.removeNodeAndChildren(removedNodeId);\n }\n }\n\n private handleAttributeMutation(\n targetId: number,\n attributes: {\n [p: string]: string | null;\n },\n ) {\n const target = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!target) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const resultAttributes: { [key: string]: string | null } = {};\n for (const [key, value] of Object.entries(attributes)) {\n if (key === visibleToAttrName) {\n const hasOwnSubjectivity = target.subjectivity !== target.parent?.subjectivity;\n const previousSet = hasOwnSubjectivity ? target.subjectivity.visibleTo : new Set<number>();\n const newVisibleTo = listAttributeToSet(value);\n const added = new Set(Array.from(newVisibleTo).filter((x) => !previousSet.has(x)));\n const removed = new Set(Array.from(previousSet).filter((x) => !newVisibleTo.has(x)));\n this.handleVisibleToChange(targetId, added, removed);\n continue;\n }\n if (key === hiddenFromAttrName) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const hasOwnSubjectivity = target.subjectivity !== target.parent!.subjectivity;\n const previousSet = hasOwnSubjectivity ? target.subjectivity.hiddenFrom : new Set<number>();\n const newHiddenFrom = listAttributeToSet(value);\n const added = new Set(Array.from(newHiddenFrom).filter((x) => !previousSet.has(x)));\n const removed = new Set(Array.from(previousSet).filter((x) => !newHiddenFrom.has(x)));\n this.handleHiddenFromChange(targetId, added, removed);\n continue;\n }\n const existingAttribute = target.attributes[key];\n if (value !== null) {\n if (existingAttribute === value) {\n // Already set to this value - don't need to set again\n continue;\n }\n } else {\n if (existingAttribute === undefined) {\n // Already unset - don't need to unset again\n continue;\n }\n }\n resultAttributes[key] = value;\n }\n\n if (Object.keys(resultAttributes).length > 0) {\n // There are attribute changes other than visible-to and hidden-from\n this.handleAttributeChange(targetId, resultAttributes);\n }\n }\n\n private handleAttributeChange(targetId: number, attributes: { [key: string]: string | null }) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const nodeIsSubjectiveForV01 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, true);\n const nodeIsSubjectiveForV02 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, false);\n\n for (const [attributeName, value] of Object.entries(attributes)) {\n if (value !== null) {\n node.attributes[attributeName] = value;\n } else {\n delete node.attributes[attributeName];\n }\n }\n\n // v01 connections\n if (this.networkedDOMV01Connections.size > 0) {\n const allMessages: Array<NetworkedDOMV01ServerMessage> = [];\n\n for (const [attributeName, value] of Object.entries(attributes)) {\n const reprojectedMsg: NetworkedDOMV01AttributeChangedDiff = {\n type: \"attributeChange\",\n nodeId: node.nodeId,\n attribute: attributeName,\n newValue: value,\n };\n allMessages.push(reprojectedMsg);\n }\n const encoded = JSON.stringify(allMessages);\n if (nodeIsSubjectiveForV01) {\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n client.internalIdToExternalId,\n true,\n );\n if (canSee) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n } else {\n // forward to interested clients\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n const message: NetworkedDOMV02AttributesChangedDiff = {\n type: \"attributesChanged\",\n nodeId: node.nodeId,\n attributes: Object.entries(attributes).map(([attribute, value]) => [attribute, value]),\n };\n const encoded = encodeAttributesChanged(message).getBuffer();\n\n // v02 connections\n if (nodeIsSubjectiveForV02) {\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, false);\n if (canSee) {\n client.sendEncodedBytes(encoded);\n }\n }\n } else {\n // forward to all clients\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n }\n\n private handleVisibleToChange(targetId: number, added: Set<number>, removed: Set<number>) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n if (node.parent == null) {\n // TODO - handle/reject changeVisibleTo for root node\n return;\n }\n const previousSubjectivity = node.subjectivity;\n\n const visibilityRecords = this.calculatePreVisibilityChangeRecords(node);\n\n for (const internalConnectionId of removed) {\n this.visibilityManager.removeSpecificallyVisibleNode(internalConnectionId, node.nodeId);\n }\n const newVisibleTo = new Set<number>();\n for (const internalConnectionId of added) {\n newVisibleTo.add(internalConnectionId);\n\n this.visibilityManager.addSpecificallyVisibleNode(internalConnectionId, node.nodeId);\n }\n\n const hasNonInheritedSubjectivity =\n previousSubjectivity != null && previousSubjectivity !== node.parent.subjectivity;\n if (hasNonInheritedSubjectivity) {\n // This node had its own list of visibleTo connections, so we need to re-add the ids that are not being removed\n for (const connectionId of previousSubjectivity.visibleTo) {\n if (!removed.has(connectionId)) {\n newVisibleTo.add(connectionId);\n }\n }\n }\n\n if (hasNonInheritedSubjectivity) {\n // If the node has its own subjectivity then it is not inherited and the children already point to this node's subjectivity as their ancestor\n node.subjectivity.visibleTo = newVisibleTo;\n if (newVisibleTo.size === 0 && node.subjectivity.hiddenFrom.size === 0) {\n // This node's subjectivity has no effect so we can remove it and replace it with the parent's subjectivity\n if (!node.subjectivity.ancestorSubjectivity) {\n throw new Error(\"Expected ancestorSubjectivity to be set\");\n }\n node.subjectivity = node.subjectivity.ancestorSubjectivity;\n applySubjectivityToChildren(node, node.subjectivity, previousSubjectivity);\n }\n } else {\n // If this node uses the same subjectivity as the parent then it is inherited and needs its own which is then applied to all children\n const newSubjectivity: Subjectivity = {\n visibleTo: newVisibleTo,\n hiddenFrom: new Set<number>(),\n ancestorSubjectivity: previousSubjectivity, // The previous subjectivity is that of the parent/ancestor\n };\n node.subjectivity = newSubjectivity;\n applySubjectivityToChildren(node, newSubjectivity, previousSubjectivity);\n }\n\n this.applyVisibilityAfterChanges(node, visibilityRecords, added, removed, VisibleToMode);\n }\n\n private handleHiddenFromChange(targetId: number, added: Set<number>, removed: Set<number>) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n if (node.parent == null) {\n // TODO - handle/reject changeVisibleTo for root node\n return;\n }\n\n const previousSubjectivity = node.subjectivity;\n\n const visibilityRecords = this.calculatePreVisibilityChangeRecords(node);\n\n const newHiddenFrom = new Set<number>();\n for (const connectionId of added) {\n newHiddenFrom.add(connectionId);\n }\n\n const hasNonInheritedSubjectivity =\n previousSubjectivity !== null && previousSubjectivity !== node.parent.subjectivity;\n if (hasNonInheritedSubjectivity) {\n // This node had its own list of hiddenFrom connections, so we need to re-add the ids that are not being removed\n for (const connectionId of previousSubjectivity.hiddenFrom) {\n if (!removed.has(connectionId)) {\n newHiddenFrom.add(connectionId);\n }\n }\n }\n\n if (hasNonInheritedSubjectivity) {\n // If the node has its own subjectivity then it is not inherited and the children already point to this node's subjectivity as their ancestor\n node.subjectivity.hiddenFrom = newHiddenFrom;\n if (newHiddenFrom.size === 0 && node.subjectivity.visibleTo.size === 0) {\n // This node's subjectivity has no effect so we can remove it and replace it with the parent's subjectivity\n if (!node.subjectivity.ancestorSubjectivity) {\n throw new Error(\"Expected ancestorSubjectivity to be set\");\n }\n node.subjectivity = node.subjectivity.ancestorSubjectivity;\n applySubjectivityToChildren(node, node.subjectivity, previousSubjectivity);\n }\n } else {\n // If this node uses the same subjectivity as the parent then it is inherited and needs its own which is then applied to all children\n const newSubjectivity: Subjectivity = {\n hiddenFrom: newHiddenFrom,\n visibleTo: new Set<number>(),\n ancestorSubjectivity: previousSubjectivity, // The previous subjectivity is that of the parent/ancestor\n };\n node.subjectivity = newSubjectivity;\n applySubjectivityToChildren(node, newSubjectivity, previousSubjectivity);\n }\n\n this.applyVisibilityAfterChanges(node, visibilityRecords, added, removed, HiddenFromMode);\n }\n\n private handleCharacterData(targetId: number, textContent: string) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(targetId);\n if (!node) {\n console.error(\"Target node not found for mutation\", targetId);\n return;\n }\n\n const nodeIsSubjectiveForV01 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, true);\n const nodeIsSubjectiveForV02 =\n node.subjectivity != null && !IsVisibleToAll(node.subjectivity, false);\n\n node.textContent = textContent;\n\n // v01 connections\n if (this.networkedDOMV01Connections.size > 0) {\n const allMessages: Array<NetworkedDOMV01ServerMessage> = [\n {\n type: \"textChanged\",\n nodeId: node.nodeId,\n text: textContent,\n },\n ];\n const encoded = JSON.stringify(allMessages);\n if (nodeIsSubjectiveForV01) {\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n node.subjectivity,\n client.internalIdToExternalId,\n true,\n );\n if (canSee) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n } else {\n // forward to interested clients\n for (const client of this.networkedDOMV01Connections) {\n client.sendStringifiedJSONArray(encoded);\n }\n }\n }\n\n const message: NetworkedDOMV02TextChangedDiff = {\n type: \"textChanged\",\n nodeId: node.nodeId,\n text: textContent,\n };\n const encoded = encodeTextChanged(message).getBuffer();\n\n // v02 connections\n if (nodeIsSubjectiveForV02) {\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, false);\n if (canSee) {\n client.sendEncodedBytes(encoded);\n }\n }\n } else {\n // forward to all clients\n for (const client of this.networkedDOMV02Connections) {\n client.sendEncodedBytes(encoded);\n }\n }\n }\n\n private calculatePreVisibilityChangeRecords(\n node: NodeWithSubjectivity,\n ): PreVisibilityChangeRecords {\n const priorVisibleToV01Connections = new Set<NetworkedDOMV01Connection>();\n const priorVisibleToV02Connections = new Set<NetworkedDOMV02Connection>();\n const previousSubjectivity = node.subjectivity;\n\n // Need to work out which connections can currently see this element and which ones will see it after the change\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n previousSubjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(previousSubjectivity, client.internalIdToExternalId, true);\n if (canSee) {\n priorVisibleToV01Connections.add(client);\n }\n }\n\n // Need to work out which connections can currently see this element and which ones will see it after the change\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n previousSubjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n previousSubjectivity,\n client.internalIdToExternalId,\n false,\n );\n if (canSee) {\n priorVisibleToV02Connections.add(client);\n }\n }\n\n return {\n priorVisibleToV01Connections,\n priorVisibleToV02Connections,\n previousSubjectivity,\n };\n }\n\n private applyVisibilityAfterChanges(\n node: NodeWithSubjectivity,\n preVisibilityChangeRecords: PreVisibilityChangeRecords,\n added: Set<number>,\n removed: Set<number>,\n mode: typeof VisibleToMode | typeof HiddenFromMode,\n ) {\n const priorVisibleToV01Connections = preVisibilityChangeRecords.priorVisibleToV01Connections;\n const priorVisibleToV02Connections = preVisibilityChangeRecords.priorVisibleToV02Connections;\n\n if (!node.parent) {\n throw new Error(\"Cannot apply visibility changes to root node\");\n }\n\n const nodeId = node.nodeId;\n let childIndex = -1;\n for (let i = 0; i < node.parent.childNodes.length; i++) {\n const child = node.parent.childNodes[i];\n if (child.nodeId === nodeId) {\n childIndex = i;\n break;\n }\n }\n\n let previousNodeId = 0;\n let previousNodeIndex: number | null = null;\n let previousNodeIsSubjectiveForV01 = false;\n let previousNodeIsSubjectiveForV02 = false;\n if (childIndex > 0) {\n previousNodeIndex = childIndex - 1;\n const previousNode = node.parent.childNodes[childIndex - 1];\n previousNodeId = previousNode.nodeId;\n previousNodeIsSubjectiveForV01 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, true);\n previousNodeIsSubjectiveForV02 =\n previousNode.subjectivity != null && !IsVisibleToAll(previousNode.subjectivity, false);\n }\n\n if (this.networkedDOMV01Connections.size > 0) {\n const removedMessage: NetworkedDOMV01ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: node.parent.nodeId,\n previousNodeId: null,\n removedNodes: [node.nodeId],\n addedNodes: [],\n };\n const encodedRemoved = JSON.stringify([removedMessage]);\n\n for (const client of this.networkedDOMV01Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, true);\n const couldSeePreviously = priorVisibleToV01Connections.has(client);\n if (canSee && !couldSeePreviously) {\n // The client could not see the node before but can now - add it\n\n let previousNodeIdForClient = previousNodeId;\n if (previousNodeId !== 0) {\n // If the previous node is subjective then we need to determine which previousNode this connection can see\n if (previousNodeIsSubjectiveForV01) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n previousNodeIdForClient = 0;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n for (let i = previousNodeIndex!; i >= 0; i--) {\n const child = node.parent.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n true,\n )\n ) {\n previousNodeIdForClient = child.nodeId;\n break;\n }\n }\n } else {\n previousNodeIdForClient = previousNodeId;\n }\n }\n\n let previousNodeIdPointer: number | null = previousNodeIdForClient;\n if (previousNodeIdForClient === 0) {\n previousNodeIdPointer = null;\n }\n client.stringifyAndSendSingleMessage({\n type: \"childrenChanged\",\n nodeId: node.parent.nodeId,\n previousNodeId: previousNodeIdPointer,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n addedNodes: [describeNodeWithChildrenForV01Connection(node, client)!],\n removedNodes: [],\n });\n } else if (!canSee && couldSeePreviously) {\n // The client could see the node before but can't now - remove it\n client.sendStringifiedJSONArray(encodedRemoved);\n } else if (canSee && couldSeePreviously) {\n // The client could see the node before and can still see it - do nothing\n } else if (!canSee && !couldSeePreviously) {\n // The client could not see the node before and still can't - do nothing\n }\n }\n }\n\n if (this.networkedDOMV02Connections.size > 0) {\n const removedMessage: NetworkedDOMV02ChildrenRemovedDiff = {\n type: \"childrenRemoved\",\n nodeId: node.parent.nodeId,\n removedNodes: [node.nodeId],\n };\n const encodedRemoved = encodeChildrenRemoved(removedMessage).getBuffer();\n for (const client of this.networkedDOMV02Connections) {\n const canSee =\n node.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(node.subjectivity, client.internalIdToExternalId, false);\n const couldSeePreviously = priorVisibleToV02Connections.has(client);\n if (canSee && !couldSeePreviously) {\n // The client could not see the node before but can now - add it\n\n let previousNodeIdForClient = previousNodeId;\n if (previousNodeId !== 0) {\n // If the previous node is subjective then we need to determine which previousNode this connection can see\n if (previousNodeIsSubjectiveForV02) {\n // Go in reverse from the previousNodeIndex to the start of the children to see which of them this connection can see.\n // If we reach the start of the children, then send without the previousNodeId to tell the connection to put it at the start\n previousNodeIdForClient = 0;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n for (let i = previousNodeIndex!; i >= 0; i--) {\n const child = node.parent.childNodes[i];\n if (\n child.subjectivity == null ||\n IsVisibleToAnyOneOfConnectionIds(\n child.subjectivity,\n client.internalIdToExternalId,\n false,\n )\n ) {\n previousNodeIdForClient = child.nodeId;\n break;\n }\n }\n } else {\n previousNodeIdForClient = previousNodeId;\n }\n }\n\n client.sendMessage({\n type: \"childrenAdded\",\n nodeId: node.parent.nodeId,\n previousNodeId: previousNodeIdForClient,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n addedNodes: [describeNodeWithChildrenForV02Connection(node, client)!],\n });\n } else if (!canSee && couldSeePreviously) {\n // The client could see the node before but can't now - remove it\n client.sendEncodedBytes(encodedRemoved);\n } else if (canSee && couldSeePreviously) {\n // The client could see the node before and can still see it - send a changeVisibleTo/changeHiddenFrom message with the projected ids\n\n if (mode === VisibleToMode) {\n const addVisibleTo = [];\n for (const connectionId of added) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n addVisibleTo.push(externalConnectionId);\n }\n }\n const removeVisibleTo = [];\n for (const connectionId of removed) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n removeVisibleTo.push(externalConnectionId);\n }\n }\n\n if (addVisibleTo.length > 0 || removeVisibleTo.length > 0) {\n client.sendMessage({\n type: \"changeVisibleTo\",\n nodeId: node.nodeId,\n addVisibleTo,\n removeVisibleTo,\n });\n }\n } else if (mode === HiddenFromMode) {\n const addHiddenFrom = [];\n for (const connectionId of added) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n addHiddenFrom.push(externalConnectionId);\n }\n }\n const removeHiddenFrom = [];\n for (const connectionId of removed) {\n const externalConnectionId = client.internalIdToExternalId.get(connectionId);\n if (externalConnectionId !== undefined) {\n removeHiddenFrom.push(externalConnectionId);\n }\n }\n\n if (addHiddenFrom.length > 0 || removeHiddenFrom.length > 0) {\n client.sendMessage({\n type: \"changeHiddenFrom\",\n nodeId: node.nodeId,\n addHiddenFrom,\n removeHiddenFrom,\n });\n }\n }\n } else if (!canSee && !couldSeePreviously) {\n // The client could not see the node before and still can't - do nothing\n }\n }\n }\n }\n\n private reprojectStaticVirtualDOMElementWithMappings(\n staticVirtualDOMElement: StaticVirtualDOMElement,\n createIfCollided = false,\n ): StaticVirtualDOMElement {\n return {\n nodeId: this.nodeManager.getPotentiallyRemappedNode(\n staticVirtualDOMElement.nodeId,\n createIfCollided,\n ),\n tag: staticVirtualDOMElement.tag,\n attributes: staticVirtualDOMElement.attributes,\n childNodes: staticVirtualDOMElement.childNodes.map((child) =>\n this.reprojectStaticVirtualDOMElementWithMappings(child, createIfCollided),\n ),\n textContent: staticVirtualDOMElement.textContent,\n };\n }\n\n private reprojectMutationWithMappings(\n mutation: StaticVirtualDOMMutationIdsRecord,\n ): StaticVirtualDOMMutationIdsRecord {\n if (!this.nodeManager.hasAnyRemappings()) {\n // There are no mappings - nothing could be changed\n return mutation;\n }\n\n switch (mutation.type) {\n case \"attributes\": {\n return {\n type: \"attributes\",\n targetId: this.nodeManager.getPotentiallyRemappedNode(mutation.targetId),\n attributes: mutation.attributes,\n };\n }\n case \"characterData\": {\n return {\n type: \"characterData\",\n targetId: this.nodeManager.getPotentiallyRemappedNode(mutation.targetId),\n textContent: mutation.textContent,\n };\n }\n case \"childList\": {\n return {\n type: \"childList\",\n targetId: this.nodeManager.getPotentiallyRemappedNode(mutation.targetId),\n addedNodes: mutation.addedNodes.map((node) =>\n this.reprojectStaticVirtualDOMElementWithMappings(node, true),\n ),\n removedNodeIds: mutation.removedNodeIds.map((id) =>\n this.nodeManager.getPotentiallyRemappedNode(id),\n ),\n previousSiblingId: mutation.previousSiblingId\n ? this.nodeManager.getPotentiallyRemappedNode(mutation.previousSiblingId)\n : null,\n };\n }\n }\n }\n\n private handleMutation(originalMutation: StaticVirtualDOMMutationIdsRecord, reproject = true) {\n const mutation = reproject\n ? this.reprojectMutationWithMappings(originalMutation)\n : originalMutation;\n\n if (mutation.type === \"childList\") {\n if (mutation.addedNodes.length === 0 && mutation.removedNodeIds.length === 0) {\n return;\n }\n if (mutation.removedNodeIds.length > 0) {\n this.handleRemovedNodes(mutation.targetId, mutation.removedNodeIds);\n }\n if (mutation.addedNodes.length > 0) {\n this.handleAddedNodes(mutation.targetId, mutation.previousSiblingId, mutation.addedNodes);\n }\n } else if (mutation.type === \"attributes\") {\n this.handleAttributeMutation(mutation.targetId, mutation.attributes);\n } else if (mutation.type === \"characterData\") {\n this.handleCharacterData(mutation.targetId, mutation.textContent);\n }\n }\n\n private removeNodeAndChildren(nodeId: number) {\n const node = this.nodeManager.getStaticVirtualDOMElementByInternalNodeIdOrThrow(nodeId);\n\n if (node.subjectivity != null) {\n for (const connectionId of node.subjectivity.visibleTo) {\n this.visibilityManager.removeSpecificallyVisibleNode(connectionId, nodeId);\n }\n }\n\n this.nodeManager.deleteNode(node.nodeId);\n\n for (const child of node.childNodes) {\n this.removeNodeAndChildren(child.nodeId);\n }\n }\n}\n", "export function deepEqual(a: any, b: any): boolean {\n if (a === b) {\n return true;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false;\n }\n\n return a.every((elem, index) => {\n return deepEqual(elem, b[index]);\n });\n }\n\n if (typeof a === \"object\" && typeof b === \"object\" && a !== null && b !== null) {\n if (Array.isArray(a) || Array.isArray(b)) {\n return false;\n }\n\n const keys1 = Object.keys(a);\n const keys2 = Object.keys(b);\n if (keys1.length !== keys2.length || !keys1.every((key) => keys2.includes(key))) {\n return false;\n }\n\n for (const key in a) {\n if (!deepEqual(a[key], b[key])) {\n return false;\n }\n }\n\n if (keys1.length === 0 && a instanceof Date && b instanceof Date) {\n // Only need to check the length of 1 as they are already known to be equal\n return a.getTime() === b.getTime();\n }\n\n return true;\n }\n return false;\n}\n", "/**\nUnescape token part of a JSON Pointer string\n\n`token` should *not* contain any '/' characters.\n\n> Evaluation of each reference token begins by decoding any escaped\n> character sequence. This is performed by first transforming any\n> occurrence of the sequence '~1' to '/', and then transforming any\n> occurrence of the sequence '~0' to '~'. By performing the\n> substitutions in this order, an implementation avoids the error of\n> turning '~01' first into '~1' and then into '/', which would be\n> incorrect (the string '~01' correctly becomes '~1' after\n> transformation).\n\nHere's my take:\n\n~1 is unescaped with higher priority than ~0 because it is a lower-order escape character.\nI say \"lower order\" because '/' needs escaping due to the JSON Pointer serialization technique.\nWhereas, '~' is escaped because escaping '/' uses the '~' character.\n*/\nfunction unescape(token: string): string {\n return token.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/** Escape token part of a JSON Pointer string\n\n> '~' needs to be encoded as '~0' and '/'\n> needs to be encoded as '~1' when these characters appear in a\n> reference token.\n\nThis is the exact inverse of `unescape()`, so the reverse replacements must take place in reverse order.\n*/\nfunction escape(token: string): string {\n return token.replace(/~/g, \"~0\").replace(/\\//g, \"~1\");\n}\n\nexport interface PointerEvaluation {\n parent: any;\n key: string;\n value: any;\n}\n\n/**\nJSON Pointer representation\n*/\nexport class Pointer {\n constructor(public tokens = [\"\"]) {}\n /**\n `path` *must* be a properly escaped string.\n */\n static fromJSON(path: string): Pointer {\n const tokens = path.split(\"/\").map(unescape);\n if (tokens[0] !== \"\") throw new Error(`Invalid JSON Pointer: ${path}`);\n return new Pointer(tokens);\n }\n toString(): string {\n return this.tokens.map(escape).join(\"/\");\n }\n /**\n Returns an object with 'parent', 'key', and 'value' properties.\n In the special case that this Pointer's path == \"\",\n this object will be {parent: null, key: '', value: object}.\n Otherwise, parent and key will have the property such that parent[key] == value.\n */\n evaluate(object: any): PointerEvaluation {\n let parent: any = null;\n let key = \"\";\n let value = object;\n for (let i = 1, l = this.tokens.length; i < l; i++) {\n parent = value;\n key = this.tokens[i];\n if (key === \"__proto__\" || key === \"constructor\" || key === \"prototype\") {\n continue;\n }\n // not sure if this the best way to handle non-existant paths...\n value = (parent || {})[key];\n }\n return { parent, key, value };\n }\n get(object: any): any {\n return this.evaluate(object).value;\n }\n set(object: any, value: any): void {\n let cursor: any = object;\n for (let i = 1, l = this.tokens.length - 1, token = this.tokens[i]; i < l; i++) {\n // not sure if this the best way to handle non-existant paths...\n cursor = (cursor || {})[token];\n }\n if (cursor) {\n cursor[this.tokens[this.tokens.length - 1]] = value;\n }\n }\n push(token: string): void {\n // mutable\n this.tokens.push(token);\n }\n /**\n `token` should be a String. It'll be coerced to one anyway.\n\n immutable (shallowly)\n */\n add(token: string): Pointer {\n const tokens = this.tokens.concat(String(token));\n return new Pointer(tokens);\n }\n}\n", "export const hasOwnProperty = Object.prototype.hasOwnProperty;\n\nexport function objectType(object: any) {\n if (object === undefined) {\n return \"undefined\";\n }\n if (object === null) {\n return \"null\";\n }\n if (Array.isArray(object)) {\n return \"array\";\n }\n return typeof object;\n}\n\nfunction isNonPrimitive(value: any): value is object {\n // loose-equality checking for null is faster than strict checking for each of null/undefined/true/false\n // checking null first, then calling typeof, is faster than vice-versa\n return value != null && typeof value === \"object\";\n}\n\n/**\nRecursively copy a value.\n\n@param source - should be a JavaScript primitive, Array, Date, or (plain old) Object.\n@returns copy of source where every Array and Object have been recursively\n reconstructed from their constituent elements\n*/\nexport function clone<T>(source: T): T {\n if (!isNonPrimitive(source)) {\n // short-circuiting is faster than a single return\n return source;\n }\n // x.constructor == Array is the fastest way to check if x is an Array\n if (Array.isArray(source)) {\n // construction via imperative for-loop is faster than source.map(arrayVsObject)\n const length = (source as Array<any>).length;\n // setting the Array length during construction is faster than just `[]` or `new Array()`\n const arrayTarget: any = new Array(length);\n for (let i = 0; i < length; i++) {\n arrayTarget[i] = clone(source[i]);\n }\n return arrayTarget;\n }\n // Date\n if (source.constructor === Date) {\n const dateTarget: any = new Date(+source);\n return dateTarget;\n }\n // Object\n const objectTarget: any = {};\n // declaring the variable (with const) inside the loop is faster\n for (const key in source) {\n // hasOwnProperty costs a bit of performance, but it's semantically necessary\n // using a global helper is MUCH faster than calling source.hasOwnProperty(key)\n if (hasOwnProperty.call(source, key)) {\n objectTarget[key] = clone(source[key]);\n }\n }\n return objectTarget;\n}\n", "import { deepEqual } from \"./deepEqual\";\nimport { Pointer } from \"./pointer\"; // we only need this for type inference\nimport { hasOwnProperty, objectType } from \"./util\";\n\n/**\nAll diff* functions should return a list of operations, often empty.\n\nEach operation should be an object with two to four fields:\n* `op`: the name of the operation; one of \"add\", \"remove\", \"replace\", \"move\",\n \"copy\", or \"test\".\n* `path`: a JSON pointer string\n* `from`: a JSON pointer string\n* `value`: a JSON value\n\nThe different operations have different arguments.\n* \"add\": [`path`, `value`]\n* \"remove\": [`path`]\n* \"replace\": [`path`, `value`]\n* \"move\": [`from`, `path`]\n* \"copy\": [`from`, `path`]\n* \"test\": [`path`, `value`]\n\nCurrently this only really differentiates between Arrays, Objects, and\nEverything Else, which is pretty much just what JSON substantially\ndifferentiates between.\n*/\n\nexport interface AddOperation {\n op: \"add\";\n path: string;\n value: any;\n}\nexport interface RemoveOperation {\n op: \"remove\";\n path: string;\n}\nexport interface ReplaceOperation {\n op: \"replace\";\n path: string;\n value: any;\n}\nexport interface MoveOperation {\n op: \"move\";\n from: string;\n path: string;\n}\nexport interface CopyOperation {\n op: \"copy\";\n from: string;\n path: string;\n}\nexport interface TestOperation {\n op: \"test\";\n path: string;\n value: any;\n}\n\nexport type Operation =\n | AddOperation\n | RemoveOperation\n | ReplaceOperation\n | MoveOperation\n | CopyOperation\n | TestOperation;\n\nexport function isDestructive({ op }: Operation): boolean {\n return op === \"remove\" || op === \"replace\" || op === \"copy\" || op === \"move\";\n}\n\nexport type Diff = (input: any, output: any, ptr: Pointer) => Operation[];\n/**\nVoidableDiff exists to allow the user to provide a partial diff(...) function,\nfalling back to the built-in diffAny(...) function if the user-provided function\nreturns void.\n*/\nexport type VoidableDiff = (input: any, output: any, ptr: Pointer) => Operation[] | void;\n\nfunction wrapVoidableDiff(diff: VoidableDiff): Diff {\n function wrappedDiff(input: any, output: any, ptr: Pointer): Operation[] {\n const custom_patch = diff(input, output, ptr);\n // ensure an array is always returned\n return Array.isArray(custom_patch) ? custom_patch : diffAny(input, output, ptr, wrappedDiff);\n }\n return wrappedDiff;\n}\n\n/**\n Create a test operation based on `input`'s current evaluation of the JSON\n Pointer `path`; if such a pointer cannot be resolved, returns undefined.\n */\nfunction createTest(input: any, path: string): TestOperation | undefined {\n const endpoint = Pointer.fromJSON(path).evaluate(input);\n if (endpoint !== undefined) {\n return { op: \"test\", path, value: endpoint.value };\n }\n}\n\n/**\n Produce an 'application/json-patch+json'-type list of tests, to verify that\n existing values in an object are identical to the those captured at some\n checkpoint (whenever this function is called).\n\n This does not alter `input` or `output` unless they have a property getter with\n side-effects (which is not a good idea anyway).\n\n Returns list of test operations.\n */\nexport function createTests(input: any, patch: Operation[]): TestOperation[] {\n const tests = new Array<TestOperation>();\n patch.filter(isDestructive).forEach((operation) => {\n const pathTest = createTest(input, operation.path);\n if (pathTest) tests.push(pathTest);\n if (\"from\" in operation) {\n const fromTest = createTest(input, operation.from);\n if (fromTest) tests.push(fromTest);\n }\n });\n return tests;\n}\n\n/**\n Produce a 'application/json-patch+json'-type patch to get from one object to\n another.\n\n This does not alter `input` or `output` unless they have a property getter with\n side-effects (which is not a good idea anyway).\n\n `diff` is called on each pair of comparable non-primitive nodes in the\n `input`/`output` object trees, producing nested patches. Return `undefined`\n to fall back to default behaviour.\n\n Returns list of operations to perform on `input` to produce `output`.\n */\nexport function createPatch(input: any, output: any, diff?: VoidableDiff): Operation[] {\n const ptr = new Pointer();\n // a new Pointer gets a default path of [''] if not specified\n return (diff ? wrapVoidableDiff(diff) : diffAny)(input, output, ptr);\n}\n\n/**\nList the keys in `minuend` that are not in `subtrahend`.\n\nA key is only considered if it is both 1) an own-property (o.hasOwnProperty(k))\nof the object, and 2) has a value that is not undefined. This is to match JSON\nsemantics, where JSON object serialization drops keys with undefined values.\n\n@param minuend Object of interest\n@param subtrahend Object of comparison\n@returns Array of keys that are in `minuend` but not in `subtrahend`.\n*/\nexport function subtract(\n minuend: { [index: string]: any },\n subtrahend: { [index: string]: any },\n): string[] {\n // initialize empty object; we only care about the keys, the values can be anything\n const obj: { [index: string]: number } = {};\n // build up obj with all the properties of minuend\n for (const add_key in minuend) {\n if (hasOwnProperty.call(minuend, add_key) && minuend[add_key] !== undefined) {\n obj[add_key] = 1;\n }\n }\n // now delete all the properties of subtrahend from obj\n // (deleting a missing key has no effect)\n for (const del_key in subtrahend) {\n if (hasOwnProperty.call(subtrahend, del_key) && subtrahend[del_key] !== undefined) {\n delete obj[del_key];\n }\n }\n // finally, extract whatever keys remain in obj\n return Object.keys(obj);\n}\n\n/**\nList the keys that shared by all `objects`.\n\nThe semantics of what constitutes a \"key\" is described in {@link subtract}.\n\n@param objects Array of objects to compare\n@returns Array of keys that are in (\"own-properties\" of) every object in `objects`.\n*/\nexport function intersection(objects: ArrayLike<{ [index: string]: any }>): string[] {\n const length = objects.length;\n // prepare empty counter to keep track of how many objects each key occurred in\n const counter: { [index: string]: number } = {};\n // go through each object and increment the counter for each key in that object\n for (let i = 0; i < length; i++) {\n const object = objects[i];\n for (const key in object) {\n if (hasOwnProperty.call(object, key) && object[key] !== undefined) {\n counter[key] = (counter[key] || 0) + 1;\n }\n }\n }\n // now delete all keys from the counter that were not seen in every object\n for (const key in counter) {\n if (counter[key] < length) {\n delete counter[key];\n }\n }\n // finally, extract whatever keys remain in the counter\n return Object.keys(counter);\n}\n\ninterface ArrayAdd {\n op: \"add\";\n index: number;\n value: any;\n}\ninterface ArrayRemove {\n op: \"remove\";\n index: number;\n}\ninterface ArrayReplace {\n op: \"replace\";\n index: number;\n original: any;\n value: any;\n}\n/** These are not proper Operation objects, but will be converted into\nOperation objects eventually. {index} indicates the actual target position,\nnever 'end-of-array' */\ntype ArrayOperation = ArrayAdd | ArrayRemove | ArrayReplace;\nfunction isArrayAdd(array_operation: ArrayOperation): array_operation is ArrayAdd {\n return array_operation.op === \"add\";\n}\nfunction isArrayRemove(array_operation: ArrayOperation): array_operation is ArrayRemove {\n return array_operation.op === \"remove\";\n}\n\ninterface DynamicAlternative {\n /**\n * track prev key position for less memory usage\n */\n prev: string | null;\n operation: ArrayOperation | null;\n /**\n cost indicates the total cost of getting to this position.\n */\n cost: number;\n}\n\nfunction buildOperations(memo: Array<Array<DynamicAlternative>>, i: number, j: number) {\n let memoized: DynamicAlternative = memo[i][j];\n if (!memoized) {\n throw new Error(\"invalid memo\");\n }\n const operations: ArrayOperation[] = [];\n while (memoized && memoized.prev && memoized.operation) {\n operations.push(memoized.operation);\n const index = memoized.prev.split(\",\");\n memoized = memo[Number(index[0])][Number(index[1])];\n }\n return operations.reverse();\n}\n\n/**\nCalculate the shortest sequence of operations to get from `input` to `output`,\nusing a dynamic programming implementation of the Levenshtein distance algorithm.\n\nTo get from the input ABC to the output AZ we could just delete all the input\nand say \"insert A, insert Z\" and be done with it. That's what we do if the\ninput is empty. But we can be smarter.\n\n output\n A Z\n - -\n [0] 1 2\ninput A | 1 [0] 1\n B | 2 [1] 1\n C | 3 2 [2]\n\n1) start at 0,0 (+0)\n2) keep A (+0)\n3) remove B (+1)\n4) replace C with Z (+1)\n\nIf the `input` (source) is empty, they'll all be in the top row, resulting in an\narray of 'add' operations.\nIf the `output` (target) is empty, everything will be in the left column,\nresulting in an array of 'remove' operations.\n\n@returns A list of add/remove/replace operations.\n*/\nexport function diffArrays<T>(\n input: T[],\n output: T[],\n ptr: Pointer,\n diff: Diff = diffAny,\n): Operation[] {\n if (diff === void 0) {\n diff = diffAny;\n }\n // set up cost matrix (very simple initialization: just a map)\n const input_length = isNaN(input.length) || input.length <= 0 ? 0 : input.length;\n const output_length = isNaN(output.length) || output.length <= 0 ? 0 : output.length;\n let input_end = input_length;\n let output_end = output_length;\n while (input_end > 0 && output_end > 0) {\n // accelerate same arrays\n if (deepEqual(input[input_end - 1], output[output_end - 1])) {\n input_end--;\n output_end--;\n } else {\n break;\n }\n }\n const memo: Array<Array<DynamicAlternative>> = new Array(input_end + 1);\n for (let i = 0; i <= input_end; i++) {\n memo[i] = new Array(output_end + 1);\n }\n memo[0][0] = { prev: null, operation: null, cost: 0 };\n /**\n Calculate the cheapest sequence of operations required to get from\n input.slice(0, i) to output.slice(0, j).\n There may be other valid sequences with the same cost, but none cheaper.\n\n @param i The row in the layout above\n @param j The column in the layout above\n @returns An object containing a list of operations, along with the total cost\n of applying them (+1 for each add/remove/replace operation)\n */\n // handle weird objects masquerading as Arrays that don't have proper length\n // properties by using 0 for everything but positive numbers\n for (let i = 0; i <= input_end; i++) {\n for (let j = 0; j <= output_end; j++) {\n let memoized = memo[i][j];\n if (memoized) continue;\n const add_prev_key = `${i},${j - 1}`;\n const remove_prev_key = `${i - 1},${j}`;\n const replace_prev_key = `${i - 1},${j - 1}`;\n const remove_operation: ArrayRemove = {\n op: \"remove\",\n index: i - 1,\n };\n const add_operation: ArrayAdd = {\n op: \"add\",\n index: i - 1,\n value: output[j - 1],\n };\n\n if (j === 0) {\n memoized = {\n prev: remove_prev_key,\n operation: remove_operation,\n cost: memo[i - 1][j].cost + 1,\n };\n } else if (i === 0) {\n memoized = { prev: add_prev_key, operation: add_operation, cost: memo[i][j - 1].cost + 1 };\n } else {\n if (deepEqual(input[i - 1], output[j - 1])) {\n memoized = memo[i - 1][j - 1];\n } else {\n const remove_prev = memo[i - 1][j];\n const add_prev = memo[i][j - 1];\n const replace_prev = memo[i - 1][j - 1];\n const min_cost = Math.min(replace_prev.cost, add_prev.cost, remove_prev.cost);\n if (remove_prev.cost === min_cost) {\n memoized = {\n prev: remove_prev_key,\n operation: remove_operation,\n cost: memo[i - 1][j].cost + 1,\n };\n } else if (add_prev.cost === min_cost) {\n memoized = {\n prev: add_prev_key,\n operation: add_operation,\n cost: memo[i][j - 1].cost + 1,\n };\n } else {\n const replace_operation: ArrayReplace = {\n op: \"replace\",\n index: i - 1,\n original: input[i - 1],\n value: output[j - 1],\n };\n memoized = {\n prev: replace_prev_key,\n operation: replace_operation,\n cost: memo[i - 1][j - 1].cost + 1,\n };\n }\n }\n }\n memo[i][j] = memoized;\n }\n }\n const array_operations = buildOperations(memo, input_end, output_end);\n const [padded_operations] = array_operations.reduce<[Operation[], number]>(\n ([operations, padding], array_operation) => {\n if (isArrayAdd(array_operation)) {\n const padded_index = array_operation.index + 1 + padding;\n const index_token = padded_index < input_length + padding ? String(padded_index) : \"-\";\n const operation = {\n op: array_operation.op,\n path: ptr.add(index_token).toString(),\n value: array_operation.value,\n };\n // padding++ // maybe only if array_operation.index > -1 ?\n return [operations.concat(operation), padding + 1];\n } else if (isArrayRemove(array_operation)) {\n const operation = {\n op: array_operation.op,\n path: ptr.add(String(array_operation.index + padding)).toString(),\n };\n // padding--\n return [operations.concat(operation), padding - 1];\n } else {\n // replace\n const replace_ptr = ptr.add(String(array_operation.index + padding));\n const replace_operations = diff(\n array_operation.original,\n array_operation.value,\n replace_ptr,\n );\n return [operations.concat(...replace_operations), padding];\n }\n },\n [[], 0],\n );\n return padded_operations;\n}\n\nexport function diffObjects(\n input: any,\n output: any,\n ptr: Pointer,\n diff: Diff = diffAny,\n): Operation[] {\n // if a key is in input but not output -> remove it\n const operations: Operation[] = [];\n subtract(input, output).forEach((key) => {\n operations.push({ op: \"remove\", path: ptr.add(key).toString() });\n });\n // if a key is in output but not input -> add it\n subtract(output, input).forEach((key) => {\n operations.push({ op: \"add\", path: ptr.add(key).toString(), value: output[key] });\n });\n // if a key is in both, diff it recursively\n intersection([input, output]).forEach((key) => {\n operations.push(...diff(input[key], output[key], ptr.add(key)));\n });\n return operations;\n}\n\n/**\n`diffAny()` returns an empty array if `input` and `output` are materially equal\n(i.e., would produce equivalent JSON); otherwise it produces an array of patches\nthat would transform `input` into `output`.\n\n> Here, \"equal\" means that the value at the target location and the\n> value conveyed by \"value\" are of the same JSON type, and that they\n> are considered equal by the following rules for that type:\n> o strings: are considered equal if they contain the same number of\n> Unicode characters and their code points are byte-by-byte equal.\n> o numbers: are considered equal if their values are numerically\n> equal.\n> o arrays: are considered equal if they contain the same number of\n> values, and if each value can be considered equal to the value at\n> the corresponding position in the other array, using this list of\n> type-specific rules.\n> o objects: are considered equal if they contain the same number of\n> members, and if each member can be considered equal to a member in\n> the other object, by comparing their keys (as strings) and their\n> values (using this list of type-specific rules).\n> o literals (false, true, and null): are considered equal if they are\n> the same.\n*/\nexport function diffAny(input: any, output: any, ptr: Pointer, diff: Diff = diffAny): Operation[] {\n // strict equality handles literals, numbers, and strings (a sufficient but not necessary cause)\n if (input === output) {\n return [];\n }\n const input_type = objectType(input);\n const output_type = objectType(output);\n if (input_type === \"array\" && output_type === \"array\") {\n return diffArrays(input, output, ptr, diff);\n }\n if (input_type === \"object\" && output_type === \"object\") {\n return diffObjects(input, output, ptr, diff);\n }\n // at this point we know that input and output are materially different;\n // could be array -> object, object -> array, boolean -> undefined,\n // number -> string, or some other combination, but nothing that can be split\n // up into multiple patches: so `output` must replace `input` wholesale.\n return [{ op: \"replace\", path: ptr.toString(), value: output }];\n}\n", "import {\n AddOperation,\n CopyOperation,\n diffAny,\n MoveOperation,\n Operation,\n RemoveOperation,\n ReplaceOperation,\n TestOperation,\n} from \"./diff\";\nimport { Pointer } from \"./pointer\";\nimport { clone } from \"./util\";\n\nexport class MissingError extends Error {\n constructor(public path: string) {\n super(`Value required at path: ${path}`);\n this.name = \"MissingError\";\n }\n}\n\nexport class TestError extends Error {\n constructor(\n public actual: any,\n public expected: any,\n ) {\n super(`Test failed: ${actual} != ${expected}`);\n this.name = \"TestError\";\n }\n}\n\n/**\n Apply a 'application/json-patch+json'-type patch to an object.\n\n `patch` *must* be an array of operations.\n\n > Operation objects MUST have exactly one \"op\" member, whose value\n > indicates the operation to perform. Its value MUST be one of \"add\",\n > \"remove\", \"replace\", \"move\", \"copy\", or \"test\"; other values are\n > errors.\n\n This method mutates the target object in-place.\n\n @returns list of results, one for each operation: `null` indicated success,\n otherwise, the result will be an instance of one of the Error classes:\n MissingError, InvalidOperationError, or TestError.\n */\nexport function applyPatch(object: any, patch: Operation[]) {\n return patch.map((operation) => apply(object, operation));\n}\n\nfunction _add(object: any, key: string, value: any): void {\n if (Array.isArray(object)) {\n // `key` must be an index\n if (key === \"-\") {\n object.push(value);\n } else {\n const index = parseInt(key, 10);\n object.splice(index, 0, value);\n }\n } else {\n object[key] = value;\n }\n}\n\nfunction _remove(object: any, key: string): void {\n if (Array.isArray(object)) {\n // '-' syntax doesn't make sense when removing\n const index = parseInt(key, 10);\n object.splice(index, 1);\n } else {\n // not sure what the proper behavior is when path = ''\n delete object[key];\n }\n}\n\n/**\n> o If the target location specifies an array index, a new value is\n> inserted into the array at the specified index.\n> o If the target location specifies an object member that does not\n> already exist, a new member is added to the object.\n> o If the target location specifies an object member that does exist,\n> that member's value is replaced.\n*/\nexport function add(object: any, operation: AddOperation): MissingError | null {\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n // it's not exactly a \"MissingError\" in the same way that `remove` is -- more like a MissingParent, or something\n if (endpoint.parent === undefined) {\n return new MissingError(operation.path);\n }\n _add(endpoint.parent, endpoint.key, clone(operation.value));\n return null;\n}\n\n/**\n> The \"remove\" operation removes the value at the target location.\n> The target location MUST exist for the operation to be successful.\n*/\nexport function remove(object: any, operation: RemoveOperation): MissingError | null {\n // endpoint has parent, key, and value properties\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.value === undefined) {\n return new MissingError(operation.path);\n }\n // not sure what the proper behavior is when path = ''\n _remove(endpoint.parent, endpoint.key);\n return null;\n}\n\n/**\n> The \"replace\" operation replaces the value at the target location\n> with a new value. The operation object MUST contain a \"value\" member\n> whose content specifies the replacement value.\n> The target location MUST exist for the operation to be successful.\n\n> This operation is functionally identical to a \"remove\" operation for\n> a value, followed immediately by an \"add\" operation at the same\n> location with the replacement value.\n\nEven more simply, it's like the add operation with an existence check.\n*/\nexport function replace(object: any, operation: ReplaceOperation): MissingError | null {\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.parent === null) {\n return new MissingError(operation.path);\n }\n // this existence check treats arrays as a special case\n if (Array.isArray(endpoint.parent)) {\n if (parseInt(endpoint.key, 10) >= endpoint.parent.length) {\n return new MissingError(operation.path);\n }\n } else if (endpoint.value === undefined) {\n return new MissingError(operation.path);\n }\n endpoint.parent[endpoint.key] = operation.value;\n return null;\n}\n\n/**\n> The \"move\" operation removes the value at a specified location and\n> adds it to the target location.\n> The operation object MUST contain a \"from\" member, which is a string\n> containing a JSON Pointer value that references the location in the\n> target document to move the value from.\n> This operation is functionally identical to a \"remove\" operation on\n> the \"from\" location, followed immediately by an \"add\" operation at\n> the target location with the value that was just removed.\n\n> The \"from\" location MUST NOT be a proper prefix of the \"path\"\n> location; i.e., a location cannot be moved into one of its children.\n\nTODO: throw if the check described in the previous paragraph fails.\n*/\nexport function move(object: any, operation: MoveOperation): MissingError | null {\n const from_endpoint = Pointer.fromJSON(operation.from).evaluate(object);\n if (from_endpoint.value === undefined) {\n return new MissingError(operation.from);\n }\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.parent === undefined) {\n return new MissingError(operation.path);\n }\n _remove(from_endpoint.parent, from_endpoint.key);\n _add(endpoint.parent, endpoint.key, from_endpoint.value);\n return null;\n}\n\n/**\n> The \"copy\" operation copies the value at a specified location to the\n> target location.\n> The operation object MUST contain a \"from\" member, which is a string\n> containing a JSON Pointer value that references the location in the\n> target document to copy the value from.\n> The \"from\" location MUST exist for the operation to be successful.\n\n> This operation is functionally identical to an \"add\" operation at the\n> target location using the value specified in the \"from\" member.\n\nAlternatively, it's like 'move' without the 'remove'.\n*/\nexport function copy(object: any, operation: CopyOperation): MissingError | null {\n const from_endpoint = Pointer.fromJSON(operation.from).evaluate(object);\n if (from_endpoint.value === undefined) {\n return new MissingError(operation.from);\n }\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n if (endpoint.parent === undefined) {\n return new MissingError(operation.path);\n }\n _add(endpoint.parent, endpoint.key, clone(from_endpoint.value));\n return null;\n}\n\n/**\n> The \"test\" operation tests that a value at the target location is\n> equal to a specified value.\n> The operation object MUST contain a \"value\" member that conveys the\n> value to be compared to the target location's value.\n> The target location MUST be equal to the \"value\" value for the\n> operation to be considered successful.\n*/\nexport function test(object: any, operation: TestOperation): TestError | null {\n const endpoint = Pointer.fromJSON(operation.path).evaluate(object);\n // TODO: this diffAny(...).length usage could/should be lazy\n if (diffAny(endpoint.value, operation.value, new Pointer()).length) {\n return new TestError(endpoint.value, operation.value);\n }\n return null;\n}\n\nexport class InvalidOperationError extends Error {\n constructor(public operation: Operation) {\n super(`Invalid operation: ${operation.op}`);\n this.name = \"InvalidOperationError\";\n }\n}\n\n/**\nSwitch on `operation.op`, applying the corresponding patch function for each\ncase to `object`.\n*/\nexport function apply(\n object: any,\n operation: Operation,\n): MissingError | InvalidOperationError | TestError | null {\n // not sure why TypeScript can't infer typesafety of:\n // {add, remove, replace, move, copy, test}[operation.op](object, operation)\n // (seems like a bug)\n switch (operation.op) {\n case \"add\":\n return add(object, operation);\n case \"remove\":\n return remove(object, operation);\n case \"replace\":\n return replace(object, operation);\n case \"move\":\n return move(object, operation);\n case \"copy\":\n return copy(object, operation);\n case \"test\":\n return test(object, operation);\n }\n return new InvalidOperationError(operation);\n}\n", "import { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport * as rfc6902 from \"../rfc6902\";\n\nexport type NodeMapping = {\n clientFacingNodeId: number;\n internalNodeId: number;\n};\n\n/**\n * VirtualDOMDiffStruct is a representation of how a VirtualDOM has changed. It contains the original state of the\n * VirtualDOM, a list of node ID remappings, and a list of RFC6902 operations that can be applied to the original state\n * to produce the new state.\n */\nexport type VirtualDOMDiffStruct = {\n originalState: StaticVirtualDOMElement;\n nodeIdRemappings: Array<NodeMapping>;\n virtualDOMDiffs: Array<rfc6902.Operation>;\n};\n\nexport function calculateStaticVirtualDOMDiff(\n originalState: StaticVirtualDOMElement,\n latestState: StaticVirtualDOMElement,\n): VirtualDOMDiffStruct {\n const jsonPatchDiffs = rfc6902.createPatch(\n originalState,\n latestState,\n (a, b, ptr: rfc6902.Pointer) => {\n if (a.tag !== b.tag) {\n return [{ op: \"replace\", path: ptr.toString(), value: b }];\n }\n return;\n },\n );\n\n const nodeIdRemappings: Array<NodeMapping> = [];\n const virtualDOMDiffs: Array<rfc6902.Operation> = [];\n for (const diff of jsonPatchDiffs) {\n if (diff.op === \"replace\" && diff.path.endsWith(\"/nodeId\")) {\n const pointer = rfc6902.Pointer.fromJSON(diff.path);\n const originalValue = pointer.get(originalState);\n nodeIdRemappings.push({\n internalNodeId: diff.value,\n clientFacingNodeId: originalValue,\n });\n } else {\n virtualDOMDiffs.push(diff);\n }\n }\n\n return remapDuplicatedNodeIdsInOperations(\n {\n originalState,\n nodeIdRemappings,\n virtualDOMDiffs,\n },\n latestState,\n );\n}\n\nfunction getHighestNodeId(node: StaticVirtualDOMElement) {\n let highest = node.nodeId;\n for (const child of node.childNodes) {\n highest = Math.max(highest, getHighestNodeId(child));\n }\n return highest;\n}\n\nfunction getRemovedNodeIds(before: StaticVirtualDOMElement, diff: rfc6902.Operation) {\n const removedIds = new Set<number>();\n function addNode(node: StaticVirtualDOMElement) {\n removedIds.add(node.nodeId);\n for (const child of node.childNodes) {\n addNode(child);\n }\n }\n if (diff.op === \"replace\" || diff.op === \"remove\") {\n const removedNode = rfc6902.Pointer.fromJSON(diff.path).get(before);\n addNode(removedNode);\n }\n return removedIds;\n}\n\nfunction getNodeIdsFromNodeAndChildren(node: StaticVirtualDOMElement) {\n const nodeIds = new Set<number>();\n function addNode(node: StaticVirtualDOMElement) {\n nodeIds.add(node.nodeId);\n for (const child of node.childNodes) {\n addNode(child);\n }\n }\n addNode(node);\n return nodeIds;\n}\n\n// To avoid duplicate node ids at any point in the sequence of operations, apply the operations and determine if any node ids are duplicated at any point. If so, remap the node ids to be unique.\nfunction remapDuplicatedNodeIdsInOperations(\n virtualDOMDiffStruct: VirtualDOMDiffStruct,\n latestState: StaticVirtualDOMElement,\n): VirtualDOMDiffStruct {\n const { originalState, nodeIdRemappings, virtualDOMDiffs } = virtualDOMDiffStruct;\n\n const highestNodeIdAcrossStartAndEnd = Math.max(\n getHighestNodeId(originalState),\n getHighestNodeId(latestState),\n );\n let nextNodeId = highestNodeIdAcrossStartAndEnd + 1;\n\n const before = JSON.parse(JSON.stringify(originalState));\n\n function checkAndReplaceNodeIdsIfAlreadyInUse(\n node: StaticVirtualDOMElement,\n addingNodeIds: Set<number>,\n removedIds: Set<number>,\n ) {\n if (existingNodeIds.has(node.nodeId) && removedIds && !removedIds.has(node.nodeId)) {\n // This node id is already present so it must be replaced\n const newNodeId = nextNodeId++;\n nodeIdRemappings.push({\n internalNodeId: node.nodeId,\n clientFacingNodeId: newNodeId,\n });\n node.nodeId = newNodeId;\n addingNodeIds.add(newNodeId);\n } else {\n addingNodeIds.add(node.nodeId);\n }\n for (const child of node.childNodes) {\n checkAndReplaceNodeIdsIfAlreadyInUse(child, addingNodeIds, removedIds);\n }\n }\n\n const existingNodeIds = getNodeIdsFromNodeAndChildren(before);\n\n for (const diff of virtualDOMDiffs) {\n const pointer = rfc6902.Pointer.fromJSON(diff.path);\n const secondLastToken = pointer.tokens[pointer.tokens.length - 2];\n if (secondLastToken !== \"childNodes\") {\n continue;\n }\n const removedIds = getRemovedNodeIds(before, diff);\n const addingNodeIds = new Set<number>();\n if (diff.op === \"replace\" || diff.op === \"add\") {\n // The added node can use removed node ids, but it must not use any node ids that are still in use.\n checkAndReplaceNodeIdsIfAlreadyInUse(diff.value, addingNodeIds, removedIds);\n }\n removedIds.forEach((removedId) => {\n existingNodeIds.delete(removedId);\n });\n addingNodeIds.forEach((addingNodeId) => {\n existingNodeIds.add(addingNodeId);\n });\n\n const patchErrors = rfc6902.applyPatch(before, [diff]);\n if (patchErrors.length !== 1 || patchErrors[0] !== null) {\n throw new Error(\"Patch failed\");\n }\n }\n\n return virtualDOMDiffStruct;\n}\n", "export type Subjectivity = {\n visibleTo: Set<number>;\n hiddenFrom: Set<number>;\n ancestorSubjectivity: Subjectivity | null;\n};\n\nexport function IsVisibleToAll(s: Subjectivity, applyV01Semantics: boolean): boolean {\n if (applyV01Semantics) {\n // In v0.1, hiddenFrom nodes should not be sent\n return (\n s.visibleTo.size === 0 &&\n s.hiddenFrom.size === 0 &&\n (s.ancestorSubjectivity == null || IsVisibleToAll(s.ancestorSubjectivity, applyV01Semantics))\n );\n }\n return (\n s.visibleTo.size === 0 &&\n (s.ancestorSubjectivity == null || IsVisibleToAll(s.ancestorSubjectivity, applyV01Semantics))\n );\n}\n\nexport function IsVisibleToAnyOneOfConnectionIds(\n s: Subjectivity,\n connectionIdsMap: Map<number, number>,\n applyV01Semantics: boolean,\n): boolean {\n if (IsVisibleToAll(s, applyV01Semantics)) {\n return true;\n }\n let visibleToDirectly = false;\n if (s.visibleTo.size > 0) {\n for (const connectionId of s.visibleTo) {\n if (connectionIdsMap.has(connectionId)) {\n visibleToDirectly = true;\n break;\n }\n }\n if (!visibleToDirectly) {\n // There is a visibleTo list and none of the connections are in it so this node is not visible\n return false;\n }\n }\n if (applyV01Semantics) {\n // In v0.1, hiddenFrom nodes should not be sent\n for (const connectionId of s.hiddenFrom) {\n if (connectionIdsMap.has(connectionId)) {\n // If the connection is in the HiddenFrom list then it should not be visible\n return false;\n }\n }\n }\n if (s.ancestorSubjectivity == null) {\n return true;\n }\n return IsVisibleToAnyOneOfConnectionIds(\n s.ancestorSubjectivity,\n connectionIdsMap,\n applyV01Semantics,\n );\n}\n\nexport type NodeWithSubjectivity = {\n nodeId: number;\n tag: string;\n textContent?: string;\n attributes: { [key: string]: string };\n childNodes: Array<NodeWithSubjectivity>;\n\n subjectivity: Subjectivity;\n parent: NodeWithSubjectivity | null;\n};\n\nexport function applySubjectivityToChildren(\n node: NodeWithSubjectivity,\n newSubjectivity: Subjectivity,\n previousSubjectivity: Subjectivity,\n) {\n for (const child of node.childNodes) {\n if (child.subjectivity === previousSubjectivity) {\n child.subjectivity = newSubjectivity;\n applySubjectivityToChildren(child, newSubjectivity, previousSubjectivity);\n } else {\n child.subjectivity.ancestorSubjectivity = newSubjectivity;\n }\n }\n}\n", "import {\n NetworkedDOMV01ElementNodeDescription,\n NetworkedDOMV01NodeDescription,\n NetworkedDOMV02ElementNodeDescription,\n NetworkedDOMV02NodeDescription,\n NetworkedDOMV02TextNodeDescription,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { NetworkedDOMV01Connection } from \"../NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"../NetworkedDOMV02Connection\";\nimport {\n IsVisibleToAll,\n IsVisibleToAnyOneOfConnectionIds,\n NodeWithSubjectivity,\n} from \"../NodeWithSubjectivity\";\n\nexport const visibleToAttrName = \"visible-to\";\nexport const hiddenFromAttrName = \"hidden-from\";\n\nfunction filteredV01Attributes(\n attributes: { [key: string]: string },\n excludedKeys: Set<string>,\n): { [key: string]: string } {\n const filtered: { [key: string]: string } = {};\n for (const key in attributes) {\n if (!excludedKeys.has(key)) {\n filtered[key] = attributes[key];\n }\n }\n return filtered;\n}\n\nfunction filteredV02Attributes(\n attributes: { [key: string]: string },\n excludedKeys: Set<string>,\n): Array<[string, string]> {\n const filtered: Array<[string, string]> = [];\n for (const key in attributes) {\n if (!excludedKeys.has(key)) {\n filtered.push([key, attributes[key]]);\n }\n }\n return filtered;\n}\n\nconst excludedAttributes = new Set([visibleToAttrName, hiddenFromAttrName]);\n\nexport function describeNodeWithChildrenForV01Connection(\n virtualDOMElement: NodeWithSubjectivity,\n networkedDOMConnection: NetworkedDOMV01Connection | null,\n): NetworkedDOMV01NodeDescription | null {\n if (\n networkedDOMConnection\n ? !IsVisibleToAnyOneOfConnectionIds(\n virtualDOMElement.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n true,\n )\n : !IsVisibleToAll(virtualDOMElement.subjectivity, true)\n ) {\n return null;\n }\n let emittedTagName = virtualDOMElement.tag;\n if (emittedTagName === \"#DOCUMENT\") {\n emittedTagName = \"DIV\";\n }\n if (emittedTagName === \"#text\") {\n const textNode: NetworkedDOMV02TextNodeDescription = {\n type: \"text\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n return textNode;\n } else {\n const node: NetworkedDOMV01ElementNodeDescription = {\n type: \"element\",\n nodeId: virtualDOMElement.nodeId,\n tag: emittedTagName,\n attributes: filteredV01Attributes(virtualDOMElement.attributes, excludedAttributes),\n children: [],\n text: virtualDOMElement.textContent,\n };\n\n for (const child of virtualDOMElement.childNodes) {\n const childNodeDescription = describeNodeWithChildrenForV01Connection(\n child,\n networkedDOMConnection,\n );\n if (childNodeDescription) {\n node.children.push(childNodeDescription);\n }\n }\n return node;\n }\n}\n\nexport function describeNodeWithChildrenForV02Connection(\n virtualDOMElement: NodeWithSubjectivity,\n networkedDOMConnection: NetworkedDOMV02Connection | null,\n): NetworkedDOMV02NodeDescription | null {\n if (\n networkedDOMConnection\n ? !IsVisibleToAnyOneOfConnectionIds(\n virtualDOMElement.subjectivity,\n networkedDOMConnection.internalIdToExternalId,\n false,\n )\n : !IsVisibleToAll(virtualDOMElement.subjectivity, false)\n ) {\n return null;\n }\n let emittedTagName = virtualDOMElement.tag;\n if (emittedTagName === \"#DOCUMENT\") {\n emittedTagName = \"DIV\";\n }\n if (emittedTagName === \"#text\") {\n const textNode: NetworkedDOMV02TextNodeDescription = {\n type: \"text\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n return textNode;\n } else {\n const visibleTo: Array<number> = [];\n const hiddenFrom: Array<number> = [];\n const hasOwnSubjectivity =\n virtualDOMElement.parent &&\n virtualDOMElement.subjectivity !== virtualDOMElement.parent.subjectivity;\n if (networkedDOMConnection && hasOwnSubjectivity) {\n for (const id of virtualDOMElement.subjectivity.visibleTo) {\n const remapped = networkedDOMConnection.internalIdToExternalId.get(id);\n if (remapped !== undefined) {\n visibleTo.push(remapped);\n }\n }\n for (const id of virtualDOMElement.subjectivity.hiddenFrom) {\n const remapped = networkedDOMConnection.internalIdToExternalId.get(id);\n if (remapped !== undefined) {\n hiddenFrom.push(remapped);\n }\n }\n }\n\n const node: NetworkedDOMV02ElementNodeDescription = {\n type: \"element\",\n nodeId: virtualDOMElement.nodeId,\n tag: emittedTagName,\n attributes: filteredV02Attributes(virtualDOMElement.attributes, excludedAttributes),\n children: [],\n text: virtualDOMElement.textContent,\n visibleTo,\n hiddenFrom,\n };\n\n for (const child of virtualDOMElement.childNodes) {\n const childNodeDescription = describeNodeWithChildrenForV02Connection(\n child,\n networkedDOMConnection,\n );\n if (childNodeDescription) {\n node.children.push(childNodeDescription);\n }\n }\n return node;\n }\n}\n", "export function listAttributeToSet(attr?: string | null): Set<number> {\n if (attr === null || attr === undefined || attr === \"\") {\n return new Set();\n }\n let hasInvalid = false;\n const entries = attr\n .split(/[\\s,]+/)\n .map((x) => {\n // Must be an integer as a string (i.e. not 2.5 parsed as 2) or it is ignored\n // Checked with a regex to ensure it is a positive integer\n if (/^-?[0-9]\\d*$/.test(x)) {\n return parseInt(x, 10);\n }\n hasInvalid = true;\n return null;\n })\n .filter((x) => x !== null);\n if (entries.length === 0 && hasInvalid) {\n // In the case of only invalid entries, return -1 to ensure the set is not interpreted as intentionally empty\n return new Set([-1]);\n }\n return new Set(entries);\n}\n", "// TODO - there are more possible mergeable patterns\nimport { StaticVirtualDOMMutationIdsRecord } from \"@mml-io/observable-dom-common\";\n\nexport function mergeMutations(mutations: Array<StaticVirtualDOMMutationIdsRecord>) {\n if (mutations.length <= 1) {\n return mutations;\n }\n // Include the first one as the base\n const mergedMutations = [mutations[0]];\n const lastMutation = mutations[0];\n for (let i = 1; i < mutations.length; i++) {\n const currentMutation = mutations[i];\n if (\n currentMutation.type === \"childList\" &&\n lastMutation.type === \"childList\" &&\n lastMutation.targetId === currentMutation.targetId\n ) {\n const lastAddedNodeId: number | null =\n lastMutation.addedNodes.length > 0\n ? lastMutation.addedNodes[lastMutation.addedNodes.length - 1].nodeId\n : null;\n if (\n lastAddedNodeId !== null &&\n currentMutation.previousSiblingId === lastAddedNodeId &&\n currentMutation.removedNodeIds.length === 0 // Can't trivially merge if there are removed nodes because the nodes might be in the added nodes of the previous mutation\n ) {\n // Can trivially merge these as the current mutation is just adding to the end of the last mutation\n lastMutation.addedNodes.push(...currentMutation.addedNodes);\n continue;\n }\n } else if (\n currentMutation.type === \"attributes\" &&\n lastMutation.type === \"attributes\" &&\n lastMutation.targetId === currentMutation.targetId\n ) {\n // Can trivially merge these as the current mutation is just applying more attributes to the same node\n Object.assign(lastMutation.attributes, currentMutation.attributes);\n continue;\n }\n mergedMutations.push(currentMutation);\n }\n return mergedMutations;\n}\n", "import {\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\n\nimport * as rfc6902 from \"../rfc6902\";\n\nexport function virtualDOMDiffToVirtualDOMMutationRecord(\n virtualStructure: StaticVirtualDOMElement,\n domDiff: rfc6902.Operation,\n): Array<StaticVirtualDOMMutationIdsRecord> {\n const pointer = rfc6902.Pointer.fromJSON(domDiff.path);\n const grandParentTokens = pointer.tokens.slice(0, pointer.tokens.length - 2);\n const lastToken = pointer.tokens[pointer.tokens.length - 1];\n const secondLastToken = pointer.tokens[pointer.tokens.length - 2];\n\n if (lastToken === \"textContent\") {\n const nodePointer = new rfc6902.Pointer(pointer.tokens.slice(0, pointer.tokens.length - 1));\n const node = nodePointer.get(virtualStructure) as StaticVirtualDOMElement;\n if (domDiff.op === \"replace\" || domDiff.op === \"add\") {\n return [\n {\n type: \"characterData\",\n targetId: node.nodeId,\n textContent: domDiff.value as string,\n },\n ];\n } else {\n throw new Error(\"Unhandled character data diff type\");\n }\n }\n\n if (secondLastToken === \"attributes\") {\n // This handles attribute additions, changes, and removals\n const nodePointer = new rfc6902.Pointer(grandParentTokens);\n const node = nodePointer.get(virtualStructure) as StaticVirtualDOMElement;\n let value;\n if (domDiff.op === \"remove\") {\n value = null;\n } else if (domDiff.op === \"replace\" || domDiff.op === \"add\") {\n value = domDiff.value;\n } else {\n throw new Error(\"Unhandled attribute diff type\");\n }\n return [\n {\n type: \"attributes\",\n targetId: node.nodeId,\n attributes: {\n [lastToken]: value,\n },\n },\n ];\n }\n\n // Child changes\n\n if (secondLastToken === \"childNodes\") {\n const nodePointer = new rfc6902.Pointer(grandParentTokens);\n const node = nodePointer.get(virtualStructure) as StaticVirtualDOMElement;\n\n let previousSibling: StaticVirtualDOMElement | null = null;\n if (lastToken === \"-\") {\n if (node.childNodes.length > 0) {\n previousSibling = node.childNodes[node.childNodes.length - 1];\n } else {\n // There are no siblings to account for\n }\n } else {\n const index = parseInt(lastToken, 10);\n if (index === 0) {\n previousSibling = null;\n } else {\n previousSibling = node.childNodes[index - 1];\n }\n }\n const addedNodes: Array<StaticVirtualDOMElement> = [];\n const removedNodes: Array<StaticVirtualDOMElement> = [];\n switch (domDiff.op) {\n case \"add\": {\n addedNodes.push(domDiff.value as StaticVirtualDOMElement);\n return [\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes,\n removedNodeIds: [],\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n ];\n }\n case \"remove\": {\n const removedNode = pointer.get(virtualStructure) as StaticVirtualDOMElement;\n removedNodes.push(removedNode);\n return [\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes,\n removedNodeIds: removedNodes.map((node) => node.nodeId),\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n ];\n }\n case \"replace\": {\n // This is a replacement of a single node\n const removedNode = pointer.get(virtualStructure) as StaticVirtualDOMElement;\n return [\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes: [],\n removedNodeIds: [removedNode.nodeId],\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n {\n type: \"childList\",\n targetId: node.nodeId,\n addedNodes: [domDiff.value as StaticVirtualDOMElement],\n removedNodeIds: [],\n previousSiblingId: previousSibling ? previousSibling.nodeId : null,\n },\n ];\n }\n }\n }\n\n if (domDiff.op === \"replace\" && domDiff.path === \"\") {\n throw new Error(\"Not implemented - root node is not replaceable\");\n }\n\n console.error(\"Unhandled JSON diff:\", JSON.stringify(domDiff, null, 2));\n throw new Error(\"Unhandled diff type\");\n}\n", "import { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { hiddenFromAttrName, visibleToAttrName } from \"./diffing/describeNode\";\nimport { listAttributeToSet } from \"./diffing/listAttributeToSet\";\nimport { NodeWithSubjectivity, Subjectivity } from \"./NodeWithSubjectivity\";\nimport { VisibilityManager } from \"./VisibilityManager\";\n\nexport class NodeManager {\n private nodeIdToNode = new Map<number, NodeWithSubjectivity>();\n private maximumNodeId = 0;\n\n // Map from the node ids that the DOM uses internally to the node ids that clients refer to.\n private internalNodeIdToClientNodeId = new Map<number, number>();\n\n // Map from the node ids that clients refer to to the node ids that the DOM uses internally.\n private clientNodeIdToInternalNodeId = new Map<number, number>();\n\n constructor(private visibilityManager: VisibilityManager) {}\n\n public getNode(nodeId: number): NodeWithSubjectivity | undefined {\n return this.nodeIdToNode.get(nodeId);\n }\n\n public deleteNode(nodeId: number) {\n this.nodeIdToNode.delete(nodeId);\n }\n\n public addNodeFromInstance(\n node: StaticVirtualDOMElement,\n parentNode: NodeWithSubjectivity | null,\n ): [NodeWithSubjectivity, boolean] {\n let hasSubjectivity = false;\n const nodeId = node.nodeId;\n if (this.nodeIdToNode.has(nodeId)) {\n throw new Error(\"Node already exists with id \" + nodeId);\n }\n\n const parentSubjectivity = parentNode\n ? parentNode.subjectivity\n : {\n // Root node case\n visibleTo: new Set<number>(),\n hiddenFrom: new Set<number>(),\n ancestorSubjectivity: null,\n };\n const visibleTo = listAttributeToSet(node.attributes[visibleToAttrName]);\n const hiddenFrom = listAttributeToSet(node.attributes[hiddenFromAttrName]);\n let subjectivity: Subjectivity = parentSubjectivity;\n if (visibleTo.size > 0 || hiddenFrom.size > 0) {\n hasSubjectivity = true;\n subjectivity = {\n visibleTo,\n hiddenFrom,\n ancestorSubjectivity: parentSubjectivity,\n };\n for (const connectionId of visibleTo) {\n this.visibilityManager.addSpecificallyVisibleNode(connectionId, nodeId);\n }\n }\n\n const attributes = { ...node.attributes };\n if (attributes[visibleToAttrName]) {\n delete attributes[visibleToAttrName];\n }\n if (attributes[hiddenFromAttrName]) {\n delete attributes[hiddenFromAttrName];\n }\n\n const nodeWithSubjectivity: NodeWithSubjectivity = {\n nodeId,\n tag: node.tag,\n textContent: node.textContent,\n attributes,\n childNodes: [],\n subjectivity,\n parent: parentNode,\n };\n\n this.nodeIdToNode.set(nodeId, nodeWithSubjectivity);\n this.maximumNodeId = Math.max(this.maximumNodeId, nodeId);\n\n for (const childNode of node.childNodes) {\n const [addedChild, childSubjectivity] = this.addNodeFromInstance(\n childNode,\n nodeWithSubjectivity,\n );\n if (childSubjectivity) {\n hasSubjectivity = true;\n }\n nodeWithSubjectivity.childNodes.push(addedChild);\n }\n\n return [nodeWithSubjectivity, hasSubjectivity];\n }\n\n public addRemappedNodeId(clientFacingNodeId: number, internalNodeId: number) {\n if (this.internalNodeIdToClientNodeId.has(internalNodeId)) {\n throw new Error(\"Node already exists with internal node id \" + internalNodeId);\n }\n if (this.clientNodeIdToInternalNodeId.has(clientFacingNodeId)) {\n throw new Error(\"Node already exists with client id \" + clientFacingNodeId);\n }\n this.internalNodeIdToClientNodeId.set(internalNodeId, clientFacingNodeId);\n this.clientNodeIdToInternalNodeId.set(clientFacingNodeId, internalNodeId);\n this.maximumNodeId = Math.max(this.maximumNodeId, Math.max(clientFacingNodeId, internalNodeId));\n }\n\n public hasAnyRemappings(): boolean {\n return this.internalNodeIdToClientNodeId.size > 0;\n }\n\n public getPotentiallyRemappedNode(nodeId: number, createIfCollided = false): number {\n const newId = this.internalNodeIdToClientNodeId.get(nodeId);\n if (newId !== undefined) {\n return newId;\n }\n if (createIfCollided) {\n // If a node already exists with this id, we need to create a new id and return that instead, otherwise we can use the id\n if (this.nodeIdToNode.has(nodeId) || this.clientNodeIdToInternalNodeId.has(nodeId)) {\n // Collision - need to create a new id\n const newId2 = ++this.maximumNodeId;\n this.addRemappedNodeId(newId2, nodeId);\n return newId2;\n }\n return nodeId;\n }\n return nodeId;\n }\n\n public getStaticVirtualDOMElementByInternalNodeIdOrThrow(\n internalNodeId: number,\n ): NodeWithSubjectivity {\n const node = this.nodeIdToNode.get(internalNodeId);\n if (!node) {\n throw new Error(\"Node not found with nodeId:\" + internalNodeId);\n }\n return node;\n }\n\n public getInternalRemappedNodeId(nodeId: number): number | undefined {\n return this.clientNodeIdToInternalNodeId.get(nodeId);\n }\n}\n", "export class VisibilityManager {\n private connectionIdToSpecificallyVisibleNodes = new Map<number, Set<number>>();\n\n public addSpecificallyVisibleNode(internalConnectionId: number, nodeId: number) {\n let connectionIdNodes = this.connectionIdToSpecificallyVisibleNodes.get(internalConnectionId);\n if (!connectionIdNodes) {\n connectionIdNodes = new Set<number>();\n this.connectionIdToSpecificallyVisibleNodes.set(internalConnectionId, connectionIdNodes);\n }\n connectionIdNodes.add(nodeId);\n }\n\n public removeSpecificallyVisibleNode(internalConnectionId: number, nodeId: number) {\n const connectionIdNodes = this.connectionIdToSpecificallyVisibleNodes.get(internalConnectionId);\n if (connectionIdNodes) {\n connectionIdNodes.delete(nodeId);\n if (connectionIdNodes.size === 0) {\n this.connectionIdToSpecificallyVisibleNodes.delete(internalConnectionId);\n }\n }\n }\n\n public getSpecificallyVisibleNodes(internalConnectionId: number): Set<number> | undefined {\n return this.connectionIdToSpecificallyVisibleNodes.get(internalConnectionId);\n }\n}\n", "import { LogMessage, StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { createNetworkedDOMConnectionForWebsocket } from \"./createNetworkedDOMConnectionForWebsocket\";\nimport { VirtualDOMDiffStruct } from \"./diffing/calculateStaticVirtualDOMDiff\";\nimport { NetworkedDOM, ObservableDOMFactory } from \"./NetworkedDOM\";\nimport { NetworkedDOMV01Connection } from \"./NetworkedDOMV01Connection\";\nimport { NetworkedDOMV02Connection } from \"./NetworkedDOMV02Connection\";\n\nenum NetworkedDOMState {\n DocumentLoading,\n DocumentLoaded,\n BeforeDocumentLoaded,\n}\n\ntype LoadedState =\n | {\n type: NetworkedDOMState.DocumentLoaded;\n htmlContents: string;\n networkedDOM: NetworkedDOM;\n }\n | {\n type: NetworkedDOMState.DocumentLoading;\n htmlContents: string;\n networkedDOM: NetworkedDOM;\n }\n | {\n type: NetworkedDOMState.BeforeDocumentLoaded;\n };\n\n/**\n * EditableNetworkedDOM wraps NetworkedDOM instances and presents them as a single document that can iterate through\n * revisions by being loaded multiple times with different contents. The connected clients receive deltas between the\n * revisions rather than a complete refresh.\n */\nexport class EditableNetworkedDOM {\n private htmlPath: string;\n private params: object = {};\n\n private websockets = new Map<WebSocket, NetworkedDOMV01Connection | NetworkedDOMV02Connection>();\n private loadedState: LoadedState = {\n type: NetworkedDOMState.BeforeDocumentLoaded,\n };\n\n private observableDOMFactory: ObservableDOMFactory;\n private ignoreTextNodes: boolean;\n\n private logCallback?: (message: LogMessage) => void;\n\n constructor(\n htmlPath: string,\n observableDOMFactory: ObservableDOMFactory,\n ignoreTextNodes = true,\n logCallback?: (message: LogMessage) => void,\n ) {\n this.htmlPath = htmlPath;\n this.observableDOMFactory = observableDOMFactory;\n this.ignoreTextNodes = ignoreTextNodes;\n this.logCallback = logCallback;\n }\n\n public isLoaded() {\n return this.loadedState !== null;\n }\n\n public load(htmlContents: string, params?: object) {\n if (params !== undefined) {\n this.params = params;\n }\n\n let oldInstanceRoot: StaticVirtualDOMElement | null = null;\n if (\n this.loadedState.type === NetworkedDOMState.DocumentLoaded ||\n this.loadedState.type === NetworkedDOMState.DocumentLoading\n ) {\n const oldInstance = this.loadedState.networkedDOM;\n oldInstance.dispose();\n oldInstanceRoot = oldInstance.getSnapshot();\n }\n let didLoad = false;\n let hasSetLoading = false;\n const networkedDOM = new NetworkedDOM(\n this.observableDOMFactory,\n this.htmlPath,\n htmlContents,\n oldInstanceRoot,\n (domDiff: VirtualDOMDiffStruct | null, networkedDOM: NetworkedDOM) => {\n didLoad = true;\n if (!hasSetLoading) {\n hasSetLoading = true;\n this.loadedState = {\n type: NetworkedDOMState.DocumentLoaded,\n htmlContents,\n networkedDOM,\n };\n } else if (\n this.loadedState &&\n this.loadedState.type === NetworkedDOMState.DocumentLoading &&\n this.loadedState.networkedDOM === networkedDOM\n ) {\n this.loadedState = {\n type: NetworkedDOMState.DocumentLoaded,\n htmlContents,\n networkedDOM,\n };\n }\n networkedDOM.addExistingNetworkedDOMConnections(new Set(this.websockets.values()), domDiff);\n },\n this.params,\n this.ignoreTextNodes,\n this.logCallback,\n );\n hasSetLoading = true;\n if (!didLoad) {\n this.loadedState = {\n type: NetworkedDOMState.DocumentLoading,\n htmlContents,\n networkedDOM,\n };\n }\n }\n\n public reload() {\n if (this.loadedState && this.loadedState.type === NetworkedDOMState.DocumentLoaded) {\n this.load(this.loadedState.htmlContents, this.params);\n } else {\n console.warn(\"EditableNetworkedDOM.reload called whilst not loaded\");\n }\n }\n\n public dispose() {\n for (const [ws, networkedDOMConnection] of this.websockets) {\n networkedDOMConnection.dispose();\n ws.close();\n }\n this.websockets.clear();\n if (\n this.loadedState.type === NetworkedDOMState.DocumentLoaded ||\n this.loadedState.type === NetworkedDOMState.DocumentLoading\n ) {\n this.loadedState.networkedDOM.dispose();\n }\n this.loadedState = {\n type: NetworkedDOMState.BeforeDocumentLoaded,\n };\n }\n\n public addWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = createNetworkedDOMConnectionForWebsocket(webSocket);\n if (networkedDOMConnection === null) {\n // Error is handled in createNetworkedDOMConnectionForWebsocket\n return;\n }\n\n this.websockets.set(webSocket, networkedDOMConnection);\n if (this.loadedState.type === NetworkedDOMState.DocumentLoaded) {\n this.loadedState.networkedDOM.addNetworkedDOMConnection(networkedDOMConnection);\n }\n }\n\n public hasWebSocket(webSocket: WebSocket): boolean {\n return this.websockets.has(webSocket);\n }\n\n public removeWebSocket(webSocket: WebSocket) {\n const networkedDOMConnection = this.websockets.get(webSocket);\n if (networkedDOMConnection === undefined) {\n throw new Error(\"Unknown websocket\");\n }\n networkedDOMConnection.dispose();\n this.websockets.delete(webSocket);\n if (this.loadedState.type === NetworkedDOMState.DocumentLoaded) {\n this.loadedState.networkedDOM.removeNetworkedDOMConnection(networkedDOMConnection);\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["isNetworkedDOMProtocolSubProtocol_v0_2", "isNetworkedDOMProtocolSubProtocol_v0_2", "BufferWriter", "node", "node", "virtualDOMDiff", "BufferWriter", "encoded", "networkedDOM"]
|
|
7
7
|
}
|