@mml-io/networked-dom-document 0.15.0 → 0.16.1

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/common.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StaticVirtualDOMElement } from "@mml-io/observable-dom-common";
2
- import * as rfc6902 from "rfc6902";
2
+ import * as rfc6902 from "./rfc6902";
3
3
  export type NodeMapping = {
4
4
  clientFacingNodeId: number;
5
5
  internalNodeId: number;
@@ -1,7 +1,7 @@
1
1
  import { Diff, NodeDescription } from "@mml-io/networked-dom-protocol";
2
2
  import { StaticVirtualDOMElement } from "@mml-io/observable-dom-common";
3
- import * as rfc6902 from "rfc6902";
4
3
  import { StaticVirtualDOMMutationRecord, VirtualDOMDiffStruct } from "./common";
4
+ import * as rfc6902 from "./rfc6902";
5
5
  export declare const visibleToAttrName = "visible-to";
6
6
  export declare const hiddenFromAttrName = "hidden-from";
7
7
  /**
package/build/index.js CHANGED
@@ -1,8 +1,484 @@
1
- // src/NetworkedDOM.ts
2
- import { applyPatch as applyPatch2 } from "rfc6902";
1
+ // src/rfc6902/pointer.ts
2
+ function unescape(token) {
3
+ return token.replace(/~1/g, "/").replace(/~0/g, "~");
4
+ }
5
+ function escape(token) {
6
+ return token.replace(/~/g, "~0").replace(/\//g, "~1");
7
+ }
8
+ var Pointer = class _Pointer {
9
+ constructor(tokens = [""]) {
10
+ this.tokens = tokens;
11
+ }
12
+ /**
13
+ `path` *must* be a properly escaped string.
14
+ */
15
+ static fromJSON(path) {
16
+ const tokens = path.split("/").map(unescape);
17
+ if (tokens[0] !== "")
18
+ throw new Error(`Invalid JSON Pointer: ${path}`);
19
+ return new _Pointer(tokens);
20
+ }
21
+ toString() {
22
+ return this.tokens.map(escape).join("/");
23
+ }
24
+ /**
25
+ Returns an object with 'parent', 'key', and 'value' properties.
26
+ In the special case that this Pointer's path == "",
27
+ this object will be {parent: null, key: '', value: object}.
28
+ Otherwise, parent and key will have the property such that parent[key] == value.
29
+ */
30
+ evaluate(object) {
31
+ let parent = null;
32
+ let key = "";
33
+ let value = object;
34
+ for (let i = 1, l = this.tokens.length; i < l; i++) {
35
+ parent = value;
36
+ key = this.tokens[i];
37
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
38
+ continue;
39
+ }
40
+ value = (parent || {})[key];
41
+ }
42
+ return { parent, key, value };
43
+ }
44
+ get(object) {
45
+ return this.evaluate(object).value;
46
+ }
47
+ set(object, value) {
48
+ let cursor = object;
49
+ for (let i = 1, l = this.tokens.length - 1, token = this.tokens[i]; i < l; i++) {
50
+ cursor = (cursor || {})[token];
51
+ }
52
+ if (cursor) {
53
+ cursor[this.tokens[this.tokens.length - 1]] = value;
54
+ }
55
+ }
56
+ push(token) {
57
+ this.tokens.push(token);
58
+ }
59
+ /**
60
+ `token` should be a String. It'll be coerced to one anyway.
61
+
62
+ immutable (shallowly)
63
+ */
64
+ add(token) {
65
+ const tokens = this.tokens.concat(String(token));
66
+ return new _Pointer(tokens);
67
+ }
68
+ };
69
+
70
+ // src/rfc6902/deepEqual.ts
71
+ function deepEqual(a, b) {
72
+ if (a === b) {
73
+ return true;
74
+ }
75
+ if (Array.isArray(a) && Array.isArray(b)) {
76
+ if (a.length !== b.length) {
77
+ return false;
78
+ }
79
+ return a.every((elem, index) => {
80
+ return deepEqual(elem, b[index]);
81
+ });
82
+ }
83
+ if (typeof a === "object" && typeof b === "object" && a !== null && b !== null) {
84
+ if (Array.isArray(a) || Array.isArray(b)) {
85
+ return false;
86
+ }
87
+ const keys1 = Object.keys(a);
88
+ const keys2 = Object.keys(b);
89
+ if (keys1.length !== keys2.length || !keys1.every((key) => keys2.includes(key))) {
90
+ return false;
91
+ }
92
+ for (const key in a) {
93
+ if (!deepEqual(a[key], b[key])) {
94
+ return false;
95
+ }
96
+ }
97
+ if (keys1.length === 0 && a instanceof Date && b instanceof Date) {
98
+ return a.getTime() === b.getTime();
99
+ }
100
+ return true;
101
+ }
102
+ return false;
103
+ }
104
+
105
+ // src/rfc6902/util.ts
106
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
107
+ function objectType(object) {
108
+ if (object === void 0) {
109
+ return "undefined";
110
+ }
111
+ if (object === null) {
112
+ return "null";
113
+ }
114
+ if (Array.isArray(object)) {
115
+ return "array";
116
+ }
117
+ return typeof object;
118
+ }
119
+ function isNonPrimitive(value) {
120
+ return value != null && typeof value === "object";
121
+ }
122
+ function clone(source) {
123
+ if (!isNonPrimitive(source)) {
124
+ return source;
125
+ }
126
+ if (Array.isArray(source)) {
127
+ const length = source.length;
128
+ const arrayTarget = new Array(length);
129
+ for (let i = 0; i < length; i++) {
130
+ arrayTarget[i] = clone(source[i]);
131
+ }
132
+ return arrayTarget;
133
+ }
134
+ if (source.constructor === Date) {
135
+ const dateTarget = /* @__PURE__ */ new Date(+source);
136
+ return dateTarget;
137
+ }
138
+ const objectTarget = {};
139
+ for (const key in source) {
140
+ if (hasOwnProperty.call(source, key)) {
141
+ objectTarget[key] = clone(source[key]);
142
+ }
143
+ }
144
+ return objectTarget;
145
+ }
146
+
147
+ // src/rfc6902/diff.ts
148
+ function wrapVoidableDiff(diff) {
149
+ function wrappedDiff(input, output, ptr) {
150
+ const custom_patch = diff(input, output, ptr);
151
+ return Array.isArray(custom_patch) ? custom_patch : diffAny(input, output, ptr, wrappedDiff);
152
+ }
153
+ return wrappedDiff;
154
+ }
155
+ function createPatch(input, output, diff) {
156
+ const ptr = new Pointer();
157
+ return (diff ? wrapVoidableDiff(diff) : diffAny)(input, output, ptr);
158
+ }
159
+ function subtract(minuend, subtrahend) {
160
+ const obj = {};
161
+ for (const add_key in minuend) {
162
+ if (hasOwnProperty.call(minuend, add_key) && minuend[add_key] !== void 0) {
163
+ obj[add_key] = 1;
164
+ }
165
+ }
166
+ for (const del_key in subtrahend) {
167
+ if (hasOwnProperty.call(subtrahend, del_key) && subtrahend[del_key] !== void 0) {
168
+ delete obj[del_key];
169
+ }
170
+ }
171
+ return Object.keys(obj);
172
+ }
173
+ function intersection(objects) {
174
+ const length = objects.length;
175
+ const counter = {};
176
+ for (let i = 0; i < length; i++) {
177
+ const object = objects[i];
178
+ for (const key in object) {
179
+ if (hasOwnProperty.call(object, key) && object[key] !== void 0) {
180
+ counter[key] = (counter[key] || 0) + 1;
181
+ }
182
+ }
183
+ }
184
+ for (const key in counter) {
185
+ if (counter[key] < length) {
186
+ delete counter[key];
187
+ }
188
+ }
189
+ return Object.keys(counter);
190
+ }
191
+ function isArrayAdd(array_operation) {
192
+ return array_operation.op === "add";
193
+ }
194
+ function isArrayRemove(array_operation) {
195
+ return array_operation.op === "remove";
196
+ }
197
+ function buildOperations(memo, i, j) {
198
+ let memoized = memo[i][j];
199
+ if (!memoized) {
200
+ throw new Error("invalid memo");
201
+ }
202
+ const operations = [];
203
+ while (memoized && memoized.prev && memoized.operation) {
204
+ operations.push(memoized.operation);
205
+ const index = memoized.prev.split(",");
206
+ memoized = memo[Number(index[0])][Number(index[1])];
207
+ }
208
+ return operations.reverse();
209
+ }
210
+ function diffArrays(input, output, ptr, diff = diffAny) {
211
+ if (diff === void 0) {
212
+ diff = diffAny;
213
+ }
214
+ const input_length = isNaN(input.length) || input.length <= 0 ? 0 : input.length;
215
+ const output_length = isNaN(output.length) || output.length <= 0 ? 0 : output.length;
216
+ let input_end = input_length;
217
+ let output_end = output_length;
218
+ while (input_end > 0 && output_end > 0) {
219
+ if (deepEqual(input[input_end - 1], output[output_end - 1])) {
220
+ input_end--;
221
+ output_end--;
222
+ } else {
223
+ break;
224
+ }
225
+ }
226
+ const memo = new Array(input_end + 1);
227
+ for (let i = 0; i <= input_end; i++) {
228
+ memo[i] = new Array(output_end + 1);
229
+ }
230
+ memo[0][0] = { prev: null, operation: null, cost: 0 };
231
+ for (let i = 0; i <= input_end; i++) {
232
+ for (let j = 0; j <= output_end; j++) {
233
+ let memoized = memo[i][j];
234
+ if (memoized)
235
+ continue;
236
+ const add_prev_key = `${i},${j - 1}`;
237
+ const remove_prev_key = `${i - 1},${j}`;
238
+ const replace_prev_key = `${i - 1},${j - 1}`;
239
+ const remove_operation = {
240
+ op: "remove",
241
+ index: i - 1
242
+ };
243
+ const add_operation = {
244
+ op: "add",
245
+ index: i - 1,
246
+ value: output[j - 1]
247
+ };
248
+ if (j === 0) {
249
+ memoized = {
250
+ prev: remove_prev_key,
251
+ operation: remove_operation,
252
+ cost: memo[i - 1][j].cost + 1
253
+ };
254
+ } else if (i === 0) {
255
+ memoized = { prev: add_prev_key, operation: add_operation, cost: memo[i][j - 1].cost + 1 };
256
+ } else {
257
+ if (deepEqual(input[i - 1], output[j - 1])) {
258
+ memoized = memo[i - 1][j - 1];
259
+ } else {
260
+ const remove_prev = memo[i - 1][j];
261
+ const add_prev = memo[i][j - 1];
262
+ const replace_prev = memo[i - 1][j - 1];
263
+ const min_cost = Math.min(replace_prev.cost, add_prev.cost, remove_prev.cost);
264
+ if (remove_prev.cost === min_cost) {
265
+ memoized = {
266
+ prev: remove_prev_key,
267
+ operation: remove_operation,
268
+ cost: memo[i - 1][j].cost + 1
269
+ };
270
+ } else if (add_prev.cost === min_cost) {
271
+ memoized = {
272
+ prev: add_prev_key,
273
+ operation: add_operation,
274
+ cost: memo[i][j - 1].cost + 1
275
+ };
276
+ } else {
277
+ const replace_operation = {
278
+ op: "replace",
279
+ index: i - 1,
280
+ original: input[i - 1],
281
+ value: output[j - 1]
282
+ };
283
+ memoized = {
284
+ prev: replace_prev_key,
285
+ operation: replace_operation,
286
+ cost: memo[i - 1][j - 1].cost + 1
287
+ };
288
+ }
289
+ }
290
+ }
291
+ memo[i][j] = memoized;
292
+ }
293
+ }
294
+ const array_operations = buildOperations(memo, input_end, output_end);
295
+ const [padded_operations] = array_operations.reduce(
296
+ ([operations, padding], array_operation) => {
297
+ if (isArrayAdd(array_operation)) {
298
+ const padded_index = array_operation.index + 1 + padding;
299
+ const index_token = padded_index < input_length + padding ? String(padded_index) : "-";
300
+ const operation = {
301
+ op: array_operation.op,
302
+ path: ptr.add(index_token).toString(),
303
+ value: array_operation.value
304
+ };
305
+ return [operations.concat(operation), padding + 1];
306
+ } else if (isArrayRemove(array_operation)) {
307
+ const operation = {
308
+ op: array_operation.op,
309
+ path: ptr.add(String(array_operation.index + padding)).toString()
310
+ };
311
+ return [operations.concat(operation), padding - 1];
312
+ } else {
313
+ const replace_ptr = ptr.add(String(array_operation.index + padding));
314
+ const replace_operations = diff(
315
+ array_operation.original,
316
+ array_operation.value,
317
+ replace_ptr
318
+ );
319
+ return [operations.concat(...replace_operations), padding];
320
+ }
321
+ },
322
+ [[], 0]
323
+ );
324
+ return padded_operations;
325
+ }
326
+ function diffObjects(input, output, ptr, diff = diffAny) {
327
+ const operations = [];
328
+ subtract(input, output).forEach((key) => {
329
+ operations.push({ op: "remove", path: ptr.add(key).toString() });
330
+ });
331
+ subtract(output, input).forEach((key) => {
332
+ operations.push({ op: "add", path: ptr.add(key).toString(), value: output[key] });
333
+ });
334
+ intersection([input, output]).forEach((key) => {
335
+ operations.push(...diff(input[key], output[key], ptr.add(key)));
336
+ });
337
+ return operations;
338
+ }
339
+ function diffAny(input, output, ptr, diff = diffAny) {
340
+ if (input === output) {
341
+ return [];
342
+ }
343
+ const input_type = objectType(input);
344
+ const output_type = objectType(output);
345
+ if (input_type === "array" && output_type === "array") {
346
+ return diffArrays(input, output, ptr, diff);
347
+ }
348
+ if (input_type === "object" && output_type === "object") {
349
+ return diffObjects(input, output, ptr, diff);
350
+ }
351
+ return [{ op: "replace", path: ptr.toString(), value: output }];
352
+ }
353
+
354
+ // src/rfc6902/patch.ts
355
+ var MissingError = class extends Error {
356
+ constructor(path) {
357
+ super(`Value required at path: ${path}`);
358
+ this.path = path;
359
+ this.name = "MissingError";
360
+ }
361
+ };
362
+ var TestError = class extends Error {
363
+ constructor(actual, expected) {
364
+ super(`Test failed: ${actual} != ${expected}`);
365
+ this.actual = actual;
366
+ this.expected = expected;
367
+ this.name = "TestError";
368
+ }
369
+ };
370
+ function applyPatch(object, patch) {
371
+ return patch.map((operation) => apply(object, operation));
372
+ }
373
+ function _add(object, key, value) {
374
+ if (Array.isArray(object)) {
375
+ if (key === "-") {
376
+ object.push(value);
377
+ } else {
378
+ const index = parseInt(key, 10);
379
+ object.splice(index, 0, value);
380
+ }
381
+ } else {
382
+ object[key] = value;
383
+ }
384
+ }
385
+ function _remove(object, key) {
386
+ if (Array.isArray(object)) {
387
+ const index = parseInt(key, 10);
388
+ object.splice(index, 1);
389
+ } else {
390
+ delete object[key];
391
+ }
392
+ }
393
+ function add(object, operation) {
394
+ const endpoint = Pointer.fromJSON(operation.path).evaluate(object);
395
+ if (endpoint.parent === void 0) {
396
+ return new MissingError(operation.path);
397
+ }
398
+ _add(endpoint.parent, endpoint.key, clone(operation.value));
399
+ return null;
400
+ }
401
+ function remove(object, operation) {
402
+ const endpoint = Pointer.fromJSON(operation.path).evaluate(object);
403
+ if (endpoint.value === void 0) {
404
+ return new MissingError(operation.path);
405
+ }
406
+ _remove(endpoint.parent, endpoint.key);
407
+ return null;
408
+ }
409
+ function replace(object, operation) {
410
+ const endpoint = Pointer.fromJSON(operation.path).evaluate(object);
411
+ if (endpoint.parent === null) {
412
+ return new MissingError(operation.path);
413
+ }
414
+ if (Array.isArray(endpoint.parent)) {
415
+ if (parseInt(endpoint.key, 10) >= endpoint.parent.length) {
416
+ return new MissingError(operation.path);
417
+ }
418
+ } else if (endpoint.value === void 0) {
419
+ return new MissingError(operation.path);
420
+ }
421
+ endpoint.parent[endpoint.key] = operation.value;
422
+ return null;
423
+ }
424
+ function move(object, operation) {
425
+ const from_endpoint = Pointer.fromJSON(operation.from).evaluate(object);
426
+ if (from_endpoint.value === void 0) {
427
+ return new MissingError(operation.from);
428
+ }
429
+ const endpoint = Pointer.fromJSON(operation.path).evaluate(object);
430
+ if (endpoint.parent === void 0) {
431
+ return new MissingError(operation.path);
432
+ }
433
+ _remove(from_endpoint.parent, from_endpoint.key);
434
+ _add(endpoint.parent, endpoint.key, from_endpoint.value);
435
+ return null;
436
+ }
437
+ function copy(object, operation) {
438
+ const from_endpoint = Pointer.fromJSON(operation.from).evaluate(object);
439
+ if (from_endpoint.value === void 0) {
440
+ return new MissingError(operation.from);
441
+ }
442
+ const endpoint = Pointer.fromJSON(operation.path).evaluate(object);
443
+ if (endpoint.parent === void 0) {
444
+ return new MissingError(operation.path);
445
+ }
446
+ _add(endpoint.parent, endpoint.key, clone(from_endpoint.value));
447
+ return null;
448
+ }
449
+ function test(object, operation) {
450
+ const endpoint = Pointer.fromJSON(operation.path).evaluate(object);
451
+ if (diffAny(endpoint.value, operation.value, new Pointer()).length) {
452
+ return new TestError(endpoint.value, operation.value);
453
+ }
454
+ return null;
455
+ }
456
+ var InvalidOperationError = class extends Error {
457
+ constructor(operation) {
458
+ super(`Invalid operation: ${operation.op}`);
459
+ this.operation = operation;
460
+ this.name = "InvalidOperationError";
461
+ }
462
+ };
463
+ function apply(object, operation) {
464
+ switch (operation.op) {
465
+ case "add":
466
+ return add(object, operation);
467
+ case "remove":
468
+ return remove(object, operation);
469
+ case "replace":
470
+ return replace(object, operation);
471
+ case "move":
472
+ return move(object, operation);
473
+ case "copy":
474
+ return copy(object, operation);
475
+ case "test":
476
+ return test(object, operation);
477
+ }
478
+ return new InvalidOperationError(operation);
479
+ }
3
480
 
4
481
  // src/diffing.ts
5
- import * as rfc6902 from "rfc6902";
6
482
  var visibleToAttrName = "visible-to";
7
483
  var hiddenFromAttrName = "hidden-from";
8
484
  function diffFromApplicationOfStaticVirtualDOMMutationRecordToConnection(mutation, parentNode, connectionId, visibleNodesForConnection) {
@@ -249,12 +725,12 @@ function findParentNodeOfNodeId(virtualDOMElement, targetNodeId) {
249
725
  return null;
250
726
  }
251
727
  function virtualDOMDiffToVirtualDOMMutationRecord(virtualStructure, domDiff) {
252
- const pointer = rfc6902.Pointer.fromJSON(domDiff.path);
728
+ const pointer = Pointer.fromJSON(domDiff.path);
253
729
  const grandParentTokens = pointer.tokens.slice(0, pointer.tokens.length - 2);
254
730
  const lastToken = pointer.tokens[pointer.tokens.length - 1];
255
731
  const secondLastToken = pointer.tokens[pointer.tokens.length - 2];
256
732
  if (lastToken === "textContent") {
257
- const nodePointer = new rfc6902.Pointer(pointer.tokens.slice(0, pointer.tokens.length - 1));
733
+ const nodePointer = new Pointer(pointer.tokens.slice(0, pointer.tokens.length - 1));
258
734
  const node = nodePointer.get(virtualStructure);
259
735
  return [
260
736
  {
@@ -268,7 +744,7 @@ function virtualDOMDiffToVirtualDOMMutationRecord(virtualStructure, domDiff) {
268
744
  ];
269
745
  }
270
746
  if (secondLastToken === "attributes") {
271
- const nodePointer = new rfc6902.Pointer(grandParentTokens);
747
+ const nodePointer = new Pointer(grandParentTokens);
272
748
  const node = nodePointer.get(virtualStructure);
273
749
  return [
274
750
  {
@@ -282,7 +758,7 @@ function virtualDOMDiffToVirtualDOMMutationRecord(virtualStructure, domDiff) {
282
758
  ];
283
759
  }
284
760
  if (secondLastToken === "childNodes") {
285
- const nodePointer = new rfc6902.Pointer(grandParentTokens);
761
+ const nodePointer = new Pointer(grandParentTokens);
286
762
  const node = nodePointer.get(virtualStructure);
287
763
  let previousSibling = null;
288
764
  if (lastToken === "-") {
@@ -366,7 +842,7 @@ function virtualDOMDiffToVirtualDOMMutationRecord(virtualStructure, domDiff) {
366
842
  throw new Error("Unhandled diff type");
367
843
  }
368
844
  function calculateStaticVirtualDOMDiff(originalState, latestState) {
369
- const jsonPatchDiffs = rfc6902.createPatch(
845
+ const jsonPatchDiffs = createPatch(
370
846
  originalState,
371
847
  latestState,
372
848
  (a, b, ptr) => {
@@ -380,7 +856,7 @@ function calculateStaticVirtualDOMDiff(originalState, latestState) {
380
856
  const virtualDOMDiffs = [];
381
857
  for (const diff of jsonPatchDiffs) {
382
858
  if (diff.op === "replace" && diff.path.endsWith("/nodeId")) {
383
- const pointer = rfc6902.Pointer.fromJSON(diff.path);
859
+ const pointer = Pointer.fromJSON(diff.path);
384
860
  const originalValue = pointer.get(originalState);
385
861
  nodeIdRemappings.push({
386
862
  internalNodeId: diff.value,
@@ -415,7 +891,7 @@ function getRemovedNodeIds(before, diff) {
415
891
  }
416
892
  }
417
893
  if (diff.op === "replace" || diff.op === "remove") {
418
- const removedNode = rfc6902.Pointer.fromJSON(diff.path).get(before);
894
+ const removedNode = Pointer.fromJSON(diff.path).get(before);
419
895
  addNode(removedNode);
420
896
  }
421
897
  return removedIds;
@@ -457,7 +933,7 @@ function remapDuplicatedNodeIdsInOperations(virtualDOMDiffStruct, latestState) {
457
933
  }
458
934
  const existingNodeIds = getNodeIdsFromNodeAndChildren(before);
459
935
  for (const diff of virtualDOMDiffs) {
460
- const pointer = rfc6902.Pointer.fromJSON(diff.path);
936
+ const pointer = Pointer.fromJSON(diff.path);
461
937
  const secondLastToken = pointer.tokens[pointer.tokens.length - 2];
462
938
  if (secondLastToken !== "childNodes") {
463
939
  continue;
@@ -473,7 +949,7 @@ function remapDuplicatedNodeIdsInOperations(virtualDOMDiffStruct, latestState) {
473
949
  addingNodeIds.forEach((addingNodeId) => {
474
950
  existingNodeIds.add(addingNodeId);
475
951
  });
476
- const patchErrors = rfc6902.applyPatch(before, [diff]);
952
+ const patchErrors = applyPatch(before, [diff]);
477
953
  if (patchErrors.length !== 1 || patchErrors[0] !== null) {
478
954
  throw new Error("Patch failed");
479
955
  }
@@ -648,7 +1124,7 @@ var _NetworkedDOM = class _NetworkedDOM {
648
1124
  );
649
1125
  if (virtualDOMDiff.path === "" && virtualDOMDiff.op === "replace") {
650
1126
  } else {
651
- const patchResults = applyPatch2(domDiff.originalState, [virtualDOMDiff]);
1127
+ const patchResults = applyPatch(domDiff.originalState, [virtualDOMDiff]);
652
1128
  for (const patchResult of patchResults) {
653
1129
  if (patchResult !== null) {
654
1130
  console.error("Patching virtual dom structure resulted in error", patchResult);
@@ -686,7 +1162,7 @@ var _NetworkedDOM = class _NetworkedDOM {
686
1162
  const asServerMessages = diffs;
687
1163
  const firstDiff = diffs[0];
688
1164
  firstDiff.documentTime = this.getDocumentTime();
689
- const serializedDiffs = JSON.stringify(asServerMessages, null, 4);
1165
+ const serializedDiffs = JSON.stringify(asServerMessages);
690
1166
  const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);
691
1167
  if (!webSocketContext) {
692
1168
  throw new Error(`webSocketContext not found in addExistingWebsockets`);
@@ -868,7 +1344,7 @@ var _NetworkedDOM = class _NetworkedDOM {
868
1344
  diffsByConnectionId.forEach((diffs, connectionId) => {
869
1345
  if (diffs.length > 0) {
870
1346
  const asServerMessages = diffs;
871
- const serializedDiffs = JSON.stringify(asServerMessages, null, 4);
1347
+ const serializedDiffs = JSON.stringify(asServerMessages);
872
1348
  const webSocketContext = this.connectionIdToWebSocketContext.get(connectionId);
873
1349
  if (!webSocketContext) {
874
1350
  throw new Error(`webSocketContext not found in processModificationList`);