@mml-io/observable-dom 0.6.2 → 0.7.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.
@@ -3,7 +3,6 @@ import { DOMWindow } from "jsdom";
3
3
  import { DOMRunnerFactory, DOMRunnerMessage } from "./ObservableDOM";
4
4
  export declare const JSDOMRunnerFactory: DOMRunnerFactory;
5
5
  export declare class JSDOMRunner {
6
- private monkeyPatchMutationRecordCallback;
7
6
  domWindow: DOMWindow | null;
8
7
  private jsdom;
9
8
  private callback;
package/build/index.js CHANGED
@@ -1,40 +1,3 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
-
29
- // src/index.ts
30
- var src_exports = {};
31
- __export(src_exports, {
32
- JSDOMRunner: () => JSDOMRunner,
33
- JSDOMRunnerFactory: () => JSDOMRunnerFactory,
34
- ObservableDOM: () => ObservableDOM
35
- });
36
- module.exports = __toCommonJS(src_exports);
37
-
38
1
  // src/utils.ts
39
2
  function virtualDOMElementToStatic(el) {
40
3
  return {
@@ -384,27 +347,15 @@ var ObservableDOM = class {
384
347
  };
385
348
 
386
349
  // src/JSDOMRunner.ts
387
- var import_vm = __toESM(require("vm"));
388
- var import_jsdom = require("jsdom");
389
- var nodeFetch = __toESM(require("node-fetch"));
390
- var import_node_fetch = __toESM(require("node-fetch"));
350
+ import vm from "vm";
351
+ import { JSDOM, ResourceLoader, VirtualConsole } from "jsdom";
352
+ import * as nodeFetch from "node-fetch";
353
+ import nodeFetchFn from "node-fetch";
391
354
  var ErrDOMWindowNotInitialized = "DOMWindow not initialized";
392
- var monkeyPatchedMutationRecordCallbacks = /* @__PURE__ */ new Set();
393
- function installMutationObserverMonkeyPatch() {
394
- const MutationRecordExports = require("jsdom/lib/jsdom/living/generated/MutationRecord");
395
- const originalCreateImpl = MutationRecordExports.createImpl;
396
- MutationRecordExports.createImpl = (...args) => {
397
- for (const callback of monkeyPatchedMutationRecordCallbacks) {
398
- callback();
399
- }
400
- return originalCreateImpl.call(null, ...args);
401
- };
402
- }
403
- var monkeyPatchInstalled = false;
404
355
  var JSDOMRunnerFactory = (htmlPath, htmlContents, params, callback) => {
405
356
  return new JSDOMRunner(htmlPath, htmlContents, params, callback);
406
357
  };
407
- var RejectionResourceLoader = class extends import_jsdom.ResourceLoader {
358
+ var RejectionResourceLoader = class extends ResourceLoader {
408
359
  fetch(url) {
409
360
  console.error("RejectionResourceLoader.fetch", url);
410
361
  return null;
@@ -419,32 +370,14 @@ var JSDOMRunner = class {
419
370
  this.logBuffer = [];
420
371
  this.htmlPath = htmlPath;
421
372
  this.callback = callback;
422
- if (!monkeyPatchInstalled) {
423
- installMutationObserverMonkeyPatch();
424
- monkeyPatchInstalled = true;
425
- }
426
- this.monkeyPatchMutationRecordCallback = () => {
427
- var _a;
428
- const records = (_a = this.mutationObserver) == null ? void 0 : _a.takeRecords();
429
- if (records && records.length > 1) {
430
- throw new Error(
431
- "The monkey patching should have prevented more than one record being handled at a time"
432
- );
433
- } else if (records && records.length > 0) {
434
- this.callback({
435
- mutationList: records
436
- });
437
- }
438
- };
439
- monkeyPatchedMutationRecordCallbacks.add(this.monkeyPatchMutationRecordCallback);
440
- this.jsdom = new import_jsdom.JSDOM(htmlContents, {
373
+ this.jsdom = new JSDOM(htmlContents, {
441
374
  runScripts: "dangerously",
442
375
  resources: new RejectionResourceLoader(),
443
376
  url: this.htmlPath,
444
377
  virtualConsole: this.createVirtualConsole(),
445
378
  beforeParse: (window) => {
446
379
  this.domWindow = window;
447
- this.domWindow.fetch = import_node_fetch.default;
380
+ this.domWindow.fetch = nodeFetchFn;
448
381
  this.domWindow.Headers = nodeFetch.Headers;
449
382
  this.domWindow.Request = nodeFetch.Request;
450
383
  this.domWindow.Response = nodeFetch.Response;
@@ -510,7 +443,6 @@ var JSDOMRunner = class {
510
443
  this.callback({
511
444
  mutationList: records
512
445
  });
513
- monkeyPatchedMutationRecordCallbacks.delete(this.monkeyPatchMutationRecordCallback);
514
446
  (_b = this.mutationObserver) == null ? void 0 : _b.disconnect();
515
447
  this.jsdom.window.close();
516
448
  }
@@ -534,7 +466,7 @@ var JSDOMRunner = class {
534
466
  const script = handlerAttributeValue;
535
467
  const vmContext = this.jsdom.getInternalVMContext();
536
468
  try {
537
- const invoke = import_vm.default.runInContext(`(function(event){ ${script} })`, vmContext);
469
+ const invoke = vm.runInContext(`(function(event){ ${script} })`, vmContext);
538
470
  Reflect.apply(invoke, domNode, [remoteEventObject]);
539
471
  } catch (e) {
540
472
  console.error("Error running event handler:", e);
@@ -544,7 +476,7 @@ var JSDOMRunner = class {
544
476
  domNode.dispatchEvent(remoteEventObject);
545
477
  }
546
478
  createVirtualConsole() {
547
- const virtualConsole = new import_jsdom.VirtualConsole();
479
+ const virtualConsole = new VirtualConsole();
548
480
  virtualConsole.on("jsdomError", (...args) => {
549
481
  this.log({
550
482
  level: "system",
@@ -578,10 +510,9 @@ var JSDOMRunner = class {
578
510
  return virtualConsole;
579
511
  }
580
512
  };
581
- // Annotate the CommonJS export names for ESM import in node:
582
- 0 && (module.exports = {
513
+ export {
583
514
  JSDOMRunner,
584
515
  JSDOMRunnerFactory,
585
516
  ObservableDOM
586
- });
517
+ };
587
518
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/utils.ts", "../src/ObservableDOM.ts", "../src/JSDOMRunner.ts"],
4
- "sourcesContent": ["export * from \"./ObservableDOM\";\nexport * from \"./JSDOMRunner\";\n", "import { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { LiveVirtualDOMElement } from \"./ObservableDOM\";\n\nexport function virtualDOMElementToStatic(el: LiveVirtualDOMElement): StaticVirtualDOMElement {\n return {\n nodeId: el.nodeId,\n tag: el.tag,\n attributes: el.attributes,\n childNodes: el.childNodes.map((child) => virtualDOMElementToStatic(child)),\n textContent: el.textContent,\n };\n}\n", "import {\n LogMessage,\n ObservableDOMInterface,\n ObservableDOMMessage,\n ObservableDOMParameters,\n RemoteEvent,\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\n\nimport { virtualDOMElementToStatic } from \"./utils\";\n\nexport type DOMRunnerMessage = {\n loaded?: boolean;\n mutationList?: Array<MutationRecord>;\n logMessage?: LogMessage;\n};\n\nexport type DOMRunnerInterface = {\n getDocument(): Document;\n getWindow(): Window & {\n CustomEvent: typeof CustomEvent;\n Text: typeof Text;\n HTMLScriptElement: typeof HTMLScriptElement;\n Comment: typeof Comment;\n }; // TODO - Define this without using JSDOM types\n dispatchRemoteEventFromConnectionId(\n connectionId: number,\n realElement: Element,\n remoteEvent: RemoteEvent,\n ): void;\n dispose(): void;\n getDocumentTime(): number;\n};\n\nexport type DOMRunnerFactory = (\n htmlPath: string,\n htmlContents: string,\n params: object,\n callback: (domRunnerMessage: DOMRunnerMessage) => void,\n) => DOMRunnerInterface;\n\nexport type LiveVirtualDOMElement = Omit<StaticVirtualDOMElement, \"childNodes\"> & {\n realElement: Element | Text;\n childNodes: Array<LiveVirtualDOMElement>;\n parent: LiveVirtualDOMElement | null;\n};\n\nexport class ObservableDOM implements ObservableDOMInterface {\n private nodeToNodeId = new Map<LiveVirtualDOMElement, number>();\n private nodeIdToNode = new Map<number, LiveVirtualDOMElement>();\n private realElementToVirtualElement = new Map<Element | Text, LiveVirtualDOMElement>();\n private ignoreTextNodes = true;\n private callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void;\n private nextNodeId = 1;\n private htmlPath: string;\n private domRunner: DOMRunnerInterface;\n\n private documentTimeIntervalTimer: NodeJS.Timeout;\n\n constructor(\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n runnerFactory: DOMRunnerFactory,\n ) {\n this.htmlPath = observableDOMParameters.htmlPath;\n this.ignoreTextNodes = observableDOMParameters.ignoreTextNodes;\n this.callback = callback;\n\n this.documentTimeIntervalTimer = setInterval(() => {\n this.callback(\n {\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n }, observableDOMParameters.pingIntervalMilliseconds || 5000);\n\n this.domRunner = runnerFactory(\n observableDOMParameters.htmlPath,\n observableDOMParameters.htmlContents,\n observableDOMParameters.params,\n (domRunnerMessage: DOMRunnerMessage) => {\n if (domRunnerMessage.loaded) {\n this.createVirtualDOMElementWithChildren(\n this.domRunner.getDocument() as unknown as Element,\n null,\n );\n\n const snapshot = virtualDOMElementToStatic(\n this.getVirtualDOMElementForRealElementOrThrow(\n this.domRunner.getDocument() as unknown as Element,\n ),\n );\n\n this.callback(\n {\n snapshot,\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n } else if (domRunnerMessage.mutationList) {\n this.processModificationList(domRunnerMessage.mutationList);\n } else if (domRunnerMessage.logMessage) {\n this.callback(\n {\n logMessage: domRunnerMessage.logMessage,\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n }\n },\n );\n }\n\n public addConnectedUserId(connectionId: number): void {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow().CustomEvent)(\"connected\", {\n detail: { connectionId },\n }),\n );\n }\n\n public removeConnectedUserId(connectionId: number): void {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow().CustomEvent)(\"disconnected\", {\n detail: { connectionId },\n }),\n );\n }\n\n private processModificationList(mutationList: Array<MutationRecord>): void {\n const documentEl = this.domRunner.getDocument() as unknown as Element;\n const documentVirtualDOMElement = this.realElementToVirtualElement.get(documentEl);\n if (!documentVirtualDOMElement) {\n throw new Error(`document not created in processModificationList`);\n }\n\n if (mutationList.length > 1) {\n // TODO (https://github.com/mml-io/mml/issues/100) - walk back through the records to derive the intermediate\n // states (e.g. if an attribute is later added to an element created in an earlier record then it should not\n // have that attribute when the element is added. This is important as incorrect attribute sets can affect\n // visibility and expected client performance.\n }\n\n for (const mutation of mutationList) {\n if (this.isIgnoredElement(mutation.target as Element | Text)) {\n continue;\n }\n\n if (\n mutation.type === \"attributes\" &&\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.isIgnoredAttribute(mutation.target as Element | Text, mutation.attributeName!)\n ) {\n continue;\n }\n\n this.addKnownNodesInMutation(mutation);\n\n // Convert the \"real\" DOM MutationRecord into a \"virtual\" DOM MutationRecord that references the VirtualDOMElements\n // This is done so that the same process for handling mutations can be used for both changes to a live DOM and also\n // to diffs between DOM snapshots when reloading\n const firstNonIgnoredPreviousSibling = mutation.previousSibling\n ? this.getFirstNonIgnoredPreviousSibling(mutation.previousSibling as Element | Text)\n : null;\n const targetElement = this.getVirtualDOMElementForRealElementOrThrow(\n mutation.target as Element | Text,\n );\n const addedNodes: Array<StaticVirtualDOMElement> = [];\n for (const node of mutation.addedNodes) {\n if (this.isIgnoredElement(node as Element | Text)) {\n continue;\n }\n const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(\n node as Element | Text,\n );\n addedNodes.push(virtualDOMElementToStatic(virtualDOMElement));\n }\n\n const removedNodeIds: Array<number> = [];\n for (const node of mutation.removedNodes) {\n if (this.isIgnoredElement(node as Element | Text)) {\n continue;\n }\n const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(\n node as Element | Text,\n );\n removedNodeIds.push(virtualDOMElement.nodeId);\n }\n\n const mutationRecord: StaticVirtualDOMMutationIdsRecord = {\n type: mutation.type,\n targetId: targetElement.nodeId,\n addedNodes,\n removedNodeIds,\n previousSiblingId:\n firstNonIgnoredPreviousSibling !== null\n ? this.getVirtualDOMElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId\n : null,\n attribute: mutation.attributeName\n ? {\n attributeName: mutation.attributeName,\n value: (mutation.target as Element).getAttribute(mutation.attributeName),\n }\n : null,\n };\n\n this.callback(\n {\n mutation: mutationRecord,\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n\n this.removeKnownNodesInMutation(mutation);\n }\n }\n\n private addKnownNodesInMutation(mutation: MutationRecord): void {\n const targetNode = mutation.target as Element | Text;\n const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDOMElement) {\n throw new Error(\n \"Unknown node in addKnownNodesInMutation:\" + targetNode + \",\" + mutation.type,\n );\n }\n if (mutation.type === \"childList\") {\n let previousSibling = mutation.previousSibling;\n let index = 0;\n while (previousSibling && this.isIgnoredElement(previousSibling as Element | Text)) {\n previousSibling = previousSibling.previousSibling;\n }\n if (previousSibling) {\n const previousSiblingElement = this.realElementToVirtualElement.get(\n previousSibling as Element | Text,\n );\n if (!previousSiblingElement) {\n throw new Error(\"Unknown previous sibling\");\n }\n index = virtualDOMElement.childNodes.indexOf(previousSiblingElement);\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((node: Node) => {\n const asElementOrText = node as Element | Text;\n const childVirtualDOMElement = this.createVirtualDOMElementWithChildren(\n asElementOrText,\n virtualDOMElement,\n );\n if (childVirtualDOMElement) {\n if (virtualDOMElement.childNodes.indexOf(childVirtualDOMElement) === -1) {\n virtualDOMElement.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n }\n });\n } else if (mutation.type === \"attributes\") {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const attributeName = mutation.attributeName!;\n if (this.isIgnoredAttribute(targetNode, attributeName)) {\n return;\n }\n const attributeValue = (targetNode as Element).getAttribute(attributeName);\n if (attributeValue === null) {\n delete virtualDOMElement.attributes[attributeName];\n } else {\n virtualDOMElement.attributes[attributeName] = attributeValue;\n }\n } else if (mutation.type === \"characterData\") {\n virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : undefined;\n }\n }\n\n private removeKnownNodesInMutation(mutation: MutationRecord): void {\n const targetNode = mutation.target as Element | Text;\n const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDOMElement) {\n throw new Error(\"Unknown node in mutation list:\" + targetNode + \", \" + mutation.type);\n }\n if (mutation.type === \"childList\") {\n for (const node of mutation.removedNodes) {\n const asElementOrText = node as Element | Text;\n if (this.isIgnoredElement(asElementOrText)) {\n continue;\n }\n const childDOMElement = this.realElementToVirtualElement.get(asElementOrText);\n if (!childDOMElement) {\n console.warn(this.htmlPath, \"Unknown node in removeKnownNodesInMutation\");\n continue;\n } else {\n this.removeVirtualDOMElement(childDOMElement);\n const index = virtualDOMElement.childNodes.indexOf(childDOMElement);\n virtualDOMElement.childNodes.splice(index, 1);\n }\n }\n return;\n }\n }\n\n private removeVirtualDOMElement(virtualDOMElement: LiveVirtualDOMElement): void {\n this.nodeIdToNode.delete(virtualDOMElement.nodeId);\n this.nodeToNodeId.delete(virtualDOMElement);\n this.realElementToVirtualElement.delete(virtualDOMElement.realElement);\n for (const child of virtualDOMElement.childNodes) {\n this.removeVirtualDOMElement(child);\n }\n }\n\n private createVirtualDOMElementWithChildren(\n node: Element | Text,\n parent: LiveVirtualDOMElement | null,\n ): LiveVirtualDOMElement | null {\n const virtualElement = this.createVirtualDOMElement(node, parent);\n if (!virtualElement) {\n return null;\n }\n if ((node as Element).childNodes) {\n for (let i = 0; i < (node as Element).childNodes.length; i++) {\n const child = (node as Element).childNodes[i];\n const childVirtualElement = this.createVirtualDOMElementWithChildren(\n child as Element | Text,\n virtualElement,\n );\n if (childVirtualElement) {\n virtualElement.childNodes.push(childVirtualElement);\n }\n }\n }\n\n return virtualElement;\n }\n\n private createVirtualDOMElement(\n node: Element | Text,\n parent: LiveVirtualDOMElement | null,\n ): LiveVirtualDOMElement | null {\n if (this.isIgnoredElement(node)) {\n return null;\n }\n const existingValue = this.realElementToVirtualElement.get(node);\n if (existingValue !== undefined) {\n throw new Error(\"Node already has a virtual element: \" + node.nodeName);\n }\n if (!node) {\n throw new Error(\"Cannot assign node id to null\");\n }\n\n const attributes: { [key: string]: string } = {};\n if ((node as any).attributes) {\n const asHTMLElement = node as HTMLElement;\n for (const key of asHTMLElement.getAttributeNames()) {\n const value = asHTMLElement.getAttribute(key);\n if (value === null) {\n throw new Error(\"Null attribute value for key: \" + key);\n }\n if (!this.isIgnoredAttribute(node, key)) {\n attributes[key] = value;\n }\n }\n }\n\n const nodeId = this.nextNodeId++;\n const virtualElement: LiveVirtualDOMElement = {\n nodeId,\n tag: node.nodeName,\n attributes,\n childNodes: [],\n realElement: node,\n parent,\n };\n if (node instanceof this.domRunner.getWindow().Text && node.textContent) {\n virtualElement.textContent = node.textContent;\n }\n this.nodeToNodeId.set(virtualElement, nodeId);\n this.nodeIdToNode.set(nodeId, virtualElement);\n this.realElementToVirtualElement.set(node, virtualElement);\n return virtualElement;\n }\n\n private getFirstNonIgnoredPreviousSibling(node: Element | Text): Element | Text | null {\n let currentNode = node;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n while (currentNode && currentNode.previousSibling) {\n currentNode = currentNode.previousSibling as Element | Text;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n }\n return null;\n }\n\n private getVirtualDOMElementForRealElementOrThrow(\n realElement: Element | Text,\n ): LiveVirtualDOMElement {\n const virtualElement = this.realElementToVirtualElement.get(realElement);\n if (!virtualElement) {\n throw new Error(`Virtual element not found for real element`);\n }\n return virtualElement;\n }\n\n private isIgnoredElement(node: Element | Text): boolean {\n if (this.ignoreTextNodes && node instanceof this.domRunner.getWindow().Text) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().HTMLScriptElement) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().Comment) {\n return true;\n }\n return false;\n }\n\n private isIgnoredAttribute(node: Element | Text, attributeName: string): boolean {\n return attributeName.startsWith(\"on\");\n }\n\n public dispatchRemoteEventFromConnectionId(connectionId: number, remoteEvent: RemoteEvent): void {\n const domNode = this.nodeIdToNode.get(remoteEvent.nodeId);\n if (!domNode) {\n console.error(\"Unknown node ID in remote event: \" + remoteEvent.nodeId);\n return;\n }\n\n if (domNode instanceof this.domRunner.getWindow().Text) {\n console.warn(\"Cannot dispatch remote event to text node\");\n return;\n }\n\n this.domRunner.dispatchRemoteEventFromConnectionId(\n connectionId,\n domNode.realElement as Element,\n remoteEvent,\n );\n }\n\n public dispose() {\n clearInterval(this.documentTimeIntervalTimer);\n this.domRunner.dispose();\n }\n\n private getDocumentTime() {\n return this.domRunner.getDocumentTime();\n }\n}\n", "import vm from \"vm\";\n\nimport { LogMessage, RemoteEvent } from \"@mml-io/observable-dom-common\";\nimport { AbortablePromise, DOMWindow, JSDOM, ResourceLoader, VirtualConsole } from \"jsdom\";\nimport * as nodeFetch from \"node-fetch\";\nimport nodeFetchFn from \"node-fetch\";\n\nimport { DOMRunnerFactory, DOMRunnerInterface, DOMRunnerMessage } from \"./ObservableDOM\";\n\nconst ErrDOMWindowNotInitialized = \"DOMWindow not initialized\";\n\n// TODO - remove this monkeypatching if it's possible to avoid the race conditions in naive MutationObserver usage\nconst monkeyPatchedMutationRecordCallbacks = new Set<() => void>();\nfunction installMutationObserverMonkeyPatch() {\n /*\n This monkey patch replaces the `createImpl` exported function implementation in the `MutationRecord` class in JSDOM\n to insert an iteration through callbacks that are therefore fired before a subsequent MutationRecord is created.\n This provides an opportunity to invoke the MutationObservers with a single MutationRecord rather than multiple.\n\n This is necessary as (at least intuitive) usage of the MutationObserver API does not enable creating accurate\n incremental diffs as the handling of all-but-the-last MutationRecord in a list requires collecting state from the\n DOM that has been since been mutated further. (e.g. if an attribute is changed twice in a row the first event cannot\n discover the intermediate value of the attribute as it can only query the latest DOM state). Whilst this simple case\n is solvable by walking backwards through the list of MutationRecords and using `oldValue` there are cases where adding\n child elements with the correct attributes is not possible when handling intermediate diffs.\n */\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const MutationRecordExports = require(\"jsdom/lib/jsdom/living/generated/MutationRecord\");\n const originalCreateImpl = MutationRecordExports.createImpl;\n // This overwrites the function property on the exports that mutation-observers.js uses to create MutationRecords.\n MutationRecordExports.createImpl = (...args: any[]) => {\n for (const callback of monkeyPatchedMutationRecordCallbacks) {\n callback();\n }\n return originalCreateImpl.call(null, ...args);\n };\n}\nlet monkeyPatchInstalled = false;\n\nexport const JSDOMRunnerFactory: DOMRunnerFactory = (\n htmlPath: string,\n htmlContents: string,\n params: object,\n callback: (mutationList: DOMRunnerMessage) => void,\n): DOMRunnerInterface => {\n return new JSDOMRunner(htmlPath, htmlContents, params, callback);\n};\n\n// This is used to stop JSDOM trying to load resources\nclass RejectionResourceLoader extends ResourceLoader {\n public fetch(url: string): AbortablePromise<Buffer> | null {\n console.error(\"RejectionResourceLoader.fetch\", url);\n return null;\n }\n}\n\nexport class JSDOMRunner {\n private monkeyPatchMutationRecordCallback: () => void;\n\n public domWindow: DOMWindow | null = null;\n private jsdom: JSDOM;\n\n private callback: (message: DOMRunnerMessage) => void;\n private mutationObserver: MutationObserver | null = null;\n private htmlPath: string;\n\n private documentStartTime = Date.now();\n\n private isLoaded = false;\n private logBuffer: LogMessage[] = [];\n\n constructor(\n htmlPath: string,\n htmlContents: string,\n params: object,\n callback: (domRunnerMessage: DOMRunnerMessage) => void,\n ) {\n this.htmlPath = htmlPath;\n this.callback = callback;\n\n if (!monkeyPatchInstalled) {\n installMutationObserverMonkeyPatch();\n monkeyPatchInstalled = true;\n }\n\n this.monkeyPatchMutationRecordCallback = () => {\n /*\n This is called before every creation of a MutationRecord so that it can be used to process an existing record to\n avoid handling multiple MutationRecords at a time (see comment at the top of this file).\n */\n const records = this.mutationObserver?.takeRecords();\n if (records && records.length > 1) {\n throw new Error(\n \"The monkey patching should have prevented more than one record being handled at a time\",\n );\n } else if (records && records.length > 0) {\n this.callback({\n mutationList: records,\n });\n }\n };\n monkeyPatchedMutationRecordCallbacks.add(this.monkeyPatchMutationRecordCallback);\n\n this.jsdom = new JSDOM(htmlContents, {\n runScripts: \"dangerously\",\n resources: new RejectionResourceLoader(),\n url: this.htmlPath,\n virtualConsole: this.createVirtualConsole(),\n beforeParse: (window) => {\n this.domWindow = window;\n\n this.domWindow.fetch = nodeFetchFn as unknown as typeof fetch;\n this.domWindow.Headers = nodeFetch.Headers as unknown as typeof Headers;\n this.domWindow.Request = nodeFetch.Request as unknown as typeof Request;\n this.domWindow.Response = nodeFetch.Response as unknown as typeof Response;\n\n // This is a polyfill for https://developer.mozilla.org/en-US/docs/Web/API/Document/timeline\n const timeline = {};\n Object.defineProperty(timeline, \"currentTime\", {\n get: () => {\n return this.getDocumentTime();\n },\n });\n (window.document as any).timeline = timeline;\n\n // JSON stringify and parse to avoid potential reference leaks from the params object\n window.params = JSON.parse(JSON.stringify(params));\n\n this.mutationObserver = new window.MutationObserver((mutationList) => {\n this.callback({\n mutationList,\n });\n });\n\n window.addEventListener(\"load\", () => {\n this.mutationObserver?.observe(window.document, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n this.isLoaded = true;\n\n this.callback({\n loaded: true,\n });\n\n this.flushLogBuffer();\n });\n },\n });\n }\n\n private flushLogBuffer() {\n for (const logMessage of this.logBuffer) {\n this.callback({\n logMessage,\n });\n }\n\n this.logBuffer = [];\n }\n\n private log(message: LogMessage) {\n if (!this.isLoaded) {\n this.logBuffer.push(message);\n return;\n }\n\n this.callback({\n logMessage: message,\n });\n }\n\n public getDocument(): Document {\n if (!this.domWindow) {\n throw new Error(ErrDOMWindowNotInitialized);\n }\n\n return this.domWindow.document;\n }\n\n public getWindow(): any {\n return this.domWindow;\n }\n\n public dispose() {\n const records = this.mutationObserver?.takeRecords();\n this.callback({\n mutationList: records,\n });\n monkeyPatchedMutationRecordCallbacks.delete(this.monkeyPatchMutationRecordCallback);\n this.mutationObserver?.disconnect();\n this.jsdom.window.close();\n }\n\n public getDocumentTime() {\n return Date.now() - this.documentStartTime;\n }\n\n public dispatchRemoteEventFromConnectionId(\n connectionId: number,\n domNode: Element,\n remoteEvent: RemoteEvent,\n ) {\n if (!this.domWindow) {\n throw new Error(ErrDOMWindowNotInitialized);\n }\n\n const bubbles = remoteEvent.bubbles || false;\n const remoteEventObject = new this.domWindow.CustomEvent(remoteEvent.name, {\n bubbles,\n detail: { ...remoteEvent.params, connectionId },\n });\n\n const eventTypeLowerCase = remoteEvent.name.toLowerCase();\n\n // TODO - check if there are other events that automatically wire up similarly to click->onclick and avoid those too\n if (eventTypeLowerCase !== \"click\") {\n const handlerAttributeName = \"on\" + eventTypeLowerCase;\n const handlerAttributeValue = domNode.getAttribute(handlerAttributeName);\n if (handlerAttributeValue) {\n // This event is defined as an HTML event attribute.\n const script = handlerAttributeValue;\n const vmContext = this.jsdom.getInternalVMContext();\n try {\n const invoke = vm.runInContext(`(function(event){ ${script} })`, vmContext);\n Reflect.apply(invoke, domNode, [remoteEventObject]);\n } catch (e) {\n console.error(\"Error running event handler:\", e);\n }\n }\n }\n\n // Dispatch the event via JavaScript.\n domNode.dispatchEvent(remoteEventObject);\n }\n\n private createVirtualConsole(): VirtualConsole {\n const virtualConsole = new VirtualConsole();\n virtualConsole.on(\"jsdomError\", (...args) => {\n this.log({\n level: \"system\",\n content: args,\n });\n });\n virtualConsole.on(\"error\", (...args) => {\n this.log({\n level: \"error\",\n content: args,\n });\n });\n virtualConsole.on(\"warn\", (...args) => {\n this.log({\n level: \"warn\",\n content: args,\n });\n });\n virtualConsole.on(\"log\", (...args) => {\n this.log({\n level: \"log\",\n content: args,\n });\n });\n virtualConsole.on(\"info\", (...args) => {\n this.log({\n level: \"info\",\n content: args,\n });\n });\n return virtualConsole;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["nodeFetchFn", "vm"]
3
+ "sources": ["../src/utils.ts", "../src/ObservableDOM.ts", "../src/JSDOMRunner.ts"],
4
+ "sourcesContent": ["import { StaticVirtualDOMElement } from \"@mml-io/observable-dom-common\";\n\nimport { LiveVirtualDOMElement } from \"./ObservableDOM\";\n\nexport function virtualDOMElementToStatic(el: LiveVirtualDOMElement): StaticVirtualDOMElement {\n return {\n nodeId: el.nodeId,\n tag: el.tag,\n attributes: el.attributes,\n childNodes: el.childNodes.map((child) => virtualDOMElementToStatic(child)),\n textContent: el.textContent,\n };\n}\n", "import {\n LogMessage,\n ObservableDOMInterface,\n ObservableDOMMessage,\n ObservableDOMParameters,\n RemoteEvent,\n StaticVirtualDOMElement,\n StaticVirtualDOMMutationIdsRecord,\n} from \"@mml-io/observable-dom-common\";\n\nimport { virtualDOMElementToStatic } from \"./utils\";\n\nexport type DOMRunnerMessage = {\n loaded?: boolean;\n mutationList?: Array<MutationRecord>;\n logMessage?: LogMessage;\n};\n\nexport type DOMRunnerInterface = {\n getDocument(): Document;\n getWindow(): Window & {\n CustomEvent: typeof CustomEvent;\n Text: typeof Text;\n HTMLScriptElement: typeof HTMLScriptElement;\n Comment: typeof Comment;\n }; // TODO - Define this without using JSDOM types\n dispatchRemoteEventFromConnectionId(\n connectionId: number,\n realElement: Element,\n remoteEvent: RemoteEvent,\n ): void;\n dispose(): void;\n getDocumentTime(): number;\n};\n\nexport type DOMRunnerFactory = (\n htmlPath: string,\n htmlContents: string,\n params: object,\n callback: (domRunnerMessage: DOMRunnerMessage) => void,\n) => DOMRunnerInterface;\n\nexport type LiveVirtualDOMElement = Omit<StaticVirtualDOMElement, \"childNodes\"> & {\n realElement: Element | Text;\n childNodes: Array<LiveVirtualDOMElement>;\n parent: LiveVirtualDOMElement | null;\n};\n\nexport class ObservableDOM implements ObservableDOMInterface {\n private nodeToNodeId = new Map<LiveVirtualDOMElement, number>();\n private nodeIdToNode = new Map<number, LiveVirtualDOMElement>();\n private realElementToVirtualElement = new Map<Element | Text, LiveVirtualDOMElement>();\n private ignoreTextNodes = true;\n private callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void;\n private nextNodeId = 1;\n private htmlPath: string;\n private domRunner: DOMRunnerInterface;\n\n private documentTimeIntervalTimer: NodeJS.Timeout;\n\n constructor(\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n runnerFactory: DOMRunnerFactory,\n ) {\n this.htmlPath = observableDOMParameters.htmlPath;\n this.ignoreTextNodes = observableDOMParameters.ignoreTextNodes;\n this.callback = callback;\n\n this.documentTimeIntervalTimer = setInterval(() => {\n this.callback(\n {\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n }, observableDOMParameters.pingIntervalMilliseconds || 5000);\n\n this.domRunner = runnerFactory(\n observableDOMParameters.htmlPath,\n observableDOMParameters.htmlContents,\n observableDOMParameters.params,\n (domRunnerMessage: DOMRunnerMessage) => {\n if (domRunnerMessage.loaded) {\n this.createVirtualDOMElementWithChildren(\n this.domRunner.getDocument() as unknown as Element,\n null,\n );\n\n const snapshot = virtualDOMElementToStatic(\n this.getVirtualDOMElementForRealElementOrThrow(\n this.domRunner.getDocument() as unknown as Element,\n ),\n );\n\n this.callback(\n {\n snapshot,\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n } else if (domRunnerMessage.mutationList) {\n this.processModificationList(domRunnerMessage.mutationList);\n } else if (domRunnerMessage.logMessage) {\n this.callback(\n {\n logMessage: domRunnerMessage.logMessage,\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n }\n },\n );\n }\n\n public addConnectedUserId(connectionId: number): void {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow().CustomEvent)(\"connected\", {\n detail: { connectionId },\n }),\n );\n }\n\n public removeConnectedUserId(connectionId: number): void {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow().CustomEvent)(\"disconnected\", {\n detail: { connectionId },\n }),\n );\n }\n\n private processModificationList(mutationList: Array<MutationRecord>): void {\n const documentEl = this.domRunner.getDocument() as unknown as Element;\n const documentVirtualDOMElement = this.realElementToVirtualElement.get(documentEl);\n if (!documentVirtualDOMElement) {\n throw new Error(`document not created in processModificationList`);\n }\n\n if (mutationList.length > 1) {\n // TODO (https://github.com/mml-io/mml/issues/100) - walk back through the records to derive the intermediate\n // states (e.g. if an attribute is later added to an element created in an earlier record then it should not\n // have that attribute when the element is added. This is important as incorrect attribute sets can affect\n // visibility and expected client performance.\n }\n\n for (const mutation of mutationList) {\n if (this.isIgnoredElement(mutation.target as Element | Text)) {\n continue;\n }\n\n if (\n mutation.type === \"attributes\" &&\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.isIgnoredAttribute(mutation.target as Element | Text, mutation.attributeName!)\n ) {\n continue;\n }\n\n this.addKnownNodesInMutation(mutation);\n\n // Convert the \"real\" DOM MutationRecord into a \"virtual\" DOM MutationRecord that references the VirtualDOMElements\n // This is done so that the same process for handling mutations can be used for both changes to a live DOM and also\n // to diffs between DOM snapshots when reloading\n const firstNonIgnoredPreviousSibling = mutation.previousSibling\n ? this.getFirstNonIgnoredPreviousSibling(mutation.previousSibling as Element | Text)\n : null;\n const targetElement = this.getVirtualDOMElementForRealElementOrThrow(\n mutation.target as Element | Text,\n );\n const addedNodes: Array<StaticVirtualDOMElement> = [];\n for (const node of mutation.addedNodes) {\n if (this.isIgnoredElement(node as Element | Text)) {\n continue;\n }\n const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(\n node as Element | Text,\n );\n addedNodes.push(virtualDOMElementToStatic(virtualDOMElement));\n }\n\n const removedNodeIds: Array<number> = [];\n for (const node of mutation.removedNodes) {\n if (this.isIgnoredElement(node as Element | Text)) {\n continue;\n }\n const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(\n node as Element | Text,\n );\n removedNodeIds.push(virtualDOMElement.nodeId);\n }\n\n const mutationRecord: StaticVirtualDOMMutationIdsRecord = {\n type: mutation.type,\n targetId: targetElement.nodeId,\n addedNodes,\n removedNodeIds,\n previousSiblingId:\n firstNonIgnoredPreviousSibling !== null\n ? this.getVirtualDOMElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId\n : null,\n attribute: mutation.attributeName\n ? {\n attributeName: mutation.attributeName,\n value: (mutation.target as Element).getAttribute(mutation.attributeName),\n }\n : null,\n };\n\n this.callback(\n {\n mutation: mutationRecord,\n documentTime: this.getDocumentTime(),\n },\n this,\n );\n\n this.removeKnownNodesInMutation(mutation);\n }\n }\n\n private addKnownNodesInMutation(mutation: MutationRecord): void {\n const targetNode = mutation.target as Element | Text;\n const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDOMElement) {\n throw new Error(\n \"Unknown node in addKnownNodesInMutation:\" + targetNode + \",\" + mutation.type,\n );\n }\n if (mutation.type === \"childList\") {\n let previousSibling = mutation.previousSibling;\n let index = 0;\n while (previousSibling && this.isIgnoredElement(previousSibling as Element | Text)) {\n previousSibling = previousSibling.previousSibling;\n }\n if (previousSibling) {\n const previousSiblingElement = this.realElementToVirtualElement.get(\n previousSibling as Element | Text,\n );\n if (!previousSiblingElement) {\n throw new Error(\"Unknown previous sibling\");\n }\n index = virtualDOMElement.childNodes.indexOf(previousSiblingElement);\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((node: Node) => {\n const asElementOrText = node as Element | Text;\n const childVirtualDOMElement = this.createVirtualDOMElementWithChildren(\n asElementOrText,\n virtualDOMElement,\n );\n if (childVirtualDOMElement) {\n if (virtualDOMElement.childNodes.indexOf(childVirtualDOMElement) === -1) {\n virtualDOMElement.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n }\n });\n } else if (mutation.type === \"attributes\") {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const attributeName = mutation.attributeName!;\n if (this.isIgnoredAttribute(targetNode, attributeName)) {\n return;\n }\n const attributeValue = (targetNode as Element).getAttribute(attributeName);\n if (attributeValue === null) {\n delete virtualDOMElement.attributes[attributeName];\n } else {\n virtualDOMElement.attributes[attributeName] = attributeValue;\n }\n } else if (mutation.type === \"characterData\") {\n virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : undefined;\n }\n }\n\n private removeKnownNodesInMutation(mutation: MutationRecord): void {\n const targetNode = mutation.target as Element | Text;\n const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDOMElement) {\n throw new Error(\"Unknown node in mutation list:\" + targetNode + \", \" + mutation.type);\n }\n if (mutation.type === \"childList\") {\n for (const node of mutation.removedNodes) {\n const asElementOrText = node as Element | Text;\n if (this.isIgnoredElement(asElementOrText)) {\n continue;\n }\n const childDOMElement = this.realElementToVirtualElement.get(asElementOrText);\n if (!childDOMElement) {\n console.warn(this.htmlPath, \"Unknown node in removeKnownNodesInMutation\");\n continue;\n } else {\n this.removeVirtualDOMElement(childDOMElement);\n const index = virtualDOMElement.childNodes.indexOf(childDOMElement);\n virtualDOMElement.childNodes.splice(index, 1);\n }\n }\n return;\n }\n }\n\n private removeVirtualDOMElement(virtualDOMElement: LiveVirtualDOMElement): void {\n this.nodeIdToNode.delete(virtualDOMElement.nodeId);\n this.nodeToNodeId.delete(virtualDOMElement);\n this.realElementToVirtualElement.delete(virtualDOMElement.realElement);\n for (const child of virtualDOMElement.childNodes) {\n this.removeVirtualDOMElement(child);\n }\n }\n\n private createVirtualDOMElementWithChildren(\n node: Element | Text,\n parent: LiveVirtualDOMElement | null,\n ): LiveVirtualDOMElement | null {\n const virtualElement = this.createVirtualDOMElement(node, parent);\n if (!virtualElement) {\n return null;\n }\n if ((node as Element).childNodes) {\n for (let i = 0; i < (node as Element).childNodes.length; i++) {\n const child = (node as Element).childNodes[i];\n const childVirtualElement = this.createVirtualDOMElementWithChildren(\n child as Element | Text,\n virtualElement,\n );\n if (childVirtualElement) {\n virtualElement.childNodes.push(childVirtualElement);\n }\n }\n }\n\n return virtualElement;\n }\n\n private createVirtualDOMElement(\n node: Element | Text,\n parent: LiveVirtualDOMElement | null,\n ): LiveVirtualDOMElement | null {\n if (this.isIgnoredElement(node)) {\n return null;\n }\n const existingValue = this.realElementToVirtualElement.get(node);\n if (existingValue !== undefined) {\n throw new Error(\"Node already has a virtual element: \" + node.nodeName);\n }\n if (!node) {\n throw new Error(\"Cannot assign node id to null\");\n }\n\n const attributes: { [key: string]: string } = {};\n if ((node as any).attributes) {\n const asHTMLElement = node as HTMLElement;\n for (const key of asHTMLElement.getAttributeNames()) {\n const value = asHTMLElement.getAttribute(key);\n if (value === null) {\n throw new Error(\"Null attribute value for key: \" + key);\n }\n if (!this.isIgnoredAttribute(node, key)) {\n attributes[key] = value;\n }\n }\n }\n\n const nodeId = this.nextNodeId++;\n const virtualElement: LiveVirtualDOMElement = {\n nodeId,\n tag: node.nodeName,\n attributes,\n childNodes: [],\n realElement: node,\n parent,\n };\n if (node instanceof this.domRunner.getWindow().Text && node.textContent) {\n virtualElement.textContent = node.textContent;\n }\n this.nodeToNodeId.set(virtualElement, nodeId);\n this.nodeIdToNode.set(nodeId, virtualElement);\n this.realElementToVirtualElement.set(node, virtualElement);\n return virtualElement;\n }\n\n private getFirstNonIgnoredPreviousSibling(node: Element | Text): Element | Text | null {\n let currentNode = node;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n while (currentNode && currentNode.previousSibling) {\n currentNode = currentNode.previousSibling as Element | Text;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n }\n return null;\n }\n\n private getVirtualDOMElementForRealElementOrThrow(\n realElement: Element | Text,\n ): LiveVirtualDOMElement {\n const virtualElement = this.realElementToVirtualElement.get(realElement);\n if (!virtualElement) {\n throw new Error(`Virtual element not found for real element`);\n }\n return virtualElement;\n }\n\n private isIgnoredElement(node: Element | Text): boolean {\n if (this.ignoreTextNodes && node instanceof this.domRunner.getWindow().Text) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().HTMLScriptElement) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().Comment) {\n return true;\n }\n return false;\n }\n\n private isIgnoredAttribute(node: Element | Text, attributeName: string): boolean {\n return attributeName.startsWith(\"on\");\n }\n\n public dispatchRemoteEventFromConnectionId(connectionId: number, remoteEvent: RemoteEvent): void {\n const domNode = this.nodeIdToNode.get(remoteEvent.nodeId);\n if (!domNode) {\n console.error(\"Unknown node ID in remote event: \" + remoteEvent.nodeId);\n return;\n }\n\n if (domNode instanceof this.domRunner.getWindow().Text) {\n console.warn(\"Cannot dispatch remote event to text node\");\n return;\n }\n\n this.domRunner.dispatchRemoteEventFromConnectionId(\n connectionId,\n domNode.realElement as Element,\n remoteEvent,\n );\n }\n\n public dispose() {\n clearInterval(this.documentTimeIntervalTimer);\n this.domRunner.dispose();\n }\n\n private getDocumentTime() {\n return this.domRunner.getDocumentTime();\n }\n}\n", "import vm from \"vm\";\n\nimport { LogMessage, RemoteEvent } from \"@mml-io/observable-dom-common\";\nimport { AbortablePromise, DOMWindow, JSDOM, ResourceLoader, VirtualConsole } from \"jsdom\";\nimport * as nodeFetch from \"node-fetch\";\nimport nodeFetchFn from \"node-fetch\";\n\nimport { DOMRunnerFactory, DOMRunnerInterface, DOMRunnerMessage } from \"./ObservableDOM\";\n\nconst ErrDOMWindowNotInitialized = \"DOMWindow not initialized\";\n\nexport const JSDOMRunnerFactory: DOMRunnerFactory = (\n htmlPath: string,\n htmlContents: string,\n params: object,\n callback: (mutationList: DOMRunnerMessage) => void,\n): DOMRunnerInterface => {\n return new JSDOMRunner(htmlPath, htmlContents, params, callback);\n};\n\n// This is used to stop JSDOM trying to load resources\nclass RejectionResourceLoader extends ResourceLoader {\n public fetch(url: string): AbortablePromise<Buffer> | null {\n console.error(\"RejectionResourceLoader.fetch\", url);\n return null;\n }\n}\n\nexport class JSDOMRunner {\n public domWindow: DOMWindow | null = null;\n private jsdom: JSDOM;\n\n private callback: (message: DOMRunnerMessage) => void;\n private mutationObserver: MutationObserver | null = null;\n private htmlPath: string;\n\n private documentStartTime = Date.now();\n\n private isLoaded = false;\n private logBuffer: LogMessage[] = [];\n\n constructor(\n htmlPath: string,\n htmlContents: string,\n params: object,\n callback: (domRunnerMessage: DOMRunnerMessage) => void,\n ) {\n this.htmlPath = htmlPath;\n this.callback = callback;\n\n this.jsdom = new JSDOM(htmlContents, {\n runScripts: \"dangerously\",\n resources: new RejectionResourceLoader(),\n url: this.htmlPath,\n virtualConsole: this.createVirtualConsole(),\n beforeParse: (window) => {\n this.domWindow = window;\n\n this.domWindow.fetch = nodeFetchFn as unknown as typeof fetch;\n this.domWindow.Headers = nodeFetch.Headers as unknown as typeof Headers;\n this.domWindow.Request = nodeFetch.Request as unknown as typeof Request;\n this.domWindow.Response = nodeFetch.Response as unknown as typeof Response;\n\n // This is a polyfill for https://developer.mozilla.org/en-US/docs/Web/API/Document/timeline\n const timeline = {};\n Object.defineProperty(timeline, \"currentTime\", {\n get: () => {\n return this.getDocumentTime();\n },\n });\n (window.document as any).timeline = timeline;\n\n // JSON stringify and parse to avoid potential reference leaks from the params object\n window.params = JSON.parse(JSON.stringify(params));\n\n this.mutationObserver = new window.MutationObserver((mutationList) => {\n this.callback({\n mutationList,\n });\n });\n\n window.addEventListener(\"load\", () => {\n this.mutationObserver?.observe(window.document, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n this.isLoaded = true;\n\n this.callback({\n loaded: true,\n });\n\n this.flushLogBuffer();\n });\n },\n });\n }\n\n private flushLogBuffer() {\n for (const logMessage of this.logBuffer) {\n this.callback({\n logMessage,\n });\n }\n\n this.logBuffer = [];\n }\n\n private log(message: LogMessage) {\n if (!this.isLoaded) {\n this.logBuffer.push(message);\n return;\n }\n\n this.callback({\n logMessage: message,\n });\n }\n\n public getDocument(): Document {\n if (!this.domWindow) {\n throw new Error(ErrDOMWindowNotInitialized);\n }\n\n return this.domWindow.document;\n }\n\n public getWindow(): any {\n return this.domWindow;\n }\n\n public dispose() {\n const records = this.mutationObserver?.takeRecords();\n this.callback({\n mutationList: records,\n });\n this.mutationObserver?.disconnect();\n this.jsdom.window.close();\n }\n\n public getDocumentTime() {\n return Date.now() - this.documentStartTime;\n }\n\n public dispatchRemoteEventFromConnectionId(\n connectionId: number,\n domNode: Element,\n remoteEvent: RemoteEvent,\n ) {\n if (!this.domWindow) {\n throw new Error(ErrDOMWindowNotInitialized);\n }\n\n const bubbles = remoteEvent.bubbles || false;\n const remoteEventObject = new this.domWindow.CustomEvent(remoteEvent.name, {\n bubbles,\n detail: { ...remoteEvent.params, connectionId },\n });\n\n const eventTypeLowerCase = remoteEvent.name.toLowerCase();\n\n // TODO - check if there are other events that automatically wire up similarly to click->onclick and avoid those too\n if (eventTypeLowerCase !== \"click\") {\n const handlerAttributeName = \"on\" + eventTypeLowerCase;\n const handlerAttributeValue = domNode.getAttribute(handlerAttributeName);\n if (handlerAttributeValue) {\n // This event is defined as an HTML event attribute.\n const script = handlerAttributeValue;\n const vmContext = this.jsdom.getInternalVMContext();\n try {\n const invoke = vm.runInContext(`(function(event){ ${script} })`, vmContext);\n Reflect.apply(invoke, domNode, [remoteEventObject]);\n } catch (e) {\n console.error(\"Error running event handler:\", e);\n }\n }\n }\n\n // Dispatch the event via JavaScript.\n domNode.dispatchEvent(remoteEventObject);\n }\n\n private createVirtualConsole(): VirtualConsole {\n const virtualConsole = new VirtualConsole();\n virtualConsole.on(\"jsdomError\", (...args) => {\n this.log({\n level: \"system\",\n content: args,\n });\n });\n virtualConsole.on(\"error\", (...args) => {\n this.log({\n level: \"error\",\n content: args,\n });\n });\n virtualConsole.on(\"warn\", (...args) => {\n this.log({\n level: \"warn\",\n content: args,\n });\n });\n virtualConsole.on(\"log\", (...args) => {\n this.log({\n level: \"log\",\n content: args,\n });\n });\n virtualConsole.on(\"info\", (...args) => {\n this.log({\n level: \"info\",\n content: args,\n });\n });\n return virtualConsole;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
7
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@mml-io/observable-dom",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
7
  "main": "./build/index.js",
8
8
  "types": "./build/index.d.ts",
9
+ "type": "module",
9
10
  "files": [
10
11
  "/build"
11
12
  ],
@@ -13,17 +14,18 @@
13
14
  "type-check": "tsc --noEmit",
14
15
  "build": "tsx ./build.ts --build",
15
16
  "iterate": "tsx ./build.ts --watch",
16
- "lint": "eslint \"./src/**/*.{js,jsx,ts,tsx}\" --max-warnings 0",
17
- "lint-fix": "eslint \"./src/**/*.{js,jsx,ts,tsx}\" --fix"
17
+ "lint": "eslint \"./{src,test}/**/*.{js,jsx,ts,tsx}\" --max-warnings 0",
18
+ "lint-fix": "eslint \"./{src,test}/**/*.{js,jsx,ts,tsx}\" --fix",
19
+ "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest"
18
20
  },
19
21
  "dependencies": {
20
- "@mml-io/observable-dom-common": "^0.6.2",
22
+ "@mml-io/observable-dom-common": "^0.7.0",
21
23
  "jsdom": "22.1.0",
22
24
  "node-fetch": "2.6.12"
23
25
  },
24
26
  "devDependencies": {
25
- "@types/jsdom": "21.1.1",
27
+ "@types/jsdom": "^21.1.2",
26
28
  "@types/node-fetch": "2.6.4"
27
29
  },
28
- "gitHead": "0ac70ab8ff9164c5dc2b9541ff7319a94ebaccf4"
30
+ "gitHead": "aa75274d1ee99afdb8d5ff7432cb57c23d09186e"
29
31
  }