@mml-io/observable-dom 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
@@ -31,23 +31,23 @@ var src_exports = {};
31
31
  __export(src_exports, {
32
32
  JSDOMRunner: () => JSDOMRunner,
33
33
  JSDOMRunnerFactory: () => JSDOMRunnerFactory,
34
- ObservableDom: () => ObservableDom
34
+ ObservableDOM: () => ObservableDOM
35
35
  });
36
36
  module.exports = __toCommonJS(src_exports);
37
37
 
38
38
  // src/utils.ts
39
- function virtualDomElementToStatic(el) {
39
+ function virtualDOMElementToStatic(el) {
40
40
  return {
41
41
  nodeId: el.nodeId,
42
42
  tag: el.tag,
43
43
  attributes: el.attributes,
44
- childNodes: el.childNodes.map((child) => virtualDomElementToStatic(child)),
44
+ childNodes: el.childNodes.map((child) => virtualDOMElementToStatic(child)),
45
45
  textContent: el.textContent
46
46
  };
47
47
  }
48
48
 
49
- // src/ObservableDom.ts
50
- var ObservableDom = class {
49
+ // src/ObservableDOM.ts
50
+ var ObservableDOM = class {
51
51
  constructor(observableDOMParameters, callback, runnerFactory) {
52
52
  this.nodeToNodeId = /* @__PURE__ */ new Map();
53
53
  this.nodeIdToNode = /* @__PURE__ */ new Map();
@@ -58,9 +58,12 @@ var ObservableDom = class {
58
58
  this.ignoreTextNodes = observableDOMParameters.ignoreTextNodes;
59
59
  this.callback = callback;
60
60
  this.documentTimeIntervalTimer = setInterval(() => {
61
- this.callback({
62
- documentTime: this.getDocumentTime()
63
- });
61
+ this.callback(
62
+ {
63
+ documentTime: this.getDocumentTime()
64
+ },
65
+ this
66
+ );
64
67
  }, observableDOMParameters.pingIntervalMilliseconds || 5e3);
65
68
  this.domRunner = runnerFactory(
66
69
  observableDOMParameters.htmlPath,
@@ -68,33 +71,36 @@ var ObservableDom = class {
68
71
  observableDOMParameters.params,
69
72
  (domRunnerMessage) => {
70
73
  if (domRunnerMessage.loaded) {
71
- this.createVirtualDomElementWithChildren(
74
+ this.createVirtualDOMElementWithChildren(
72
75
  this.domRunner.getDocument(),
73
76
  null
74
77
  );
75
- const snapshot = virtualDomElementToStatic(
76
- this.getVirtualDomElementForRealElementOrThrow(
78
+ const snapshot = virtualDOMElementToStatic(
79
+ this.getVirtualDOMElementForRealElementOrThrow(
77
80
  this.domRunner.getDocument()
78
81
  )
79
82
  );
80
- this.callback({
81
- snapshot,
82
- documentTime: this.getDocumentTime()
83
- });
83
+ this.callback(
84
+ {
85
+ snapshot,
86
+ documentTime: this.getDocumentTime()
87
+ },
88
+ this
89
+ );
84
90
  } else if (domRunnerMessage.mutationList) {
85
91
  this.processModificationList(domRunnerMessage.mutationList);
86
92
  } else if (domRunnerMessage.logMessage) {
87
- this.callback({
88
- logMessage: domRunnerMessage.logMessage,
89
- documentTime: this.getDocumentTime()
90
- });
93
+ this.callback(
94
+ {
95
+ logMessage: domRunnerMessage.logMessage,
96
+ documentTime: this.getDocumentTime()
97
+ },
98
+ this
99
+ );
91
100
  }
92
101
  }
93
102
  );
94
103
  }
95
- addIPCWebsocket(webSocket) {
96
- return this.domRunner.addIPCWebsocket(webSocket);
97
- }
98
104
  addConnectedUserId(connectionId) {
99
105
  this.domRunner.getWindow().dispatchEvent(
100
106
  new (this.domRunner.getWindow()).CustomEvent("connected", {
@@ -111,8 +117,8 @@ var ObservableDom = class {
111
117
  }
112
118
  processModificationList(mutationList) {
113
119
  const documentEl = this.domRunner.getDocument();
114
- const documentVirtualDomElement = this.realElementToVirtualElement.get(documentEl);
115
- if (!documentVirtualDomElement) {
120
+ const documentVirtualDOMElement = this.realElementToVirtualElement.get(documentEl);
121
+ if (!documentVirtualDOMElement) {
116
122
  throw new Error(`document not created in processModificationList`);
117
123
  }
118
124
  if (mutationList.length > 1) {
@@ -130,7 +136,7 @@ var ObservableDom = class {
130
136
  }
131
137
  this.addKnownNodesInMutation(mutation);
132
138
  const firstNonIgnoredPreviousSibling = mutation.previousSibling ? this.getFirstNonIgnoredPreviousSibling(mutation.previousSibling) : null;
133
- const targetElement = this.getVirtualDomElementForRealElementOrThrow(
139
+ const targetElement = this.getVirtualDOMElementForRealElementOrThrow(
134
140
  mutation.target
135
141
  );
136
142
  const addedNodes = [];
@@ -138,43 +144,46 @@ var ObservableDom = class {
138
144
  if (this.isIgnoredElement(node)) {
139
145
  continue;
140
146
  }
141
- const virtualDomElement = this.getVirtualDomElementForRealElementOrThrow(
147
+ const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(
142
148
  node
143
149
  );
144
- addedNodes.push(virtualDomElementToStatic(virtualDomElement));
150
+ addedNodes.push(virtualDOMElementToStatic(virtualDOMElement));
145
151
  }
146
152
  const removedNodeIds = [];
147
153
  for (const node of mutation.removedNodes) {
148
154
  if (this.isIgnoredElement(node)) {
149
155
  continue;
150
156
  }
151
- const virtualDomElement = this.getVirtualDomElementForRealElementOrThrow(
157
+ const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(
152
158
  node
153
159
  );
154
- removedNodeIds.push(virtualDomElement.nodeId);
160
+ removedNodeIds.push(virtualDOMElement.nodeId);
155
161
  }
156
162
  const mutationRecord = {
157
163
  type: mutation.type,
158
164
  targetId: targetElement.nodeId,
159
165
  addedNodes,
160
166
  removedNodeIds,
161
- previousSiblingId: firstNonIgnoredPreviousSibling !== null ? this.getVirtualDomElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId : null,
167
+ previousSiblingId: firstNonIgnoredPreviousSibling !== null ? this.getVirtualDOMElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId : null,
162
168
  attribute: mutation.attributeName ? {
163
169
  attributeName: mutation.attributeName,
164
170
  value: mutation.target.getAttribute(mutation.attributeName)
165
171
  } : null
166
172
  };
167
- this.callback({
168
- mutation: mutationRecord,
169
- documentTime: this.getDocumentTime()
170
- });
173
+ this.callback(
174
+ {
175
+ mutation: mutationRecord,
176
+ documentTime: this.getDocumentTime()
177
+ },
178
+ this
179
+ );
171
180
  this.removeKnownNodesInMutation(mutation);
172
181
  }
173
182
  }
174
183
  addKnownNodesInMutation(mutation) {
175
184
  const targetNode = mutation.target;
176
- const virtualDomElement = this.realElementToVirtualElement.get(targetNode);
177
- if (!virtualDomElement) {
185
+ const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);
186
+ if (!virtualDOMElement) {
178
187
  throw new Error(
179
188
  "Unknown node in addKnownNodesInMutation:" + targetNode + "," + mutation.type
180
189
  );
@@ -192,7 +201,7 @@ var ObservableDom = class {
192
201
  if (!previousSiblingElement) {
193
202
  throw new Error("Unknown previous sibling");
194
203
  }
195
- index = virtualDomElement.childNodes.indexOf(previousSiblingElement);
204
+ index = virtualDOMElement.childNodes.indexOf(previousSiblingElement);
196
205
  if (index === -1) {
197
206
  throw new Error("Previous sibling is not currently a child of the parent element");
198
207
  }
@@ -200,13 +209,13 @@ var ObservableDom = class {
200
209
  }
201
210
  mutation.addedNodes.forEach((node) => {
202
211
  const asElementOrText = node;
203
- const childVirtualDomElement = this.createVirtualDomElementWithChildren(
212
+ const childVirtualDOMElement = this.createVirtualDOMElementWithChildren(
204
213
  asElementOrText,
205
- virtualDomElement
214
+ virtualDOMElement
206
215
  );
207
- if (childVirtualDomElement) {
208
- if (virtualDomElement.childNodes.indexOf(childVirtualDomElement) === -1) {
209
- virtualDomElement.childNodes.splice(index, 0, childVirtualDomElement);
216
+ if (childVirtualDOMElement) {
217
+ if (virtualDOMElement.childNodes.indexOf(childVirtualDOMElement) === -1) {
218
+ virtualDOMElement.childNodes.splice(index, 0, childVirtualDOMElement);
210
219
  index++;
211
220
  }
212
221
  }
@@ -218,18 +227,18 @@ var ObservableDom = class {
218
227
  }
219
228
  const attributeValue = targetNode.getAttribute(attributeName);
220
229
  if (attributeValue === null) {
221
- delete virtualDomElement.attributes[attributeName];
230
+ delete virtualDOMElement.attributes[attributeName];
222
231
  } else {
223
- virtualDomElement.attributes[attributeName] = attributeValue;
232
+ virtualDOMElement.attributes[attributeName] = attributeValue;
224
233
  }
225
234
  } else if (mutation.type === "characterData") {
226
- virtualDomElement.textContent = targetNode.textContent ? targetNode.textContent : void 0;
235
+ virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : void 0;
227
236
  }
228
237
  }
229
238
  removeKnownNodesInMutation(mutation) {
230
239
  const targetNode = mutation.target;
231
- const virtualDomElement = this.realElementToVirtualElement.get(targetNode);
232
- if (!virtualDomElement) {
240
+ const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);
241
+ if (!virtualDOMElement) {
233
242
  throw new Error("Unknown node in mutation list:" + targetNode + ", " + mutation.type);
234
243
  }
235
244
  if (mutation.type === "childList") {
@@ -238,36 +247,36 @@ var ObservableDom = class {
238
247
  if (this.isIgnoredElement(asElementOrText)) {
239
248
  continue;
240
249
  }
241
- const childDomElement = this.realElementToVirtualElement.get(asElementOrText);
242
- if (!childDomElement) {
250
+ const childDOMElement = this.realElementToVirtualElement.get(asElementOrText);
251
+ if (!childDOMElement) {
243
252
  console.warn(this.htmlPath, "Unknown node in removeKnownNodesInMutation");
244
253
  continue;
245
254
  } else {
246
- this.removeVirtualDomElement(childDomElement);
247
- const index = virtualDomElement.childNodes.indexOf(childDomElement);
248
- virtualDomElement.childNodes.splice(index, 1);
255
+ this.removeVirtualDOMElement(childDOMElement);
256
+ const index = virtualDOMElement.childNodes.indexOf(childDOMElement);
257
+ virtualDOMElement.childNodes.splice(index, 1);
249
258
  }
250
259
  }
251
260
  return;
252
261
  }
253
262
  }
254
- removeVirtualDomElement(virtualDomElement) {
255
- this.nodeIdToNode.delete(virtualDomElement.nodeId);
256
- this.nodeToNodeId.delete(virtualDomElement);
257
- this.realElementToVirtualElement.delete(virtualDomElement.realElement);
258
- for (const child of virtualDomElement.childNodes) {
259
- this.removeVirtualDomElement(child);
263
+ removeVirtualDOMElement(virtualDOMElement) {
264
+ this.nodeIdToNode.delete(virtualDOMElement.nodeId);
265
+ this.nodeToNodeId.delete(virtualDOMElement);
266
+ this.realElementToVirtualElement.delete(virtualDOMElement.realElement);
267
+ for (const child of virtualDOMElement.childNodes) {
268
+ this.removeVirtualDOMElement(child);
260
269
  }
261
270
  }
262
- createVirtualDomElementWithChildren(node, parent) {
263
- const virtualElement = this.createVirtualDomElement(node, parent);
271
+ createVirtualDOMElementWithChildren(node, parent) {
272
+ const virtualElement = this.createVirtualDOMElement(node, parent);
264
273
  if (!virtualElement) {
265
274
  return null;
266
275
  }
267
276
  if (node.childNodes) {
268
277
  for (let i = 0; i < node.childNodes.length; i++) {
269
278
  const child = node.childNodes[i];
270
- const childVirtualElement = this.createVirtualDomElementWithChildren(
279
+ const childVirtualElement = this.createVirtualDOMElementWithChildren(
271
280
  child,
272
281
  virtualElement
273
282
  );
@@ -278,7 +287,7 @@ var ObservableDom = class {
278
287
  }
279
288
  return virtualElement;
280
289
  }
281
- createVirtualDomElement(node, parent) {
290
+ createVirtualDOMElement(node, parent) {
282
291
  if (this.isIgnoredElement(node)) {
283
292
  return null;
284
293
  }
@@ -332,7 +341,7 @@ var ObservableDom = class {
332
341
  }
333
342
  return null;
334
343
  }
335
- getVirtualDomElementForRealElementOrThrow(realElement) {
344
+ getVirtualDOMElementForRealElementOrThrow(realElement) {
336
345
  const virtualElement = this.realElementToVirtualElement.get(realElement);
337
346
  if (!virtualElement) {
338
347
  throw new Error(`Virtual element not found for real element`);
@@ -382,7 +391,7 @@ var import_vm = __toESM(require("vm"));
382
391
  var import_jsdom = require("jsdom");
383
392
  var nodeFetch = __toESM(require("node-fetch"));
384
393
  var import_node_fetch = __toESM(require("node-fetch"));
385
- var ErrDomWindowNotInitialized = "DOMWindow not initialized";
394
+ var ErrDOMWindowNotInitialized = "DOMWindow not initialized";
386
395
  var monkeyPatchedMutationRecordCallbacks = /* @__PURE__ */ new Set();
387
396
  function installMutationObserverMonkeyPatch() {
388
397
  const MutationRecordExports = require("jsdom/lib/jsdom/living/generated/MutationRecord");
@@ -406,10 +415,8 @@ var RejectionResourceLoader = class extends import_jsdom.ResourceLoader {
406
415
  };
407
416
  var JSDOMRunner = class {
408
417
  constructor(htmlPath, htmlContents, params, callback) {
409
- this.ipcWebsockets = /* @__PURE__ */ new Set();
410
418
  this.domWindow = null;
411
419
  this.mutationObserver = null;
412
- this.ipcListeners = /* @__PURE__ */ new Set();
413
420
  this.documentStartTime = Date.now();
414
421
  this.isLoaded = false;
415
422
  this.logBuffer = [];
@@ -433,7 +440,7 @@ var JSDOMRunner = class {
433
440
  }
434
441
  };
435
442
  monkeyPatchedMutationRecordCallbacks.add(this.monkeyPatchMutationRecordCallback);
436
- this.jsDom = new import_jsdom.JSDOM(htmlContents, {
443
+ this.jsdom = new import_jsdom.JSDOM(htmlContents, {
437
444
  runScripts: "dangerously",
438
445
  resources: new RejectionResourceLoader(),
439
446
  url: this.htmlPath,
@@ -452,22 +459,6 @@ var JSDOMRunner = class {
452
459
  });
453
460
  window.document.timeline = timeline;
454
461
  window.params = JSON.parse(JSON.stringify(params));
455
- const oldDocumentAddEventListener = window.document.addEventListener;
456
- window.document.addEventListener = (...args) => {
457
- const [eventName, listener] = args;
458
- if (eventName === "ipc") {
459
- this.ipcListeners.add(listener);
460
- }
461
- return oldDocumentAddEventListener.call(window.document, ...args);
462
- };
463
- const oldDocumentRemoveEventListener = window.document.addEventListener;
464
- window.document.removeEventListener = (...args) => {
465
- const [eventName, listener] = args;
466
- if (eventName === "ipc") {
467
- this.ipcListeners.delete(listener);
468
- }
469
- return oldDocumentRemoveEventListener.call(window.document, ...args);
470
- };
471
462
  this.mutationObserver = new window.MutationObserver((mutationList) => {
472
463
  this.callback({
473
464
  mutationList
@@ -509,36 +500,13 @@ var JSDOMRunner = class {
509
500
  }
510
501
  getDocument() {
511
502
  if (!this.domWindow) {
512
- throw new Error(ErrDomWindowNotInitialized);
503
+ throw new Error(ErrDOMWindowNotInitialized);
513
504
  }
514
505
  return this.domWindow.document;
515
506
  }
516
507
  getWindow() {
517
508
  return this.domWindow;
518
509
  }
519
- addIPCWebsocket(webSocket) {
520
- if (!this.domWindow) {
521
- throw new Error(ErrDomWindowNotInitialized);
522
- }
523
- if (this.ipcListeners.size === 0) {
524
- console.error("ipc requested, but no ipc listeners registered on document:", this.htmlPath);
525
- webSocket.close();
526
- return;
527
- }
528
- this.ipcWebsockets.add(webSocket);
529
- const event = new this.domWindow.CustomEvent("ipc", {
530
- detail: {
531
- webSocket
532
- }
533
- });
534
- for (const ipcListener of this.ipcListeners) {
535
- ipcListener(event);
536
- }
537
- webSocket.addEventListener("close", () => {
538
- this.ipcWebsockets.delete(webSocket);
539
- });
540
- return;
541
- }
542
510
  dispose() {
543
511
  var _a, _b;
544
512
  const records = (_a = this.mutationObserver) == null ? void 0 : _a.takeRecords();
@@ -547,14 +515,14 @@ var JSDOMRunner = class {
547
515
  });
548
516
  monkeyPatchedMutationRecordCallbacks.delete(this.monkeyPatchMutationRecordCallback);
549
517
  (_b = this.mutationObserver) == null ? void 0 : _b.disconnect();
550
- this.jsDom.window.close();
518
+ this.jsdom.window.close();
551
519
  }
552
520
  getDocumentTime() {
553
521
  return Date.now() - this.documentStartTime;
554
522
  }
555
523
  dispatchRemoteEventFromConnectionId(connectionId, domNode, remoteEvent) {
556
524
  if (!this.domWindow) {
557
- throw new Error(ErrDomWindowNotInitialized);
525
+ throw new Error(ErrDOMWindowNotInitialized);
558
526
  }
559
527
  const bubbles = remoteEvent.bubbles || false;
560
528
  const remoteEventObject = new this.domWindow.CustomEvent(remoteEvent.name, {
@@ -567,7 +535,7 @@ var JSDOMRunner = class {
567
535
  const handlerAttributeValue = domNode.getAttribute(handlerAttributeName);
568
536
  if (handlerAttributeValue) {
569
537
  const script = handlerAttributeValue;
570
- const vmContext = this.jsDom.getInternalVMContext();
538
+ const vmContext = this.jsdom.getInternalVMContext();
571
539
  try {
572
540
  const invoke = import_vm.default.runInContext(`(function(event){ ${script} })`, vmContext);
573
541
  Reflect.apply(invoke, domNode, [remoteEventObject]);
@@ -617,6 +585,6 @@ var JSDOMRunner = class {
617
585
  0 && (module.exports = {
618
586
  JSDOMRunner,
619
587
  JSDOMRunnerFactory,
620
- ObservableDom
588
+ ObservableDOM
621
589
  });
622
590
  //# 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 addIPCWebsocket(webSocket: WebSocket): void;\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) => void;\n private nextNodeId = 1;\n private htmlPath: string;\n private domRunner: DOMRunnerInterface;\n\n private documentTimeIntervalTimer: NodeJS.Timer;\n\n constructor(\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDomMessage) => 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 documentTime: this.getDocumentTime(),\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 snapshot,\n documentTime: this.getDocumentTime(),\n });\n } else if (domRunnerMessage.mutationList) {\n this.processModificationList(domRunnerMessage.mutationList);\n } else if (domRunnerMessage.logMessage) {\n this.callback({\n logMessage: domRunnerMessage.logMessage,\n documentTime: this.getDocumentTime(),\n });\n }\n },\n );\n }\n\n public addIPCWebsocket(webSocket: WebSocket) {\n return this.domRunner.addIPCWebsocket(webSocket);\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 - walk back through the records to derive the intermediate states (e.g. if an attribute is later added to\n // an element created in an earlier record then it should not have that attribute when the element is added.\n // This is important as incorrect attribute sets can affect visibility and expected client performance.\n console.error(\n \"More than one mutation record received. It is possible that intermediate states are incorrect.\",\n );\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 mutation: mutationRecord,\n documentTime: this.getDocumentTime(),\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 private ipcWebsockets = new Set<WebSocket>();\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 private ipcListeners = new Set<(event: any) => void>();\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 const oldDocumentAddEventListener = window.document.addEventListener;\n window.document.addEventListener = (...args: [string, EventListener, ...any[]]) => {\n const [eventName, listener] = args;\n if (eventName === \"ipc\") {\n this.ipcListeners.add(listener);\n }\n return oldDocumentAddEventListener.call(window.document, ...args);\n };\n\n const oldDocumentRemoveEventListener = window.document.addEventListener;\n window.document.removeEventListener = (...args: [string, EventListener, ...any[]]) => {\n const [eventName, listener] = args;\n if (eventName === \"ipc\") {\n this.ipcListeners.delete(listener);\n }\n return oldDocumentRemoveEventListener.call(window.document, ...args);\n };\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 addIPCWebsocket(webSocket: WebSocket) {\n if (!this.domWindow) {\n throw new Error(ErrDomWindowNotInitialized);\n }\n if (this.ipcListeners.size === 0) {\n console.error(\"ipc requested, but no ipc listeners registered on document:\", this.htmlPath);\n webSocket.close();\n return;\n }\n this.ipcWebsockets.add(webSocket);\n const event = new this.domWindow.CustomEvent(\"ipc\", {\n detail: {\n webSocket,\n },\n });\n for (const ipcListener of this.ipcListeners) {\n ipcListener(event);\n }\n webSocket.addEventListener(\"close\", () => {\n this.ipcWebsockets.delete(webSocket);\n });\n return;\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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",
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.Timer;\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 - walk back through the records to derive the intermediate states (e.g. if an attribute is later added to\n // an element created in an earlier record then it should not have that attribute when the element is added.\n // This is important as incorrect attribute sets can affect visibility and expected client performance.\n console.error(\n \"More than one mutation record received. It is possible that intermediate states are incorrect.\",\n );\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
6
  "names": ["nodeFetchFn", "vm"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mml-io/observable-dom",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "files": [
@@ -16,7 +16,7 @@
16
16
  "lint-fix": "eslint \"./src/**/*.{js,jsx,ts,tsx}\" --fix"
17
17
  },
18
18
  "dependencies": {
19
- "@mml-io/observable-dom-common": "^0.1.3",
19
+ "@mml-io/observable-dom-common": "^0.2.0",
20
20
  "jsdom": "22.1.0",
21
21
  "node-fetch": "2.6.11"
22
22
  },
@@ -5,9 +5,9 @@ import { AbortablePromise, DOMWindow, JSDOM, ResourceLoader, VirtualConsole } fr
5
5
  import * as nodeFetch from "node-fetch";
6
6
  import nodeFetchFn from "node-fetch";
7
7
 
8
- import { DOMRunnerFactory, DOMRunnerInterface, DOMRunnerMessage } from "./ObservableDom";
8
+ import { DOMRunnerFactory, DOMRunnerInterface, DOMRunnerMessage } from "./ObservableDOM";
9
9
 
10
- const ErrDomWindowNotInitialized = "DOMWindow not initialized";
10
+ const ErrDOMWindowNotInitialized = "DOMWindow not initialized";
11
11
 
12
12
  // TODO - remove this monkeypatching if it's possible to avoid the race conditions in naive MutationObserver usage
13
13
  const monkeyPatchedMutationRecordCallbacks = new Set<() => void>();
@@ -57,15 +57,12 @@ class RejectionResourceLoader extends ResourceLoader {
57
57
  export class JSDOMRunner {
58
58
  private monkeyPatchMutationRecordCallback: () => void;
59
59
 
60
- private ipcWebsockets = new Set<WebSocket>();
61
-
62
60
  public domWindow: DOMWindow | null = null;
63
- private jsDom: JSDOM;
61
+ private jsdom: JSDOM;
64
62
 
65
63
  private callback: (message: DOMRunnerMessage) => void;
66
64
  private mutationObserver: MutationObserver | null = null;
67
65
  private htmlPath: string;
68
- private ipcListeners = new Set<(event: any) => void>();
69
66
 
70
67
  private documentStartTime = Date.now();
71
68
 
@@ -104,7 +101,7 @@ export class JSDOMRunner {
104
101
  };
105
102
  monkeyPatchedMutationRecordCallbacks.add(this.monkeyPatchMutationRecordCallback);
106
103
 
107
- this.jsDom = new JSDOM(htmlContents, {
104
+ this.jsdom = new JSDOM(htmlContents, {
108
105
  runScripts: "dangerously",
109
106
  resources: new RejectionResourceLoader(),
110
107
  url: this.htmlPath,
@@ -129,24 +126,6 @@ export class JSDOMRunner {
129
126
  // JSON stringify and parse to avoid potential reference leaks from the params object
130
127
  window.params = JSON.parse(JSON.stringify(params));
131
128
 
132
- const oldDocumentAddEventListener = window.document.addEventListener;
133
- window.document.addEventListener = (...args: [string, EventListener, ...any[]]) => {
134
- const [eventName, listener] = args;
135
- if (eventName === "ipc") {
136
- this.ipcListeners.add(listener);
137
- }
138
- return oldDocumentAddEventListener.call(window.document, ...args);
139
- };
140
-
141
- const oldDocumentRemoveEventListener = window.document.addEventListener;
142
- window.document.removeEventListener = (...args: [string, EventListener, ...any[]]) => {
143
- const [eventName, listener] = args;
144
- if (eventName === "ipc") {
145
- this.ipcListeners.delete(listener);
146
- }
147
- return oldDocumentRemoveEventListener.call(window.document, ...args);
148
- };
149
-
150
129
  this.mutationObserver = new window.MutationObserver((mutationList) => {
151
130
  this.callback({
152
131
  mutationList,
@@ -196,7 +175,7 @@ export class JSDOMRunner {
196
175
 
197
176
  public getDocument(): Document {
198
177
  if (!this.domWindow) {
199
- throw new Error(ErrDomWindowNotInitialized);
178
+ throw new Error(ErrDOMWindowNotInitialized);
200
179
  }
201
180
 
202
181
  return this.domWindow.document;
@@ -206,30 +185,6 @@ export class JSDOMRunner {
206
185
  return this.domWindow;
207
186
  }
208
187
 
209
- public addIPCWebsocket(webSocket: WebSocket) {
210
- if (!this.domWindow) {
211
- throw new Error(ErrDomWindowNotInitialized);
212
- }
213
- if (this.ipcListeners.size === 0) {
214
- console.error("ipc requested, but no ipc listeners registered on document:", this.htmlPath);
215
- webSocket.close();
216
- return;
217
- }
218
- this.ipcWebsockets.add(webSocket);
219
- const event = new this.domWindow.CustomEvent("ipc", {
220
- detail: {
221
- webSocket,
222
- },
223
- });
224
- for (const ipcListener of this.ipcListeners) {
225
- ipcListener(event);
226
- }
227
- webSocket.addEventListener("close", () => {
228
- this.ipcWebsockets.delete(webSocket);
229
- });
230
- return;
231
- }
232
-
233
188
  public dispose() {
234
189
  const records = this.mutationObserver?.takeRecords();
235
190
  this.callback({
@@ -237,7 +192,7 @@ export class JSDOMRunner {
237
192
  });
238
193
  monkeyPatchedMutationRecordCallbacks.delete(this.monkeyPatchMutationRecordCallback);
239
194
  this.mutationObserver?.disconnect();
240
- this.jsDom.window.close();
195
+ this.jsdom.window.close();
241
196
  }
242
197
 
243
198
  public getDocumentTime() {
@@ -250,7 +205,7 @@ export class JSDOMRunner {
250
205
  remoteEvent: RemoteEvent,
251
206
  ) {
252
207
  if (!this.domWindow) {
253
- throw new Error(ErrDomWindowNotInitialized);
208
+ throw new Error(ErrDOMWindowNotInitialized);
254
209
  }
255
210
 
256
211
  const bubbles = remoteEvent.bubbles || false;
@@ -268,7 +223,7 @@ export class JSDOMRunner {
268
223
  if (handlerAttributeValue) {
269
224
  // This event is defined as an HTML event attribute.
270
225
  const script = handlerAttributeValue;
271
- const vmContext = this.jsDom.getInternalVMContext();
226
+ const vmContext = this.jsdom.getInternalVMContext();
272
227
  try {
273
228
  const invoke = vm.runInContext(`(function(event){ ${script} })`, vmContext);
274
229
  Reflect.apply(invoke, domNode, [remoteEventObject]);
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  LogMessage,
3
- ObservableDomInterface,
4
- ObservableDomMessage,
3
+ ObservableDOMInterface,
4
+ ObservableDOMMessage,
5
5
  ObservableDOMParameters,
6
6
  RemoteEvent,
7
- StaticVirtualDomElement,
8
- StaticVirtualDomMutationIdsRecord,
7
+ StaticVirtualDOMElement,
8
+ StaticVirtualDOMMutationIdsRecord,
9
9
  } from "@mml-io/observable-dom-common";
10
10
 
11
- import { virtualDomElementToStatic } from "./utils";
11
+ import { virtualDOMElementToStatic } from "./utils";
12
12
 
13
13
  export type DOMRunnerMessage = {
14
14
  loaded?: boolean;
@@ -24,7 +24,6 @@ export type DOMRunnerInterface = {
24
24
  HTMLScriptElement: typeof HTMLScriptElement;
25
25
  Comment: typeof Comment;
26
26
  }; // TODO - Define this without using JSDOM types
27
- addIPCWebsocket(webSocket: WebSocket): void;
28
27
  dispatchRemoteEventFromConnectionId(
29
28
  connectionId: number,
30
29
  realElement: Element,
@@ -41,18 +40,18 @@ export type DOMRunnerFactory = (
41
40
  callback: (domRunnerMessage: DOMRunnerMessage) => void,
42
41
  ) => DOMRunnerInterface;
43
42
 
44
- export type LiveVirtualDomElement = Omit<StaticVirtualDomElement, "childNodes"> & {
43
+ export type LiveVirtualDOMElement = Omit<StaticVirtualDOMElement, "childNodes"> & {
45
44
  realElement: Element | Text;
46
- childNodes: Array<LiveVirtualDomElement>;
47
- parent: LiveVirtualDomElement | null;
45
+ childNodes: Array<LiveVirtualDOMElement>;
46
+ parent: LiveVirtualDOMElement | null;
48
47
  };
49
48
 
50
- export class ObservableDom implements ObservableDomInterface {
51
- private nodeToNodeId = new Map<LiveVirtualDomElement, number>();
52
- private nodeIdToNode = new Map<number, LiveVirtualDomElement>();
53
- private realElementToVirtualElement = new Map<Element | Text, LiveVirtualDomElement>();
49
+ export class ObservableDOM implements ObservableDOMInterface {
50
+ private nodeToNodeId = new Map<LiveVirtualDOMElement, number>();
51
+ private nodeIdToNode = new Map<number, LiveVirtualDOMElement>();
52
+ private realElementToVirtualElement = new Map<Element | Text, LiveVirtualDOMElement>();
54
53
  private ignoreTextNodes = true;
55
- private callback: (message: ObservableDomMessage) => void;
54
+ private callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void;
56
55
  private nextNodeId = 1;
57
56
  private htmlPath: string;
58
57
  private domRunner: DOMRunnerInterface;
@@ -61,7 +60,7 @@ export class ObservableDom implements ObservableDomInterface {
61
60
 
62
61
  constructor(
63
62
  observableDOMParameters: ObservableDOMParameters,
64
- callback: (message: ObservableDomMessage) => void,
63
+ callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,
65
64
  runnerFactory: DOMRunnerFactory,
66
65
  ) {
67
66
  this.htmlPath = observableDOMParameters.htmlPath;
@@ -69,9 +68,12 @@ export class ObservableDom implements ObservableDomInterface {
69
68
  this.callback = callback;
70
69
 
71
70
  this.documentTimeIntervalTimer = setInterval(() => {
72
- this.callback({
73
- documentTime: this.getDocumentTime(),
74
- });
71
+ this.callback(
72
+ {
73
+ documentTime: this.getDocumentTime(),
74
+ },
75
+ this,
76
+ );
75
77
  }, observableDOMParameters.pingIntervalMilliseconds || 5000);
76
78
 
77
79
  this.domRunner = runnerFactory(
@@ -80,37 +82,39 @@ export class ObservableDom implements ObservableDomInterface {
80
82
  observableDOMParameters.params,
81
83
  (domRunnerMessage: DOMRunnerMessage) => {
82
84
  if (domRunnerMessage.loaded) {
83
- this.createVirtualDomElementWithChildren(
85
+ this.createVirtualDOMElementWithChildren(
84
86
  this.domRunner.getDocument() as unknown as Element,
85
87
  null,
86
88
  );
87
89
 
88
- const snapshot = virtualDomElementToStatic(
89
- this.getVirtualDomElementForRealElementOrThrow(
90
+ const snapshot = virtualDOMElementToStatic(
91
+ this.getVirtualDOMElementForRealElementOrThrow(
90
92
  this.domRunner.getDocument() as unknown as Element,
91
93
  ),
92
94
  );
93
95
 
94
- this.callback({
95
- snapshot,
96
- documentTime: this.getDocumentTime(),
97
- });
96
+ this.callback(
97
+ {
98
+ snapshot,
99
+ documentTime: this.getDocumentTime(),
100
+ },
101
+ this,
102
+ );
98
103
  } else if (domRunnerMessage.mutationList) {
99
104
  this.processModificationList(domRunnerMessage.mutationList);
100
105
  } else if (domRunnerMessage.logMessage) {
101
- this.callback({
102
- logMessage: domRunnerMessage.logMessage,
103
- documentTime: this.getDocumentTime(),
104
- });
106
+ this.callback(
107
+ {
108
+ logMessage: domRunnerMessage.logMessage,
109
+ documentTime: this.getDocumentTime(),
110
+ },
111
+ this,
112
+ );
105
113
  }
106
114
  },
107
115
  );
108
116
  }
109
117
 
110
- public addIPCWebsocket(webSocket: WebSocket) {
111
- return this.domRunner.addIPCWebsocket(webSocket);
112
- }
113
-
114
118
  public addConnectedUserId(connectionId: number): void {
115
119
  this.domRunner.getWindow().dispatchEvent(
116
120
  new (this.domRunner.getWindow().CustomEvent)("connected", {
@@ -129,8 +133,8 @@ export class ObservableDom implements ObservableDomInterface {
129
133
 
130
134
  private processModificationList(mutationList: Array<MutationRecord>): void {
131
135
  const documentEl = this.domRunner.getDocument() as unknown as Element;
132
- const documentVirtualDomElement = this.realElementToVirtualElement.get(documentEl);
133
- if (!documentVirtualDomElement) {
136
+ const documentVirtualDOMElement = this.realElementToVirtualElement.get(documentEl);
137
+ if (!documentVirtualDOMElement) {
134
138
  throw new Error(`document not created in processModificationList`);
135
139
  }
136
140
 
@@ -164,18 +168,18 @@ export class ObservableDom implements ObservableDomInterface {
164
168
  const firstNonIgnoredPreviousSibling = mutation.previousSibling
165
169
  ? this.getFirstNonIgnoredPreviousSibling(mutation.previousSibling as Element | Text)
166
170
  : null;
167
- const targetElement = this.getVirtualDomElementForRealElementOrThrow(
171
+ const targetElement = this.getVirtualDOMElementForRealElementOrThrow(
168
172
  mutation.target as Element | Text,
169
173
  );
170
- const addedNodes: Array<StaticVirtualDomElement> = [];
174
+ const addedNodes: Array<StaticVirtualDOMElement> = [];
171
175
  for (const node of mutation.addedNodes) {
172
176
  if (this.isIgnoredElement(node as Element | Text)) {
173
177
  continue;
174
178
  }
175
- const virtualDomElement = this.getVirtualDomElementForRealElementOrThrow(
179
+ const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(
176
180
  node as Element | Text,
177
181
  );
178
- addedNodes.push(virtualDomElementToStatic(virtualDomElement));
182
+ addedNodes.push(virtualDOMElementToStatic(virtualDOMElement));
179
183
  }
180
184
 
181
185
  const removedNodeIds: Array<number> = [];
@@ -183,20 +187,20 @@ export class ObservableDom implements ObservableDomInterface {
183
187
  if (this.isIgnoredElement(node as Element | Text)) {
184
188
  continue;
185
189
  }
186
- const virtualDomElement = this.getVirtualDomElementForRealElementOrThrow(
190
+ const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(
187
191
  node as Element | Text,
188
192
  );
189
- removedNodeIds.push(virtualDomElement.nodeId);
193
+ removedNodeIds.push(virtualDOMElement.nodeId);
190
194
  }
191
195
 
192
- const mutationRecord: StaticVirtualDomMutationIdsRecord = {
196
+ const mutationRecord: StaticVirtualDOMMutationIdsRecord = {
193
197
  type: mutation.type,
194
198
  targetId: targetElement.nodeId,
195
199
  addedNodes,
196
200
  removedNodeIds,
197
201
  previousSiblingId:
198
202
  firstNonIgnoredPreviousSibling !== null
199
- ? this.getVirtualDomElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId
203
+ ? this.getVirtualDOMElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId
200
204
  : null,
201
205
  attribute: mutation.attributeName
202
206
  ? {
@@ -206,10 +210,13 @@ export class ObservableDom implements ObservableDomInterface {
206
210
  : null,
207
211
  };
208
212
 
209
- this.callback({
210
- mutation: mutationRecord,
211
- documentTime: this.getDocumentTime(),
212
- });
213
+ this.callback(
214
+ {
215
+ mutation: mutationRecord,
216
+ documentTime: this.getDocumentTime(),
217
+ },
218
+ this,
219
+ );
213
220
 
214
221
  this.removeKnownNodesInMutation(mutation);
215
222
  }
@@ -217,8 +224,8 @@ export class ObservableDom implements ObservableDomInterface {
217
224
 
218
225
  private addKnownNodesInMutation(mutation: MutationRecord): void {
219
226
  const targetNode = mutation.target as Element | Text;
220
- const virtualDomElement = this.realElementToVirtualElement.get(targetNode);
221
- if (!virtualDomElement) {
227
+ const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);
228
+ if (!virtualDOMElement) {
222
229
  throw new Error(
223
230
  "Unknown node in addKnownNodesInMutation:" + targetNode + "," + mutation.type,
224
231
  );
@@ -236,7 +243,7 @@ export class ObservableDom implements ObservableDomInterface {
236
243
  if (!previousSiblingElement) {
237
244
  throw new Error("Unknown previous sibling");
238
245
  }
239
- index = virtualDomElement.childNodes.indexOf(previousSiblingElement);
246
+ index = virtualDOMElement.childNodes.indexOf(previousSiblingElement);
240
247
  if (index === -1) {
241
248
  throw new Error("Previous sibling is not currently a child of the parent element");
242
249
  }
@@ -244,13 +251,13 @@ export class ObservableDom implements ObservableDomInterface {
244
251
  }
245
252
  mutation.addedNodes.forEach((node: Node) => {
246
253
  const asElementOrText = node as Element | Text;
247
- const childVirtualDomElement = this.createVirtualDomElementWithChildren(
254
+ const childVirtualDOMElement = this.createVirtualDOMElementWithChildren(
248
255
  asElementOrText,
249
- virtualDomElement,
256
+ virtualDOMElement,
250
257
  );
251
- if (childVirtualDomElement) {
252
- if (virtualDomElement.childNodes.indexOf(childVirtualDomElement) === -1) {
253
- virtualDomElement.childNodes.splice(index, 0, childVirtualDomElement);
258
+ if (childVirtualDOMElement) {
259
+ if (virtualDOMElement.childNodes.indexOf(childVirtualDOMElement) === -1) {
260
+ virtualDOMElement.childNodes.splice(index, 0, childVirtualDOMElement);
254
261
  index++;
255
262
  }
256
263
  }
@@ -263,19 +270,19 @@ export class ObservableDom implements ObservableDomInterface {
263
270
  }
264
271
  const attributeValue = (targetNode as Element).getAttribute(attributeName);
265
272
  if (attributeValue === null) {
266
- delete virtualDomElement.attributes[attributeName];
273
+ delete virtualDOMElement.attributes[attributeName];
267
274
  } else {
268
- virtualDomElement.attributes[attributeName] = attributeValue;
275
+ virtualDOMElement.attributes[attributeName] = attributeValue;
269
276
  }
270
277
  } else if (mutation.type === "characterData") {
271
- virtualDomElement.textContent = targetNode.textContent ? targetNode.textContent : undefined;
278
+ virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : undefined;
272
279
  }
273
280
  }
274
281
 
275
282
  private removeKnownNodesInMutation(mutation: MutationRecord): void {
276
283
  const targetNode = mutation.target as Element | Text;
277
- const virtualDomElement = this.realElementToVirtualElement.get(targetNode);
278
- if (!virtualDomElement) {
284
+ const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);
285
+ if (!virtualDOMElement) {
279
286
  throw new Error("Unknown node in mutation list:" + targetNode + ", " + mutation.type);
280
287
  }
281
288
  if (mutation.type === "childList") {
@@ -284,41 +291,41 @@ export class ObservableDom implements ObservableDomInterface {
284
291
  if (this.isIgnoredElement(asElementOrText)) {
285
292
  continue;
286
293
  }
287
- const childDomElement = this.realElementToVirtualElement.get(asElementOrText);
288
- if (!childDomElement) {
294
+ const childDOMElement = this.realElementToVirtualElement.get(asElementOrText);
295
+ if (!childDOMElement) {
289
296
  console.warn(this.htmlPath, "Unknown node in removeKnownNodesInMutation");
290
297
  continue;
291
298
  } else {
292
- this.removeVirtualDomElement(childDomElement);
293
- const index = virtualDomElement.childNodes.indexOf(childDomElement);
294
- virtualDomElement.childNodes.splice(index, 1);
299
+ this.removeVirtualDOMElement(childDOMElement);
300
+ const index = virtualDOMElement.childNodes.indexOf(childDOMElement);
301
+ virtualDOMElement.childNodes.splice(index, 1);
295
302
  }
296
303
  }
297
304
  return;
298
305
  }
299
306
  }
300
307
 
301
- private removeVirtualDomElement(virtualDomElement: LiveVirtualDomElement): void {
302
- this.nodeIdToNode.delete(virtualDomElement.nodeId);
303
- this.nodeToNodeId.delete(virtualDomElement);
304
- this.realElementToVirtualElement.delete(virtualDomElement.realElement);
305
- for (const child of virtualDomElement.childNodes) {
306
- this.removeVirtualDomElement(child);
308
+ private removeVirtualDOMElement(virtualDOMElement: LiveVirtualDOMElement): void {
309
+ this.nodeIdToNode.delete(virtualDOMElement.nodeId);
310
+ this.nodeToNodeId.delete(virtualDOMElement);
311
+ this.realElementToVirtualElement.delete(virtualDOMElement.realElement);
312
+ for (const child of virtualDOMElement.childNodes) {
313
+ this.removeVirtualDOMElement(child);
307
314
  }
308
315
  }
309
316
 
310
- private createVirtualDomElementWithChildren(
317
+ private createVirtualDOMElementWithChildren(
311
318
  node: Element | Text,
312
- parent: LiveVirtualDomElement | null,
313
- ): LiveVirtualDomElement | null {
314
- const virtualElement = this.createVirtualDomElement(node, parent);
319
+ parent: LiveVirtualDOMElement | null,
320
+ ): LiveVirtualDOMElement | null {
321
+ const virtualElement = this.createVirtualDOMElement(node, parent);
315
322
  if (!virtualElement) {
316
323
  return null;
317
324
  }
318
325
  if ((node as Element).childNodes) {
319
326
  for (let i = 0; i < (node as Element).childNodes.length; i++) {
320
327
  const child = (node as Element).childNodes[i];
321
- const childVirtualElement = this.createVirtualDomElementWithChildren(
328
+ const childVirtualElement = this.createVirtualDOMElementWithChildren(
322
329
  child as Element | Text,
323
330
  virtualElement,
324
331
  );
@@ -331,10 +338,10 @@ export class ObservableDom implements ObservableDomInterface {
331
338
  return virtualElement;
332
339
  }
333
340
 
334
- private createVirtualDomElement(
341
+ private createVirtualDOMElement(
335
342
  node: Element | Text,
336
- parent: LiveVirtualDomElement | null,
337
- ): LiveVirtualDomElement | null {
343
+ parent: LiveVirtualDOMElement | null,
344
+ ): LiveVirtualDOMElement | null {
338
345
  if (this.isIgnoredElement(node)) {
339
346
  return null;
340
347
  }
@@ -361,7 +368,7 @@ export class ObservableDom implements ObservableDomInterface {
361
368
  }
362
369
 
363
370
  const nodeId = this.nextNodeId++;
364
- const virtualElement: LiveVirtualDomElement = {
371
+ const virtualElement: LiveVirtualDOMElement = {
365
372
  nodeId,
366
373
  tag: node.nodeName,
367
374
  attributes,
@@ -392,9 +399,9 @@ export class ObservableDom implements ObservableDomInterface {
392
399
  return null;
393
400
  }
394
401
 
395
- private getVirtualDomElementForRealElementOrThrow(
402
+ private getVirtualDOMElementForRealElementOrThrow(
396
403
  realElement: Element | Text,
397
- ): LiveVirtualDomElement {
404
+ ): LiveVirtualDOMElement {
398
405
  const virtualElement = this.realElementToVirtualElement.get(realElement);
399
406
  if (!virtualElement) {
400
407
  throw new Error(`Virtual element not found for real element`);
package/src/index.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./ObservableDom";
1
+ export * from "./ObservableDOM";
2
2
  export * from "./JSDOMRunner";
package/src/utils.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { StaticVirtualDomElement } from "@mml-io/observable-dom-common";
1
+ import { StaticVirtualDOMElement } from "@mml-io/observable-dom-common";
2
2
 
3
- import { LiveVirtualDomElement } from "./ObservableDom";
3
+ import { LiveVirtualDOMElement } from "./ObservableDOM";
4
4
 
5
- export function virtualDomElementToStatic(el: LiveVirtualDomElement): StaticVirtualDomElement {
5
+ export function virtualDOMElementToStatic(el: LiveVirtualDOMElement): StaticVirtualDOMElement {
6
6
  return {
7
7
  nodeId: el.nodeId,
8
8
  tag: el.tag,
9
9
  attributes: el.attributes,
10
- childNodes: el.childNodes.map((child) => virtualDomElementToStatic(child)),
10
+ childNodes: el.childNodes.map((child) => virtualDOMElementToStatic(child)),
11
11
  textContent: el.textContent,
12
12
  };
13
13
  }