@mml-io/networked-dom-document 0.4.0 → 0.6.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/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2023 Improbable MV Limited
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/build/index.js CHANGED
@@ -128,6 +128,10 @@ function diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(mutatio
128
128
  break;
129
129
  }
130
130
  case "characterData": {
131
+ const visible = visibleNodesForConnection.has(virtualDOMElement.nodeId);
132
+ if (!visible) {
133
+ return null;
134
+ }
131
135
  const diff = {
132
136
  type: "textChanged",
133
137
  nodeId: virtualDOMElement.nodeId,
@@ -136,6 +140,10 @@ function diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(mutatio
136
140
  return diff;
137
141
  }
138
142
  case "childList": {
143
+ const visible = visibleNodesForConnection.has(virtualDOMElement.nodeId);
144
+ if (!visible) {
145
+ return null;
146
+ }
139
147
  let previousSibling = mutation.previousSibling;
140
148
  let previousNodeId = null;
141
149
  if (previousSibling) {
@@ -514,7 +522,7 @@ function remapDuplicatedNodeIdsInOperations(virtualDOMDiffStruct, latestState) {
514
522
  // src/NetworkedDOM.ts
515
523
  var networkedDOMProtocolSubProtocol_v0_1 = "networked-dom-v0.1";
516
524
  var defaultWebsocketSubProtocol = networkedDOMProtocolSubProtocol_v0_1;
517
- var _NetworkedDOM = class {
525
+ var _NetworkedDOM = class _NetworkedDOM {
518
526
  constructor(observableDOMFactory, htmlPath, htmlContents, oldInstanceDocumentRoot, onLoad, params = {}, ignoreTextNodes = true, logCallback) {
519
527
  // Map from the node ids that the DOM uses internally to the node ids that clients refer to.
520
528
  this.internalNodeIdToClientNodeId = /* @__PURE__ */ new Map();
@@ -1045,11 +1053,11 @@ var _NetworkedDOM = class {
1045
1053
  return new Map(this.webSocketToConnectionId);
1046
1054
  }
1047
1055
  };
1048
- var NetworkedDOM = _NetworkedDOM;
1049
1056
  // First to last in order of preference
1050
- NetworkedDOM.SupportedWebsocketSubProtocolsPreferenceOrder = [
1057
+ _NetworkedDOM.SupportedWebsocketSubProtocolsPreferenceOrder = [
1051
1058
  networkedDOMProtocolSubProtocol_v0_1
1052
1059
  ];
1060
+ var NetworkedDOM = _NetworkedDOM;
1053
1061
 
1054
1062
  // src/EditableNetworkedDOM.ts
1055
1063
  var EditableNetworkedDOM = class {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/NetworkedDOM.ts", "../src/diffing.ts", "../src/EditableNetworkedDOM.ts"],
4
- "sourcesContent": ["export * from \"./NetworkedDOM\";\nexport * from \"./EditableNetworkedDOM\";\n", "import {\n ClientMessage,\n Diff,\n NodeDescription,\n PongMessage,\n RemoteEvent,\n ServerMessage,\n SnapshotMessage,\n} from \"@mml-io/networked-dom-protocol\";\nimport {\n LogMessage,\n ObservableDOMInterface,\n ObservableDOMMessage,\n ObservableDOMParameters,\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\nimport { applyPatch } from \"rfc6902\";\n\nimport { StaticVirtualDOMMutationRecord, VirtualDOMDiffStruct } from \"./common\";\nimport {\n calculateStaticVirtualDOMDiff,\n describeNodeWithChildrenForConnectionId,\n diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection,\n findParentNodeOfNodeId,\n virtualDOMDiffToVirtualDOMMutationRecord,\n} from \"./diffing\";\n\nexport const networkedDOMProtocolSubProtocol_v0_1 = \"networked-dom-v0.1\";\nexport const defaultWebsocketSubProtocol = networkedDOMProtocolSubProtocol_v0_1;\n\nexport type ObservableDOMFactory = (\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n) => ObservableDOMInterface;\n\nexport class NetworkedDOM {\n // First to last in order of preference\n public static SupportedWebsocketSubProtocolsPreferenceOrder = [\n networkedDOMProtocolSubProtocol_v0_1,\n ];\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 private currentConnectionId = 1;\n private connectionIdToWebSocketContext = new Map<\n number,\n { webSocket: WebSocket; messageListener: (messageEvent: MessageEvent) => void }\n >();\n private webSocketToConnectionId = new Map<WebSocket, number>();\n private visibleNodeIdsByConnectionId = new Map<number, Set<number>>();\n private initialLoad = true;\n private readonly htmlPath: string;\n\n private disposed = false;\n private ignoreTextNodes: boolean;\n\n private documentRoot!: StaticVirtualDOMElement;\n private nodeIdToNode = new Map<number, StaticVirtualDOMElement>();\n private nodeIdToParentNodeId = new Map<number, number>();\n\n private observableDOM: ObservableDOMInterface;\n\n private documentEffectiveStartTime = Date.now();\n private latestDocumentTime = 0;\n private pingCounter = 1;\n private maximumNodeId = 0;\n\n private logCallback?: (message: LogMessage) => void;\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 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 this.documentRoot = 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(oldInstanceDocumentRoot, clonedSnapshot);\n for (const remapping of domDiff.nodeIdRemappings) {\n this.addRemappedNodeId(remapping.clientFacingNodeId, remapping.internalNodeId);\n }\n }\n\n this.addAndRemapNodeFromInstance(this.documentRoot, -1);\n\n onLoad(domDiff, this);\n } else if (message.mutation) {\n if (this.initialLoad) {\n throw new Error(\"Received mutation before initial load\");\n }\n const mutation = this.addKnownNodesInMutation(message.mutation);\n this.processModification(mutation);\n this.removeKnownNodesInMutation(mutation);\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 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 addRemappedNodeId(clientFacingNodeId: number, internalNodeId: number) {\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 private sendPings() {\n const ping = this.pingCounter++;\n if (this.pingCounter > 1000) {\n this.pingCounter = 1;\n }\n const pingMessage: Array<ServerMessage> = [\n {\n type: \"ping\",\n ping,\n documentTime: this.getDocumentTime(),\n },\n ];\n const stringified = JSON.stringify(pingMessage);\n this.connectionIdToWebSocketContext.forEach((webSocketContext) => {\n webSocketContext.webSocket.send(stringified);\n });\n }\n\n private getInitialSnapshot(\n connectionId: number,\n documentVirtualDOMElement: StaticVirtualDOMElement,\n ): SnapshotMessage {\n const visibleNodesForConnection = this.visibleNodeIdsByConnectionId.get(connectionId);\n if (!visibleNodesForConnection) {\n const err = new Error(\n `visibleNodesForConnection not found for connectionId in getInitialSnapshot: ${connectionId}`,\n );\n console.error(err);\n throw err;\n }\n const domSnapshot: NodeDescription | null = describeNodeWithChildrenForConnectionId(\n documentVirtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\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 addExistingWebsockets(\n websockets: Array<WebSocket>,\n existingWebsocketMap: Map<WebSocket, number> | null,\n domDiff: VirtualDOMDiffStruct | null,\n ) {\n const connectionIds = [];\n for (const websocket of websockets) {\n let existingId = null;\n if (existingWebsocketMap !== null) {\n existingId = existingWebsocketMap.get(websocket);\n }\n const { connectionId } = this.registerWebsocket(websocket, existingId);\n connectionIds.push(connectionId);\n }\n\n if (domDiff) {\n const diffsByConnectionId = new Map<number, Array<Diff>>(\n connectionIds.map((connectionId) => [connectionId, []]),\n );\n\n // Each of the websockets needs to have the original state of the document re-applied to it to determine visible\n // nodes, but not sent (they already have the old version of the document as their state).\n for (const connectionId of connectionIds) {\n // Ignore the return value - the side effect is that the visible nodes for the connection are set\n this.getInitialSnapshot(connectionId, domDiff.originalState);\n }\n\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\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 for (const mutationRecordLike of mutationRecordLikes) {\n const targetNodeId = mutationRecordLike.target.nodeId;\n const virtualElementParent = findParentNodeOfNodeId(domDiff.originalState, targetNodeId);\n diffsByConnectionId.forEach((diffs, connectionId) => {\n const mutationDiff = diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(\n mutationRecordLike,\n virtualElementParent,\n connectionId,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.visibleNodeIdsByConnectionId.get(connectionId)!,\n );\n if (mutationDiff) {\n diffs.push(mutationDiff);\n }\n });\n }\n }\n\n diffsByConnectionId.forEach((diffs, connectionId) => {\n if (diffs.length === 0) {\n // Need to add an \"empty\" message to allow passing the document time to the client\n diffs.push({\n type: \"childrenChanged\",\n nodeId: this.documentRoot.nodeId,\n previousNodeId: null,\n addedNodes: [],\n removedNodes: [],\n });\n }\n const asServerMessages: Array<ServerMessage> = diffs;\n const firstDiff = diffs[0];\n firstDiff.documentTime = this.getDocumentTime();\n const serializedDiffs = JSON.stringify(asServerMessages, null, 4);\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(`webSocketContext not found in addExistingWebsockets`);\n }\n webSocketContext.webSocket.send(serializedDiffs);\n });\n } else {\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n for (const connectionId of connectionIds) {\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(`webSocketContext not found in addExistingWebsockets`);\n }\n const asServerMessages: Array<ServerMessage> = [\n this.getInitialSnapshot(connectionId, documentVirtualDOMElement),\n ];\n const serializedSnapshotMessage = JSON.stringify(asServerMessages);\n webSocketContext.webSocket.send(serializedSnapshotMessage);\n }\n }\n\n for (const connectionId of connectionIds) {\n this.observableDOM.addConnectedUserId(connectionId);\n }\n }\n\n private findParentNodeOfNodeId(targetNodeId: number): StaticVirtualDOMElement | null {\n const parentNodeId = this.nodeIdToParentNodeId.get(targetNodeId);\n if (parentNodeId === undefined) {\n throw new Error(\"Parent node ID not found\");\n }\n return this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(parentNodeId);\n }\n\n private registerWebsocket(\n webSocket: WebSocket,\n existingConnectionId: number | null = null,\n ): { connectionId: number } {\n let connectionId: number;\n if (existingConnectionId !== null) {\n connectionId = existingConnectionId;\n this.currentConnectionId = Math.max(this.currentConnectionId, connectionId + 1);\n } else {\n connectionId = this.currentConnectionId++;\n }\n const webSocketContext = {\n webSocket,\n messageListener: (messageEvent: MessageEvent) => {\n const string = String(messageEvent.data);\n let parsed;\n try {\n parsed = JSON.parse(string) as ClientMessage;\n } catch (e) {\n console.error(`Error parsing message from websocket: ${string}`);\n console.trace();\n return;\n }\n\n if (NetworkedDOM.IsPongMessage(parsed)) {\n // Ignore pongs for now\n return;\n }\n\n this.dispatchRemoteEvent(webSocket, parsed);\n },\n };\n this.connectionIdToWebSocketContext.set(connectionId, webSocketContext);\n this.visibleNodeIdsByConnectionId.set(connectionId, new Set());\n this.webSocketToConnectionId.set(webSocket, connectionId);\n webSocket.addEventListener(\"message\", webSocketContext.messageListener);\n return { connectionId };\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 NetworkedDOM.SupportedWebsocketSubProtocolsPreferenceOrder) {\n if (protocolsSet.has(protocol)) {\n return protocol;\n }\n }\n return false;\n }\n\n public addWebSocket(webSocket: WebSocket): void {\n if (this.initialLoad) {\n throw new Error(\"addWebSocket called before initial load - unsupported at this time\");\n }\n if (this.disposed) {\n console.error(\"addWebSocket called on disposed NetworkedDOM\");\n throw new Error(\"This NetworkedDOM has been disposed\");\n }\n\n if (webSocket.protocol) {\n if (\n NetworkedDOM.SupportedWebsocketSubProtocolsPreferenceOrder.indexOf(webSocket.protocol) ===\n -1\n ) {\n const errorMessageString = `Unsupported websocket subprotocol: ${webSocket.protocol}`;\n const errorMessage: Array<ServerMessage> = [\n {\n type: \"error\",\n message: errorMessageString,\n },\n ];\n webSocket.send(JSON.stringify(errorMessage));\n webSocket.close();\n return;\n }\n } else {\n // TODO - Revisit the default handling of non-protocol websockets. It is easier to debug if a lack of protocol results in an error.\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<ServerMessage> = [\n {\n type: \"warning\",\n message: warningMessageString,\n },\n ];\n webSocket.send(JSON.stringify(warningMessage));\n }\n\n const { connectionId } = this.registerWebsocket(webSocket);\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n const asServerMessages: Array<ServerMessage> = [\n this.getInitialSnapshot(connectionId, documentVirtualDOMElement),\n ];\n const serializedSnapshotMessage = JSON.stringify(asServerMessages);\n webSocket.send(serializedSnapshotMessage);\n this.observableDOM.addConnectedUserId(connectionId);\n }\n\n public removeWebSocket(webSocket: WebSocket): void {\n const connectionId = this.webSocketToConnectionId.get(webSocket);\n if (!connectionId) {\n return;\n }\n this.observableDOM.removeConnectedUserId(connectionId);\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(\"Missing context for websocket\");\n }\n webSocket.removeEventListener(\"message\", webSocketContext.messageListener);\n this.connectionIdToWebSocketContext.delete(connectionId);\n this.visibleNodeIdsByConnectionId.delete(connectionId);\n this.webSocketToConnectionId.delete(webSocket);\n }\n\n public dispose(): void {\n this.disposed = true;\n\n // Handle all of the remaining mutations that the disconnections could have caused\n this.observableDOM.dispose();\n\n for (const [webSocket, connectionId] of this.webSocketToConnectionId) {\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(\"Missing context for websocket\");\n }\n webSocket.removeEventListener(\"message\", webSocketContext.messageListener);\n this.connectionIdToWebSocketContext.delete(connectionId);\n this.visibleNodeIdsByConnectionId.delete(connectionId);\n this.webSocketToConnectionId.delete(webSocket);\n }\n }\n\n private processModification(mutationRecord: StaticVirtualDOMMutationRecord): void {\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`document not created in processModification`);\n }\n\n for (const [, visibleNodesForConnection] of this.visibleNodeIdsByConnectionId) {\n visibleNodesForConnection.add(documentVirtualDOMElement.nodeId);\n }\n\n const diffsByConnectionId = new Map<number, Array<Diff>>(\n Array.from(this.connectionIdToWebSocketContext.keys()).map((connectionId) => [\n connectionId,\n [],\n ]),\n );\n\n diffsByConnectionId.forEach((diffs, connectionId) => {\n const parentNode = this.findParentNodeOfNodeId(mutationRecord.target.nodeId);\n if (mutationRecord.type === \"attributes\" && !parentNode) {\n console.error(\"parentNode not found for attribute mutationRecord\", mutationRecord);\n console.error(\"this.documentRoot\", JSON.stringify(this.documentRoot, null, 2));\n }\n const diff = diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(\n mutationRecord,\n parentNode,\n connectionId,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.visibleNodeIdsByConnectionId.get(connectionId)!,\n );\n if (diff) {\n diffs.push(diff);\n }\n });\n\n diffsByConnectionId.forEach((diffs, connectionId) => {\n if (diffs.length > 0) {\n const asServerMessages: Array<ServerMessage> = diffs;\n const serializedDiffs = JSON.stringify(asServerMessages, null, 4);\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(`webSocketContext not found in processModificationList`);\n }\n webSocketContext.webSocket.send(serializedDiffs);\n }\n });\n }\n\n private removeKnownNodesInMutation(mutation: StaticVirtualDOMMutationRecord): void {\n const virtualDOMElement = mutation.target;\n if (mutation.type === \"childList\") {\n mutation.removedNodes.forEach((childDOMElement: StaticVirtualDOMElement) => {\n this.removeVirtualDOMElement(childDOMElement);\n const index = virtualDOMElement.childNodes.indexOf(childDOMElement);\n virtualDOMElement.childNodes.splice(index, 1);\n });\n return;\n }\n }\n\n private removeVirtualDOMElement(virtualDOMElement: StaticVirtualDOMElement): void {\n this.nodeIdToNode.delete(virtualDOMElement.nodeId);\n this.nodeIdToParentNodeId.delete(virtualDOMElement.nodeId);\n for (const child of virtualDOMElement.childNodes) {\n this.removeVirtualDOMElement(child);\n }\n }\n\n static IsPongMessage(message: ClientMessage): message is PongMessage {\n return (message as PongMessage).type === \"pong\";\n }\n\n private dispatchRemoteEvent(webSocket: WebSocket, remoteEvent: RemoteEvent): 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 connectionId = this.webSocketToConnectionId.get(webSocket);\n if (!connectionId) {\n console.error(\"Unknown web socket dispatched event:\", webSocket);\n return;\n }\n\n const visibleNodes = this.visibleNodeIdsByConnectionId.get(connectionId);\n if (!visibleNodes) {\n console.error(\"No visible nodes for connection: \" + connectionId);\n return;\n }\n\n if (!visibleNodes.has(remoteEvent.nodeId)) {\n // TODO - do a pass through the hierarchy to determine if this node should be visible to this connection id to prevent clients submitting events for nodes they can't (currently) see\n console.error(\"Node not visible for connection: \" + remoteEvent.nodeId);\n return;\n }\n\n const remappedNode = this.clientNodeIdToInternalNodeId.get(remoteEvent.nodeId);\n if (remappedNode) {\n remoteEvent.nodeId = remappedNode;\n }\n\n this.observableDOM.dispatchRemoteEventFromConnectionId(connectionId, remoteEvent);\n }\n\n private getStaticVirtualDOMElementByInternalNodeIdOrThrow(\n internalNodeId: number,\n ): StaticVirtualDOMElement {\n const remappedId = this.internalNodeIdToClientNodeId.get(internalNodeId);\n if (remappedId !== undefined) {\n const node = this.nodeIdToNode.get(remappedId);\n if (!node) {\n throw new Error(\"Remapped node not found with nodeId \" + remappedId);\n }\n return node;\n }\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 private addKnownNodesInMutation(\n mutation: StaticVirtualDOMMutationIdsRecord,\n ): StaticVirtualDOMMutationRecord {\n const target = this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(mutation.targetId);\n\n // TODO - avoid mutation in this conversion - use the attribute pair in the handling (would require changing StaticVirtualDOMMutationRecord.attributeName to be the key/value pair).\n if (mutation.attribute) {\n if (mutation.attribute.value !== null) {\n target.attributes[mutation.attribute.attributeName] = mutation.attribute.value;\n } else {\n delete target.attributes[mutation.attribute.attributeName];\n }\n }\n\n const previousSibling = mutation.previousSiblingId\n ? this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(mutation.previousSiblingId)\n : null;\n\n if (mutation.type === \"childList\") {\n let index = 0;\n if (previousSibling) {\n index = target.childNodes.indexOf(previousSibling);\n if (index === -1) {\n throw new Error(\"Previous sibling is not currently a child of the parent element\");\n }\n index += 1;\n }\n mutation.addedNodes.forEach((childVirtualDOMElement: StaticVirtualDOMElement) => {\n this.addAndRemapNodeFromInstance(childVirtualDOMElement, target.nodeId);\n\n if (target.childNodes.indexOf(childVirtualDOMElement) === -1) {\n target.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n });\n } else if (mutation.type === \"attributes\") {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const attributePair = mutation.attribute!;\n if (attributePair.value === null) {\n delete target.attributes[attributePair.attributeName];\n } else {\n target.attributes[attributePair.attributeName] = attributePair.value;\n }\n } else if (mutation.type === \"characterData\") {\n // TODO - reimplement characterData\n throw new Error(\"characterData not supported\");\n // virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : undefined;\n }\n\n const record: StaticVirtualDOMMutationRecord = {\n type: mutation.type,\n target,\n addedNodes: mutation.addedNodes,\n removedNodes: mutation.removedNodeIds.map((nodeId) => {\n return this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(nodeId);\n }),\n previousSibling: mutation.previousSiblingId\n ? this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(mutation.previousSiblingId)\n : null,\n attributeName: mutation.attribute ? mutation.attribute.attributeName : null,\n };\n\n return record;\n }\n\n getSnapshot(): StaticVirtualDOMElement {\n return this.documentRoot;\n }\n\n private addAndRemapNodeFromInstance(node: StaticVirtualDOMElement, parentNodeId: number) {\n const remappedNodeId = this.internalNodeIdToClientNodeId.get(node.nodeId);\n if (remappedNodeId !== undefined) {\n node.nodeId = remappedNodeId;\n } else {\n // This id might already refer to a node in this client's view. If so, we need to remap it to a new id.\n const existingClientReference = this.clientNodeIdToInternalNodeId.get(node.nodeId);\n if (existingClientReference) {\n const newNodeId = ++this.maximumNodeId;\n this.addRemappedNodeId(newNodeId, node.nodeId);\n node.nodeId = newNodeId;\n }\n }\n\n if (this.nodeIdToNode.has(node.nodeId)) {\n throw new Error(\"Node already exists with id \" + node.nodeId);\n }\n\n this.nodeIdToNode.set(node.nodeId, node);\n this.nodeIdToParentNodeId.set(node.nodeId, parentNodeId);\n this.maximumNodeId = Math.max(this.maximumNodeId, node.nodeId);\n\n for (const childNode of node.childNodes) {\n this.addAndRemapNodeFromInstance(childNode, node.nodeId);\n }\n }\n\n public getWebsocketConnectionIdMap() {\n // return a clone of the map\n return new Map(this.webSocketToConnectionId);\n }\n}\n", "import {\n AttributeChangedDiff,\n ChildrenChangedDiff,\n Diff,\n ElementNodeDescription,\n NodeDescription,\n SnapshotMessage,\n TextChangedDiff,\n TextNodeDescription,\n} from \"@mml-io/networked-dom-protocol\";\nimport { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\nimport * as rfc6902 from \"rfc6902\";\n\nimport { NodeMapping, StaticVirtualDOMMutationRecord, VirtualDOMDiffStruct } from \"./common\";\n\nexport const visibleToAttrName = \"visible-to\";\nexport const hiddenFromAttrName = \"hidden-from\";\n\n// This function does a lot of heavy lifting - it takes a mutation and applies it to the connection's view (affecting which nodes are visible based on attributes etc.)\n// As a result of that application it generates a diff for that client's view of the DOM.\nexport function diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(\n mutation: StaticVirtualDOMMutationRecord,\n parentNode: StaticVirtualDOMElement | null,\n connectionId: number,\n visibleNodesForConnection: Set<number>,\n): Diff | null {\n const virtualDOMElement = mutation.target;\n\n switch (mutation.type) {\n case \"snapshot\": {\n const nodeDescription = describeNodeWithChildrenForConnectionId(\n virtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\n if (!nodeDescription) {\n return null;\n }\n const diff: SnapshotMessage = {\n type: \"snapshot\",\n snapshot: nodeDescription,\n documentTime: 0,\n };\n return diff;\n }\n case \"attributes\": {\n const visible = visibleNodesForConnection.has(virtualDOMElement.nodeId);\n\n if (!parentNode) {\n throw new Error(\"Node has no parent\");\n }\n const parentNodeId = parentNode.nodeId;\n const shouldBeVisible =\n shouldShowNodeToConnectionId(virtualDOMElement, connectionId) &&\n visibleNodesForConnection.has(parentNodeId);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const attributeName = mutation.attributeName!;\n\n if (visible && shouldBeVisible) {\n let newValue = null; // null indicates deleted\n if (virtualDOMElement.attributes[attributeName] !== undefined) {\n newValue = virtualDOMElement.attributes[attributeName];\n }\n const diff: AttributeChangedDiff = {\n type: \"attributeChange\",\n nodeId: virtualDOMElement.nodeId,\n attribute: attributeName,\n newValue,\n };\n return diff;\n } else if (!visible && shouldBeVisible) {\n // Need to add this child to the connection's view now\n visibleNodesForConnection.add(virtualDOMElement.nodeId);\n\n const index = parentNode.childNodes.indexOf(virtualDOMElement);\n if (index === -1) {\n throw new Error(\"Node not found in parent's children\");\n }\n\n let previousNodeId = null;\n if (index > 0) {\n previousNodeId = getNodeIdOfPreviousVisibleSibling(\n parentNode,\n index - 1,\n visibleNodesForConnection,\n );\n }\n\n const nodeDescription = describeNodeWithChildrenForConnectionId(\n virtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\n if (!nodeDescription) {\n throw new Error(\"Node description not found\");\n }\n const diff: ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: parentNodeId,\n previousNodeId,\n addedNodes: [nodeDescription],\n removedNodes: [],\n };\n return diff;\n } else if (visible && !shouldBeVisible) {\n removeNodeAndChildrenFromVisibleNodes(virtualDOMElement, visibleNodesForConnection);\n const diff: ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: parentNodeId,\n previousNodeId: null,\n addedNodes: [],\n removedNodes: [virtualDOMElement.nodeId],\n };\n return diff;\n } else if (!visible && !shouldBeVisible) {\n return null;\n }\n break;\n }\n case \"characterData\": {\n const diff: TextChangedDiff = {\n type: \"textChanged\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n return diff;\n }\n case \"childList\": {\n let previousSibling = mutation.previousSibling;\n let previousNodeId: number | null = null;\n if (previousSibling) {\n let previousIndex = virtualDOMElement.childNodes.indexOf(previousSibling);\n while (previousIndex !== -1) {\n previousSibling = virtualDOMElement.childNodes[previousIndex];\n if (visibleNodesForConnection.has(previousSibling.nodeId)) {\n previousNodeId = previousSibling.nodeId;\n break;\n }\n previousIndex--;\n }\n }\n\n const diff: ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: virtualDOMElement.nodeId,\n previousNodeId,\n addedNodes: [],\n removedNodes: [],\n };\n\n mutation.addedNodes.forEach((childVirtualDOMElement: StaticVirtualDOMElement) => {\n const describedNode = describeNodeWithChildrenForConnectionId(\n childVirtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\n if (!describedNode) {\n return;\n }\n diff.addedNodes.push(describedNode);\n });\n mutation.removedNodes.forEach((childVirtualDOMElement: StaticVirtualDOMElement) => {\n if (visibleNodesForConnection.has(childVirtualDOMElement.nodeId)) {\n removeNodeAndChildrenFromVisibleNodes(childVirtualDOMElement, visibleNodesForConnection);\n diff.removedNodes.push(childVirtualDOMElement.nodeId);\n }\n });\n\n if (diff.addedNodes.length > 0 || diff.removedNodes.length > 0) {\n return diff;\n }\n return null;\n }\n default:\n console.error(\"Unknown mutation type: \" + mutation.type);\n break;\n }\n return null;\n}\n\nfunction getNodeIdOfPreviousVisibleSibling(\n parentVirtualElement: StaticVirtualDOMElement,\n candidateIndex: number,\n visibleNodesForConnection: Set<number>,\n): number | null {\n if (candidateIndex > 0) {\n let previousSiblingIndex = candidateIndex;\n while (previousSiblingIndex >= 0) {\n const previousSibling = parentVirtualElement.childNodes[previousSiblingIndex];\n if (visibleNodesForConnection.has(previousSibling.nodeId)) {\n return previousSibling.nodeId;\n }\n previousSiblingIndex--;\n }\n }\n return null;\n}\n\nfunction shouldShowNodeToConnectionId(\n virtualDOMElement: StaticVirtualDOMElement,\n connectionId: number,\n): boolean {\n const visibleToAttr = virtualDOMElement.attributes[visibleToAttrName];\n const hiddenFromAttr = virtualDOMElement.attributes[hiddenFromAttrName];\n const connectionIdString = connectionId.toString();\n if (visibleToAttr !== undefined) {\n const visibleToList = visibleToAttr.split(\" \");\n const explicityVisible = visibleToList.includes(connectionIdString);\n if (!explicityVisible) {\n return false;\n }\n }\n if (hiddenFromAttr !== undefined) {\n const hiddenFromList = hiddenFromAttr.split(\" \");\n const explicityHidden = hiddenFromList.includes(connectionIdString);\n if (explicityHidden) {\n return false;\n }\n }\n return true;\n}\n\nexport function describeNodeWithChildrenForConnectionId(\n virtualDOMElement: StaticVirtualDOMElement,\n connectionId: number,\n visibleNodesForConnection: Set<number>,\n): NodeDescription | null {\n if (!shouldShowNodeToConnectionId(virtualDOMElement, connectionId)) {\n return null;\n }\n\n let emittedTagName = virtualDOMElement.tag;\n if (emittedTagName === \"#document\") {\n emittedTagName = \"DIV\";\n }\n if (emittedTagName === \"#text\") {\n const textNode: TextNodeDescription = {\n type: \"text\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n visibleNodesForConnection.add(textNode.nodeId);\n return textNode;\n } else {\n const node: ElementNodeDescription = {\n type: \"element\",\n nodeId: virtualDOMElement.nodeId,\n tag: emittedTagName,\n attributes: virtualDOMElement.attributes,\n children: [],\n text: virtualDOMElement.textContent,\n };\n visibleNodesForConnection.add(node.nodeId);\n\n for (const child of virtualDOMElement.childNodes) {\n const childNodeDescription = describeNodeWithChildrenForConnectionId(\n child,\n connectionId,\n visibleNodesForConnection,\n );\n if (childNodeDescription) {\n node.children.push(childNodeDescription);\n }\n }\n return node;\n }\n}\n\nfunction removeNodeAndChildrenFromVisibleNodes(\n virtualDOMElement: StaticVirtualDOMElement,\n visibleNodesForConnection: Set<number>,\n): void {\n visibleNodesForConnection.delete(virtualDOMElement.nodeId);\n for (const child of virtualDOMElement.childNodes) {\n if (!visibleNodesForConnection.has(child.nodeId)) {\n console.error(\"Inner child of removed element was not visible\", child.nodeId);\n }\n removeNodeAndChildrenFromVisibleNodes(child, visibleNodesForConnection);\n }\n}\n\nexport function findParentNodeOfNodeId(\n virtualDOMElement: StaticVirtualDOMElement,\n targetNodeId: number,\n): StaticVirtualDOMElement | null {\n // TODO - avoid a search of the whole tree for the node's parent\n // depth-first search of the whole virtual dom structure to find the node's parent\n for (const child of virtualDOMElement.childNodes) {\n if (child.nodeId === targetNodeId) {\n return virtualDOMElement;\n } else {\n const foundParentId = findParentNodeOfNodeId(child, targetNodeId);\n if (foundParentId) {\n return foundParentId;\n }\n }\n }\n return null;\n}\n\nexport function virtualDOMDiffToVirtualDOMMutationRecord(\n virtualStructure: StaticVirtualDOMElement,\n domDiff: rfc6902.Operation,\n): Array<StaticVirtualDOMMutationRecord> {\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 return [\n {\n type: \"characterData\",\n target: node,\n addedNodes: [],\n removedNodes: [],\n attributeName: null,\n previousSibling: null,\n },\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 return [\n {\n type: \"attributes\",\n target: node,\n addedNodes: [],\n removedNodes: [],\n attributeName: lastToken,\n previousSibling: null,\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 // Append to the end of the children\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);\n return [\n {\n type: \"childList\",\n target: node,\n addedNodes,\n removedNodes,\n previousSibling,\n attributeName: 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 target: node,\n addedNodes,\n removedNodes,\n previousSibling,\n attributeName: 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 removedNodes.push(removedNode);\n addedNodes.push(domDiff.value);\n return [\n {\n type: \"childList\",\n target: node,\n addedNodes: [],\n removedNodes,\n previousSibling,\n attributeName: null,\n },\n {\n type: \"childList\",\n target: node,\n addedNodes,\n removedNodes: [],\n previousSibling,\n attributeName: null,\n },\n ];\n }\n }\n }\n\n if (domDiff.op === \"replace\" && domDiff.path === \"\") {\n const node = domDiff.value as StaticVirtualDOMElement;\n return [\n {\n type: \"snapshot\",\n target: node,\n addedNodes: [],\n removedNodes: [],\n previousSibling: null,\n attributeName: null,\n },\n ];\n }\n\n console.error(\"Unhandled JSON diff:\", JSON.stringify(domDiff, null, 2));\n throw new Error(\"Unhandled diff type\");\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 value = pointer.get(originalState);\n nodeIdRemappings.push({\n internalNodeId: diff.value,\n clientFacingNodeId: value,\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", "import { LogMessage, StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { VirtualDOMDiffStruct } from \"./common\";\nimport { NetworkedDOM, ObservableDOMFactory } from \"./NetworkedDOM\";\n\ntype LoadedState = {\n htmlContents: string;\n networkedDOM: NetworkedDOM;\n loaded: boolean;\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.\nexport class EditableNetworkedDOM {\n private htmlPath: string;\n private params: object = {};\n\n private websockets = new Set<WebSocket>();\n private loadedState: LoadedState | null = null;\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 let existingWebsocketMap: Map<WebSocket, number> | null = null;\n if (this.loadedState) {\n const oldInstance = this.loadedState.networkedDOM;\n existingWebsocketMap = oldInstance.getWebsocketConnectionIdMap();\n oldInstance.dispose();\n oldInstanceRoot = oldInstance.getSnapshot();\n }\n this.loadedState = null;\n\n let didLoad = 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 (this.loadedState) {\n this.loadedState.loaded = true;\n }\n networkedDOM.addExistingWebsockets(\n Array.from(this.websockets),\n existingWebsocketMap,\n domDiff,\n );\n },\n this.params,\n this.ignoreTextNodes,\n this.logCallback,\n );\n this.loadedState = {\n htmlContents,\n networkedDOM,\n loaded: didLoad,\n };\n }\n\n public reload() {\n if (this.loadedState) {\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 of this.websockets) {\n ws.close();\n }\n this.websockets.clear();\n if (this.loadedState) {\n this.loadedState.networkedDOM.dispose();\n }\n this.loadedState = null;\n }\n\n public addWebSocket(webSocket: WebSocket) {\n this.websockets.add(webSocket);\n if (this.loadedState && this.loadedState.loaded) {\n this.loadedState.networkedDOM.addWebSocket(webSocket);\n }\n }\n\n public removeWebSocket(webSocket: WebSocket) {\n this.websockets.delete(webSocket);\n if (this.loadedState && this.loadedState.loaded) {\n this.loadedState.networkedDOM.removeWebSocket(webSocket);\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export * from \"./NetworkedDOM\";\nexport * from \"./EditableNetworkedDOM\";\n", "import {\n ClientMessage,\n Diff,\n NodeDescription,\n PongMessage,\n RemoteEvent,\n ServerMessage,\n SnapshotMessage,\n} from \"@mml-io/networked-dom-protocol\";\nimport {\n LogMessage,\n ObservableDOMInterface,\n ObservableDOMMessage,\n ObservableDOMParameters,\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\nimport { applyPatch } from \"rfc6902\";\n\nimport { StaticVirtualDOMMutationRecord, VirtualDOMDiffStruct } from \"./common\";\nimport {\n calculateStaticVirtualDOMDiff,\n describeNodeWithChildrenForConnectionId,\n diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection,\n findParentNodeOfNodeId,\n virtualDOMDiffToVirtualDOMMutationRecord,\n} from \"./diffing\";\n\nexport const networkedDOMProtocolSubProtocol_v0_1 = \"networked-dom-v0.1\";\nexport const defaultWebsocketSubProtocol = networkedDOMProtocolSubProtocol_v0_1;\n\nexport type ObservableDOMFactory = (\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n) => ObservableDOMInterface;\n\nexport class NetworkedDOM {\n // First to last in order of preference\n public static SupportedWebsocketSubProtocolsPreferenceOrder = [\n networkedDOMProtocolSubProtocol_v0_1,\n ];\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 private currentConnectionId = 1;\n private connectionIdToWebSocketContext = new Map<\n number,\n { webSocket: WebSocket; messageListener: (messageEvent: MessageEvent) => void }\n >();\n private webSocketToConnectionId = new Map<WebSocket, number>();\n private visibleNodeIdsByConnectionId = new Map<number, Set<number>>();\n private initialLoad = true;\n private readonly htmlPath: string;\n\n private disposed = false;\n private ignoreTextNodes: boolean;\n\n private documentRoot!: StaticVirtualDOMElement;\n private nodeIdToNode = new Map<number, StaticVirtualDOMElement>();\n private nodeIdToParentNodeId = new Map<number, number>();\n\n private observableDOM: ObservableDOMInterface;\n\n private documentEffectiveStartTime = Date.now();\n private latestDocumentTime = 0;\n private pingCounter = 1;\n private maximumNodeId = 0;\n\n private logCallback?: (message: LogMessage) => void;\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 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 this.documentRoot = 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(oldInstanceDocumentRoot, clonedSnapshot);\n for (const remapping of domDiff.nodeIdRemappings) {\n this.addRemappedNodeId(remapping.clientFacingNodeId, remapping.internalNodeId);\n }\n }\n\n this.addAndRemapNodeFromInstance(this.documentRoot, -1);\n\n onLoad(domDiff, this);\n } else if (message.mutation) {\n if (this.initialLoad) {\n throw new Error(\"Received mutation before initial load\");\n }\n const mutation = this.addKnownNodesInMutation(message.mutation);\n this.processModification(mutation);\n this.removeKnownNodesInMutation(mutation);\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 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 addRemappedNodeId(clientFacingNodeId: number, internalNodeId: number) {\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 private sendPings() {\n const ping = this.pingCounter++;\n if (this.pingCounter > 1000) {\n this.pingCounter = 1;\n }\n const pingMessage: Array<ServerMessage> = [\n {\n type: \"ping\",\n ping,\n documentTime: this.getDocumentTime(),\n },\n ];\n const stringified = JSON.stringify(pingMessage);\n this.connectionIdToWebSocketContext.forEach((webSocketContext) => {\n webSocketContext.webSocket.send(stringified);\n });\n }\n\n private getInitialSnapshot(\n connectionId: number,\n documentVirtualDOMElement: StaticVirtualDOMElement,\n ): SnapshotMessage {\n const visibleNodesForConnection = this.visibleNodeIdsByConnectionId.get(connectionId);\n if (!visibleNodesForConnection) {\n const err = new Error(\n `visibleNodesForConnection not found for connectionId in getInitialSnapshot: ${connectionId}`,\n );\n console.error(err);\n throw err;\n }\n const domSnapshot: NodeDescription | null = describeNodeWithChildrenForConnectionId(\n documentVirtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\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 addExistingWebsockets(\n websockets: Array<WebSocket>,\n existingWebsocketMap: Map<WebSocket, number> | null,\n domDiff: VirtualDOMDiffStruct | null,\n ) {\n const connectionIds = [];\n for (const websocket of websockets) {\n let existingId = null;\n if (existingWebsocketMap !== null) {\n existingId = existingWebsocketMap.get(websocket);\n }\n const { connectionId } = this.registerWebsocket(websocket, existingId);\n connectionIds.push(connectionId);\n }\n\n if (domDiff) {\n const diffsByConnectionId = new Map<number, Array<Diff>>(\n connectionIds.map((connectionId) => [connectionId, []]),\n );\n\n // Each of the websockets needs to have the original state of the document re-applied to it to determine visible\n // nodes, but not sent (they already have the old version of the document as their state).\n for (const connectionId of connectionIds) {\n // Ignore the return value - the side effect is that the visible nodes for the connection are set\n this.getInitialSnapshot(connectionId, domDiff.originalState);\n }\n\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\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 for (const mutationRecordLike of mutationRecordLikes) {\n const targetNodeId = mutationRecordLike.target.nodeId;\n const virtualElementParent = findParentNodeOfNodeId(domDiff.originalState, targetNodeId);\n diffsByConnectionId.forEach((diffs, connectionId) => {\n const mutationDiff = diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(\n mutationRecordLike,\n virtualElementParent,\n connectionId,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.visibleNodeIdsByConnectionId.get(connectionId)!,\n );\n if (mutationDiff) {\n diffs.push(mutationDiff);\n }\n });\n }\n }\n\n diffsByConnectionId.forEach((diffs, connectionId) => {\n if (diffs.length === 0) {\n // Need to add an \"empty\" message to allow passing the document time to the client\n diffs.push({\n type: \"childrenChanged\",\n nodeId: this.documentRoot.nodeId,\n previousNodeId: null,\n addedNodes: [],\n removedNodes: [],\n });\n }\n const asServerMessages: Array<ServerMessage> = diffs;\n const firstDiff = diffs[0];\n firstDiff.documentTime = this.getDocumentTime();\n const serializedDiffs = JSON.stringify(asServerMessages, null, 4);\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(`webSocketContext not found in addExistingWebsockets`);\n }\n webSocketContext.webSocket.send(serializedDiffs);\n });\n } else {\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n for (const connectionId of connectionIds) {\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(`webSocketContext not found in addExistingWebsockets`);\n }\n const asServerMessages: Array<ServerMessage> = [\n this.getInitialSnapshot(connectionId, documentVirtualDOMElement),\n ];\n const serializedSnapshotMessage = JSON.stringify(asServerMessages);\n webSocketContext.webSocket.send(serializedSnapshotMessage);\n }\n }\n\n for (const connectionId of connectionIds) {\n this.observableDOM.addConnectedUserId(connectionId);\n }\n }\n\n private findParentNodeOfNodeId(targetNodeId: number): StaticVirtualDOMElement | null {\n const parentNodeId = this.nodeIdToParentNodeId.get(targetNodeId);\n if (parentNodeId === undefined) {\n throw new Error(\"Parent node ID not found\");\n }\n return this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(parentNodeId);\n }\n\n private registerWebsocket(\n webSocket: WebSocket,\n existingConnectionId: number | null = null,\n ): { connectionId: number } {\n let connectionId: number;\n if (existingConnectionId !== null) {\n connectionId = existingConnectionId;\n this.currentConnectionId = Math.max(this.currentConnectionId, connectionId + 1);\n } else {\n connectionId = this.currentConnectionId++;\n }\n const webSocketContext = {\n webSocket,\n messageListener: (messageEvent: MessageEvent) => {\n const string = String(messageEvent.data);\n let parsed;\n try {\n parsed = JSON.parse(string) as ClientMessage;\n } catch (e) {\n console.error(`Error parsing message from websocket: ${string}`);\n console.trace();\n return;\n }\n\n if (NetworkedDOM.IsPongMessage(parsed)) {\n // Ignore pongs for now\n return;\n }\n\n this.dispatchRemoteEvent(webSocket, parsed);\n },\n };\n this.connectionIdToWebSocketContext.set(connectionId, webSocketContext);\n this.visibleNodeIdsByConnectionId.set(connectionId, new Set());\n this.webSocketToConnectionId.set(webSocket, connectionId);\n webSocket.addEventListener(\"message\", webSocketContext.messageListener);\n return { connectionId };\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 NetworkedDOM.SupportedWebsocketSubProtocolsPreferenceOrder) {\n if (protocolsSet.has(protocol)) {\n return protocol;\n }\n }\n return false;\n }\n\n public addWebSocket(webSocket: WebSocket): void {\n if (this.initialLoad) {\n throw new Error(\"addWebSocket called before initial load - unsupported at this time\");\n }\n if (this.disposed) {\n console.error(\"addWebSocket called on disposed NetworkedDOM\");\n throw new Error(\"This NetworkedDOM has been disposed\");\n }\n\n if (webSocket.protocol) {\n if (\n NetworkedDOM.SupportedWebsocketSubProtocolsPreferenceOrder.indexOf(webSocket.protocol) ===\n -1\n ) {\n const errorMessageString = `Unsupported websocket subprotocol: ${webSocket.protocol}`;\n const errorMessage: Array<ServerMessage> = [\n {\n type: \"error\",\n message: errorMessageString,\n },\n ];\n webSocket.send(JSON.stringify(errorMessage));\n webSocket.close();\n return;\n }\n } else {\n // TODO - Revisit the default handling of non-protocol websockets. It is easier to debug if a lack of protocol results in an error.\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<ServerMessage> = [\n {\n type: \"warning\",\n message: warningMessageString,\n },\n ];\n webSocket.send(JSON.stringify(warningMessage));\n }\n\n const { connectionId } = this.registerWebsocket(webSocket);\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`documentVirtualDOMElement not found in getInitialSnapshot`);\n }\n const asServerMessages: Array<ServerMessage> = [\n this.getInitialSnapshot(connectionId, documentVirtualDOMElement),\n ];\n const serializedSnapshotMessage = JSON.stringify(asServerMessages);\n webSocket.send(serializedSnapshotMessage);\n this.observableDOM.addConnectedUserId(connectionId);\n }\n\n public removeWebSocket(webSocket: WebSocket): void {\n const connectionId = this.webSocketToConnectionId.get(webSocket);\n if (!connectionId) {\n return;\n }\n this.observableDOM.removeConnectedUserId(connectionId);\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(\"Missing context for websocket\");\n }\n webSocket.removeEventListener(\"message\", webSocketContext.messageListener);\n this.connectionIdToWebSocketContext.delete(connectionId);\n this.visibleNodeIdsByConnectionId.delete(connectionId);\n this.webSocketToConnectionId.delete(webSocket);\n }\n\n public dispose(): void {\n this.disposed = true;\n\n // Handle all of the remaining mutations that the disconnections could have caused\n this.observableDOM.dispose();\n\n for (const [webSocket, connectionId] of this.webSocketToConnectionId) {\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(\"Missing context for websocket\");\n }\n webSocket.removeEventListener(\"message\", webSocketContext.messageListener);\n this.connectionIdToWebSocketContext.delete(connectionId);\n this.visibleNodeIdsByConnectionId.delete(connectionId);\n this.webSocketToConnectionId.delete(webSocket);\n }\n }\n\n private processModification(mutationRecord: StaticVirtualDOMMutationRecord): void {\n const documentVirtualDOMElement = this.documentRoot;\n if (!documentVirtualDOMElement) {\n throw new Error(`document not created in processModification`);\n }\n\n for (const [, visibleNodesForConnection] of this.visibleNodeIdsByConnectionId) {\n visibleNodesForConnection.add(documentVirtualDOMElement.nodeId);\n }\n\n const diffsByConnectionId = new Map<number, Array<Diff>>(\n Array.from(this.connectionIdToWebSocketContext.keys()).map((connectionId) => [\n connectionId,\n [],\n ]),\n );\n\n diffsByConnectionId.forEach((diffs, connectionId) => {\n const parentNode = this.findParentNodeOfNodeId(mutationRecord.target.nodeId);\n if (mutationRecord.type === \"attributes\" && !parentNode) {\n console.error(\"parentNode not found for attribute mutationRecord\", mutationRecord);\n console.error(\"this.documentRoot\", JSON.stringify(this.documentRoot, null, 2));\n }\n const diff = diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(\n mutationRecord,\n parentNode,\n connectionId,\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.visibleNodeIdsByConnectionId.get(connectionId)!,\n );\n if (diff) {\n diffs.push(diff);\n }\n });\n\n diffsByConnectionId.forEach((diffs, connectionId) => {\n if (diffs.length > 0) {\n const asServerMessages: Array<ServerMessage> = diffs;\n const serializedDiffs = JSON.stringify(asServerMessages, null, 4);\n const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);\n if (!webSocketContext) {\n throw new Error(`webSocketContext not found in processModificationList`);\n }\n webSocketContext.webSocket.send(serializedDiffs);\n }\n });\n }\n\n private removeKnownNodesInMutation(mutation: StaticVirtualDOMMutationRecord): void {\n const virtualDOMElement = mutation.target;\n if (mutation.type === \"childList\") {\n mutation.removedNodes.forEach((childDOMElement: StaticVirtualDOMElement) => {\n this.removeVirtualDOMElement(childDOMElement);\n const index = virtualDOMElement.childNodes.indexOf(childDOMElement);\n virtualDOMElement.childNodes.splice(index, 1);\n });\n return;\n }\n }\n\n private removeVirtualDOMElement(virtualDOMElement: StaticVirtualDOMElement): void {\n this.nodeIdToNode.delete(virtualDOMElement.nodeId);\n this.nodeIdToParentNodeId.delete(virtualDOMElement.nodeId);\n for (const child of virtualDOMElement.childNodes) {\n this.removeVirtualDOMElement(child);\n }\n }\n\n static IsPongMessage(message: ClientMessage): message is PongMessage {\n return (message as PongMessage).type === \"pong\";\n }\n\n private dispatchRemoteEvent(webSocket: WebSocket, remoteEvent: RemoteEvent): 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 connectionId = this.webSocketToConnectionId.get(webSocket);\n if (!connectionId) {\n console.error(\"Unknown web socket dispatched event:\", webSocket);\n return;\n }\n\n const visibleNodes = this.visibleNodeIdsByConnectionId.get(connectionId);\n if (!visibleNodes) {\n console.error(\"No visible nodes for connection: \" + connectionId);\n return;\n }\n\n if (!visibleNodes.has(remoteEvent.nodeId)) {\n // TODO - do a pass through the hierarchy to determine if this node should be visible to this connection id to prevent clients submitting events for nodes they can't (currently) see\n console.error(\"Node not visible for connection: \" + remoteEvent.nodeId);\n return;\n }\n\n const remappedNode = this.clientNodeIdToInternalNodeId.get(remoteEvent.nodeId);\n if (remappedNode) {\n remoteEvent.nodeId = remappedNode;\n }\n\n this.observableDOM.dispatchRemoteEventFromConnectionId(connectionId, remoteEvent);\n }\n\n private getStaticVirtualDOMElementByInternalNodeIdOrThrow(\n internalNodeId: number,\n ): StaticVirtualDOMElement {\n const remappedId = this.internalNodeIdToClientNodeId.get(internalNodeId);\n if (remappedId !== undefined) {\n const node = this.nodeIdToNode.get(remappedId);\n if (!node) {\n throw new Error(\"Remapped node not found with nodeId \" + remappedId);\n }\n return node;\n }\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 private addKnownNodesInMutation(\n mutation: StaticVirtualDOMMutationIdsRecord,\n ): StaticVirtualDOMMutationRecord {\n const target = this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(mutation.targetId);\n\n // TODO - avoid mutation in this conversion - use the attribute pair in the handling (would require changing StaticVirtualDOMMutationRecord.attributeName to be the key/value pair).\n if (mutation.attribute) {\n if (mutation.attribute.value !== null) {\n target.attributes[mutation.attribute.attributeName] = mutation.attribute.value;\n } else {\n delete target.attributes[mutation.attribute.attributeName];\n }\n }\n\n const previousSibling = mutation.previousSiblingId\n ? this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(mutation.previousSiblingId)\n : null;\n\n if (mutation.type === \"childList\") {\n let index = 0;\n if (previousSibling) {\n index = target.childNodes.indexOf(previousSibling);\n if (index === -1) {\n throw new Error(\"Previous sibling is not currently a child of the parent element\");\n }\n index += 1;\n }\n mutation.addedNodes.forEach((childVirtualDOMElement: StaticVirtualDOMElement) => {\n this.addAndRemapNodeFromInstance(childVirtualDOMElement, target.nodeId);\n\n if (target.childNodes.indexOf(childVirtualDOMElement) === -1) {\n target.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n });\n } else if (mutation.type === \"attributes\") {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const attributePair = mutation.attribute!;\n if (attributePair.value === null) {\n delete target.attributes[attributePair.attributeName];\n } else {\n target.attributes[attributePair.attributeName] = attributePair.value;\n }\n } else if (mutation.type === \"characterData\") {\n // TODO - reimplement characterData\n throw new Error(\"characterData not supported\");\n // virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : undefined;\n }\n\n const record: StaticVirtualDOMMutationRecord = {\n type: mutation.type,\n target,\n addedNodes: mutation.addedNodes,\n removedNodes: mutation.removedNodeIds.map((nodeId) => {\n return this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(nodeId);\n }),\n previousSibling: mutation.previousSiblingId\n ? this.getStaticVirtualDOMElementByInternalNodeIdOrThrow(mutation.previousSiblingId)\n : null,\n attributeName: mutation.attribute ? mutation.attribute.attributeName : null,\n };\n\n return record;\n }\n\n getSnapshot(): StaticVirtualDOMElement {\n return this.documentRoot;\n }\n\n private addAndRemapNodeFromInstance(node: StaticVirtualDOMElement, parentNodeId: number) {\n const remappedNodeId = this.internalNodeIdToClientNodeId.get(node.nodeId);\n if (remappedNodeId !== undefined) {\n node.nodeId = remappedNodeId;\n } else {\n // This id might already refer to a node in this client's view. If so, we need to remap it to a new id.\n const existingClientReference = this.clientNodeIdToInternalNodeId.get(node.nodeId);\n if (existingClientReference) {\n const newNodeId = ++this.maximumNodeId;\n this.addRemappedNodeId(newNodeId, node.nodeId);\n node.nodeId = newNodeId;\n }\n }\n\n if (this.nodeIdToNode.has(node.nodeId)) {\n throw new Error(\"Node already exists with id \" + node.nodeId);\n }\n\n this.nodeIdToNode.set(node.nodeId, node);\n this.nodeIdToParentNodeId.set(node.nodeId, parentNodeId);\n this.maximumNodeId = Math.max(this.maximumNodeId, node.nodeId);\n\n for (const childNode of node.childNodes) {\n this.addAndRemapNodeFromInstance(childNode, node.nodeId);\n }\n }\n\n public getWebsocketConnectionIdMap() {\n // return a clone of the map\n return new Map(this.webSocketToConnectionId);\n }\n}\n", "import {\n AttributeChangedDiff,\n ChildrenChangedDiff,\n Diff,\n ElementNodeDescription,\n NodeDescription,\n SnapshotMessage,\n TextChangedDiff,\n TextNodeDescription,\n} from \"@mml-io/networked-dom-protocol\";\nimport { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\nimport * as rfc6902 from \"rfc6902\";\n\nimport { NodeMapping, StaticVirtualDOMMutationRecord, VirtualDOMDiffStruct } from \"./common\";\n\nexport const visibleToAttrName = \"visible-to\";\nexport const hiddenFromAttrName = \"hidden-from\";\n\n// This function does a lot of heavy lifting - it takes a mutation and applies it to the connection's view (affecting which nodes are visible based on attributes etc.)\n// As a result of that application it generates a diff for that client's view of the DOM.\nexport function diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(\n mutation: StaticVirtualDOMMutationRecord,\n parentNode: StaticVirtualDOMElement | null,\n connectionId: number,\n visibleNodesForConnection: Set<number>,\n): Diff | null {\n const virtualDOMElement = mutation.target;\n\n switch (mutation.type) {\n case \"snapshot\": {\n const nodeDescription = describeNodeWithChildrenForConnectionId(\n virtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\n if (!nodeDescription) {\n return null;\n }\n const diff: SnapshotMessage = {\n type: \"snapshot\",\n snapshot: nodeDescription,\n documentTime: 0,\n };\n return diff;\n }\n case \"attributes\": {\n const visible = visibleNodesForConnection.has(virtualDOMElement.nodeId);\n\n if (!parentNode) {\n throw new Error(\"Node has no parent\");\n }\n const parentNodeId = parentNode.nodeId;\n const shouldBeVisible =\n shouldShowNodeToConnectionId(virtualDOMElement, connectionId) &&\n visibleNodesForConnection.has(parentNodeId);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const attributeName = mutation.attributeName!;\n\n if (visible && shouldBeVisible) {\n let newValue = null; // null indicates deleted\n if (virtualDOMElement.attributes[attributeName] !== undefined) {\n newValue = virtualDOMElement.attributes[attributeName];\n }\n const diff: AttributeChangedDiff = {\n type: \"attributeChange\",\n nodeId: virtualDOMElement.nodeId,\n attribute: attributeName,\n newValue,\n };\n return diff;\n } else if (!visible && shouldBeVisible) {\n // Need to add this child to the connection's view now\n visibleNodesForConnection.add(virtualDOMElement.nodeId);\n\n const index = parentNode.childNodes.indexOf(virtualDOMElement);\n if (index === -1) {\n throw new Error(\"Node not found in parent's children\");\n }\n\n let previousNodeId = null;\n if (index > 0) {\n previousNodeId = getNodeIdOfPreviousVisibleSibling(\n parentNode,\n index - 1,\n visibleNodesForConnection,\n );\n }\n\n const nodeDescription = describeNodeWithChildrenForConnectionId(\n virtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\n if (!nodeDescription) {\n throw new Error(\"Node description not found\");\n }\n const diff: ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: parentNodeId,\n previousNodeId,\n addedNodes: [nodeDescription],\n removedNodes: [],\n };\n return diff;\n } else if (visible && !shouldBeVisible) {\n removeNodeAndChildrenFromVisibleNodes(virtualDOMElement, visibleNodesForConnection);\n const diff: ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: parentNodeId,\n previousNodeId: null,\n addedNodes: [],\n removedNodes: [virtualDOMElement.nodeId],\n };\n return diff;\n } else if (!visible && !shouldBeVisible) {\n return null;\n }\n break;\n }\n case \"characterData\": {\n const visible = visibleNodesForConnection.has(virtualDOMElement.nodeId);\n if (!visible) {\n return null;\n }\n const diff: TextChangedDiff = {\n type: \"textChanged\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n return diff;\n }\n case \"childList\": {\n const visible = visibleNodesForConnection.has(virtualDOMElement.nodeId);\n if (!visible) {\n return null;\n }\n let previousSibling = mutation.previousSibling;\n let previousNodeId: number | null = null;\n if (previousSibling) {\n let previousIndex = virtualDOMElement.childNodes.indexOf(previousSibling);\n while (previousIndex !== -1) {\n previousSibling = virtualDOMElement.childNodes[previousIndex];\n if (visibleNodesForConnection.has(previousSibling.nodeId)) {\n previousNodeId = previousSibling.nodeId;\n break;\n }\n previousIndex--;\n }\n }\n\n const diff: ChildrenChangedDiff = {\n type: \"childrenChanged\",\n nodeId: virtualDOMElement.nodeId,\n previousNodeId,\n addedNodes: [],\n removedNodes: [],\n };\n\n mutation.addedNodes.forEach((childVirtualDOMElement: StaticVirtualDOMElement) => {\n const describedNode = describeNodeWithChildrenForConnectionId(\n childVirtualDOMElement,\n connectionId,\n visibleNodesForConnection,\n );\n if (!describedNode) {\n return;\n }\n diff.addedNodes.push(describedNode);\n });\n mutation.removedNodes.forEach((childVirtualDOMElement: StaticVirtualDOMElement) => {\n if (visibleNodesForConnection.has(childVirtualDOMElement.nodeId)) {\n removeNodeAndChildrenFromVisibleNodes(childVirtualDOMElement, visibleNodesForConnection);\n diff.removedNodes.push(childVirtualDOMElement.nodeId);\n }\n });\n\n if (diff.addedNodes.length > 0 || diff.removedNodes.length > 0) {\n return diff;\n }\n return null;\n }\n default:\n console.error(\"Unknown mutation type: \" + mutation.type);\n break;\n }\n return null;\n}\n\nfunction getNodeIdOfPreviousVisibleSibling(\n parentVirtualElement: StaticVirtualDOMElement,\n candidateIndex: number,\n visibleNodesForConnection: Set<number>,\n): number | null {\n if (candidateIndex > 0) {\n let previousSiblingIndex = candidateIndex;\n while (previousSiblingIndex >= 0) {\n const previousSibling = parentVirtualElement.childNodes[previousSiblingIndex];\n if (visibleNodesForConnection.has(previousSibling.nodeId)) {\n return previousSibling.nodeId;\n }\n previousSiblingIndex--;\n }\n }\n return null;\n}\n\nfunction shouldShowNodeToConnectionId(\n virtualDOMElement: StaticVirtualDOMElement,\n connectionId: number,\n): boolean {\n const visibleToAttr = virtualDOMElement.attributes[visibleToAttrName];\n const hiddenFromAttr = virtualDOMElement.attributes[hiddenFromAttrName];\n const connectionIdString = connectionId.toString();\n if (visibleToAttr !== undefined) {\n const visibleToList = visibleToAttr.split(\" \");\n const explicityVisible = visibleToList.includes(connectionIdString);\n if (!explicityVisible) {\n return false;\n }\n }\n if (hiddenFromAttr !== undefined) {\n const hiddenFromList = hiddenFromAttr.split(\" \");\n const explicityHidden = hiddenFromList.includes(connectionIdString);\n if (explicityHidden) {\n return false;\n }\n }\n return true;\n}\n\nexport function describeNodeWithChildrenForConnectionId(\n virtualDOMElement: StaticVirtualDOMElement,\n connectionId: number,\n visibleNodesForConnection: Set<number>,\n): NodeDescription | null {\n if (!shouldShowNodeToConnectionId(virtualDOMElement, connectionId)) {\n return null;\n }\n\n let emittedTagName = virtualDOMElement.tag;\n if (emittedTagName === \"#document\") {\n emittedTagName = \"DIV\";\n }\n if (emittedTagName === \"#text\") {\n const textNode: TextNodeDescription = {\n type: \"text\",\n nodeId: virtualDOMElement.nodeId,\n text: virtualDOMElement.textContent || \"\",\n };\n visibleNodesForConnection.add(textNode.nodeId);\n return textNode;\n } else {\n const node: ElementNodeDescription = {\n type: \"element\",\n nodeId: virtualDOMElement.nodeId,\n tag: emittedTagName,\n attributes: virtualDOMElement.attributes,\n children: [],\n text: virtualDOMElement.textContent,\n };\n visibleNodesForConnection.add(node.nodeId);\n\n for (const child of virtualDOMElement.childNodes) {\n const childNodeDescription = describeNodeWithChildrenForConnectionId(\n child,\n connectionId,\n visibleNodesForConnection,\n );\n if (childNodeDescription) {\n node.children.push(childNodeDescription);\n }\n }\n return node;\n }\n}\n\nfunction removeNodeAndChildrenFromVisibleNodes(\n virtualDOMElement: StaticVirtualDOMElement,\n visibleNodesForConnection: Set<number>,\n): void {\n visibleNodesForConnection.delete(virtualDOMElement.nodeId);\n for (const child of virtualDOMElement.childNodes) {\n if (!visibleNodesForConnection.has(child.nodeId)) {\n console.error(\"Inner child of removed element was not visible\", child.nodeId);\n }\n removeNodeAndChildrenFromVisibleNodes(child, visibleNodesForConnection);\n }\n}\n\nexport function findParentNodeOfNodeId(\n virtualDOMElement: StaticVirtualDOMElement,\n targetNodeId: number,\n): StaticVirtualDOMElement | null {\n // TODO - avoid a search of the whole tree for the node's parent\n // depth-first search of the whole virtual dom structure to find the node's parent\n for (const child of virtualDOMElement.childNodes) {\n if (child.nodeId === targetNodeId) {\n return virtualDOMElement;\n } else {\n const foundParentId = findParentNodeOfNodeId(child, targetNodeId);\n if (foundParentId) {\n return foundParentId;\n }\n }\n }\n return null;\n}\n\nexport function virtualDOMDiffToVirtualDOMMutationRecord(\n virtualStructure: StaticVirtualDOMElement,\n domDiff: rfc6902.Operation,\n): Array<StaticVirtualDOMMutationRecord> {\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 return [\n {\n type: \"characterData\",\n target: node,\n addedNodes: [],\n removedNodes: [],\n attributeName: null,\n previousSibling: null,\n },\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 return [\n {\n type: \"attributes\",\n target: node,\n addedNodes: [],\n removedNodes: [],\n attributeName: lastToken,\n previousSibling: null,\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 // Append to the end of the children\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);\n return [\n {\n type: \"childList\",\n target: node,\n addedNodes,\n removedNodes,\n previousSibling,\n attributeName: 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 target: node,\n addedNodes,\n removedNodes,\n previousSibling,\n attributeName: 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 removedNodes.push(removedNode);\n addedNodes.push(domDiff.value);\n return [\n {\n type: \"childList\",\n target: node,\n addedNodes: [],\n removedNodes,\n previousSibling,\n attributeName: null,\n },\n {\n type: \"childList\",\n target: node,\n addedNodes,\n removedNodes: [],\n previousSibling,\n attributeName: null,\n },\n ];\n }\n }\n }\n\n if (domDiff.op === \"replace\" && domDiff.path === \"\") {\n const node = domDiff.value as StaticVirtualDOMElement;\n return [\n {\n type: \"snapshot\",\n target: node,\n addedNodes: [],\n removedNodes: [],\n previousSibling: null,\n attributeName: null,\n },\n ];\n }\n\n console.error(\"Unhandled JSON diff:\", JSON.stringify(domDiff, null, 2));\n throw new Error(\"Unhandled diff type\");\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 value = pointer.get(originalState);\n nodeIdRemappings.push({\n internalNodeId: diff.value,\n clientFacingNodeId: value,\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", "import { LogMessage, StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { VirtualDOMDiffStruct } from \"./common\";\nimport { NetworkedDOM, ObservableDOMFactory } from \"./NetworkedDOM\";\n\ntype LoadedState = {\n htmlContents: string;\n networkedDOM: NetworkedDOM;\n loaded: boolean;\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.\nexport class EditableNetworkedDOM {\n private htmlPath: string;\n private params: object = {};\n\n private websockets = new Set<WebSocket>();\n private loadedState: LoadedState | null = null;\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 let existingWebsocketMap: Map<WebSocket, number> | null = null;\n if (this.loadedState) {\n const oldInstance = this.loadedState.networkedDOM;\n existingWebsocketMap = oldInstance.getWebsocketConnectionIdMap();\n oldInstance.dispose();\n oldInstanceRoot = oldInstance.getSnapshot();\n }\n this.loadedState = null;\n\n let didLoad = 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 (this.loadedState) {\n this.loadedState.loaded = true;\n }\n networkedDOM.addExistingWebsockets(\n Array.from(this.websockets),\n existingWebsocketMap,\n domDiff,\n );\n },\n this.params,\n this.ignoreTextNodes,\n this.logCallback,\n );\n this.loadedState = {\n htmlContents,\n networkedDOM,\n loaded: didLoad,\n };\n }\n\n public reload() {\n if (this.loadedState) {\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 of this.websockets) {\n ws.close();\n }\n this.websockets.clear();\n if (this.loadedState) {\n this.loadedState.networkedDOM.dispose();\n }\n this.loadedState = null;\n }\n\n public addWebSocket(webSocket: WebSocket) {\n this.websockets.add(webSocket);\n if (this.loadedState && this.loadedState.loaded) {\n this.loadedState.networkedDOM.addWebSocket(webSocket);\n }\n }\n\n public removeWebSocket(webSocket: WebSocket) {\n this.websockets.delete(webSocket);\n if (this.loadedState && this.loadedState.loaded) {\n this.loadedState.networkedDOM.removeWebSocket(webSocket);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["node", "node", "networkedDOM"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@mml-io/networked-dom-document",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
4
7
  "main": "./build/index.js",
5
8
  "types": "./build/index.d.ts",
6
9
  "files": [
@@ -8,16 +11,16 @@
8
11
  ],
9
12
  "scripts": {
10
13
  "type-check": "tsc --noEmit",
11
- "build": "node ./build.js --build",
12
- "iterate": "node ./build.js --watch",
13
- "npm-publish": "npm run build && publish-if-not-exists --access=public",
14
+ "build": "tsx ./build.ts --build",
15
+ "iterate": "tsx ./build.ts --watch",
14
16
  "lint": "eslint \"./src/**/*.{js,jsx,ts,tsx}\" --max-warnings 0",
15
17
  "lint-fix": "eslint \"./src/**/*.{js,jsx,ts,tsx}\" --fix",
16
18
  "test": "jest"
17
19
  },
18
20
  "dependencies": {
19
- "@mml-io/networked-dom-protocol": "^0.4.0",
20
- "@mml-io/observable-dom-common": "^0.4.0",
21
+ "@mml-io/networked-dom-protocol": "^0.6.0",
22
+ "@mml-io/observable-dom-common": "^0.6.0",
21
23
  "rfc6902": "https://github.com/marcuslongmuir/rfc6902.git#7b81b044d7c2cd36f34f9f30d106e7f5db8a0589"
22
- }
24
+ },
25
+ "gitHead": "27c25d717efe7f7e883cd81afed18737f12e5938"
23
26
  }
@@ -1 +0,0 @@
1
- {"program":{"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../networked-dom-protocol/build/networked-dom-v0.1/from-client.d.ts","../../networked-dom-protocol/build/networked-dom-v0.1/from-server.d.ts","../../networked-dom-protocol/build/networked-dom-v0.1/index.d.ts","../../networked-dom-protocol/build/index.d.ts","../../observable-dom-common/build/ObservableDOMInterface.d.ts","../../observable-dom-common/build/messages.d.ts","../../observable-dom-common/build/index.d.ts","../../../node_modules/rfc6902/src/pointer.ts","../../../node_modules/rfc6902/src/util.ts","../../../node_modules/@types/deep-equal/index.d.ts","../../../node_modules/rfc6902/src/diff.ts","../../../node_modules/rfc6902/src/patch.ts","../../../node_modules/rfc6902/src/index.ts","../../../node_modules/rfc6902/build/index.d.ts","../src/common.ts","../src/diffing.ts","../src/NetworkedDOM.ts","../src/EditableNetworkedDOM.ts","../src/index.ts","../../../node_modules/@types/node/assert.d.ts","../../../node_modules/@types/node/assert/strict.d.ts","../../../node_modules/@types/node/globals.d.ts","../../../node_modules/@types/node/async_hooks.d.ts","../../../node_modules/@types/node/buffer.d.ts","../../../node_modules/@types/node/child_process.d.ts","../../../node_modules/@types/node/cluster.d.ts","../../../node_modules/@types/node/console.d.ts","../../../node_modules/@types/node/constants.d.ts","../../../node_modules/@types/node/crypto.d.ts","../../../node_modules/@types/node/dgram.d.ts","../../../node_modules/@types/node/diagnostics_channel.d.ts","../../../node_modules/@types/node/dns.d.ts","../../../node_modules/@types/node/dns/promises.d.ts","../../../node_modules/@types/node/domain.d.ts","../../../node_modules/@types/node/dom-events.d.ts","../../../node_modules/@types/node/events.d.ts","../../../node_modules/@types/node/fs.d.ts","../../../node_modules/@types/node/fs/promises.d.ts","../../../node_modules/@types/node/http.d.ts","../../../node_modules/@types/node/http2.d.ts","../../../node_modules/@types/node/https.d.ts","../../../node_modules/@types/node/inspector.d.ts","../../../node_modules/@types/node/module.d.ts","../../../node_modules/@types/node/net.d.ts","../../../node_modules/@types/node/os.d.ts","../../../node_modules/@types/node/path.d.ts","../../../node_modules/@types/node/perf_hooks.d.ts","../../../node_modules/@types/node/process.d.ts","../../../node_modules/@types/node/punycode.d.ts","../../../node_modules/@types/node/querystring.d.ts","../../../node_modules/@types/node/readline.d.ts","../../../node_modules/@types/node/readline/promises.d.ts","../../../node_modules/@types/node/repl.d.ts","../../../node_modules/@types/node/stream.d.ts","../../../node_modules/@types/node/stream/promises.d.ts","../../../node_modules/@types/node/stream/consumers.d.ts","../../../node_modules/@types/node/stream/web.d.ts","../../../node_modules/@types/node/string_decoder.d.ts","../../../node_modules/@types/node/test.d.ts","../../../node_modules/@types/node/timers.d.ts","../../../node_modules/@types/node/timers/promises.d.ts","../../../node_modules/@types/node/tls.d.ts","../../../node_modules/@types/node/trace_events.d.ts","../../../node_modules/@types/node/tty.d.ts","../../../node_modules/@types/node/url.d.ts","../../../node_modules/@types/node/util.d.ts","../../../node_modules/@types/node/v8.d.ts","../../../node_modules/@types/node/vm.d.ts","../../../node_modules/@types/node/wasi.d.ts","../../../node_modules/@types/node/worker_threads.d.ts","../../../node_modules/@types/node/zlib.d.ts","../../../node_modules/@types/node/globals.global.d.ts","../../../node_modules/@types/node/index.d.ts"],"fileInfos":[{"version":"6a6b471e7e43e15ef6f8fe617a22ce4ecb0e34efa6c3dfcfe7cebd392bcca9d2","affectsGlobalScope":true},"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","dc48272d7c333ccf58034c0026162576b7d50ea0e69c3b9292f803fc20720fd5","27147504487dc1159369da4f4da8a26406364624fa9bc3db632f7d94a5bae2c3","5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4",{"version":"fcd3ecc9f764f06f4d5c467677f4f117f6abf49dee6716283aa204ff1162498b","affectsGlobalScope":true},{"version":"f296963760430fb65b4e5d91f0ed770a91c6e77455bacf8fa23a1501654ede0e","affectsGlobalScope":true},{"version":"5114a95689b63f96b957e00216bc04baf9e1a1782aa4d8ee7e5e9acbf768e301","affectsGlobalScope":true},{"version":"4443e68b35f3332f753eacc66a04ac1d2053b8b035a0e0ac1d455392b5e243b3","affectsGlobalScope":true},{"version":"ab22100fdd0d24cfc2cc59d0a00fc8cf449830d9c4030dc54390a46bd562e929","affectsGlobalScope":true},{"version":"f7bd636ae3a4623c503359ada74510c4005df5b36de7f23e1db8a5c543fd176b","affectsGlobalScope":true},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true},{"version":"0c20f4d2358eb679e4ae8a4432bdd96c857a2960fd6800b21ec4008ec59d60ea","affectsGlobalScope":true},{"version":"36ae84ccc0633f7c0787bc6108386c8b773e95d3b052d9464a99cd9b8795fbec","affectsGlobalScope":true},{"version":"82d0d8e269b9eeac02c3bd1c9e884e85d483fcb2cd168bccd6bc54df663da031","affectsGlobalScope":true},{"version":"b8deab98702588840be73d67f02412a2d45a417a3c097b2e96f7f3a42ac483d1","affectsGlobalScope":true},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true},{"version":"376d554d042fb409cb55b5cbaf0b2b4b7e669619493c5d18d5fa8bd67273f82a","affectsGlobalScope":true},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true},{"version":"61c37c1de663cf4171e1192466e52c7a382afa58da01b1dc75058f032ddf0839","affectsGlobalScope":true},{"version":"c4138a3dd7cd6cf1f363ca0f905554e8d81b45844feea17786cdf1626cb8ea06","affectsGlobalScope":true},{"version":"6ff3e2452b055d8f0ec026511c6582b55d935675af67cdb67dd1dc671e8065df","affectsGlobalScope":true},{"version":"03de17b810f426a2f47396b0b99b53a82c1b60e9cba7a7edda47f9bb077882f4","affectsGlobalScope":true},{"version":"8184c6ddf48f0c98429326b428478ecc6143c27f79b79e85740f17e6feb090f1","affectsGlobalScope":true},{"version":"261c4d2cf86ac5a89ad3fb3fafed74cbb6f2f7c1d139b0540933df567d64a6ca","affectsGlobalScope":true},{"version":"6af1425e9973f4924fca986636ac19a0cf9909a7e0d9d3009c349e6244e957b6","affectsGlobalScope":true},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true},{"version":"15a630d6817718a2ddd7088c4f83e4673fde19fa992d2eae2cf51132a302a5d3","affectsGlobalScope":true},{"version":"b7e9f95a7387e3f66be0ed6db43600c49cec33a3900437ce2fd350d9b7cb16f2","affectsGlobalScope":true},{"version":"01e0ee7e1f661acedb08b51f8a9b7d7f959e9cdb6441360f06522cc3aea1bf2e","affectsGlobalScope":true},{"version":"ac17a97f816d53d9dd79b0d235e1c0ed54a8cc6a0677e9a3d61efb480b2a3e4e","affectsGlobalScope":true},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true},{"version":"ec0104fee478075cb5171e5f4e3f23add8e02d845ae0165bfa3f1099241fa2aa","affectsGlobalScope":true},{"version":"2b72d528b2e2fe3c57889ca7baef5e13a56c957b946906d03767c642f386bbc3","affectsGlobalScope":true},{"version":"9cc66b0513ad41cb5f5372cca86ef83a0d37d1c1017580b7dace3ea5661836df","affectsGlobalScope":true},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true},{"version":"307c8b7ebbd7f23a92b73a4c6c0a697beca05b06b036c23a34553e5fe65e4fdc","affectsGlobalScope":true},{"version":"189c0703923150aa30673fa3de411346d727cc44a11c75d05d7cf9ef095daa22","affectsGlobalScope":true},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true},"328c09d87a15cde5936230f085c6888e6dc5f31a7c600a8a222419e28ea02812","e46f9c26b401a050e372280c49fd564d27dca4ca2b0e3e8585b07578661b2279","660b97032e7c3a5a094b60e3de0bf602626931fe0167dbad07e9ada9f683161e","28e083d1a14be292588f05b70cf7852deb63a3e0da35a0156bcbe361b5072562","4e9e7984ad6e180c5c3363d3478d71558d7d3949c45685951aef7e06e4d6b6a4","ffe0e53edfbab16e0c9bacf0d61b8091d2cf46fbca310d2602036793fda5a058","a63268b15ba72e389b1eaf9752ca501a2965923096ea28c2c98a4db1ec0e8a22","470bca533c6d21326973461b547470d7499ea91ca8a34c2e940ed87a81197126","de355ee45c24981723e98415c331656000b5045895e34bee0423f60eb71a7ef7","2e345cb6511f4c4c60c274df6626c94f3182939034f06cdf414bfbccc584f822","36d82d79e5c2cff1f55302638e4986abbc110fad92910c5e765d73fdc1af2ce9","267fa352bafe9b69cbc35cf110e595c7aec48b80b7bafeb53eb4a07859c509e8","259b99a5b98db5d0bdb1c9743d00283ca45b4d5c06e6ae1ce3b98634237009f6","88c62c04db59e39dd5b82ddd9cb8d0b287255e8d9604b36a4139cabd0536fb9b","420d0b4eb59f272658fa93a3aa57cda51d0f4cea68bd0ab4f0c1134aab2c38d8","a73895b17769d005f2871b92d0a348811879d84077f3efc368149a4d06ec2145","6a0940f95baeb932cb15cac7167e0fe6a564eaeee55d65216dbdd645bf8d6ba0","ad644a4792116c657e122f7017191a9e822df9c35a4f50dc711a176d83020ae1","894eeb8ce9aaa37362d97f8a0f7dbc0feb4585ccdcc99d882a80c5e8a0c8062c","587f13f1e8157bd8cec0adda0de4ef558bb8573daa9d518d1e2af38e87ecc91f","a69c09dbea52352f479d3e7ac949fde3d17b195abe90b045d619f747b38d6d1a",{"version":"bce910d9164785c9f0d4dcea4be359f5f92130c7c7833dea6138ab1db310a1f9","affectsGlobalScope":true},"7a435e0c814f58f23e9a0979045ec0ef5909aac95a70986e8bcce30c27dff228",{"version":"a7534271773a27ff7d136d550e86b41894d8090fa857ba4c02b5bb18d2eb1c8e","affectsGlobalScope":true},"db71be322f07f769200108aa19b79a75dd19a187c9dca2a30c4537b233aa2863","57135ce61976a8b1dadd01bb412406d1805b90db6e8ecb726d0d78e0b5f76050",{"version":"49479e21a040c0177d1b1bc05a124c0383df7a08a0726ad4d9457619642e875a","affectsGlobalScope":true},"82408ed3e959ddc60d3e9904481b5a8dc16469928257af22a3f7d1a3bc7fd8c4","b8e431e9b9bb2dc832b23d4e3e02774e953d5537998923f215ea446169e9a61e","3690133deae19c8127c5505fcb67b04bdc9eb053796008538a9b9abbb70d85aa","5b1c0a23f464f894e7c2b2b6c56df7b9afa60ed48c5345f8618d389a636b2108","be2b092f2765222757c6441b86c53a5ea8dfed47bbc43eab4c5fe37942c866b3","8e6b05abc98adba15e1ac78e137c64576c74002e301d682e66feb77a23907ab8","1ca735bb3d407b2af4fbee7665f3a0a83be52168c728cc209755060ba7ed67bd",{"version":"6b526a5ec4a401ca7c26cfe6a48e641d8f30af76673bad3b06a1b4504594a960","affectsGlobalScope":true},{"version":"b85c02e14ecb2a873dad5a1de72319b265160ba48f1b83661aeb3bba1366c1bc","affectsGlobalScope":true},"7a2ba0c9af860ac3e77b35ed01fd96d15986f17aa22fe40f188ae556fb1070df","fc3764040518a1008dd04bdc80964591b566b896283e00df85c95851c1f46237","55709608060f77965c270ac10ac646286589f1bd1cb174fff1778a2dd9a7ef31","790623a47c5eda62910098884ecb154dc0e5f3a23fc36c1bfb3b5b9ed44e2c2d","42b40e40f2a358cda332456214fad311e1806a6abf3cebaaac72496e07556642","354612fe1d49ecc9551ea3a27d94eef2887b64ef4a71f72ca444efe0f2f0ba80",{"version":"125af9d85cb9d5e508353f10a8d52f01652d2d48b2cea54789a33e5b4d289c1c","affectsGlobalScope":true},"f5490f53d40291cc8607f5463434d1ac6c5564bc4fbb03abceb03a8f6b014457","5e2b91328a540a0933ab5c2203f4358918e6f0fe7505d22840a891a6117735f1","3abc3512fa04aa0230f59ea1019311fd8667bd935d28306311dccc8b17e79d5d",{"version":"14a50dafe3f45713f7f27cb6320dff07c6ac31678f07959c2134260061bf91ff","affectsGlobalScope":true},{"version":"19da7150ca062323b1db6311a6ef058c9b0a39cc64d836b5e9b75d301869653b","affectsGlobalScope":true},"1349077576abb41f0e9c78ec30762ff75b710208aff77f5fdcc6a8c8ce6289dd","e2ce82603102b5c0563f59fb40314cc1ff95a4d521a66ad14146e130ea80d89c","a3e0395220255a350aa9c6d56f882bfcb5b85c19fddf5419ec822cf22246a26d","c27b01e8ddff5cd280711af5e13aecd9a3228d1c256ea797dd64f8fdec5f7df5","898840e876dfd21843db9f2aa6ae38ba2eab550eb780ff62b894b9fbfebfae6b","0cab4d7d4edc40cd3af9eea7c3ed6d1016910c0954c49c4297e479bf3822a625","1b952304137851e45bc009785de89ada562d9376177c97e37702e39e60c2f1ff","785e5be57d4f20f290a20e7b0c6263f6c57fd6e51283050756cef07d6d651c68","44b8b584a338b190a59f4f6929d072431950c7bd92ec2694821c11bce180c8a5","164deb2409ac5f4da3cd139dbcee7f7d66753d90363a4d7e2db8d8874f272270","1fb6c5ec52332a8b531a8d7a5300ac9301f98c4fe62f68e744e0841ccba65e7e",{"version":"ab294c4b7279318ee2a8fdf681305457ecc05970c94108d304933f18823eeac1","affectsGlobalScope":true},"ad08154d9602429522cac965a715fde27d421d69b24756c5d291877dda75353e","bbda6ea452a2386093a1eda18a6e26a989e98869f1b9f37e46f510a986d2e740","812b25f798033c202baedf386a1ccc41f9191b122f089bffd10fdccce99fba11","993325544790073f77e945bee046d53988c0bc3ac5695c9cf8098166feb82661",{"version":"75dd741ca6a6c8d2437a6ca8349b64b816421dbf9fe82dd026afaba965576962","affectsGlobalScope":true},{"version":"8799401a7ab57764f0d464513a7fa7c72e1d70a226b172ec60fff534ea94d108","affectsGlobalScope":true},"2ce2210032ccaff7710e2abf6a722e62c54960458e73e356b6a365c93ab6ca66","92db194ef7d208d5e4b6242a3434573fd142a621ff996d84cc9dbba3553277d0","16a3080e885ed52d4017c902227a8d0d8daf723d062bec9e45627c6fdcd6699b",{"version":"0bd9543cd8fc0959c76fb8f4f5a26626c2ed62ef4be98fd857bce268066db0a2","affectsGlobalScope":true},"1ca6858a0cbcd74d7db72d7b14c5360a928d1d16748a55ecfa6bfaff8b83071b",{"version":"ab9b9a36e5284fd8d3bf2f7d5fcbc60052f25f27e4d20954782099282c60d23e","affectsGlobalScope":true},"247aa3419c98713231952b33801d4f46563fe542e03604acd8c63ac45a32409c"],"root":[[59,63]],"options":{"allowSyntheticDefaultImports":true,"downlevelIteration":true,"jsx":2,"module":99,"noImplicitAny":true,"outDir":"./","sourceMap":true,"strictNullChecks":true,"target":2},"fileIdsList":[[110],[64,110],[67,110],[68,73,101,110],[69,80,81,88,98,109,110],[69,70,80,88,110],[71,110],[72,73,81,89,110],[73,98,106,110],[74,76,80,88,110],[75,110],[76,77,110],[80,110],[78,80,110],[80,81,82,98,109,110],[80,81,82,95,98,101,110],[110,114],[76,80,83,88,98,109,110],[80,81,83,84,88,98,106,109,110],[83,85,98,106,109,110],[64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116],[80,86,110],[87,109,110],[76,80,88,98,110],[89,110],[90,110],[67,91,110],[92,108,110,114],[93,110],[94,110],[80,95,96,110],[95,97,110,112],[68,80,98,99,100,101,110],[68,98,100,110],[98,99,110],[101,110],[102,110],[98,110],[80,104,105,110],[104,105,110],[73,88,98,106,110],[107,110],[88,108,110],[68,83,94,109,110],[73,110],[98,110,111],[110,112],[110,113],[68,73,80,82,91,98,109,110,112,114],[98,110,115],[57,110],[52,53,54,110],[52,55,56,110],[52,53,55,110],[51,59,61,110],[48,51,58,59,60,110],[51,58,110],[48,51,58,59,110],[61,62,110],[47,110],[45,46,110],[48,110],[48,49,50,110],[48,49,110]],"referencedMap":[[54,1],[64,2],[65,2],[67,3],[68,4],[69,5],[70,6],[71,7],[72,8],[73,9],[74,10],[75,11],[76,12],[77,12],[79,13],[78,14],[80,13],[81,15],[82,16],[66,17],[116,1],[83,18],[84,19],[85,20],[117,21],[86,22],[87,23],[88,24],[89,25],[90,26],[91,27],[92,28],[93,29],[94,30],[95,31],[96,31],[97,32],[98,33],[100,34],[99,35],[101,36],[102,37],[103,38],[104,39],[105,40],[106,41],[107,42],[108,43],[109,44],[110,45],[111,46],[112,47],[113,48],[114,49],[115,50],[58,51],[55,52],[57,53],[56,54],[52,1],[53,1],[43,1],[44,1],[8,1],[10,1],[9,1],[2,1],[11,1],[12,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[3,1],[4,1],[22,1],[19,1],[20,1],[21,1],[23,1],[24,1],[25,1],[5,1],[26,1],[27,1],[28,1],[29,1],[6,1],[33,1],[30,1],[31,1],[32,1],[34,1],[7,1],[35,1],[40,1],[41,1],[36,1],[37,1],[38,1],[39,1],[1,1],[42,1],[62,55],[61,56],[59,57],[60,58],[63,59],[48,60],[45,1],[46,1],[47,61],[49,62],[51,63],[50,64]],"exportedModulesMap":[[54,1],[64,2],[65,2],[67,3],[68,4],[69,5],[70,6],[71,7],[72,8],[73,9],[74,10],[75,11],[76,12],[77,12],[79,13],[78,14],[80,13],[81,15],[82,16],[66,17],[116,1],[83,18],[84,19],[85,20],[117,21],[86,22],[87,23],[88,24],[89,25],[90,26],[91,27],[92,28],[93,29],[94,30],[95,31],[96,31],[97,32],[98,33],[100,34],[99,35],[101,36],[102,37],[103,38],[104,39],[105,40],[106,41],[107,42],[108,43],[109,44],[110,45],[111,46],[112,47],[113,48],[114,49],[115,50],[58,51],[55,52],[57,53],[56,54],[52,1],[53,1],[43,1],[44,1],[8,1],[10,1],[9,1],[2,1],[11,1],[12,1],[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[3,1],[4,1],[22,1],[19,1],[20,1],[21,1],[23,1],[24,1],[25,1],[5,1],[26,1],[27,1],[28,1],[29,1],[6,1],[33,1],[30,1],[31,1],[32,1],[34,1],[7,1],[35,1],[40,1],[41,1],[36,1],[37,1],[38,1],[39,1],[1,1],[42,1],[62,55],[61,56],[59,57],[60,58],[63,59],[48,60],[45,1],[46,1],[47,61],[49,62],[51,63],[50,64]],"semanticDiagnosticsPerFile":[54,64,65,67,68,69,70,71,72,73,74,75,76,77,79,78,80,81,82,66,116,83,84,85,117,86,87,88,89,90,91,92,93,94,95,96,97,98,100,99,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,58,55,57,56,52,53,43,44,8,10,9,2,11,12,13,14,15,16,17,18,3,4,22,19,20,21,23,24,25,5,26,27,28,29,6,33,30,31,32,34,7,35,40,41,36,37,38,39,1,42,62,61,59,60,63,48,45,46,47,49,51,50],"affectedFilesPendingEmit":[62,61,59,60,63]},"version":"5.0.4"}