@mml-io/networked-dom-web-client 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -113,24 +113,6 @@ var require_build = __commonJS({
113
113
  NetworkedDOMWebsocketStatus2[NetworkedDOMWebsocketStatus2["Disconnected"] = 3] = "Disconnected";
114
114
  return NetworkedDOMWebsocketStatus2;
115
115
  })(NetworkedDOMWebsocketStatus || {});
116
- function isHTMLElement(node) {
117
- if (node instanceof HTMLElement) {
118
- return true;
119
- }
120
- if (!this.parentElement.ownerDocument.defaultView) {
121
- return false;
122
- }
123
- return node instanceof this.parentElement.ownerDocument.defaultView.HTMLElement;
124
- }
125
- function isText(node) {
126
- if (node instanceof Text) {
127
- return true;
128
- }
129
- if (!this.parentElement.ownerDocument.defaultView) {
130
- return false;
131
- }
132
- return node instanceof this.parentElement.ownerDocument.defaultView.Text;
133
- }
134
116
  var NetworkedDOMWebsocket2 = class {
135
117
  constructor(url, websocketFactory, parentElement, timeCallback, statusUpdateCallback) {
136
118
  this.idToElement = /* @__PURE__ */ new Map();
@@ -162,6 +144,24 @@ var require_build = __commonJS({
162
144
  this.statusUpdateCallback(status);
163
145
  }
164
146
  }
147
+ isHTMLElement(node) {
148
+ if (node instanceof HTMLElement) {
149
+ return true;
150
+ }
151
+ if (!this.parentElement.ownerDocument.defaultView) {
152
+ return false;
153
+ }
154
+ return node instanceof this.parentElement.ownerDocument.defaultView.HTMLElement;
155
+ }
156
+ isText(node) {
157
+ if (node instanceof Text) {
158
+ return true;
159
+ }
160
+ if (!this.parentElement.ownerDocument.defaultView) {
161
+ return false;
162
+ }
163
+ return node instanceof this.parentElement.ownerDocument.defaultView.Text;
164
+ }
165
165
  createWebsocketWithTimeout(timeout) {
166
166
  return new Promise((resolve, reject) => {
167
167
  const timeoutId = setTimeout(() => {
@@ -254,50 +254,42 @@ var require_build = __commonJS({
254
254
  handleIncomingWebsocketMessage(event) {
255
255
  const messages = JSON.parse(event.data);
256
256
  for (const message of messages) {
257
- if (message.type === "error") {
258
- console.error("Error from server", message);
259
- } else if (message.type === "warning") {
260
- console.warn("Warning from server", message);
261
- } else {
262
- if (message.documentTime) {
263
- if (this.timeCallback) {
264
- this.timeCallback(message.documentTime);
265
- }
266
- }
267
- if (message.type === "snapshot") {
268
- this.backoffTime = startingBackoffTimeMilliseconds;
269
- this.setStatus(
270
- 1
271
- /* Connected */
272
- );
273
- if (this.currentRoot) {
274
- this.currentRoot.remove();
275
- this.currentRoot = null;
276
- this.elementToId.clear();
277
- this.idToElement.clear();
257
+ switch (message.type) {
258
+ case "error":
259
+ console.error("Error from server", message);
260
+ break;
261
+ case "warning":
262
+ console.warn("Warning from server", message);
263
+ break;
264
+ default: {
265
+ if (message.documentTime) {
266
+ if (this.timeCallback) {
267
+ this.timeCallback(message.documentTime);
268
+ }
278
269
  }
279
- const element = this.handleNewElement(message.snapshot);
280
- if (!element) {
281
- throw new Error("Snapshot element not created");
270
+ switch (message.type) {
271
+ case "snapshot":
272
+ this.handleSnapshot(message);
273
+ break;
274
+ case "attributeChange":
275
+ this.handleAttributeChange(message);
276
+ break;
277
+ case "childrenChanged":
278
+ this.handleChildrenChanged(message);
279
+ break;
280
+ case "textChanged":
281
+ this.handleTextChanged(message);
282
+ break;
283
+ case "ping":
284
+ this.send({
285
+ type: "pong",
286
+ pong: message.ping
287
+ });
288
+ break;
289
+ default:
290
+ console.warn("unknown message type", message);
291
+ break;
282
292
  }
283
- if (!isHTMLElement(element)) {
284
- throw new Error("Snapshot element is not an HTMLElement");
285
- }
286
- this.currentRoot = element;
287
- this.parentElement.append(element);
288
- } else if (message.type === "attributeChange") {
289
- this.handleAttributeChange(message);
290
- } else if (message.type === "childrenChanged") {
291
- this.handleChildrenChanged(message);
292
- } else if (message.type === "textChanged") {
293
- this.handleTextChanged(message);
294
- } else if (message.type === "ping") {
295
- this.send({
296
- type: "pong",
297
- pong: message.ping
298
- });
299
- } else {
300
- console.warn("unknown message type", message);
301
293
  }
302
294
  }
303
295
  }
@@ -346,7 +338,7 @@ var require_build = __commonJS({
346
338
  if (!node) {
347
339
  throw new Error("No node found for textChanged message");
348
340
  }
349
- if (!isText(node)) {
341
+ if (!this.isText(node)) {
350
342
  throw new Error("Node for textChanged message is not a Text node");
351
343
  }
352
344
  node.textContent = text;
@@ -364,7 +356,7 @@ var require_build = __commonJS({
364
356
  if (!parent.isConnected) {
365
357
  console.error("Parent is not connected", parent);
366
358
  }
367
- if (!isHTMLElement(parent)) {
359
+ if (!this.isHTMLElement(parent)) {
368
360
  throw new Error("Parent is not an HTMLElement (that supports children)");
369
361
  }
370
362
  let previousElement;
@@ -397,7 +389,7 @@ var require_build = __commonJS({
397
389
  this.elementToId.delete(childElement);
398
390
  this.idToElement.delete(removedNode);
399
391
  parent.removeChild(childElement);
400
- if (isHTMLElement(childElement)) {
392
+ if (this.isHTMLElement(childElement)) {
401
393
  this.removeChildElementIds(childElement);
402
394
  }
403
395
  }
@@ -415,6 +407,28 @@ var require_build = __commonJS({
415
407
  this.removeChildElementIds(child);
416
408
  }
417
409
  }
410
+ handleSnapshot(message) {
411
+ this.backoffTime = startingBackoffTimeMilliseconds;
412
+ this.setStatus(
413
+ 1
414
+ /* Connected */
415
+ );
416
+ if (this.currentRoot) {
417
+ this.currentRoot.remove();
418
+ this.currentRoot = null;
419
+ this.elementToId.clear();
420
+ this.idToElement.clear();
421
+ }
422
+ const element = this.handleNewElement(message.snapshot);
423
+ if (!element) {
424
+ throw new Error("Snapshot element not created");
425
+ }
426
+ if (!this.isHTMLElement(element)) {
427
+ throw new Error("Snapshot element is not an HTMLElement");
428
+ }
429
+ this.currentRoot = element;
430
+ this.parentElement.append(element);
431
+ }
418
432
  handleAttributeChange(message) {
419
433
  const { nodeId, attribute, newValue } = message;
420
434
  if (nodeId === void 0 || nodeId === null) {
@@ -423,7 +437,7 @@ var require_build = __commonJS({
423
437
  }
424
438
  const element = this.idToElement.get(nodeId);
425
439
  if (element) {
426
- if (isHTMLElement(element)) {
440
+ if (this.isHTMLElement(element)) {
427
441
  if (newValue === null) {
428
442
  element.removeAttribute(attribute);
429
443
  } else {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../networked-dom-web/src/index.ts", "../../networked-dom-web/src/DOMSanitizer.ts", "../../networked-dom-web/src/NetworkedDOMWebsocket.ts", "../src/index.ts"],
4
- "sourcesContent": ["export * from \"./NetworkedDOMWebsocket\";\nexport * from \"./DOMSanitizer\";\n", "export class DOMSanitizer {\n static sanitise(node: HTMLElement) {\n if (node.getAttributeNames) {\n for (const attr of node.getAttributeNames()) {\n if (!DOMSanitizer.IsValidAttributeName(attr)) {\n node.removeAttribute(attr);\n }\n }\n }\n if (node.nodeName === \"SCRIPT\") {\n // set text to empty string\n node.innerText = \"\";\n } else {\n if (node.getAttributeNames) {\n for (const attr of node.getAttributeNames()) {\n if (!DOMSanitizer.shouldAcceptAttribute(attr)) {\n node.removeAttribute(attr);\n }\n }\n }\n for (let i = 0; i < node.childNodes.length; i++) {\n DOMSanitizer.sanitise(node.childNodes[i] as HTMLElement);\n }\n }\n }\n\n static IsASCIIDigit(c: string): boolean {\n return c >= \"0\" && c <= \"9\";\n }\n\n static IsASCIIAlpha(c: string) {\n return c >= \"a\" && c <= \"z\";\n }\n\n static IsValidAttributeName(characters: string): boolean {\n const c = characters[0];\n if (!(DOMSanitizer.IsASCIIAlpha(c) || c === \":\" || c === \"_\")) {\n return false;\n }\n\n for (let i = 1; i < characters.length; i++) {\n const c = characters[i];\n if (\n !(\n DOMSanitizer.IsASCIIDigit(c) ||\n DOMSanitizer.IsASCIIAlpha(c) ||\n c === \":\" ||\n c === \"_\" ||\n c === \"-\" ||\n c === \".\"\n )\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n static shouldAcceptAttribute(attribute: string) {\n if (!DOMSanitizer.IsValidAttributeName(attribute)) {\n console.warn(\"Invalid attribute name\", attribute);\n return false;\n }\n\n // TODO - this might be overly restrictive - apologies to someone that finds this because you have a non-event attribute filtered by this\n return !attribute.startsWith(\"on\");\n }\n}\n", "import {\n AttributeChangedDiff,\n ChildrenChangedDiff,\n ClientMessage,\n NodeDescription,\n RemoteEvent,\n ServerMessage,\n TextChangedDiff,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { DOMSanitizer } from \"./DOMSanitizer\";\n\nconst websocketProtocol = \"networked-dom-v0.1\";\n\nconst startingBackoffTimeMilliseconds = 100;\nconst maximumBackoffTimeMilliseconds = 10000;\nconst maximumWebsocketConnectionTimeout = 5000;\n\nexport type NetworkedDOMWebsocketFactory = (url: string) => WebSocket;\n\nexport enum NetworkedDOMWebsocketStatus {\n Connecting,\n Connected,\n Reconnecting,\n Disconnected,\n}\n\nfunction isHTMLElement(node: unknown): node is HTMLElement {\n if (node instanceof HTMLElement) {\n return true;\n }\n if (!this.parentElement.ownerDocument.defaultView) {\n return false;\n }\n return node instanceof this.parentElement.ownerDocument.defaultView.HTMLElement;\n}\n\nfunction isText(node: unknown): node is Text {\n if (node instanceof Text) {\n return true;\n }\n if (!this.parentElement.ownerDocument.defaultView) {\n return false;\n }\n return node instanceof this.parentElement.ownerDocument.defaultView.Text;\n}\n\nexport class NetworkedDOMWebsocket {\n private idToElement = new Map<number, Node>();\n private elementToId = new Map<Node, number>();\n private websocket: WebSocket | null = null;\n private currentRoot: HTMLElement | null = null;\n\n private url: string;\n private websocketFactory: NetworkedDOMWebsocketFactory;\n private parentElement: HTMLElement;\n private timeCallback: (time: number) => void;\n private statusUpdateCallback: (status: NetworkedDOMWebsocketStatus) => void;\n private stopped = false;\n private backoffTime = startingBackoffTimeMilliseconds;\n private status: NetworkedDOMWebsocketStatus | null = null;\n\n public static createWebSocket(url: string): WebSocket {\n return new WebSocket(url, [websocketProtocol]);\n }\n\n constructor(\n url: string,\n websocketFactory: NetworkedDOMWebsocketFactory,\n parentElement: HTMLElement,\n timeCallback?: (time: number) => void,\n statusUpdateCallback?: (status: NetworkedDOMWebsocketStatus) => void,\n ) {\n this.url = url;\n this.websocketFactory = websocketFactory;\n this.parentElement = parentElement;\n this.timeCallback =\n timeCallback ||\n (() => {\n // no-op\n });\n this.statusUpdateCallback =\n statusUpdateCallback ||\n (() => {\n // no-op\n });\n this.setStatus(NetworkedDOMWebsocketStatus.Connecting);\n this.startWebSocketConnectionAttempt();\n }\n\n private setStatus(status: NetworkedDOMWebsocketStatus) {\n if (this.status !== status) {\n this.status = status;\n this.statusUpdateCallback(status);\n }\n }\n\n private createWebsocketWithTimeout(timeout: number): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(\"websocket connection timed out\"));\n }, timeout);\n const websocket = this.websocketFactory(this.url);\n websocket.addEventListener(\"open\", () => {\n clearTimeout(timeoutId);\n\n this.websocket = websocket;\n\n websocket.addEventListener(\"message\", (event) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket message event because it is no longer current\");\n websocket.close();\n return;\n }\n this.handleIncomingWebsocketMessage(event);\n });\n\n const onWebsocketClose = async () => {\n const hadContents = this.currentRoot !== null;\n this.clearContents();\n if (this.stopped) {\n // This closing is expected. The client closed the websocket.\n this.setStatus(NetworkedDOMWebsocketStatus.Disconnected);\n return;\n }\n if (!hadContents) {\n // The websocket did not deliver any contents. It may have been successfully opened, but immediately closed. This client should back off to prevent this happening in a rapid loop.\n await this.waitBackoffTime();\n }\n // The websocket closed unexpectedly. Try to reconnect.\n this.setStatus(NetworkedDOMWebsocketStatus.Reconnecting);\n this.startWebSocketConnectionAttempt();\n };\n\n websocket.addEventListener(\"close\", (e) => {\n if (websocket !== this.websocket) {\n console.warn(\"Ignoring websocket close event because it is no longer current\");\n return;\n }\n console.log(\"NetworkedDOMWebsocket close\", e);\n onWebsocketClose();\n });\n websocket.addEventListener(\"error\", (e) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket error event because it is no longer current\");\n return;\n }\n console.error(\"NetworkedDOMWebsocket error\", e);\n onWebsocketClose();\n });\n\n resolve(websocket);\n });\n websocket.addEventListener(\"error\", (e) => {\n clearTimeout(timeoutId);\n reject(e);\n });\n });\n }\n\n private async waitBackoffTime(): Promise<void> {\n console.warn(`Websocket connection to '${this.url}' failed: retrying in ${this.backoffTime}ms`);\n await new Promise((resolve) => setTimeout(resolve, this.backoffTime));\n this.backoffTime = Math.min(\n // Introduce a small amount of randomness to prevent clients from retrying in lockstep\n this.backoffTime * (1.5 + Math.random() * 0.5),\n maximumBackoffTimeMilliseconds,\n );\n }\n\n private async startWebSocketConnectionAttempt() {\n if (this.stopped) {\n return;\n }\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (this.stopped) {\n return;\n }\n try {\n await this.createWebsocketWithTimeout(maximumWebsocketConnectionTimeout);\n break;\n } catch (e) {\n // Connection failed, retry with backoff\n this.setStatus(NetworkedDOMWebsocketStatus.Reconnecting);\n await this.waitBackoffTime();\n }\n }\n }\n\n private handleIncomingWebsocketMessage(event: MessageEvent) {\n const messages = JSON.parse(event.data) as Array<ServerMessage>;\n for (const message of messages) {\n if (message.type === \"error\") {\n console.error(\"Error from server\", message);\n } else if (message.type === \"warning\") {\n console.warn(\"Warning from server\", message);\n } else {\n if (message.documentTime) {\n if (this.timeCallback) {\n this.timeCallback(message.documentTime);\n }\n }\n if (message.type === \"snapshot\") {\n // This websocket is successfully connected. Reset the backoff time.\n this.backoffTime = startingBackoffTimeMilliseconds;\n this.setStatus(NetworkedDOMWebsocketStatus.Connected);\n\n if (this.currentRoot) {\n this.currentRoot.remove();\n this.currentRoot = null;\n this.elementToId.clear();\n this.idToElement.clear();\n }\n\n // create a tree of DOM elements\n // NOTE: the MLElement contructors are not executed during this stage\n const element = this.handleNewElement(message.snapshot);\n if (!element) {\n throw new Error(\"Snapshot element not created\");\n }\n if (!isHTMLElement(element)) {\n throw new Error(\"Snapshot element is not an HTMLElement\");\n }\n this.currentRoot = element;\n // appending to the tree causes MElements to be constructed\n this.parentElement.append(element);\n } else if (message.type === \"attributeChange\") {\n this.handleAttributeChange(message);\n } else if (message.type === \"childrenChanged\") {\n this.handleChildrenChanged(message);\n } else if (message.type === \"textChanged\") {\n this.handleTextChanged(message);\n } else if (message.type === \"ping\") {\n this.send({\n type: \"pong\",\n pong: message.ping,\n });\n } else {\n console.warn(\"unknown message type\", message);\n }\n }\n }\n }\n\n public stop() {\n this.stopped = true;\n if (this.websocket !== null) {\n this.websocket.close();\n this.websocket = null;\n }\n }\n\n public handleEvent(element: HTMLElement, event: CustomEvent<{ element: HTMLElement }>) {\n const nodeId = this.elementToId.get(element);\n if (nodeId === undefined || nodeId === null) {\n throw new Error(\"Element not found\");\n }\n\n console.log(\n `Sending event to websocket: \"${event.type}\" on node: ${nodeId} type: ${element.tagName}`,\n );\n\n const detailWithoutElement: Partial<typeof event.detail> = {\n ...event.detail,\n };\n delete detailWithoutElement.element;\n\n const remoteEvent: RemoteEvent = {\n type: \"event\",\n nodeId,\n name: event.type,\n bubbles: event.bubbles,\n params: detailWithoutElement,\n };\n\n this.send(remoteEvent);\n }\n\n private send(fromClientMessage: ClientMessage) {\n if (!this.websocket) {\n throw new Error(\"No websocket created\");\n }\n this.websocket.send(JSON.stringify(fromClientMessage));\n }\n\n private handleTextChanged(message: TextChangedDiff) {\n const { nodeId, text } = message;\n\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in textChanged message\");\n return;\n }\n const node = this.idToElement.get(nodeId);\n if (!node) {\n throw new Error(\"No node found for textChanged message\");\n }\n if (!isText(node)) {\n throw new Error(\"Node for textChanged message is not a Text node\");\n }\n node.textContent = text;\n }\n\n private handleChildrenChanged(message: ChildrenChangedDiff) {\n const { nodeId, addedNodes, removedNodes, previousNodeId } = message;\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in childrenChanged message\");\n return;\n }\n const parent = this.idToElement.get(nodeId);\n if (!parent) {\n throw new Error(\"No parent found for childrenChanged message\");\n }\n if (!parent.isConnected) {\n console.error(\"Parent is not connected\", parent);\n }\n if (!isHTMLElement(parent)) {\n throw new Error(\"Parent is not an HTMLElement (that supports children)\");\n }\n let previousElement;\n if (previousNodeId) {\n previousElement = this.idToElement.get(previousNodeId);\n if (!previousElement) {\n throw new Error(\"No previous element found for childrenChanged message\");\n }\n }\n\n for (const addedNode of addedNodes) {\n const childElement = this.handleNewElement(addedNode);\n if (childElement) {\n if (previousElement) {\n const nextElement = previousElement.nextSibling;\n if (nextElement) {\n parent.insertBefore(childElement, nextElement);\n } else {\n parent.append(childElement);\n }\n } else {\n parent.append(childElement);\n }\n }\n }\n for (const removedNode of removedNodes) {\n const childElement = this.idToElement.get(removedNode);\n if (!childElement) {\n throw new Error(`Child element not found: ${removedNode}`);\n }\n this.elementToId.delete(childElement);\n this.idToElement.delete(removedNode);\n parent.removeChild(childElement);\n if (isHTMLElement(childElement)) {\n // If child is capable of supporting children then remove any that exist\n this.removeChildElementIds(childElement);\n }\n }\n }\n\n private removeChildElementIds(parent: HTMLElement) {\n for (let i = 0; i < parent.children.length; i++) {\n const child = parent.children[i];\n const childId = this.elementToId.get(child as HTMLElement);\n if (!childId) {\n console.error(\"Inner child of removed element had no id\", child);\n } else {\n this.elementToId.delete(child);\n this.idToElement.delete(childId);\n }\n this.removeChildElementIds(child as HTMLElement);\n }\n }\n\n private handleAttributeChange(message: AttributeChangedDiff) {\n const { nodeId, attribute, newValue } = message;\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in attributeChange message\");\n return;\n }\n const element = this.idToElement.get(nodeId);\n if (element) {\n if (isHTMLElement(element)) {\n if (newValue === null) {\n element.removeAttribute(attribute);\n } else {\n if (DOMSanitizer.shouldAcceptAttribute(attribute)) {\n element.setAttribute(attribute, newValue);\n }\n }\n } else {\n console.error(\"Element is not an HTMLElement and cannot support attributes\", element);\n }\n } else {\n console.error(\"No element found for attributeChange message\");\n }\n }\n\n private handleNewElement(message: NodeDescription): Node | null {\n if (message.type === \"text\") {\n const { nodeId, text } = message;\n const textNode = document.createTextNode(\"\");\n textNode.textContent = text;\n this.idToElement.set(nodeId, textNode);\n this.elementToId.set(textNode, nodeId);\n return textNode;\n }\n const { tag, nodeId, attributes, children, text } = message;\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in handleNewElement message\", message);\n return null;\n }\n if (this.idToElement.has(nodeId)) {\n console.error(\n \"Received nodeId to add that is already present\",\n nodeId,\n this.idToElement.get(nodeId),\n );\n }\n if (tag === \"#text\") {\n const textNode = document.createTextNode(\"\");\n textNode.textContent = text || null;\n this.idToElement.set(nodeId, textNode);\n this.elementToId.set(textNode, nodeId);\n return textNode;\n }\n\n let element;\n try {\n element = document.createElement(tag);\n } catch (e) {\n console.error(`Error creating element: (${tag})`, e);\n element = document.createElement(\"div\");\n }\n this.idToElement.set(nodeId, element);\n this.elementToId.set(element, nodeId);\n for (const key in attributes) {\n if (DOMSanitizer.shouldAcceptAttribute(key)) {\n const value = attributes[key];\n element.setAttribute(key, value);\n }\n }\n if (children) {\n for (const child of children) {\n const childElement = this.handleNewElement(child);\n if (childElement) {\n element.append(childElement);\n }\n }\n }\n return element;\n }\n\n private clearContents() {\n this.idToElement.clear();\n this.elementToId.clear();\n if (this.currentRoot) {\n this.currentRoot.remove();\n this.currentRoot = null;\n }\n }\n}\n", "import { NetworkedDOMWebsocket } from \"@mml-io/networked-dom-web\";\n\nconst thisScript = document.currentScript as HTMLScriptElement;\nconst scriptUrl = new URL(thisScript.src);\n\n(function () {\n const websocketUrl = scriptUrl.searchParams.get(\"websocketUrl\");\n if (!websocketUrl) {\n console.error(\"websocketUrl not set\");\n return;\n }\n window.addEventListener(\"load\", () => {\n const documentWebsocketUrls = websocketUrl.split(\",\");\n\n for (const documentWebsocketUrl of documentWebsocketUrls) {\n let overriddenHandler: ((element: HTMLElement, event: CustomEvent) => void) | null = null;\n const eventHandler = (element: HTMLElement, event: CustomEvent) => {\n if (!overriddenHandler) {\n throw new Error(\"overriddenHandler not set\");\n }\n overriddenHandler(element, event);\n };\n const remoteDocumentHolder = document.createElement(\"div\");\n document.body.append(remoteDocumentHolder);\n\n remoteDocumentHolder.addEventListener(\"click\", (event: Event) => {\n eventHandler(event.target as HTMLElement, event as CustomEvent);\n return false;\n });\n\n const websocket = new NetworkedDOMWebsocket(\n documentWebsocketUrl,\n NetworkedDOMWebsocket.createWebSocket,\n remoteDocumentHolder,\n );\n overriddenHandler = (element: HTMLElement, event: CustomEvent) => {\n websocket.handleEvent(element, event);\n };\n }\n });\n})();\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export * from \"./NetworkedDOMWebsocket\";\nexport * from \"./DOMSanitizer\";\n", "export class DOMSanitizer {\n static sanitise(node: HTMLElement) {\n if (node.getAttributeNames) {\n for (const attr of node.getAttributeNames()) {\n if (!DOMSanitizer.IsValidAttributeName(attr)) {\n node.removeAttribute(attr);\n }\n }\n }\n if (node.nodeName === \"SCRIPT\") {\n // set text to empty string\n node.innerText = \"\";\n } else {\n if (node.getAttributeNames) {\n for (const attr of node.getAttributeNames()) {\n if (!DOMSanitizer.shouldAcceptAttribute(attr)) {\n node.removeAttribute(attr);\n }\n }\n }\n for (let i = 0; i < node.childNodes.length; i++) {\n DOMSanitizer.sanitise(node.childNodes[i] as HTMLElement);\n }\n }\n }\n\n static IsASCIIDigit(c: string): boolean {\n return c >= \"0\" && c <= \"9\";\n }\n\n static IsASCIIAlpha(c: string) {\n return c >= \"a\" && c <= \"z\";\n }\n\n static IsValidAttributeName(characters: string): boolean {\n const c = characters[0];\n if (!(DOMSanitizer.IsASCIIAlpha(c) || c === \":\" || c === \"_\")) {\n return false;\n }\n\n for (let i = 1; i < characters.length; i++) {\n const c = characters[i];\n if (\n !(\n DOMSanitizer.IsASCIIDigit(c) ||\n DOMSanitizer.IsASCIIAlpha(c) ||\n c === \":\" ||\n c === \"_\" ||\n c === \"-\" ||\n c === \".\"\n )\n ) {\n return false;\n }\n }\n\n return true;\n }\n\n static shouldAcceptAttribute(attribute: string) {\n if (!DOMSanitizer.IsValidAttributeName(attribute)) {\n console.warn(\"Invalid attribute name\", attribute);\n return false;\n }\n\n // TODO - this might be overly restrictive - apologies to someone that finds this because you have a non-event attribute filtered by this\n return !attribute.startsWith(\"on\");\n }\n}\n", "import {\n AttributeChangedDiff,\n ChildrenChangedDiff,\n ClientMessage,\n NodeDescription,\n RemoteEvent,\n ServerMessage,\n SnapshotMessage,\n TextChangedDiff,\n} from \"@mml-io/networked-dom-protocol\";\n\nimport { DOMSanitizer } from \"./DOMSanitizer\";\n\nconst websocketProtocol = \"networked-dom-v0.1\";\n\nconst startingBackoffTimeMilliseconds = 100;\nconst maximumBackoffTimeMilliseconds = 10000;\nconst maximumWebsocketConnectionTimeout = 5000;\n\nexport type NetworkedDOMWebsocketFactory = (url: string) => WebSocket;\n\nexport enum NetworkedDOMWebsocketStatus {\n Connecting,\n Connected,\n Reconnecting,\n Disconnected,\n}\n\nexport class NetworkedDOMWebsocket {\n private idToElement = new Map<number, Node>();\n private elementToId = new Map<Node, number>();\n private websocket: WebSocket | null = null;\n private currentRoot: HTMLElement | null = null;\n\n private url: string;\n private websocketFactory: NetworkedDOMWebsocketFactory;\n private parentElement: HTMLElement;\n private timeCallback: (time: number) => void;\n private statusUpdateCallback: (status: NetworkedDOMWebsocketStatus) => void;\n private stopped = false;\n private backoffTime = startingBackoffTimeMilliseconds;\n private status: NetworkedDOMWebsocketStatus | null = null;\n\n public static createWebSocket(url: string): WebSocket {\n return new WebSocket(url, [websocketProtocol]);\n }\n\n constructor(\n url: string,\n websocketFactory: NetworkedDOMWebsocketFactory,\n parentElement: HTMLElement,\n timeCallback?: (time: number) => void,\n statusUpdateCallback?: (status: NetworkedDOMWebsocketStatus) => void,\n ) {\n this.url = url;\n this.websocketFactory = websocketFactory;\n this.parentElement = parentElement;\n this.timeCallback =\n timeCallback ||\n (() => {\n // no-op\n });\n this.statusUpdateCallback =\n statusUpdateCallback ||\n (() => {\n // no-op\n });\n this.setStatus(NetworkedDOMWebsocketStatus.Connecting);\n this.startWebSocketConnectionAttempt();\n }\n\n private setStatus(status: NetworkedDOMWebsocketStatus) {\n if (this.status !== status) {\n this.status = status;\n this.statusUpdateCallback(status);\n }\n }\n\n private isHTMLElement(node: unknown): node is HTMLElement {\n if (node instanceof HTMLElement) {\n return true;\n }\n if (!this.parentElement.ownerDocument.defaultView) {\n return false;\n }\n return node instanceof this.parentElement.ownerDocument.defaultView.HTMLElement;\n }\n\n private isText(node: unknown): node is Text {\n if (node instanceof Text) {\n return true;\n }\n if (!this.parentElement.ownerDocument.defaultView) {\n return false;\n }\n return node instanceof this.parentElement.ownerDocument.defaultView.Text;\n }\n\n private createWebsocketWithTimeout(timeout: number): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n reject(new Error(\"websocket connection timed out\"));\n }, timeout);\n const websocket = this.websocketFactory(this.url);\n websocket.addEventListener(\"open\", () => {\n clearTimeout(timeoutId);\n\n this.websocket = websocket;\n\n websocket.addEventListener(\"message\", (event) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket message event because it is no longer current\");\n websocket.close();\n return;\n }\n this.handleIncomingWebsocketMessage(event);\n });\n\n const onWebsocketClose = async () => {\n const hadContents = this.currentRoot !== null;\n this.clearContents();\n if (this.stopped) {\n // This closing is expected. The client closed the websocket.\n this.setStatus(NetworkedDOMWebsocketStatus.Disconnected);\n return;\n }\n if (!hadContents) {\n // The websocket did not deliver any contents. It may have been successfully opened, but immediately closed. This client should back off to prevent this happening in a rapid loop.\n await this.waitBackoffTime();\n }\n // The websocket closed unexpectedly. Try to reconnect.\n this.setStatus(NetworkedDOMWebsocketStatus.Reconnecting);\n this.startWebSocketConnectionAttempt();\n };\n\n websocket.addEventListener(\"close\", (e) => {\n if (websocket !== this.websocket) {\n console.warn(\"Ignoring websocket close event because it is no longer current\");\n return;\n }\n console.log(\"NetworkedDOMWebsocket close\", e);\n onWebsocketClose();\n });\n websocket.addEventListener(\"error\", (e) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket error event because it is no longer current\");\n return;\n }\n console.error(\"NetworkedDOMWebsocket error\", e);\n onWebsocketClose();\n });\n\n resolve(websocket);\n });\n websocket.addEventListener(\"error\", (e) => {\n clearTimeout(timeoutId);\n reject(e);\n });\n });\n }\n\n private async waitBackoffTime(): Promise<void> {\n console.warn(`Websocket connection to '${this.url}' failed: retrying in ${this.backoffTime}ms`);\n await new Promise((resolve) => setTimeout(resolve, this.backoffTime));\n this.backoffTime = Math.min(\n // Introduce a small amount of randomness to prevent clients from retrying in lockstep\n this.backoffTime * (1.5 + Math.random() * 0.5),\n maximumBackoffTimeMilliseconds,\n );\n }\n\n private async startWebSocketConnectionAttempt() {\n if (this.stopped) {\n return;\n }\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (this.stopped) {\n return;\n }\n try {\n await this.createWebsocketWithTimeout(maximumWebsocketConnectionTimeout);\n break;\n } catch (e) {\n // Connection failed, retry with backoff\n this.setStatus(NetworkedDOMWebsocketStatus.Reconnecting);\n await this.waitBackoffTime();\n }\n }\n }\n\n private handleIncomingWebsocketMessage(event: MessageEvent) {\n const messages = JSON.parse(event.data) as Array<ServerMessage>;\n for (const message of messages) {\n switch (message.type) {\n case \"error\":\n console.error(\"Error from server\", message);\n break;\n case \"warning\":\n console.warn(\"Warning from server\", message);\n break;\n default: {\n if (message.documentTime) {\n if (this.timeCallback) {\n this.timeCallback(message.documentTime);\n }\n }\n switch (message.type) {\n case \"snapshot\":\n this.handleSnapshot(message);\n break;\n case \"attributeChange\":\n this.handleAttributeChange(message);\n break;\n case \"childrenChanged\":\n this.handleChildrenChanged(message);\n break;\n case \"textChanged\":\n this.handleTextChanged(message);\n break;\n case \"ping\":\n this.send({\n type: \"pong\",\n pong: message.ping,\n });\n break;\n default:\n console.warn(\"unknown message type\", message);\n break;\n }\n }\n }\n }\n }\n\n public stop() {\n this.stopped = true;\n if (this.websocket !== null) {\n this.websocket.close();\n this.websocket = null;\n }\n }\n\n public handleEvent(element: HTMLElement, event: CustomEvent<{ element: HTMLElement }>) {\n const nodeId = this.elementToId.get(element);\n if (nodeId === undefined || nodeId === null) {\n throw new Error(\"Element not found\");\n }\n\n console.log(\n `Sending event to websocket: \"${event.type}\" on node: ${nodeId} type: ${element.tagName}`,\n );\n\n const detailWithoutElement: Partial<typeof event.detail> = {\n ...event.detail,\n };\n delete detailWithoutElement.element;\n\n const remoteEvent: RemoteEvent = {\n type: \"event\",\n nodeId,\n name: event.type,\n bubbles: event.bubbles,\n params: detailWithoutElement,\n };\n\n this.send(remoteEvent);\n }\n\n private send(fromClientMessage: ClientMessage) {\n if (!this.websocket) {\n throw new Error(\"No websocket created\");\n }\n this.websocket.send(JSON.stringify(fromClientMessage));\n }\n\n private handleTextChanged(message: TextChangedDiff) {\n const { nodeId, text } = message;\n\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in textChanged message\");\n return;\n }\n const node = this.idToElement.get(nodeId);\n if (!node) {\n throw new Error(\"No node found for textChanged message\");\n }\n if (!this.isText(node)) {\n throw new Error(\"Node for textChanged message is not a Text node\");\n }\n node.textContent = text;\n }\n\n private handleChildrenChanged(message: ChildrenChangedDiff) {\n const { nodeId, addedNodes, removedNodes, previousNodeId } = message;\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in childrenChanged message\");\n return;\n }\n const parent = this.idToElement.get(nodeId);\n if (!parent) {\n throw new Error(\"No parent found for childrenChanged message\");\n }\n if (!parent.isConnected) {\n console.error(\"Parent is not connected\", parent);\n }\n if (!this.isHTMLElement(parent)) {\n throw new Error(\"Parent is not an HTMLElement (that supports children)\");\n }\n let previousElement;\n if (previousNodeId) {\n previousElement = this.idToElement.get(previousNodeId);\n if (!previousElement) {\n throw new Error(\"No previous element found for childrenChanged message\");\n }\n }\n\n for (const addedNode of addedNodes) {\n const childElement = this.handleNewElement(addedNode);\n if (childElement) {\n if (previousElement) {\n const nextElement = previousElement.nextSibling;\n if (nextElement) {\n parent.insertBefore(childElement, nextElement);\n } else {\n parent.append(childElement);\n }\n } else {\n parent.append(childElement);\n }\n }\n }\n for (const removedNode of removedNodes) {\n const childElement = this.idToElement.get(removedNode);\n if (!childElement) {\n throw new Error(`Child element not found: ${removedNode}`);\n }\n this.elementToId.delete(childElement);\n this.idToElement.delete(removedNode);\n parent.removeChild(childElement);\n if (this.isHTMLElement(childElement)) {\n // If child is capable of supporting children then remove any that exist\n this.removeChildElementIds(childElement);\n }\n }\n }\n\n private removeChildElementIds(parent: HTMLElement) {\n for (let i = 0; i < parent.children.length; i++) {\n const child = parent.children[i];\n const childId = this.elementToId.get(child as HTMLElement);\n if (!childId) {\n console.error(\"Inner child of removed element had no id\", child);\n } else {\n this.elementToId.delete(child);\n this.idToElement.delete(childId);\n }\n this.removeChildElementIds(child as HTMLElement);\n }\n }\n\n private handleSnapshot(message: SnapshotMessage) {\n // This websocket is successfully connected. Reset the backoff time.\n this.backoffTime = startingBackoffTimeMilliseconds;\n this.setStatus(NetworkedDOMWebsocketStatus.Connected);\n\n if (this.currentRoot) {\n this.currentRoot.remove();\n this.currentRoot = null;\n this.elementToId.clear();\n this.idToElement.clear();\n }\n\n // create a tree of DOM elements\n // NOTE: the MElement constructors are not executed during this stage\n const element = this.handleNewElement(message.snapshot);\n if (!element) {\n throw new Error(\"Snapshot element not created\");\n }\n if (!this.isHTMLElement(element)) {\n throw new Error(\"Snapshot element is not an HTMLElement\");\n }\n this.currentRoot = element;\n // appending to the tree causes MElements to be constructed\n this.parentElement.append(element);\n }\n\n private handleAttributeChange(message: AttributeChangedDiff) {\n const { nodeId, attribute, newValue } = message;\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in attributeChange message\");\n return;\n }\n const element = this.idToElement.get(nodeId);\n if (element) {\n if (this.isHTMLElement(element)) {\n if (newValue === null) {\n element.removeAttribute(attribute);\n } else {\n if (DOMSanitizer.shouldAcceptAttribute(attribute)) {\n element.setAttribute(attribute, newValue);\n }\n }\n } else {\n console.error(\"Element is not an HTMLElement and cannot support attributes\", element);\n }\n } else {\n console.error(\"No element found for attributeChange message\");\n }\n }\n\n private handleNewElement(message: NodeDescription): Node | null {\n if (message.type === \"text\") {\n const { nodeId, text } = message;\n const textNode = document.createTextNode(\"\");\n textNode.textContent = text;\n this.idToElement.set(nodeId, textNode);\n this.elementToId.set(textNode, nodeId);\n return textNode;\n }\n const { tag, nodeId, attributes, children, text } = message;\n if (nodeId === undefined || nodeId === null) {\n console.warn(\"No nodeId in handleNewElement message\", message);\n return null;\n }\n if (this.idToElement.has(nodeId)) {\n console.error(\n \"Received nodeId to add that is already present\",\n nodeId,\n this.idToElement.get(nodeId),\n );\n }\n if (tag === \"#text\") {\n const textNode = document.createTextNode(\"\");\n textNode.textContent = text || null;\n this.idToElement.set(nodeId, textNode);\n this.elementToId.set(textNode, nodeId);\n return textNode;\n }\n\n let element;\n try {\n element = document.createElement(tag);\n } catch (e) {\n console.error(`Error creating element: (${tag})`, e);\n element = document.createElement(\"div\");\n }\n this.idToElement.set(nodeId, element);\n this.elementToId.set(element, nodeId);\n for (const key in attributes) {\n if (DOMSanitizer.shouldAcceptAttribute(key)) {\n const value = attributes[key];\n element.setAttribute(key, value);\n }\n }\n if (children) {\n for (const child of children) {\n const childElement = this.handleNewElement(child);\n if (childElement) {\n element.append(childElement);\n }\n }\n }\n return element;\n }\n\n private clearContents() {\n this.idToElement.clear();\n this.elementToId.clear();\n if (this.currentRoot) {\n this.currentRoot.remove();\n this.currentRoot = null;\n }\n }\n}\n", "import { NetworkedDOMWebsocket } from \"@mml-io/networked-dom-web\";\n\nconst thisScript = document.currentScript as HTMLScriptElement;\nconst scriptUrl = new URL(thisScript.src);\n\n(function () {\n const websocketUrl = scriptUrl.searchParams.get(\"websocketUrl\");\n if (!websocketUrl) {\n console.error(\"websocketUrl not set\");\n return;\n }\n window.addEventListener(\"load\", () => {\n const documentWebsocketUrls = websocketUrl.split(\",\");\n\n for (const documentWebsocketUrl of documentWebsocketUrls) {\n let overriddenHandler: ((element: HTMLElement, event: CustomEvent) => void) | null = null;\n const eventHandler = (element: HTMLElement, event: CustomEvent) => {\n if (!overriddenHandler) {\n throw new Error(\"overriddenHandler not set\");\n }\n overriddenHandler(element, event);\n };\n const remoteDocumentHolder = document.createElement(\"div\");\n document.body.append(remoteDocumentHolder);\n\n remoteDocumentHolder.addEventListener(\"click\", (event: Event) => {\n eventHandler(event.target as HTMLElement, event as CustomEvent);\n return false;\n });\n\n const websocket = new NetworkedDOMWebsocket(\n documentWebsocketUrl,\n NetworkedDOMWebsocket.createWebSocket,\n remoteDocumentHolder,\n );\n overriddenHandler = (element: HTMLElement, event: CustomEvent) => {\n websocket.handleEvent(element, event);\n };\n }\n });\n})();\n"],
5
+ "mappings": "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",
6
6
  "names": ["NetworkedDOMWebsocket", "module", "c", "NetworkedDOMWebsocketStatus", "nodeId", "text"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mml-io/networked-dom-web-client",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "files": [
5
5
  "/build",
6
6
  "/src"
@@ -15,6 +15,6 @@
15
15
  "lint-fix": "eslint \"./src/**/*.{js,jsx,ts,tsx}\" --fix"
16
16
  },
17
17
  "dependencies": {
18
- "@mml-io/networked-dom-web": "^0.1.3"
18
+ "@mml-io/networked-dom-web": "^0.2.0"
19
19
  }
20
20
  }