@mml-io/delta-net-web 0.0.0-experimental-3a2278c-20250715 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2023 Improbable MV Limited
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
@@ -10,6 +10,7 @@ export declare class DeltaNetClientWebsocketV01Adapter implements DeltaNetClient
10
10
  private sentUserConnect;
11
11
  private receivedUserIndex;
12
12
  private queuedStateUpdates;
13
+ private components;
13
14
  private states;
14
15
  private disposed;
15
16
  private isObserver;
package/build/index.js CHANGED
@@ -1,15 +1,15 @@
1
1
  // src/DeltaNetClientState.ts
2
2
  var DeltaNetClientState = class {
3
+ componentValues = /* @__PURE__ */ new Map();
4
+ allStates = /* @__PURE__ */ new Map();
5
+ byStableId = /* @__PURE__ */ new Map();
6
+ localClientIndex = -1;
7
+ indicesCount = 0;
8
+ stableIdToIndex = /* @__PURE__ */ new Map();
9
+ stableIds = [];
10
+ stableIdCounter = 1e3;
3
11
  // Start at 1000 to avoid confusion with indices
4
12
  constructor() {
5
- this.componentValues = /* @__PURE__ */ new Map();
6
- this.allStates = /* @__PURE__ */ new Map();
7
- this.byStableId = /* @__PURE__ */ new Map();
8
- this.localClientIndex = -1;
9
- this.indicesCount = 0;
10
- this.stableIdToIndex = /* @__PURE__ */ new Map();
11
- this.stableIds = [];
12
- this.stableIdCounter = 1e3;
13
13
  this.reset();
14
14
  }
15
15
  /**
@@ -292,7 +292,7 @@ var DeltaNetClientState = class {
292
292
  };
293
293
 
294
294
  // src/DeltaNetClientWebsocket.ts
295
- import { deltaNetProtocolSubProtocol_v0_1 } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-protocol/build/index.js";
295
+ import { deltaNetProtocolSubProtocol_v0_1 } from "@mml-io/delta-net-protocol";
296
296
 
297
297
  // src/DeltaNetClientWebsocketV01Adapter.ts
298
298
  import {
@@ -302,7 +302,7 @@ import {
302
302
  encodeClientMessage,
303
303
  lastInitialCheckoutDebugData,
304
304
  lastTickDebugData
305
- } from "/Users/marcuslongmuir/mml/3d-web-experience/packages/deltanet/delta-net-protocol/build/index.js";
305
+ } from "@mml-io/delta-net-protocol";
306
306
  function areUint8ArraysEqual(a, b) {
307
307
  if (a.length !== b.length) return false;
308
308
  for (let i = 0; i < a.length; i++) {
@@ -318,18 +318,20 @@ var DeltaNetClientWebsocketV01Adapter = class {
318
318
  this.token = token;
319
319
  this.internalOptions = internalOptions;
320
320
  this.timeCallback = timeCallback;
321
- this.gotInitialCheckout = false;
322
- this.sentUserConnect = false;
323
- this.receivedUserIndex = false;
324
- this.queuedStateUpdates = /* @__PURE__ */ new Map();
325
- this.states = /* @__PURE__ */ new Map();
326
- this.disposed = false;
327
321
  this.websocket.binaryType = "arraybuffer";
328
322
  this.isObserver = options.observer ?? false;
329
323
  if (this.isObserver) {
330
324
  this.sendConnectUser([], []);
331
325
  }
332
326
  }
327
+ gotInitialCheckout = false;
328
+ sentUserConnect = false;
329
+ receivedUserIndex = false;
330
+ queuedStateUpdates = /* @__PURE__ */ new Map();
331
+ components = /* @__PURE__ */ new Map();
332
+ states = /* @__PURE__ */ new Map();
333
+ disposed = false;
334
+ isObserver;
333
335
  sendConnectUser(components, states) {
334
336
  if (this.sentUserConnect) {
335
337
  return;
@@ -350,6 +352,7 @@ var DeltaNetClientWebsocketV01Adapter = class {
350
352
  const messageComponents = [];
351
353
  for (const [componentId, value] of components) {
352
354
  messageComponents.push([componentId, value]);
355
+ this.components.set(componentId, value);
353
356
  }
354
357
  const messageStates = [];
355
358
  for (const [stateId, value] of changedStates) {
@@ -367,22 +370,20 @@ var DeltaNetClientWebsocketV01Adapter = class {
367
370
  if (this.isObserver) {
368
371
  return;
369
372
  }
370
- let messageStatesToSend = [];
371
373
  if (this.receivedUserIndex) {
372
- messageStatesToSend = messageStates;
374
+ if (messageComponents.length > 0 || messageStates.length > 0) {
375
+ const setUserComponents = {
376
+ type: "setUserComponents",
377
+ components: messageComponents,
378
+ states: messageStates
379
+ };
380
+ this.send(setUserComponents);
381
+ }
373
382
  } else {
374
383
  for (const [stateId, value] of messageStates) {
375
384
  this.queuedStateUpdates.set(stateId, value);
376
385
  }
377
386
  }
378
- if (messageComponents.length > 0 || messageStatesToSend.length > 0) {
379
- const setUserComponents = {
380
- type: "setUserComponents",
381
- components: messageComponents,
382
- states: messageStatesToSend
383
- };
384
- this.send(setUserComponents);
385
- }
386
387
  }
387
388
  send(message) {
388
389
  const writer = new BufferWriter(256);
@@ -461,7 +462,7 @@ var DeltaNetClientWebsocketV01Adapter = class {
461
462
  }
462
463
  const setUserComponents = {
463
464
  type: "setUserComponents",
464
- components: [],
465
+ components: Array.from(this.components.entries()),
465
466
  states: queuedStatesArray
466
467
  };
467
468
  this.send(setUserComponents);
@@ -588,22 +589,22 @@ var DeltaNetClientWebsocket = class {
588
589
  this.options = options;
589
590
  this.timeCallback = timeCallback;
590
591
  this.statusUpdateCallback = statusUpdateCallback;
591
- this.websocket = null;
592
- this.websocketAdapter = null;
593
- this.stopped = false;
594
- this.backoffTime = startingBackoffTimeMilliseconds;
595
- this.status = 0 /* Connecting */;
596
- this.bandwidthPerSecond = 0;
597
- this.lastSecondMessageSizes = [];
598
- // Timestamp in ms, size in bytes
599
- this.componentBytesPerSecond = 0;
600
- this.lastSecondComponentBufferSizes = [];
601
- // Timestamp in ms, size in bytes
602
- this.stateBytesPerSecond = 0;
603
- this.lastSecondStateBufferSizes = [];
604
592
  this.setStatus(0 /* Connecting */);
605
593
  this.startWebSocketConnectionAttempt();
606
594
  }
595
+ websocket = null;
596
+ websocketAdapter = null;
597
+ stopped = false;
598
+ backoffTime = startingBackoffTimeMilliseconds;
599
+ status = 0 /* Connecting */;
600
+ bandwidthPerSecond = 0;
601
+ lastSecondMessageSizes = [];
602
+ // Timestamp in ms, size in bytes
603
+ componentBytesPerSecond = 0;
604
+ lastSecondComponentBufferSizes = [];
605
+ // Timestamp in ms, size in bytes
606
+ stateBytesPerSecond = 0;
607
+ lastSecondStateBufferSizes = [];
607
608
  // Timestamp in ms, size in bytes
608
609
  static createWebSocket(url) {
609
610
  return new WebSocket(url, [deltaNetProtocolSubProtocol_v0_1]);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/DeltaNetClientState.ts", "../src/DeltaNetClientWebsocket.ts", "../src/DeltaNetClientWebsocketV01Adapter.ts"],
4
- "sourcesContent": ["import {\n DeltaNetClientWebsocketInitialCheckout,\n DeltaNetClientWebsocketTick,\n} from \"./DeltaNetClientWebsocket\";\n\nexport type EntityStateUpdate = { stableId: number; stateId: number; state: Uint8Array };\n\nexport type EntityInfo = {\n stableId: number;\n components: Map<number, bigint>;\n states: Map<number, Uint8Array>;\n};\n\nexport type DeltaNetClientComponent = {\n values: BigInt64Array;\n deltas: BigInt64Array;\n deltaDeltas: BigInt64Array;\n};\n\nexport class DeltaNetClientState {\n private componentValues = new Map<number, DeltaNetClientComponent>();\n private allStates = new Map<number, Array<Uint8Array>>();\n\n public byStableId: Map<number, EntityInfo> = new Map();\n\n private localClientIndex: number = -1;\n\n private indicesCount: number = 0;\n\n private stableIdToIndex = new Map<number, number>();\n private stableIds: Array<number> = [];\n private stableIdCounter = 1000; // Start at 1000 to avoid confusion with indices\n\n constructor() {\n this.reset();\n }\n\n /**\n * Reset all state to initial values. This should be called when reconnecting\n * to ensure that stale data from previous connections doesn't interfere.\n */\n public reset() {\n this.componentValues.clear();\n this.allStates.clear();\n this.byStableId.clear();\n this.localClientIndex = -1;\n this.indicesCount = 0;\n this.stableIdToIndex.clear();\n this.stableIds.length = 0;\n this.stableIdCounter = 1000;\n }\n\n public getComponentValues(): Map<number, DeltaNetClientComponent> {\n return this.componentValues;\n }\n\n public getStateById(stateId: number): Array<Uint8Array | null> | null {\n return this.allStates.get(stateId) ?? null;\n }\n\n public getAllStates(): Map<number, Array<Uint8Array | null>> {\n return this.allStates;\n }\n\n public getLocalClientIndex(): number {\n return this.localClientIndex;\n }\n\n public getIndicesCount(): number {\n return this.indicesCount;\n }\n\n public getStableIds(): Array<number> {\n return this.stableIds;\n }\n\n public getComponentValueForStableId(stableId: number, componentId: number): bigint | null {\n const index = this.stableIdToIndex.get(stableId);\n if (index === undefined) {\n return null;\n }\n const componentValue = this.componentValues.get(componentId);\n if (!componentValue) {\n return null;\n }\n return componentValue.values[index] ?? null;\n }\n\n public getComponentsForStableId(stableId: number): Map<number, bigint> | null {\n const index = this.stableIdToIndex.get(stableId);\n if (index === undefined) {\n return null;\n }\n const componentMap = new Map<number, bigint>();\n for (const [key, componentValue] of this.componentValues) {\n if (componentValue === undefined) {\n throw new Error(`Component value for key ${key} is undefined`);\n }\n componentMap.set(key, componentValue.values[index]);\n }\n return componentMap;\n }\n\n public handleInitialCheckout(initialCheckout: DeltaNetClientWebsocketInitialCheckout): {\n addedStableIds: Array<number>;\n } {\n const { indicesCount, initialComponents, initialStates } = initialCheckout;\n const addedStableIds: Array<number> = [];\n for (let i = 0; i < indicesCount; i++) {\n const stableId = this.stableIdCounter++;\n this.stableIds.push(stableId);\n this.stableIdToIndex.set(stableId, i);\n const entityInfo: EntityInfo = {\n stableId,\n components: new Map(),\n states: new Map(),\n };\n this.byStableId.set(stableId, entityInfo);\n addedStableIds.push(stableId);\n }\n this.indicesCount = indicesCount;\n\n const deltaDeltas = new BigInt64Array(indicesCount);\n for (let i = 0; i < deltaDeltas.length; i++) {\n deltaDeltas[i] = BigInt(0);\n }\n\n for (const [key, value] of initialComponents) {\n this.componentValues.set(key, {\n values: value.values,\n deltas: value.deltas,\n deltaDeltas,\n });\n\n for (let i = 0; i < this.stableIds.length; i++) {\n const stableId = this.stableIds[i];\n const entityInfo = this.byStableId.get(stableId);\n if (entityInfo) {\n entityInfo.components.set(key, value.values[i]);\n }\n }\n }\n\n for (const [stateId, values] of initialStates) {\n this.allStates.set(stateId, values);\n\n for (let i = 0; i < this.stableIds.length; i++) {\n const stableId = this.stableIds[i];\n const entityInfo = this.byStableId.get(stableId);\n const stateValue = values[i];\n if (entityInfo) {\n entityInfo.states.set(stateId, stateValue);\n }\n }\n }\n\n return { addedStableIds };\n }\n\n public handleTick(tick: DeltaNetClientWebsocketTick): {\n stateUpdates: Array<EntityStateUpdate>;\n removedStableIds: Array<number>;\n addedStableIds: Array<number>;\n } {\n const { unoccupying, indicesCount, componentDeltaDeltas, stateChanges } = tick;\n\n let removedStableIds: Array<number> = [];\n\n if (unoccupying.length > 0) {\n // Collect stableIds to remove before mutating stableIds\n const stableIdsToRemove = unoccupying.map((index) => this.stableIds[index]);\n removedStableIds = stableIdsToRemove.filter((stableId) => stableId !== undefined);\n\n // Remove unoccupying indices from component values\n for (const [componentId, component] of this.componentValues) {\n this.removeIndicesFromBigInt64Array(unoccupying, component.values);\n this.removeIndicesFromBigInt64Array(unoccupying, component.deltas);\n }\n\n // Remove unoccupying indices from states\n for (const [stateId, state] of this.allStates) {\n this.removeIndicesFromState(unoccupying, state);\n }\n\n // Update localClientIndex\n let decrementIndex = 0;\n for (const index of unoccupying) {\n if (index <= this.localClientIndex) {\n decrementIndex++;\n }\n }\n this.localClientIndex -= decrementIndex;\n\n // Update indices count\n this.indicesCount -= unoccupying.length;\n\n // Update stable indices and stableIds array\n this.removeIndices(unoccupying);\n\n // Remove unoccupied stables from byStableId\n for (const stableId of stableIdsToRemove) {\n if (stableId === undefined) {\n throw new Error(`stableId is undefined`);\n }\n this.byStableId.delete(stableId);\n }\n }\n\n const addedStableIds: Array<number> = [];\n\n if (indicesCount > this.indicesCount) {\n const addedIndices = indicesCount - this.indicesCount;\n\n for (let i = 0; i < addedIndices; i++) {\n const stableId = this.stableIdCounter++;\n this.stableIds.push(stableId);\n this.stableIdToIndex.set(stableId, this.stableIds.length - 1);\n const entityInfo: EntityInfo = {\n stableId,\n components: new Map(),\n states: new Map(),\n };\n this.byStableId.set(stableId, entityInfo);\n addedStableIds.push(stableId);\n }\n }\n\n this.indicesCount = indicesCount;\n\n // Update component values\n for (const [key, deltaDeltas] of componentDeltaDeltas) {\n if (deltaDeltas.length !== indicesCount) {\n throw new Error(\n `DeltaDeltas length (${deltaDeltas.length}) does not match indices count (${indicesCount})`,\n );\n }\n const existingComponent = this.componentValues.get(key);\n if (!existingComponent) {\n const values = new BigInt64Array(deltaDeltas);\n const deltas = new BigInt64Array(deltaDeltas);\n this.componentValues.set(key, { values, deltas, deltaDeltas });\n } else {\n if (existingComponent.values.length < deltaDeltas.length) {\n // Resize the arrays\n const newValues = new BigInt64Array(deltaDeltas.length);\n newValues.set(existingComponent.values);\n const newDeltas = new BigInt64Array(deltaDeltas.length);\n newDeltas.set(existingComponent.deltas);\n const newDeltaDelta = new BigInt64Array(deltaDeltas.length);\n newDeltaDelta.set(existingComponent.deltaDeltas);\n for (let i = existingComponent.values.length; i < deltaDeltas.length; i++) {\n newValues[i] = BigInt(0);\n newDeltas[i] = BigInt(0);\n newDeltaDelta[i] = BigInt(0);\n }\n existingComponent.values = newValues;\n existingComponent.deltas = newDeltas;\n existingComponent.deltaDeltas = newDeltaDelta;\n }\n\n for (let i = 0; i < deltaDeltas.length; i++) {\n const deltaDelta = deltaDeltas[i];\n const stableId = this.stableIds[i];\n\n existingComponent.deltaDeltas[i] = deltaDelta;\n existingComponent.deltas[i] += deltaDelta;\n existingComponent.values[i] += existingComponent.deltas[i];\n\n // Update byStableId map with new component values\n const entityInfo = this.byStableId.get(stableId);\n if (entityInfo) {\n entityInfo.components.set(key, existingComponent.values[i]);\n }\n }\n }\n }\n\n const stateUpdates: Array<EntityStateUpdate> = [];\n\n // Update states\n for (const [stateId, states] of stateChanges) {\n let state = this.allStates.get(stateId);\n if (!state) {\n state = [];\n this.allStates.set(stateId, state);\n }\n\n for (const [index, value] of states) {\n const stableId = this.stableIds[index];\n\n if (stableId === undefined) {\n throw new Error(`Stable ID is undefined for index ${index} in state ${stateId}`);\n }\n\n stateUpdates.push({\n stableId,\n stateId,\n state: value,\n });\n state[index] = value;\n\n // Update byStableId map with new state values\n const entityInfo = this.byStableId.get(stableId);\n if (entityInfo) {\n entityInfo.states.set(stateId, value);\n }\n }\n }\n\n return { stateUpdates, removedStableIds, addedStableIds };\n }\n\n public setLocalIndex(index: number) {\n this.localClientIndex = index;\n }\n\n private removeIndices(removing: Array<number>) {\n if (removing.length === 0) {\n return;\n }\n\n let writeIndex = 0;\n let skipIndex = 0;\n\n for (let readIndex = 0; readIndex < this.stableIds.length; readIndex++) {\n if (skipIndex < removing.length && readIndex === removing[skipIndex]) {\n skipIndex++;\n continue;\n }\n\n const stableId = this.stableIds[readIndex];\n if (writeIndex !== readIndex) {\n this.stableIds[writeIndex] = this.stableIds[readIndex];\n }\n // Update the mapping for all remaining elements to their new indices\n this.stableIdToIndex.set(stableId, writeIndex);\n\n writeIndex++;\n }\n\n // Actually shrink the array to the correct size\n this.stableIds.length = writeIndex;\n }\n\n private removeIndicesFromBigInt64Array(removing: Array<number>, array: BigInt64Array) {\n if (removing.length === 0) {\n return;\n }\n\n let writeIndex = 0;\n let skipIndex = 0;\n\n for (let readIndex = 0; readIndex < array.length; readIndex++) {\n if (skipIndex < removing.length && readIndex === removing[skipIndex]) {\n skipIndex++;\n continue;\n }\n\n if (writeIndex !== readIndex) {\n array[writeIndex] = array[readIndex];\n }\n\n writeIndex++;\n }\n for (let i = writeIndex; i < array.length; i++) {\n array[i] = BigInt(0);\n }\n }\n\n private removeIndicesFromState(removing: Array<number>, state: Array<Uint8Array | null>) {\n if (removing.length === 0) {\n return;\n }\n\n let writeIndex = 0;\n let skipIndex = 0;\n\n for (let readIndex = 0; readIndex < state.length; readIndex++) {\n if (skipIndex < removing.length && readIndex === removing[skipIndex]) {\n skipIndex++;\n continue;\n }\n\n if (writeIndex !== readIndex) {\n state[writeIndex] = state[readIndex];\n }\n\n writeIndex++;\n }\n }\n}\n", "import { deltaNetProtocolSubProtocol_v0_1 } from \"@mml-io/delta-net-protocol\";\n\nimport { DeltaNetClientWebsocketV01Adapter } from \"./DeltaNetClientWebsocketV01Adapter\";\n\nconst startingBackoffTimeMilliseconds = 100;\nconst maximumBackoffTimeMilliseconds = 10000;\nconst maximumWebsocketConnectionTimeout = 5000;\n\nexport type DeltaNetClientWebsocketFactory = (url: string) => WebSocket;\n\nexport enum DeltaNetClientWebsocketStatus {\n Connecting,\n ConnectionOpen, // The websocket is open and connected, but no messages have been received yet\n Connected, // The websocket is open and connected, and messages are being received\n Reconnecting,\n Disconnected,\n}\n\nexport function DeltaNetClientWebsocketStatusToString(\n status: DeltaNetClientWebsocketStatus,\n): string {\n switch (status) {\n case DeltaNetClientWebsocketStatus.Connecting:\n return \"Connecting...\";\n case DeltaNetClientWebsocketStatus.ConnectionOpen:\n return \"Connection Open\";\n case DeltaNetClientWebsocketStatus.Connected:\n return \"Connected\";\n case DeltaNetClientWebsocketStatus.Reconnecting:\n return \"Reconnecting...\";\n case DeltaNetClientWebsocketStatus.Disconnected:\n return \"Disconnected\";\n default:\n return \"Unknown\";\n }\n}\n\nexport type DeltaNetClientWebsocketInitialCheckout = {\n indicesCount: number;\n initialComponents: Map<number, { values: BigInt64Array; deltas: BigInt64Array }>;\n initialStates: Map<number, Array<Uint8Array>>;\n};\n\nexport type DeltaNetClientWebsocketTick = {\n unoccupying: Array<number>;\n indicesCount: number;\n componentDeltaDeltas: Map<number, BigInt64Array>;\n stateChanges: Map<number, Map<number, Uint8Array>>;\n};\n\nexport type DeltaNetClientWebsocketUserIndex = {\n userIndex: number;\n};\n\nexport type DeltaNetClientWebsocketOptions = {\n ignoreData?: boolean;\n observer?: boolean;\n onUserIndex: (userIndex: DeltaNetClientWebsocketUserIndex) => void;\n onInitialCheckout: (initialCheckout: DeltaNetClientWebsocketInitialCheckout) => void;\n onTick: (tick: DeltaNetClientWebsocketTick) => void;\n onError: (errorType: string, errorMessage: string, retryable: boolean) => void;\n onWarning: (warning: string) => void;\n onServerCustom?: (customType: number, contents: string) => void;\n};\n\nexport type DeltaNetClientWebsocketAdapter = {\n receiveMessage: (message: MessageEvent) => void;\n setUserComponents: (\n components: Map<number, bigint>,\n changedStates: Map<number, Uint8Array>,\n ) => void;\n sendCustomMessage: (customType: number, contents: string) => void;\n didConnect: () => boolean;\n dispose: () => void;\n};\n\nfunction updateLastSecondArray(\n records: Array<[number, number]>,\n size: number,\n time: number,\n): number {\n let sizeChange = size;\n const oneSecondAgo = time - 1000;\n records.push([time, size]);\n let i;\n for (i = 0; i < records.length; i++) {\n if (records[i][0] < oneSecondAgo) {\n sizeChange -= records[i][1];\n } else {\n break;\n }\n }\n records.splice(0, i);\n return sizeChange;\n}\n\n/**\n * DeltaNetClientWebsocket is a client for a DeltaNetServer. It connects to a server on the provided url and receives\n * updates to the DOM. It also sends events to the server for interactions with the DOM.\n *\n * The DeltaNetClientWebsocket is attached to a parentElement and synchronizes the received DOM under that element.\n */\nexport class DeltaNetClientWebsocket {\n private websocket: WebSocket | null = null;\n private websocketAdapter: DeltaNetClientWebsocketAdapter | null = null;\n\n private stopped = false;\n private backoffTime = startingBackoffTimeMilliseconds;\n private status: DeltaNetClientWebsocketStatus = DeltaNetClientWebsocketStatus.Connecting;\n\n public bandwidthPerSecond = 0;\n public lastSecondMessageSizes: Array<[number, number]> = []; // Timestamp in ms, size in bytes\n public componentBytesPerSecond = 0;\n public lastSecondComponentBufferSizes: Array<[number, number]> = []; // Timestamp in ms, size in bytes\n public stateBytesPerSecond = 0;\n public lastSecondStateBufferSizes: Array<[number, number]> = []; // Timestamp in ms, size in bytes\n\n public static createWebSocket(url: string): WebSocket {\n return new WebSocket(url, [deltaNetProtocolSubProtocol_v0_1]);\n }\n\n constructor(\n private url: string,\n private websocketFactory: DeltaNetClientWebsocketFactory,\n private token: string,\n private options: DeltaNetClientWebsocketOptions,\n private timeCallback?: (time: number) => void,\n private statusUpdateCallback?: (status: DeltaNetClientWebsocketStatus) => void,\n ) {\n this.setStatus(DeltaNetClientWebsocketStatus.Connecting);\n this.startWebSocketConnectionAttempt();\n }\n\n private setStatus(status: DeltaNetClientWebsocketStatus) {\n if (this.status !== status) {\n this.status = status;\n if (this.statusUpdateCallback) {\n this.statusUpdateCallback(status);\n }\n }\n }\n\n public getStatus(): DeltaNetClientWebsocketStatus {\n return this.status;\n }\n\n private async createWebsocketWithTimeout(timeout: number): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const websocket = this.websocketFactory(this.url);\n const timeoutId = setTimeout(() => {\n reject(new Error(\"websocket connection timed out\"));\n websocket.close();\n }, timeout);\n websocket.binaryType = \"arraybuffer\";\n websocket.addEventListener(\"open\", () => {\n clearTimeout(timeoutId);\n\n this.websocket = websocket;\n const websocketAdapter: DeltaNetClientWebsocketAdapter =\n new DeltaNetClientWebsocketV01Adapter(\n websocket,\n () => {\n this.backoffTime = startingBackoffTimeMilliseconds;\n this.setStatus(DeltaNetClientWebsocketStatus.Connected);\n },\n this.options,\n this.token,\n {\n receivedBytes: (bytes: number, now: number) => {\n this.bandwidthPerSecond += updateLastSecondArray(\n this.lastSecondMessageSizes,\n bytes,\n now,\n );\n },\n receivedComponentBytes: (bytes: number, now: number) => {\n this.componentBytesPerSecond += updateLastSecondArray(\n this.lastSecondComponentBufferSizes,\n bytes,\n now,\n );\n },\n receivedStateBytes: (bytes: number, now: number) => {\n this.stateBytesPerSecond += updateLastSecondArray(\n this.lastSecondStateBufferSizes,\n bytes,\n now,\n );\n },\n onError: (errorType: string, errorMessage: string, retryable: boolean) => {\n this.options.onError(errorType, errorMessage, retryable);\n if (this.websocket === websocket) {\n this.websocket?.close();\n this.websocket = null;\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n onWebsocketClose(retryable);\n }\n },\n onWarning: (warning: string) => {\n this.options.onWarning(warning);\n },\n },\n this.timeCallback,\n );\n\n this.websocketAdapter = websocketAdapter;\n\n websocket.addEventListener(\"message\", (event) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket message event because it is no longer current\");\n websocket.close();\n return;\n }\n if (this.stopped) {\n console.warn(\"Ignoring websocket message event because the client is stopped\");\n return;\n }\n\n websocketAdapter.receiveMessage(event);\n });\n\n const onWebsocketClose = async (retryable: boolean = true) => {\n let didConnect = false;\n if (this.websocketAdapter) {\n didConnect = this.websocketAdapter.didConnect();\n }\n if (this.stopped) {\n // This closing is expected. The client closed the websocket.\n this.setStatus(DeltaNetClientWebsocketStatus.Disconnected);\n return;\n }\n if (retryable) {\n if (!didConnect) {\n // The websocket did not deliver any contents.\n // It may have been successfully opened, but immediately closed.\n // This client should back off to prevent this happening in a rapid loop.\n await this.waitBackoffTime();\n }\n // The websocket closed unexpectedly. Try to reconnect.\n this.setStatus(DeltaNetClientWebsocketStatus.Reconnecting);\n this.startWebSocketConnectionAttempt();\n } else {\n this.setStatus(DeltaNetClientWebsocketStatus.Disconnected);\n }\n };\n\n websocket.addEventListener(\"close\", () => {\n if (websocket !== this.websocket) {\n console.warn(\"Ignoring websocket close event because it is no longer current\");\n return;\n }\n this.websocket = null;\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n onWebsocketClose();\n });\n websocket.addEventListener(\"error\", (e) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket error event because it is no longer current\");\n return;\n }\n console.error(\"DeltaNetClientWebsocket error\", e);\n this.websocket = null;\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n onWebsocketClose();\n });\n\n this.setStatus(DeltaNetClientWebsocketStatus.ConnectionOpen);\n resolve(websocket);\n });\n websocket.addEventListener(\"error\", (e) => {\n clearTimeout(timeoutId);\n reject(e);\n });\n });\n }\n\n private async waitBackoffTime(): Promise<void> {\n console.warn(`Websocket connection to '${this.url}' failed: retrying in ${this.backoffTime}ms`);\n await new Promise((resolve) => setTimeout(resolve, this.backoffTime));\n this.backoffTime = Math.min(\n // Introduce a small amount of randomness to prevent clients from retrying in lockstep\n this.backoffTime * (1.5 + Math.random() * 0.5),\n maximumBackoffTimeMilliseconds,\n );\n }\n\n private async startWebSocketConnectionAttempt() {\n if (this.stopped) {\n return;\n }\n while (true) {\n if (this.stopped) {\n return;\n }\n try {\n await this.createWebsocketWithTimeout(maximumWebsocketConnectionTimeout);\n break;\n } catch (e) {\n console.error(\"Websocket connection failed\", e);\n // Connection failed, retry with backoff\n this.setStatus(DeltaNetClientWebsocketStatus.Reconnecting);\n await this.waitBackoffTime();\n }\n }\n }\n\n public stop() {\n this.stopped = true;\n if (this.websocket !== null) {\n this.websocket.close();\n this.websocket = null;\n }\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n }\n\n public setUserComponents(\n components: Map<number, bigint>,\n changedStates: Map<number, Uint8Array>,\n ) {\n if (this.websocketAdapter) {\n this.websocketAdapter.setUserComponents(components, changedStates);\n }\n }\n\n public sendCustomMessage(customType: number, contents: string) {\n if (this.websocketAdapter) {\n this.websocketAdapter.sendCustomMessage(customType, contents);\n }\n }\n}\n", "import {\n BufferReader,\n BufferWriter,\n decodeServerMessages,\n DeltaNetV01ClientMessage,\n DeltaNetV01ClientCustomMessage,\n DeltaNetV01InitialCheckoutMessage,\n DeltaNetV01PingMessage,\n DeltaNetV01ServerMessage,\n DeltaNetV01ServerCustomMessage,\n DeltaNetV01SetUserComponentsMessage,\n DeltaNetV01Tick,\n DeltaNetV01UserIndexMessage,\n encodeClientMessage,\n lastInitialCheckoutDebugData,\n lastTickDebugData,\n} from \"@mml-io/delta-net-protocol\";\n\nimport {\n DeltaNetClientWebsocketAdapter,\n DeltaNetClientWebsocketOptions,\n} from \"./DeltaNetClientWebsocket\";\n\nfunction areUint8ArraysEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\nexport class DeltaNetClientWebsocketV01Adapter implements DeltaNetClientWebsocketAdapter {\n private gotInitialCheckout = false;\n private sentUserConnect = false;\n private receivedUserIndex = false;\n private queuedStateUpdates = new Map<number, Uint8Array>();\n private states = new Map<number, Uint8Array>();\n private disposed = false;\n private isObserver: boolean;\n\n constructor(\n private websocket: WebSocket,\n private connectedCallback: () => void,\n private options: DeltaNetClientWebsocketOptions,\n private token: string,\n private internalOptions: {\n receivedBytes: (bytes: number, now: number) => void;\n receivedComponentBytes: (bytes: number, now: number) => void;\n receivedStateBytes: (bytes: number, now: number) => void;\n onError: (errorType: string, errorMessage: string, retryable: boolean) => void;\n onWarning: (warning: string) => void;\n },\n private timeCallback?: (time: number) => void,\n ) {\n this.websocket.binaryType = \"arraybuffer\";\n this.isObserver = options.observer ?? false;\n\n // Observers need to send connectUser message immediately since they won't call setUserComponents\n if (this.isObserver) {\n this.sendConnectUser([], []);\n }\n }\n\n private sendConnectUser(\n components: Array<[number, bigint]>,\n states: Array<[number, Uint8Array]>,\n ) {\n if (this.sentUserConnect) {\n return;\n }\n\n this.sentUserConnect = true;\n this.send({\n type: \"connectUser\",\n token: this.token,\n observer: this.isObserver,\n components: this.isObserver ? [] : components,\n states: this.isObserver ? [] : states,\n });\n }\n\n public setUserComponents(\n components: Map<number, bigint>,\n changedStates: Map<number, Uint8Array>,\n ) {\n if (this.disposed) {\n throw new Error(\"DeltaNetClientWebsocketV01Adapter is disposed\");\n }\n\n const messageComponents: Array<[number, bigint]> = [];\n for (const [componentId, value] of components) {\n messageComponents.push([componentId, value]);\n }\n\n const messageStates: Array<[number, Uint8Array]> = [];\n for (const [stateId, value] of changedStates) {\n const currentState = this.states.get(stateId);\n if (currentState && areUint8ArraysEqual(currentState, value)) {\n continue;\n }\n this.states.set(stateId, value);\n messageStates.push([stateId, value]);\n }\n\n if (!this.sentUserConnect) {\n this.sendConnectUser(messageComponents, messageStates);\n return;\n }\n\n // Observers should not send component updates after initial connection\n if (this.isObserver) {\n return;\n }\n\n let messageStatesToSend: Array<[number, Uint8Array]> = [];\n if (this.receivedUserIndex) {\n messageStatesToSend = messageStates;\n } else {\n for (const [stateId, value] of messageStates) {\n this.queuedStateUpdates.set(stateId, value);\n }\n }\n\n if (messageComponents.length > 0 || messageStatesToSend.length > 0) {\n const setUserComponents: DeltaNetV01SetUserComponentsMessage = {\n type: \"setUserComponents\",\n components: messageComponents,\n states: messageStatesToSend,\n };\n\n this.send(setUserComponents);\n }\n }\n\n private send(message: DeltaNetV01ClientMessage) {\n const writer = new BufferWriter(256);\n encodeClientMessage(message, writer);\n this.websocket.send(writer.getBuffer());\n }\n\n public sendCustomMessage(customType: number, contents: string) {\n if (this.disposed) {\n return;\n }\n\n const customMessage: DeltaNetV01ClientCustomMessage = {\n type: \"clientCustom\",\n customType,\n contents,\n };\n\n this.send(customMessage);\n }\n\n public receiveMessage(event: MessageEvent) {\n if (this.disposed) {\n return;\n }\n\n const buffer = new Uint8Array(event.data);\n const now = Date.now();\n this.internalOptions.receivedBytes(buffer.byteLength, now);\n const reader = new BufferReader(buffer);\n const messages = decodeServerMessages(reader, {\n ignoreData: this.options.ignoreData,\n });\n for (const message of messages) {\n this.applyMessage(message, now);\n }\n }\n\n private applyMessage(message: DeltaNetV01ServerMessage, now: number) {\n switch (message.type) {\n case \"error\":\n console.error(\"Error from server\", message);\n this.internalOptions.onError(message.errorType, message.message, message.retryable);\n break;\n case \"warning\":\n console.warn(\"Warning from server\", message);\n this.internalOptions.onWarning(message.message);\n break;\n case \"initialCheckout\":\n this.handleInitialCheckout(message, now);\n this.connectedCallback();\n break;\n case \"tick\":\n this.handleTick(message, now);\n break;\n case \"userIndex\":\n this.handleUserIndex(message);\n break;\n case \"ping\":\n this.handlePing(message);\n break;\n case \"serverCustom\":\n this.handleServerCustom(message);\n break;\n default:\n console.warn(\"unknown message type\", message);\n break;\n }\n }\n\n private handleUserIndex(message: DeltaNetV01UserIndexMessage) {\n this.receivedUserIndex = true;\n\n this.options.onUserIndex({\n userIndex: message.index,\n });\n\n this.sendQueuedUpdates();\n }\n\n private sendQueuedUpdates() {\n if (this.queuedStateUpdates.size > 0) {\n const queuedStatesArray: Array<[number, Uint8Array]> = [];\n for (const [stateId, value] of this.queuedStateUpdates) {\n queuedStatesArray.push([stateId, value]);\n }\n const setUserComponents: DeltaNetV01SetUserComponentsMessage = {\n type: \"setUserComponents\",\n components: [],\n states: queuedStatesArray,\n };\n this.send(setUserComponents);\n this.queuedStateUpdates.clear();\n }\n }\n\n private handlePing(message: DeltaNetV01PingMessage) {\n this.send({\n type: \"pong\",\n pong: message.ping,\n });\n }\n\n private handleServerCustom(message: DeltaNetV01ServerCustomMessage) {\n this.options.onServerCustom?.(message.customType, message.contents);\n }\n\n public didConnect(): boolean {\n return this.gotInitialCheckout;\n }\n\n private handleInitialCheckout(message: DeltaNetV01InitialCheckoutMessage, now: number) {\n this.gotInitialCheckout = true;\n\n if (this.options.ignoreData) {\n return;\n }\n\n const components = new Map<number, { values: BigInt64Array; deltas: BigInt64Array }>();\n for (const { componentId, deltas, values } of message.components) {\n components.set(componentId, { values, deltas });\n }\n\n const allStates = new Map<number, Array<Uint8Array>>();\n for (const { stateId, values } of message.states) {\n allStates.set(stateId, values);\n }\n\n this.internalOptions.receivedComponentBytes(\n lastInitialCheckoutDebugData.componentsByteLength,\n now,\n );\n this.internalOptions.receivedStateBytes(lastInitialCheckoutDebugData.statesByteLength, now);\n\n this.options.onInitialCheckout({\n indicesCount: message.indicesCount,\n initialComponents: components,\n initialStates: allStates,\n });\n }\n\n private handleTick(message: DeltaNetV01Tick, now: number) {\n if (this.options.ignoreData) {\n return;\n }\n this.timeCallback?.(message.serverTime);\n const components = new Map<number, BigInt64Array>();\n for (const { componentId, deltaDeltas } of message.componentDeltaDeltas) {\n components.set(componentId, deltaDeltas);\n }\n\n const stateChanges = new Map<number, Map<number, Uint8Array>>();\n for (const stateChange of message.states) {\n const updatedStates = new Map<number, Uint8Array>();\n for (const [index, value] of stateChange.updatedStates) {\n updatedStates.set(index, value);\n }\n stateChanges.set(stateChange.stateId, updatedStates);\n }\n\n this.internalOptions.receivedComponentBytes(lastTickDebugData.componentsByteLength, now);\n this.internalOptions.receivedStateBytes(lastTickDebugData.statesByteLength, now);\n\n this.options.onTick({\n unoccupying: message.removedIndices,\n indicesCount: message.indicesCount,\n componentDeltaDeltas: components,\n stateChanges,\n });\n }\n\n dispose() {\n this.disposed = true;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n DeltaNetClientWebsocketInitialCheckout,\n DeltaNetClientWebsocketTick,\n} from \"./DeltaNetClientWebsocket\";\n\nexport type EntityStateUpdate = { stableId: number; stateId: number; state: Uint8Array };\n\nexport type EntityInfo = {\n stableId: number;\n components: Map<number, bigint>;\n states: Map<number, Uint8Array>;\n};\n\nexport type DeltaNetClientComponent = {\n values: BigInt64Array;\n deltas: BigInt64Array;\n deltaDeltas: BigInt64Array;\n};\n\nexport class DeltaNetClientState {\n private componentValues = new Map<number, DeltaNetClientComponent>();\n private allStates = new Map<number, Array<Uint8Array>>();\n\n public byStableId: Map<number, EntityInfo> = new Map();\n\n private localClientIndex: number = -1;\n\n private indicesCount: number = 0;\n\n private stableIdToIndex = new Map<number, number>();\n private stableIds: Array<number> = [];\n private stableIdCounter = 1000; // Start at 1000 to avoid confusion with indices\n\n constructor() {\n this.reset();\n }\n\n /**\n * Reset all state to initial values. This should be called when reconnecting\n * to ensure that stale data from previous connections doesn't interfere.\n */\n public reset() {\n this.componentValues.clear();\n this.allStates.clear();\n this.byStableId.clear();\n this.localClientIndex = -1;\n this.indicesCount = 0;\n this.stableIdToIndex.clear();\n this.stableIds.length = 0;\n this.stableIdCounter = 1000;\n }\n\n public getComponentValues(): Map<number, DeltaNetClientComponent> {\n return this.componentValues;\n }\n\n public getStateById(stateId: number): Array<Uint8Array | null> | null {\n return this.allStates.get(stateId) ?? null;\n }\n\n public getAllStates(): Map<number, Array<Uint8Array | null>> {\n return this.allStates;\n }\n\n public getLocalClientIndex(): number {\n return this.localClientIndex;\n }\n\n public getIndicesCount(): number {\n return this.indicesCount;\n }\n\n public getStableIds(): Array<number> {\n return this.stableIds;\n }\n\n public getComponentValueForStableId(stableId: number, componentId: number): bigint | null {\n const index = this.stableIdToIndex.get(stableId);\n if (index === undefined) {\n return null;\n }\n const componentValue = this.componentValues.get(componentId);\n if (!componentValue) {\n return null;\n }\n return componentValue.values[index] ?? null;\n }\n\n public getComponentsForStableId(stableId: number): Map<number, bigint> | null {\n const index = this.stableIdToIndex.get(stableId);\n if (index === undefined) {\n return null;\n }\n const componentMap = new Map<number, bigint>();\n for (const [key, componentValue] of this.componentValues) {\n if (componentValue === undefined) {\n throw new Error(`Component value for key ${key} is undefined`);\n }\n componentMap.set(key, componentValue.values[index]);\n }\n return componentMap;\n }\n\n public handleInitialCheckout(initialCheckout: DeltaNetClientWebsocketInitialCheckout): {\n addedStableIds: Array<number>;\n } {\n const { indicesCount, initialComponents, initialStates } = initialCheckout;\n const addedStableIds: Array<number> = [];\n for (let i = 0; i < indicesCount; i++) {\n const stableId = this.stableIdCounter++;\n this.stableIds.push(stableId);\n this.stableIdToIndex.set(stableId, i);\n const entityInfo: EntityInfo = {\n stableId,\n components: new Map(),\n states: new Map(),\n };\n this.byStableId.set(stableId, entityInfo);\n addedStableIds.push(stableId);\n }\n this.indicesCount = indicesCount;\n\n const deltaDeltas = new BigInt64Array(indicesCount);\n for (let i = 0; i < deltaDeltas.length; i++) {\n deltaDeltas[i] = BigInt(0);\n }\n\n for (const [key, value] of initialComponents) {\n this.componentValues.set(key, {\n values: value.values,\n deltas: value.deltas,\n deltaDeltas,\n });\n\n for (let i = 0; i < this.stableIds.length; i++) {\n const stableId = this.stableIds[i];\n const entityInfo = this.byStableId.get(stableId);\n if (entityInfo) {\n entityInfo.components.set(key, value.values[i]);\n }\n }\n }\n\n for (const [stateId, values] of initialStates) {\n this.allStates.set(stateId, values);\n\n for (let i = 0; i < this.stableIds.length; i++) {\n const stableId = this.stableIds[i];\n const entityInfo = this.byStableId.get(stableId);\n const stateValue = values[i];\n if (entityInfo) {\n entityInfo.states.set(stateId, stateValue);\n }\n }\n }\n\n return { addedStableIds };\n }\n\n public handleTick(tick: DeltaNetClientWebsocketTick): {\n stateUpdates: Array<EntityStateUpdate>;\n removedStableIds: Array<number>;\n addedStableIds: Array<number>;\n } {\n const { unoccupying, indicesCount, componentDeltaDeltas, stateChanges } = tick;\n\n let removedStableIds: Array<number> = [];\n\n if (unoccupying.length > 0) {\n // Collect stableIds to remove before mutating stableIds\n const stableIdsToRemove = unoccupying.map((index) => this.stableIds[index]);\n removedStableIds = stableIdsToRemove.filter((stableId) => stableId !== undefined);\n\n // Remove unoccupying indices from component values\n for (const [componentId, component] of this.componentValues) {\n this.removeIndicesFromBigInt64Array(unoccupying, component.values);\n this.removeIndicesFromBigInt64Array(unoccupying, component.deltas);\n }\n\n // Remove unoccupying indices from states\n for (const [stateId, state] of this.allStates) {\n this.removeIndicesFromState(unoccupying, state);\n }\n\n // Update localClientIndex\n let decrementIndex = 0;\n for (const index of unoccupying) {\n if (index <= this.localClientIndex) {\n decrementIndex++;\n }\n }\n this.localClientIndex -= decrementIndex;\n\n // Update indices count\n this.indicesCount -= unoccupying.length;\n\n // Update stable indices and stableIds array\n this.removeIndices(unoccupying);\n\n // Remove unoccupied stables from byStableId\n for (const stableId of stableIdsToRemove) {\n if (stableId === undefined) {\n throw new Error(`stableId is undefined`);\n }\n this.byStableId.delete(stableId);\n }\n }\n\n const addedStableIds: Array<number> = [];\n\n if (indicesCount > this.indicesCount) {\n const addedIndices = indicesCount - this.indicesCount;\n\n for (let i = 0; i < addedIndices; i++) {\n const stableId = this.stableIdCounter++;\n this.stableIds.push(stableId);\n this.stableIdToIndex.set(stableId, this.stableIds.length - 1);\n const entityInfo: EntityInfo = {\n stableId,\n components: new Map(),\n states: new Map(),\n };\n this.byStableId.set(stableId, entityInfo);\n addedStableIds.push(stableId);\n }\n }\n\n this.indicesCount = indicesCount;\n\n // Update component values\n for (const [key, deltaDeltas] of componentDeltaDeltas) {\n if (deltaDeltas.length !== indicesCount) {\n throw new Error(\n `DeltaDeltas length (${deltaDeltas.length}) does not match indices count (${indicesCount})`,\n );\n }\n const existingComponent = this.componentValues.get(key);\n if (!existingComponent) {\n const values = new BigInt64Array(deltaDeltas);\n const deltas = new BigInt64Array(deltaDeltas);\n this.componentValues.set(key, { values, deltas, deltaDeltas });\n } else {\n if (existingComponent.values.length < deltaDeltas.length) {\n // Resize the arrays\n const newValues = new BigInt64Array(deltaDeltas.length);\n newValues.set(existingComponent.values);\n const newDeltas = new BigInt64Array(deltaDeltas.length);\n newDeltas.set(existingComponent.deltas);\n const newDeltaDelta = new BigInt64Array(deltaDeltas.length);\n newDeltaDelta.set(existingComponent.deltaDeltas);\n for (let i = existingComponent.values.length; i < deltaDeltas.length; i++) {\n newValues[i] = BigInt(0);\n newDeltas[i] = BigInt(0);\n newDeltaDelta[i] = BigInt(0);\n }\n existingComponent.values = newValues;\n existingComponent.deltas = newDeltas;\n existingComponent.deltaDeltas = newDeltaDelta;\n }\n\n for (let i = 0; i < deltaDeltas.length; i++) {\n const deltaDelta = deltaDeltas[i];\n const stableId = this.stableIds[i];\n\n existingComponent.deltaDeltas[i] = deltaDelta;\n existingComponent.deltas[i] += deltaDelta;\n existingComponent.values[i] += existingComponent.deltas[i];\n\n // Update byStableId map with new component values\n const entityInfo = this.byStableId.get(stableId);\n if (entityInfo) {\n entityInfo.components.set(key, existingComponent.values[i]);\n }\n }\n }\n }\n\n const stateUpdates: Array<EntityStateUpdate> = [];\n\n // Update states\n for (const [stateId, states] of stateChanges) {\n let state = this.allStates.get(stateId);\n if (!state) {\n state = [];\n this.allStates.set(stateId, state);\n }\n\n for (const [index, value] of states) {\n const stableId = this.stableIds[index];\n\n if (stableId === undefined) {\n throw new Error(`Stable ID is undefined for index ${index} in state ${stateId}`);\n }\n\n stateUpdates.push({\n stableId,\n stateId,\n state: value,\n });\n state[index] = value;\n\n // Update byStableId map with new state values\n const entityInfo = this.byStableId.get(stableId);\n if (entityInfo) {\n entityInfo.states.set(stateId, value);\n }\n }\n }\n\n return { stateUpdates, removedStableIds, addedStableIds };\n }\n\n public setLocalIndex(index: number) {\n this.localClientIndex = index;\n }\n\n private removeIndices(removing: Array<number>) {\n if (removing.length === 0) {\n return;\n }\n\n let writeIndex = 0;\n let skipIndex = 0;\n\n for (let readIndex = 0; readIndex < this.stableIds.length; readIndex++) {\n if (skipIndex < removing.length && readIndex === removing[skipIndex]) {\n skipIndex++;\n continue;\n }\n\n const stableId = this.stableIds[readIndex];\n if (writeIndex !== readIndex) {\n this.stableIds[writeIndex] = this.stableIds[readIndex];\n }\n // Update the mapping for all remaining elements to their new indices\n this.stableIdToIndex.set(stableId, writeIndex);\n\n writeIndex++;\n }\n\n // Actually shrink the array to the correct size\n this.stableIds.length = writeIndex;\n }\n\n private removeIndicesFromBigInt64Array(removing: Array<number>, array: BigInt64Array) {\n if (removing.length === 0) {\n return;\n }\n\n let writeIndex = 0;\n let skipIndex = 0;\n\n for (let readIndex = 0; readIndex < array.length; readIndex++) {\n if (skipIndex < removing.length && readIndex === removing[skipIndex]) {\n skipIndex++;\n continue;\n }\n\n if (writeIndex !== readIndex) {\n array[writeIndex] = array[readIndex];\n }\n\n writeIndex++;\n }\n for (let i = writeIndex; i < array.length; i++) {\n array[i] = BigInt(0);\n }\n }\n\n private removeIndicesFromState(removing: Array<number>, state: Array<Uint8Array | null>) {\n if (removing.length === 0) {\n return;\n }\n\n let writeIndex = 0;\n let skipIndex = 0;\n\n for (let readIndex = 0; readIndex < state.length; readIndex++) {\n if (skipIndex < removing.length && readIndex === removing[skipIndex]) {\n skipIndex++;\n continue;\n }\n\n if (writeIndex !== readIndex) {\n state[writeIndex] = state[readIndex];\n }\n\n writeIndex++;\n }\n }\n}\n", "import { deltaNetProtocolSubProtocol_v0_1 } from \"@mml-io/delta-net-protocol\";\n\nimport { DeltaNetClientWebsocketV01Adapter } from \"./DeltaNetClientWebsocketV01Adapter\";\n\nconst startingBackoffTimeMilliseconds = 100;\nconst maximumBackoffTimeMilliseconds = 10000;\nconst maximumWebsocketConnectionTimeout = 5000;\n\nexport type DeltaNetClientWebsocketFactory = (url: string) => WebSocket;\n\nexport enum DeltaNetClientWebsocketStatus {\n Connecting,\n ConnectionOpen, // The websocket is open and connected, but no messages have been received yet\n Connected, // The websocket is open and connected, and messages are being received\n Reconnecting,\n Disconnected,\n}\n\nexport function DeltaNetClientWebsocketStatusToString(\n status: DeltaNetClientWebsocketStatus,\n): string {\n switch (status) {\n case DeltaNetClientWebsocketStatus.Connecting:\n return \"Connecting...\";\n case DeltaNetClientWebsocketStatus.ConnectionOpen:\n return \"Connection Open\";\n case DeltaNetClientWebsocketStatus.Connected:\n return \"Connected\";\n case DeltaNetClientWebsocketStatus.Reconnecting:\n return \"Reconnecting...\";\n case DeltaNetClientWebsocketStatus.Disconnected:\n return \"Disconnected\";\n default:\n return \"Unknown\";\n }\n}\n\nexport type DeltaNetClientWebsocketInitialCheckout = {\n indicesCount: number;\n initialComponents: Map<number, { values: BigInt64Array; deltas: BigInt64Array }>;\n initialStates: Map<number, Array<Uint8Array>>;\n};\n\nexport type DeltaNetClientWebsocketTick = {\n unoccupying: Array<number>;\n indicesCount: number;\n componentDeltaDeltas: Map<number, BigInt64Array>;\n stateChanges: Map<number, Map<number, Uint8Array>>;\n};\n\nexport type DeltaNetClientWebsocketUserIndex = {\n userIndex: number;\n};\n\nexport type DeltaNetClientWebsocketOptions = {\n ignoreData?: boolean;\n observer?: boolean;\n onUserIndex: (userIndex: DeltaNetClientWebsocketUserIndex) => void;\n onInitialCheckout: (initialCheckout: DeltaNetClientWebsocketInitialCheckout) => void;\n onTick: (tick: DeltaNetClientWebsocketTick) => void;\n onError: (errorType: string, errorMessage: string, retryable: boolean) => void;\n onWarning: (warning: string) => void;\n onServerCustom?: (customType: number, contents: string) => void;\n};\n\nexport type DeltaNetClientWebsocketAdapter = {\n receiveMessage: (message: MessageEvent) => void;\n setUserComponents: (\n components: Map<number, bigint>,\n changedStates: Map<number, Uint8Array>,\n ) => void;\n sendCustomMessage: (customType: number, contents: string) => void;\n didConnect: () => boolean;\n dispose: () => void;\n};\n\nfunction updateLastSecondArray(\n records: Array<[number, number]>,\n size: number,\n time: number,\n): number {\n let sizeChange = size;\n const oneSecondAgo = time - 1000;\n records.push([time, size]);\n let i;\n for (i = 0; i < records.length; i++) {\n if (records[i][0] < oneSecondAgo) {\n sizeChange -= records[i][1];\n } else {\n break;\n }\n }\n records.splice(0, i);\n return sizeChange;\n}\n\n/**\n * DeltaNetClientWebsocket is a client for a DeltaNetServer. It connects to a server on the provided url and receives\n * updates to the DOM. It also sends events to the server for interactions with the DOM.\n *\n * The DeltaNetClientWebsocket is attached to a parentElement and synchronizes the received DOM under that element.\n */\nexport class DeltaNetClientWebsocket {\n private websocket: WebSocket | null = null;\n private websocketAdapter: DeltaNetClientWebsocketAdapter | null = null;\n\n private stopped = false;\n private backoffTime = startingBackoffTimeMilliseconds;\n private status: DeltaNetClientWebsocketStatus = DeltaNetClientWebsocketStatus.Connecting;\n\n public bandwidthPerSecond = 0;\n public lastSecondMessageSizes: Array<[number, number]> = []; // Timestamp in ms, size in bytes\n public componentBytesPerSecond = 0;\n public lastSecondComponentBufferSizes: Array<[number, number]> = []; // Timestamp in ms, size in bytes\n public stateBytesPerSecond = 0;\n public lastSecondStateBufferSizes: Array<[number, number]> = []; // Timestamp in ms, size in bytes\n\n public static createWebSocket(url: string): WebSocket {\n return new WebSocket(url, [deltaNetProtocolSubProtocol_v0_1]);\n }\n\n constructor(\n private url: string,\n private websocketFactory: DeltaNetClientWebsocketFactory,\n private token: string,\n private options: DeltaNetClientWebsocketOptions,\n private timeCallback?: (time: number) => void,\n private statusUpdateCallback?: (status: DeltaNetClientWebsocketStatus) => void,\n ) {\n this.setStatus(DeltaNetClientWebsocketStatus.Connecting);\n this.startWebSocketConnectionAttempt();\n }\n\n private setStatus(status: DeltaNetClientWebsocketStatus) {\n if (this.status !== status) {\n this.status = status;\n if (this.statusUpdateCallback) {\n this.statusUpdateCallback(status);\n }\n }\n }\n\n public getStatus(): DeltaNetClientWebsocketStatus {\n return this.status;\n }\n\n private async createWebsocketWithTimeout(timeout: number): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const websocket = this.websocketFactory(this.url);\n const timeoutId = setTimeout(() => {\n reject(new Error(\"websocket connection timed out\"));\n websocket.close();\n }, timeout);\n websocket.binaryType = \"arraybuffer\";\n websocket.addEventListener(\"open\", () => {\n clearTimeout(timeoutId);\n\n this.websocket = websocket;\n const websocketAdapter: DeltaNetClientWebsocketAdapter =\n new DeltaNetClientWebsocketV01Adapter(\n websocket,\n () => {\n this.backoffTime = startingBackoffTimeMilliseconds;\n this.setStatus(DeltaNetClientWebsocketStatus.Connected);\n },\n this.options,\n this.token,\n {\n receivedBytes: (bytes: number, now: number) => {\n this.bandwidthPerSecond += updateLastSecondArray(\n this.lastSecondMessageSizes,\n bytes,\n now,\n );\n },\n receivedComponentBytes: (bytes: number, now: number) => {\n this.componentBytesPerSecond += updateLastSecondArray(\n this.lastSecondComponentBufferSizes,\n bytes,\n now,\n );\n },\n receivedStateBytes: (bytes: number, now: number) => {\n this.stateBytesPerSecond += updateLastSecondArray(\n this.lastSecondStateBufferSizes,\n bytes,\n now,\n );\n },\n onError: (errorType: string, errorMessage: string, retryable: boolean) => {\n this.options.onError(errorType, errorMessage, retryable);\n if (this.websocket === websocket) {\n this.websocket?.close();\n this.websocket = null;\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n onWebsocketClose(retryable);\n }\n },\n onWarning: (warning: string) => {\n this.options.onWarning(warning);\n },\n },\n this.timeCallback,\n );\n\n this.websocketAdapter = websocketAdapter;\n\n websocket.addEventListener(\"message\", (event) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket message event because it is no longer current\");\n websocket.close();\n return;\n }\n if (this.stopped) {\n console.warn(\"Ignoring websocket message event because the client is stopped\");\n return;\n }\n\n websocketAdapter.receiveMessage(event);\n });\n\n const onWebsocketClose = async (retryable: boolean = true) => {\n let didConnect = false;\n if (this.websocketAdapter) {\n didConnect = this.websocketAdapter.didConnect();\n }\n if (this.stopped) {\n // This closing is expected. The client closed the websocket.\n this.setStatus(DeltaNetClientWebsocketStatus.Disconnected);\n return;\n }\n if (retryable) {\n if (!didConnect) {\n // The websocket did not deliver any contents.\n // It may have been successfully opened, but immediately closed.\n // This client should back off to prevent this happening in a rapid loop.\n await this.waitBackoffTime();\n }\n // The websocket closed unexpectedly. Try to reconnect.\n this.setStatus(DeltaNetClientWebsocketStatus.Reconnecting);\n this.startWebSocketConnectionAttempt();\n } else {\n this.setStatus(DeltaNetClientWebsocketStatus.Disconnected);\n }\n };\n\n websocket.addEventListener(\"close\", () => {\n if (websocket !== this.websocket) {\n console.warn(\"Ignoring websocket close event because it is no longer current\");\n return;\n }\n this.websocket = null;\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n onWebsocketClose();\n });\n websocket.addEventListener(\"error\", (e) => {\n if (websocket !== this.websocket) {\n console.log(\"Ignoring websocket error event because it is no longer current\");\n return;\n }\n console.error(\"DeltaNetClientWebsocket error\", e);\n this.websocket = null;\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n onWebsocketClose();\n });\n\n this.setStatus(DeltaNetClientWebsocketStatus.ConnectionOpen);\n resolve(websocket);\n });\n websocket.addEventListener(\"error\", (e) => {\n clearTimeout(timeoutId);\n reject(e);\n });\n });\n }\n\n private async waitBackoffTime(): Promise<void> {\n console.warn(`Websocket connection to '${this.url}' failed: retrying in ${this.backoffTime}ms`);\n await new Promise((resolve) => setTimeout(resolve, this.backoffTime));\n this.backoffTime = Math.min(\n // Introduce a small amount of randomness to prevent clients from retrying in lockstep\n this.backoffTime * (1.5 + Math.random() * 0.5),\n maximumBackoffTimeMilliseconds,\n );\n }\n\n private async startWebSocketConnectionAttempt() {\n if (this.stopped) {\n return;\n }\n while (true) {\n if (this.stopped) {\n return;\n }\n try {\n await this.createWebsocketWithTimeout(maximumWebsocketConnectionTimeout);\n break;\n } catch (e) {\n console.error(\"Websocket connection failed\", e);\n // Connection failed, retry with backoff\n this.setStatus(DeltaNetClientWebsocketStatus.Reconnecting);\n await this.waitBackoffTime();\n }\n }\n }\n\n public stop() {\n this.stopped = true;\n if (this.websocket !== null) {\n this.websocket.close();\n this.websocket = null;\n }\n this.websocketAdapter?.dispose();\n this.websocketAdapter = null;\n }\n\n public setUserComponents(\n components: Map<number, bigint>,\n changedStates: Map<number, Uint8Array>,\n ) {\n if (this.websocketAdapter) {\n this.websocketAdapter.setUserComponents(components, changedStates);\n }\n }\n\n public sendCustomMessage(customType: number, contents: string) {\n if (this.websocketAdapter) {\n this.websocketAdapter.sendCustomMessage(customType, contents);\n }\n }\n}\n", "import {\n BufferReader,\n BufferWriter,\n decodeServerMessages,\n DeltaNetV01ClientMessage,\n DeltaNetV01ClientCustomMessage,\n DeltaNetV01InitialCheckoutMessage,\n DeltaNetV01PingMessage,\n DeltaNetV01ServerMessage,\n DeltaNetV01ServerCustomMessage,\n DeltaNetV01SetUserComponentsMessage,\n DeltaNetV01Tick,\n DeltaNetV01UserIndexMessage,\n encodeClientMessage,\n lastInitialCheckoutDebugData,\n lastTickDebugData,\n} from \"@mml-io/delta-net-protocol\";\nimport { DeltaNetV01ConnectUserMessage } from \"@mml-io/delta-net-protocol/src\";\n\nimport {\n DeltaNetClientWebsocketAdapter,\n DeltaNetClientWebsocketOptions,\n} from \"./DeltaNetClientWebsocket\";\n\nfunction areUint8ArraysEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\nexport class DeltaNetClientWebsocketV01Adapter implements DeltaNetClientWebsocketAdapter {\n private gotInitialCheckout = false;\n private sentUserConnect = false;\n private receivedUserIndex = false;\n private queuedStateUpdates = new Map<number, Uint8Array>();\n private components = new Map<number, bigint>();\n private states = new Map<number, Uint8Array>();\n private disposed = false;\n private isObserver: boolean;\n\n constructor(\n private websocket: WebSocket,\n private connectedCallback: () => void,\n private options: DeltaNetClientWebsocketOptions,\n private token: string,\n private internalOptions: {\n receivedBytes: (bytes: number, now: number) => void;\n receivedComponentBytes: (bytes: number, now: number) => void;\n receivedStateBytes: (bytes: number, now: number) => void;\n onError: (errorType: string, errorMessage: string, retryable: boolean) => void;\n onWarning: (warning: string) => void;\n },\n private timeCallback?: (time: number) => void,\n ) {\n this.websocket.binaryType = \"arraybuffer\";\n this.isObserver = options.observer ?? false;\n\n // Observers need to send connectUser message immediately since they won't call setUserComponents\n if (this.isObserver) {\n this.sendConnectUser([], []);\n }\n }\n\n private sendConnectUser(\n components: Array<[number, bigint]>,\n states: Array<[number, Uint8Array]>,\n ) {\n if (this.sentUserConnect) {\n return;\n }\n\n this.sentUserConnect = true;\n this.send({\n type: \"connectUser\",\n token: this.token,\n observer: this.isObserver,\n components: this.isObserver ? [] : components,\n states: this.isObserver ? [] : states,\n } satisfies DeltaNetV01ConnectUserMessage);\n }\n\n public setUserComponents(\n components: Map<number, bigint>,\n changedStates: Map<number, Uint8Array>,\n ) {\n if (this.disposed) {\n throw new Error(\"DeltaNetClientWebsocketV01Adapter is disposed\");\n }\n\n const messageComponents: Array<[number, bigint]> = [];\n for (const [componentId, value] of components) {\n messageComponents.push([componentId, value]);\n this.components.set(componentId, value);\n }\n\n const messageStates: Array<[number, Uint8Array]> = [];\n for (const [stateId, value] of changedStates) {\n const currentState = this.states.get(stateId);\n if (currentState && areUint8ArraysEqual(currentState, value)) {\n continue;\n }\n this.states.set(stateId, value);\n messageStates.push([stateId, value]);\n }\n\n if (!this.sentUserConnect) {\n this.sendConnectUser(messageComponents, messageStates);\n return;\n }\n\n // Observers should not send component updates after initial connection\n if (this.isObserver) {\n return;\n }\n\n if (this.receivedUserIndex) {\n if (messageComponents.length > 0 || messageStates.length > 0) {\n const setUserComponents: DeltaNetV01SetUserComponentsMessage = {\n type: \"setUserComponents\",\n components: messageComponents,\n states: messageStates,\n };\n this.send(setUserComponents);\n }\n } else {\n for (const [stateId, value] of messageStates) {\n this.queuedStateUpdates.set(stateId, value);\n }\n }\n }\n\n private send(message: DeltaNetV01ClientMessage) {\n const writer = new BufferWriter(256);\n encodeClientMessage(message, writer);\n this.websocket.send(writer.getBuffer());\n }\n\n public sendCustomMessage(customType: number, contents: string) {\n if (this.disposed) {\n return;\n }\n\n const customMessage: DeltaNetV01ClientCustomMessage = {\n type: \"clientCustom\",\n customType,\n contents,\n };\n\n this.send(customMessage);\n }\n\n public receiveMessage(event: MessageEvent) {\n if (this.disposed) {\n return;\n }\n\n const buffer = new Uint8Array(event.data);\n const now = Date.now();\n this.internalOptions.receivedBytes(buffer.byteLength, now);\n const reader = new BufferReader(buffer);\n const messages = decodeServerMessages(reader, {\n ignoreData: this.options.ignoreData,\n });\n for (const message of messages) {\n this.applyMessage(message, now);\n }\n }\n\n private applyMessage(message: DeltaNetV01ServerMessage, now: number) {\n switch (message.type) {\n case \"error\":\n console.error(\"Error from server\", message);\n this.internalOptions.onError(message.errorType, message.message, message.retryable);\n break;\n case \"warning\":\n console.warn(\"Warning from server\", message);\n this.internalOptions.onWarning(message.message);\n break;\n case \"initialCheckout\":\n this.handleInitialCheckout(message, now);\n this.connectedCallback();\n break;\n case \"tick\":\n this.handleTick(message, now);\n break;\n case \"userIndex\":\n this.handleUserIndex(message);\n break;\n case \"ping\":\n this.handlePing(message);\n break;\n case \"serverCustom\":\n this.handleServerCustom(message);\n break;\n default:\n console.warn(\"unknown message type\", message);\n break;\n }\n }\n\n private handleUserIndex(message: DeltaNetV01UserIndexMessage) {\n this.receivedUserIndex = true;\n\n this.options.onUserIndex({\n userIndex: message.index,\n });\n\n this.sendQueuedUpdates();\n }\n\n private sendQueuedUpdates() {\n if (this.queuedStateUpdates.size > 0) {\n const queuedStatesArray: Array<[number, Uint8Array]> = [];\n for (const [stateId, value] of this.queuedStateUpdates) {\n queuedStatesArray.push([stateId, value]);\n }\n const setUserComponents: DeltaNetV01SetUserComponentsMessage = {\n type: \"setUserComponents\",\n components: Array.from(this.components.entries()),\n states: queuedStatesArray,\n };\n this.send(setUserComponents);\n this.queuedStateUpdates.clear();\n }\n }\n\n private handlePing(message: DeltaNetV01PingMessage) {\n this.send({\n type: \"pong\",\n pong: message.ping,\n });\n }\n\n private handleServerCustom(message: DeltaNetV01ServerCustomMessage) {\n this.options.onServerCustom?.(message.customType, message.contents);\n }\n\n public didConnect(): boolean {\n return this.gotInitialCheckout;\n }\n\n private handleInitialCheckout(message: DeltaNetV01InitialCheckoutMessage, now: number) {\n this.gotInitialCheckout = true;\n\n if (this.options.ignoreData) {\n return;\n }\n\n const components = new Map<number, { values: BigInt64Array; deltas: BigInt64Array }>();\n for (const { componentId, deltas, values } of message.components) {\n components.set(componentId, { values, deltas });\n }\n\n const allStates = new Map<number, Array<Uint8Array>>();\n for (const { stateId, values } of message.states) {\n allStates.set(stateId, values);\n }\n\n this.internalOptions.receivedComponentBytes(\n lastInitialCheckoutDebugData.componentsByteLength,\n now,\n );\n this.internalOptions.receivedStateBytes(lastInitialCheckoutDebugData.statesByteLength, now);\n\n this.options.onInitialCheckout({\n indicesCount: message.indicesCount,\n initialComponents: components,\n initialStates: allStates,\n });\n }\n\n private handleTick(message: DeltaNetV01Tick, now: number) {\n if (this.options.ignoreData) {\n return;\n }\n this.timeCallback?.(message.serverTime);\n const components = new Map<number, BigInt64Array>();\n for (const { componentId, deltaDeltas } of message.componentDeltaDeltas) {\n components.set(componentId, deltaDeltas);\n }\n\n const stateChanges = new Map<number, Map<number, Uint8Array>>();\n for (const stateChange of message.states) {\n const updatedStates = new Map<number, Uint8Array>();\n for (const [index, value] of stateChange.updatedStates) {\n updatedStates.set(index, value);\n }\n stateChanges.set(stateChange.stateId, updatedStates);\n }\n\n this.internalOptions.receivedComponentBytes(lastTickDebugData.componentsByteLength, now);\n this.internalOptions.receivedStateBytes(lastTickDebugData.statesByteLength, now);\n\n this.options.onTick({\n unoccupying: message.removedIndices,\n indicesCount: message.indicesCount,\n componentDeltaDeltas: components,\n stateChanges,\n });\n }\n\n dispose() {\n this.disposed = true;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["DeltaNetClientWebsocketStatus"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mml-io/delta-net-web",
3
- "version": "0.0.0-experimental-3a2278c-20250715",
3
+ "version": "0.23.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -20,12 +20,13 @@
20
20
  "test-iterate": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --watch"
21
21
  },
22
22
  "dependencies": {
23
- "@mml-io/delta-net-protocol": "0.0.0-experimental-3a2278c-20250715"
23
+ "@mml-io/delta-net-protocol": "^0.23.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "jest-canvas-mock": "2.5.2",
27
27
  "jest-environment-jsdom": "29.7.0",
28
28
  "jest-expect-message": "1.1.3",
29
29
  "jest-junit": "16.0.0"
30
- }
30
+ },
31
+ "gitHead": "1111b42ca884d9b6253b9657fa64cec3aeda4de1"
31
32
  }