@fluidframework/map 2.74.0-368706 → 2.74.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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluidframework/map
2
2
 
3
+ ## 2.74.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.73.0
4
8
 
5
9
  Dependency updates only.
@@ -1 +1 @@
1
- {"version":3,"file":"mapKernel.d.ts","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mapKernel.d.ts","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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"}
package/dist/mapKernel.js CHANGED
@@ -472,18 +472,33 @@ class MapKernel {
472
472
  const messageHandlers = new Map();
473
473
  messageHandlers.set("clear", {
474
474
  process: (op, local, localOpMetadata) => {
475
- this.sequencedData.clear();
476
475
  if (local) {
476
+ this.sequencedData.clear();
477
477
  const pendingClear = this.pendingData.shift();
478
478
  (0, internal_1.assert)(pendingClear !== undefined &&
479
479
  pendingClear.type === "clear" &&
480
480
  pendingClear === localOpMetadata, 0xbf6 /* Got a local clear message we weren't expecting */);
481
481
  }
482
482
  else {
483
+ const keysToDelete = [];
484
+ for (const [key, value] of this.sequencedData) {
485
+ // Check if this key has pending local operations that supersede the remote op
486
+ const hasPendingOps = this.pendingData.some((entry) => (entry.type === "delete" && entry.key === key) ||
487
+ (entry.type === "lifetime" && entry.key === key));
488
+ // Only collect keys without pending operations (i.e., actually deleted)
489
+ if (!hasPendingOps) {
490
+ keysToDelete.push({ key, previousValue: value.value });
491
+ }
492
+ }
493
+ this.sequencedData.clear();
483
494
  // Only emit for remote ops, we would have already emitted for local ops. Only emit if there
484
495
  // is no optimistically-applied local pending clear that would supersede this remote clear.
485
496
  if (!this.pendingData.some((entry) => entry.type === "clear")) {
486
497
  this.eventEmitter.emit("clear", local, this.eventEmitter);
498
+ // Emit delete-like valueChanged events for keys that were removed
499
+ for (const { key, previousValue } of keysToDelete) {
500
+ this.eventEmitter.emit("valueChanged", { key, previousValue }, local, this.eventEmitter);
501
+ }
487
502
  }
488
503
  }
489
504
  },
@@ -1 +1 @@
1
- {"version":3,"file":"mapKernel.js","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { ValueType } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ISharedMapEvents } from \"./interfaces.js\";\nimport type {\n\tIMapClearOperation,\n\tIMapDeleteOperation,\n\tIMapSetOperation,\n\t// eslint-disable-next-line import-x/no-deprecated\n\tISerializableValue,\n\tISerializedValue,\n} from \"./internalInterfaces.js\";\nimport {\n\ttype ILocalValue,\n\tserializeValue,\n\tmigrateIfSharedSerializable,\n} from \"./localValues.js\";\nimport { findLast, findLastIndex } from \"./utils.js\";\n\n/**\n * Defines the means to process and resubmit a given op on a map.\n */\ninterface IMapMessageHandler {\n\t/**\n\t * Apply the given operation.\n\t * @param op - The map operation to apply\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t */\n\tprocess(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t): void;\n\n\t/**\n\t * Resubmit a previously submitted operation that was not delivered.\n\t * @param op - The map operation to resubmit\n\t * @param localOpMetadata - The metadata that was originally submitted with the message.\n\t */\n\tresubmit(op: IMapOperation, localOpMetadata: PendingLocalOpMetadata): void;\n}\n\n/**\n * Union of all possible map operations.\n */\nexport type IMapOperation = IMapSetOperation | IMapDeleteOperation | IMapClearOperation;\n\n/**\n * Defines the in-memory object structure to be used for the conversion to/from serialized.\n *\n * @remarks Directly used in\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\n * | JSON.stringify}, direct result from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}.\n */\n// eslint-disable-next-line import-x/no-deprecated\nexport type IMapDataObjectSerializable = Record<string, ISerializableValue>;\n\n/**\n * Serialized key/value data.\n */\nexport type IMapDataObjectSerialized = Record<string, ISerializedValue>;\n\ninterface PendingKeySet {\n\ttype: \"set\";\n\tvalue: ILocalValue;\n}\n\ninterface PendingKeyDelete {\n\ttype: \"delete\";\n\tkey: string;\n}\n\ninterface PendingClear {\n\ttype: \"clear\";\n}\n\ninterface PendingKeyLifetime {\n\ttype: \"lifetime\";\n\tkey: string;\n\t/**\n\t * A non-empty array of pending key sets that occurred during this lifetime. If the list\n\t * becomes empty (e.g. during processing or rollback), the lifetime no longer exists and\n\t * must be removed from the pending data.\n\t */\n\tkeySets: PendingKeySet[];\n}\n\n/**\n * A member of the pendingData array, which tracks outstanding changes and can be used to\n * compute optimistic values. Local sets are aggregated into lifetimes.\n */\ntype PendingDataEntry = PendingKeyLifetime | PendingKeyDelete | PendingClear;\n/**\n * An individual outstanding change, which will also be found in the pendingData array\n * (though the PendingKeySets will be contained within a PendingKeyLifetime there).\n */\ntype PendingLocalOpMetadata = PendingKeySet | PendingKeyDelete | PendingClear;\n\n/**\n * A SharedMap is a map-like distributed data structure.\n */\nexport class MapKernel {\n\t/**\n\t * The number of key/value pairs stored in the map.\n\t */\n\tpublic get size(): number {\n\t\tconst iterableItems = [...this.internalIterator()];\n\t\treturn iterableItems.length;\n\t}\n\n\t/**\n\t * Mapping of op types to message handlers.\n\t */\n\tprivate readonly messageHandlers: ReadonlyMap<string, IMapMessageHandler> = new Map();\n\n\t/**\n\t * The data the map is storing, but only including sequenced values (no local pending\n\t * modifications are included).\n\t */\n\tprivate readonly sequencedData = new Map<string, ILocalValue>();\n\t/**\n\t * A data structure containing all local pending modifications, which is used in combination\n\t * with the sequencedData to compute optimistic values.\n\t *\n\t * Pending sets are aggregated into \"lifetimes\", which permit correct relative iteration order\n\t * even across remote operations and rollbacks.\n\t */\n\tprivate readonly pendingData: PendingDataEntry[] = [];\n\n\t/**\n\t * Create a new shared map kernel.\n\t * @param serializer - The serializer to serialize / parse handles\n\t * @param handle - The handle of the shared object using the kernel\n\t * @param submitMessage - A callback to submit a message through the shared object\n\t * @param isAttached - To query whether the shared object should generate ops\n\t * @param valueTypes - The value types to register\n\t * @param eventEmitter - The object that will emit map events\n\t */\n\tpublic constructor(\n\t\tprivate readonly serializer: IFluidSerializer,\n\t\tprivate readonly handle: IFluidHandle,\n\t\tprivate readonly submitMessage: (op: unknown, localOpMetadata: unknown) => void,\n\t\tprivate readonly isAttached: () => boolean,\n\t\tprivate readonly eventEmitter: TypedEventEmitter<ISharedMapEvents>,\n\t) {\n\t\tthis.messageHandlers = this.getMessageHandlers();\n\t}\n\n\t/**\n\t * Get an iterator over the optimistically observable ILocalValue entries in the map. For example, excluding\n\t * sequenced entries that have pending deletes/clears.\n\t *\n\t * @remarks\n\t * There is no perfect solution here, particularly when the iterator is retained over time and the map is\n\t * modified or new ack's are received. The pendingData portion of the iteration is the most susceptible to\n\t * this problem. The implementation prioritizes (in roughly this order):\n\t * 1. Correct immediate iteration (i.e. when the map is not modified before iteration completes)\n\t * 2. Consistent iteration order before/after sequencing of pending ops; acks don't change order\n\t * 3. Consistent iteration order between synchronized clients, even if they each modified the map concurrently\n\t * 4. Remaining as close as possible to the native Map iterator behavior, e.g. live-ish view rather than snapshot\n\t *\n\t * For this reason, it's important not to internally snapshot the output of the iterator for any purpose that\n\t * does not immediately (synchronously) consume that output and dispose of it.\n\t */\n\tprivate readonly internalIterator = (): IterableIterator<[string, ILocalValue]> => {\n\t\t// We perform iteration in two steps - first by iterating over members of the sequenced data that are not\n\t\t// optimistically deleted or cleared, and then over the pending data lifetimes that have not subsequently\n\t\t// been deleted or cleared. In total, this give an ordering of members based on when they were initially\n\t\t// added to the map (even if they were later modified), similar to the native Map.\n\t\tconst sequencedDataIterator = this.sequencedData.keys();\n\t\tconst pendingDataIterator = this.pendingData.values();\n\t\tconst next = (): IteratorResult<[string, ILocalValue]> => {\n\t\t\tlet nextSequencedKey = sequencedDataIterator.next();\n\t\t\twhile (!nextSequencedKey.done) {\n\t\t\t\tconst key = nextSequencedKey.value;\n\t\t\t\t// If we have any pending deletes or clears, then we won't iterate to this key yet (if at all).\n\t\t\t\t// Either it is optimistically deleted and will not be part of the iteration, or it was\n\t\t\t\t// re-added later and we'll iterate to it when we get to the pending data.\n\t\t\t\tif (\n\t\t\t\t\t!this.pendingData.some(\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" || (entry.type === \"delete\" && entry.key === key),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tconst optimisticValue = this.getOptimisticLocalValue(key);\n\t\t\t\t\tassert(\n\t\t\t\t\t\toptimisticValue !== undefined,\n\t\t\t\t\t\t0xbf1 /* Should never iterate to a key with undefined optimisticValue */,\n\t\t\t\t\t);\n\t\t\t\t\treturn { value: [key, optimisticValue], done: false };\n\t\t\t\t}\n\t\t\t\tnextSequencedKey = sequencedDataIterator.next();\n\t\t\t}\n\n\t\t\tlet nextPending = pendingDataIterator.next();\n\t\t\twhile (!nextPending.done) {\n\t\t\t\tconst nextPendingEntry = nextPending.value;\n\t\t\t\t// A lifetime entry may need to be iterated.\n\t\t\t\tif (nextPendingEntry.type === \"lifetime\") {\n\t\t\t\t\tconst nextPendingEntryIndex = this.pendingData.indexOf(nextPendingEntry);\n\t\t\t\t\tconst mostRecentDeleteOrClearIndex = findLastIndex(\n\t\t\t\t\t\tthis.pendingData,\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" ||\n\t\t\t\t\t\t\t(entry.type === \"delete\" && entry.key === nextPendingEntry.key),\n\t\t\t\t\t);\n\t\t\t\t\t// Only iterate the pending entry now if it hasn't been deleted or cleared.\n\t\t\t\t\tif (nextPendingEntryIndex > mostRecentDeleteOrClearIndex) {\n\t\t\t\t\t\tconst latestPendingValue =\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\tnextPendingEntry.keySets[nextPendingEntry.keySets.length - 1]!;\n\t\t\t\t\t\t// Skip iterating if we would have would have already iterated it as part of the sequenced data.\n\t\t\t\t\t\t// This is not a perfect check in the case the map has changed since the iterator was created\n\t\t\t\t\t\t// (e.g. if a remote client added the same key in the meantime).\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.sequencedData.has(nextPendingEntry.key) ||\n\t\t\t\t\t\t\tmostRecentDeleteOrClearIndex !== -1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn { value: [nextPendingEntry.key, latestPendingValue.value], done: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnextPending = pendingDataIterator.next();\n\t\t\t}\n\n\t\t\treturn { value: undefined, done: true };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, ILocalValue]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t};\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic entries(): IterableIterator<[string, unknown]> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<[string, unknown]> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\t// Unpack the stored value\n\t\t\tconst [key, localValue] = nextResult.value;\n\t\t\treturn { value: [key, localValue.value], done: false };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the keys in this map.\n\t * @returns The iterator\n\t */\n\tpublic keys(): IterableIterator<string> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<string> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [key] = nextResult.value;\n\t\t\treturn { value: key, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<string> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the values in this map.\n\t * @returns The iterator\n\t */\n\tpublic values(): IterableIterator<unknown> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<unknown> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [, localValue] = nextResult.value;\n\t\t\treturn { value: localValue.value, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<unknown> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic [Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\treturn this.entries();\n\t}\n\n\t/**\n\t * Executes the given callback on each entry in the map.\n\t * @param callbackFn - Callback function\n\t */\n\tpublic forEach(\n\t\tcallbackFn: (value: unknown, key: string, map: Map<string, unknown>) => void,\n\t): void {\n\t\t// It would be better to iterate over the data without a temp map. However, we don't have a valid\n\t\t// map to pass for the third argument here (really, it should probably should be a reference to the\n\t\t// SharedMap and not the MapKernel).\n\t\tconst tempMap = new Map(this.internalIterator());\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\ttempMap.forEach((localValue, key, m) => {\n\t\t\tcallbackFn(localValue.value, key, m);\n\t\t});\n\t}\n\n\t/**\n\t * Compute the optimistic local value for a given key. This combines the sequenced data with\n\t * any pending changes that have not yet been sequenced.\n\t */\n\tprivate readonly getOptimisticLocalValue = (key: string): ILocalValue | undefined => {\n\t\tconst latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\n\t\tif (latestPendingEntry === undefined) {\n\t\t\treturn this.sequencedData.get(key);\n\t\t} else if (latestPendingEntry.type === \"lifetime\") {\n\t\t\tconst latestPendingSet =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tlatestPendingEntry.keySets[latestPendingEntry.keySets.length - 1]!;\n\t\t\treturn latestPendingSet.value;\n\t\t} else {\n\t\t\t// Delete or clear\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\t/**\n\t * {@inheritDoc ISharedMap.get}\n\t */\n\tpublic get<T = unknown>(key: string): T | undefined {\n\t\tconst localValue = this.getOptimisticLocalValue(key);\n\t\treturn localValue === undefined ? undefined : (localValue.value as T);\n\t}\n\n\t/**\n\t * Check if a key exists in the map.\n\t * @param key - The key to check\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this.getOptimisticLocalValue(key) !== undefined;\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.set}\n\t */\n\tpublic set(key: string, value: unknown): void {\n\t\t// Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.\n\t\tif (key === undefined || key === null) {\n\t\t\tthrow new Error(\"Undefined and null keys are not supported\");\n\t\t}\n\n\t\tconst localValue: ILocalValue = { value };\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.set(key, localValue);\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// A new pending key lifetime is created if:\n\t\t// 1. There isn't any pending entry for the key yet\n\t\t// 2. The most recent pending entry for the key was a deletion (as this terminates the prior lifetime)\n\t\t// 3. A clear was sent after the last pending entry for the key (which also terminates the prior lifetime)\n\t\tlet latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\t\tif (\n\t\t\tlatestPendingEntry === undefined ||\n\t\t\tlatestPendingEntry.type === \"delete\" ||\n\t\t\tlatestPendingEntry.type === \"clear\"\n\t\t) {\n\t\t\tlatestPendingEntry = { type: \"lifetime\", key, keySets: [] };\n\t\t\tthis.pendingData.push(latestPendingEntry);\n\t\t}\n\t\tconst pendingKeySet: PendingKeySet = {\n\t\t\ttype: \"set\",\n\t\t\tvalue: localValue,\n\t\t};\n\t\tlatestPendingEntry.keySets.push(pendingKeySet);\n\n\t\tconst op: IMapSetOperation = {\n\t\t\tkey,\n\t\t\ttype: \"set\",\n\t\t\tvalue: { type: ValueType[ValueType.Plain], value: localValue.value },\n\t\t};\n\t\tthis.submitMessage(op, pendingKeySet);\n\t\tthis.eventEmitter.emit(\n\t\t\t\"valueChanged\",\n\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\ttrue,\n\t\t\tthis.eventEmitter,\n\t\t);\n\t}\n\n\t/**\n\t * Delete a key from the map.\n\t * @param key - Key to delete\n\t * @returns True if the key existed and was deleted, false if it did not exist\n\t */\n\tpublic delete(key: string): boolean {\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\tif (!this.isAttached()) {\n\t\t\tconst successfullyRemoved = this.sequencedData.delete(key);\n\t\t\t// Only emit if we actually deleted something.\n\t\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn successfullyRemoved;\n\t\t}\n\n\t\tconst pendingKeyDelete: PendingKeyDelete = {\n\t\t\ttype: \"delete\",\n\t\t\tkey,\n\t\t};\n\t\tthis.pendingData.push(pendingKeyDelete);\n\n\t\tconst op: IMapDeleteOperation = {\n\t\t\tkey,\n\t\t\ttype: \"delete\",\n\t\t};\n\t\tthis.submitMessage(op, pendingKeyDelete);\n\t\t// Only emit if we locally believe we deleted something. Otherwise we still send the op\n\t\t// (permitting speculative deletion even if we don't see anything locally) but don't emit\n\t\t// a valueChanged since we in fact did not locally observe a value change.\n\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear all data from the map.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.clear();\n\t\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t\t\treturn;\n\t\t}\n\n\t\tconst pendingClear: PendingClear = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.pendingData.push(pendingClear);\n\n\t\tconst op: IMapClearOperation = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitMessage(op, pendingClear);\n\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t}\n\n\t/**\n\t * Serializes the data stored in the shared map to a JSON string\n\t * @param serializer - The serializer to use to serialize handles in its values.\n\t * @returns A JSON string containing serialized map data\n\t */\n\tpublic getSerializedStorage(serializer: IFluidSerializer): IMapDataObjectSerialized {\n\t\tconst serializedMapData: IMapDataObjectSerialized = {};\n\t\tfor (const [key, localValue] of this.sequencedData.entries()) {\n\t\t\tserializedMapData[key] = serializeValue(localValue.value, serializer, this.handle);\n\t\t}\n\t\treturn serializedMapData;\n\t}\n\n\t/**\n\t * Populate the kernel with the given map data.\n\t * @param data - A JSON string containing serialized map data\n\t */\n\tpublic populateFromSerializable(json: IMapDataObjectSerializable): void {\n\t\tfor (const [key, serializable] of Object.entries(\n\t\t\tthis.serializer.decode(json) as IMapDataObjectSerializable,\n\t\t)) {\n\t\t\tmigrateIfSharedSerializable(serializable, this.serializer, this.handle);\n\t\t\tthis.sequencedData.set(key, { value: serializable.value });\n\t\t}\n\t}\n\n\t/**\n\t * Resubmit the given op if a handler is registered.\n\t * @param op - The operation to attempt to submit\n\t * @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime\n\t * and not sent to the server. This will be sent back when this message is received back from the server. This is\n\t * also sent if we are asked to resubmit the message.\n\t * @returns True if the operation was submitted, false otherwise.\n\t */\n\tpublic tryResubmitMessage(op: IMapOperation, localOpMetadata: unknown): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.resubmit(op, localOpMetadata as PendingLocalOpMetadata);\n\t\treturn true;\n\t}\n\n\tpublic tryApplyStashedOp(op: IMapOperation): void {\n\t\tswitch (op.type) {\n\t\t\tcase \"clear\": {\n\t\t\t\tthis.clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"delete\": {\n\t\t\t\tthis.delete(op.key);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"set\": {\n\t\t\t\tmigrateIfSharedSerializable(op.value, this.serializer, this.handle);\n\t\t\t\tthis.set(op.key, op.value.value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(op);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Process the given op if a handler is registered.\n\t * @param message - The message to process\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t * @returns True if the operation was recognized and thus processed, false otherwise.\n\t *\n\t * @remarks\n\t * When this returns false and the caller doesn't handle the op itself, then the op could be from a different version of this code.\n\t * In such a case, not applying the op would result in this client becoming out of sync with clients that do handle the op\n\t * and could result in data corruption or data loss as well.\n\t * Therefore, in such cases the caller should typically throw an error, ensuring that this client treats the situation as data corruption\n\t * (since its data no longer matches what other clients think the data should be) and will avoid overriding document content or misleading the users into thinking their current state is accurate.\n\t */\n\tpublic tryProcessMessage(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.process(op, local, localOpMetadata as PendingLocalOpMetadata | undefined);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Rollback a local op\n\t * @param op - The operation to rollback\n\t * @param localOpMetadata - The local metadata associated with the op.\n\t */\n\tpublic rollback(op: unknown, localOpMetadata: unknown): void {\n\t\tconst mapOp: IMapOperation = op as IMapOperation;\n\t\tconst typedLocalOpMetadata = localOpMetadata as PendingLocalOpMetadata;\n\t\tif (mapOp.type === \"clear\") {\n\t\t\t// A pending clear will be last in the list, since it terminates all prior lifetimes.\n\t\t\tconst pendingClear = this.pendingData.pop();\n\t\t\tassert(\n\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\tpendingClear === typedLocalOpMetadata,\n\t\t\t\t0xbf2 /* Unexpected clear rollback */,\n\t\t\t);\n\t\t\tfor (const [key] of this.internalIterator()) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: undefined },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// A pending set/delete may not be last in the list, as the lifetimes' order is based on when\n\t\t\t// they were created, not when they were last modified.\n\t\t\tconst pendingEntryIndex = findLastIndex(\n\t\t\t\tthis.pendingData,\n\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === mapOp.key,\n\t\t\t);\n\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\tassert(\n\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t(pendingEntry.type === \"delete\" || pendingEntry.type === \"lifetime\"),\n\t\t\t\t0xbf3 /* Unexpected pending data for set/delete op */,\n\t\t\t);\n\t\t\tif (pendingEntry.type === \"delete\") {\n\t\t\t\tassert(pendingEntry === typedLocalOpMetadata, 0xbf4 /* Unexpected delete rollback */);\n\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t// Only emit if rolling back the delete actually results in a value becoming visible.\n\t\t\t\tif (this.getOptimisticLocalValue(mapOp.key) !== undefined) {\n\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t{ key: mapOp.key, previousValue: undefined },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (pendingEntry.type === \"lifetime\") {\n\t\t\t\tconst pendingKeySet = pendingEntry.keySets.pop();\n\t\t\t\tassert(\n\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === typedLocalOpMetadata,\n\t\t\t\t\t0xbf5 /* Unexpected set rollback */,\n\t\t\t\t);\n\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t}\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key: mapOp.key, previousValue: pendingKeySet.value.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the message handlers for the map.\n\t * @returns A map of string op names to IMapMessageHandlers for those ops\n\t */\n\tprivate getMessageHandlers(): Map<string, IMapMessageHandler> {\n\t\tconst messageHandlers = new Map<string, IMapMessageHandler>();\n\t\tmessageHandlers.set(\"clear\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapClearOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tthis.sequencedData.clear();\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingClear = this.pendingData.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\t\t\tpendingClear === localOpMetadata,\n\t\t\t\t\t\t0xbf6 /* Got a local clear message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// Only emit for remote ops, we would have already emitted for local ops. Only emit if there\n\t\t\t\t\t// is no optimistically-applied local pending clear that would supersede this remote clear.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\")) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\"clear\", local, this.eventEmitter);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapClearOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"delete\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapDeleteOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t\t\tpendingEntry.type === \"delete\" &&\n\t\t\t\t\t\t\tpendingEntry === localOpMetadata,\n\t\t\t\t\t\t0xbf7 /* Got a local delete message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapDeleteOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"set\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapSetOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key, value } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined && pendingEntry.type === \"lifetime\",\n\t\t\t\t\t\t0xbf8 /* Couldn't match local set message to pending lifetime */,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingKeySet = pendingEntry.keySets.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === localOpMetadata,\n\t\t\t\t\t\t0xbf9 /* Got a local set message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.sequencedData.set(key, pendingKeySet.value);\n\t\t\t\t} else {\n\t\t\t\t\tmigrateIfSharedSerializable(value, this.serializer, this.handle);\n\t\t\t\t\tconst localValue: ILocalValue = { value: value.value };\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.set(key, localValue);\n\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapSetOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\n\t\treturn messageHandlers;\n\t}\n}\n"]}
1
+ {"version":3,"file":"mapKernel.js","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,kEAA8E;AAE9E,0EAAwE;AAWxE,qDAI0B;AAC1B,yCAAqD;AAoFrD;;GAEG;AACH,MAAa,SAAS;IACrB;;OAEG;IACH,IAAW,IAAI;QACd,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACnD,OAAO,aAAa,CAAC,MAAM,CAAC;IAC7B,CAAC;IAqBD;;;;;;;;OAQG;IACH,YACkB,UAA4B,EAC5B,MAAoB,EACpB,aAA8D,EAC9D,UAAyB,EACzB,YAAiD;QAJjD,eAAU,GAAV,UAAU,CAAkB;QAC5B,WAAM,GAAN,MAAM,CAAc;QACpB,kBAAa,GAAb,aAAa,CAAiD;QAC9D,eAAU,GAAV,UAAU,CAAe;QACzB,iBAAY,GAAZ,YAAY,CAAqC;QAjCnE;;WAEG;QACc,oBAAe,GAA4C,IAAI,GAAG,EAAE,CAAC;QAEtF;;;WAGG;QACc,kBAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;QAChE;;;;;;WAMG;QACc,gBAAW,GAAuB,EAAE,CAAC;QAqBtD;;;;;;;;;;;;;;;WAeG;QACc,qBAAgB,GAAG,GAA4C,EAAE;YACjF,yGAAyG;YACzG,yGAAyG;YACzG,yGAAyG;YACzG,kFAAkF;YAClF,MAAM,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;YACxD,MAAM,mBAAmB,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YACtD,MAAM,IAAI,GAAG,GAA0C,EAAE;gBACxD,IAAI,gBAAgB,GAAG,qBAAqB,CAAC,IAAI,EAAE,CAAC;gBACpD,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;oBAC/B,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC;oBACnC,+FAA+F;oBAC/F,uFAAuF;oBACvF,0EAA0E;oBAC1E,IACC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CACrB,CAAC,KAAK,EAAE,EAAE,CACT,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CACzE,EACA,CAAC;wBACF,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;wBAC1D,IAAA,iBAAM,EACL,eAAe,KAAK,SAAS,EAC7B,KAAK,CAAC,kEAAkE,CACxE,CAAC;wBACF,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;oBACvD,CAAC;oBACD,gBAAgB,GAAG,qBAAqB,CAAC,IAAI,EAAE,CAAC;gBACjD,CAAC;gBAED,IAAI,WAAW,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC;gBAC7C,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;oBAC1B,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC;oBAC3C,4CAA4C;oBAC5C,IAAI,gBAAgB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;wBAC1C,MAAM,qBAAqB,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;wBACzE,MAAM,4BAA4B,GAAG,IAAA,wBAAa,EACjD,IAAI,CAAC,WAAW,EAChB,CAAC,KAAK,EAAE,EAAE,CACT,KAAK,CAAC,IAAI,KAAK,OAAO;4BACtB,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,gBAAgB,CAAC,GAAG,CAAC,CAChE,CAAC;wBACF,2EAA2E;wBAC3E,IAAI,qBAAqB,GAAG,4BAA4B,EAAE,CAAC;4BAC1D,MAAM,kBAAkB;4BACvB,oEAAoE;4BACpE,gBAAgB,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;4BAChE,gGAAgG;4BAChG,6FAA6F;4BAC7F,gEAAgE;4BAChE,IACC,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,gBAAgB,CAAC,GAAG,CAAC;gCAC7C,4BAA4B,KAAK,CAAC,CAAC,EAClC,CAAC;gCACF,OAAO,EAAE,KAAK,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;4BACjF,CAAC;wBACF,CAAC;oBACF,CAAC;oBACD,WAAW,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC;gBAC1C,CAAC;gBAED,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACzC,CAAC,CAAC;YAEF,MAAM,QAAQ,GAAG;gBAChB,IAAI;gBACJ,CAAC,MAAM,CAAC,QAAQ,CAAC;oBAChB,OAAO,IAAI,CAAC;gBACb,CAAC;aACD,CAAC;YACF,OAAO,QAAQ,CAAC;QACjB,CAAC,CAAC;QAkGF;;;WAGG;QACc,4BAAuB,GAAG,CAAC,GAAW,EAA2B,EAAE;YACnF,MAAM,kBAAkB,GAAG,IAAA,mBAAQ,EAClC,IAAI,CAAC,WAAW,EAChB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CACtD,CAAC;YAEF,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;gBACtC,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpC,CAAC;iBAAM,IAAI,kBAAkB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACnD,MAAM,gBAAgB;gBACrB,oEAAoE;gBACpE,kBAAkB,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;gBACpE,OAAO,gBAAgB,CAAC,KAAK,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACP,kBAAkB;gBAClB,OAAO,SAAS,CAAC;YAClB,CAAC;QACF,CAAC,CAAC;QAjND,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAClD,CAAC;IA2FD;;;OAGG;IACI,OAAO;QACb,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,GAAsC,EAAE;YACpD,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACzC,CAAC;YACD,0BAA0B;YAC1B,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;YAC3C,OAAO,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACxD,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG;YAChB,IAAI;YACJ,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAChB,OAAO,IAAI,CAAC;YACb,CAAC;SACD,CAAC;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;OAGG;IACI,IAAI;QACV,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,GAA2B,EAAE;YACzC,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACzC,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;YAC/B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACpC,CAAC,CAAC;QACF,MAAM,QAAQ,GAAG;YAChB,IAAI;YACJ,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAChB,OAAO,IAAI,CAAC;YACb,CAAC;SACD,CAAC;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;OAGG;IACI,MAAM;QACZ,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,GAA4B,EAAE;YAC1C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;gBACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACzC,CAAC;YACD,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;YACxC,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QACjD,CAAC,CAAC;QACF,MAAM,QAAQ,GAAG;YAChB,IAAI;YACJ,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAChB,OAAO,IAAI,CAAC;YACb,CAAC;SACD,CAAC;QACF,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED;;;OAGG;IACI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACvB,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,OAAO,CACb,UAA4E;QAE5E,kGAAkG;QAClG,mGAAmG;QACnG,oCAAoC;QACpC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACjD,qDAAqD;QACrD,OAAO,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;YACtC,UAAU,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACJ,CAAC;IAyBD;;OAEG;IACI,GAAG,CAAc,GAAW;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QACrD,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,UAAU,CAAC,KAAW,CAAC;IACvE,CAAC;IAED;;;;OAIG;IACI,GAAG,CAAC,GAAW;QACrB,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACxD,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,GAAW,EAAE,KAAc;QACrC,uFAAuF;QACvF,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,UAAU,GAAgB,EAAE,KAAK,EAAE,CAAC;QAC1C,MAAM,4BAA4B,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAEvE,+CAA+C;QAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YACxC,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,4BAA4B,EAAE,KAAK,EAAE,EAC3D,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;YACF,OAAO;QACR,CAAC;QAED,4CAA4C;QAC5C,mDAAmD;QACnD,sGAAsG;QACtG,0GAA0G;QAC1G,IAAI,kBAAkB,GAAG,IAAA,mBAAQ,EAChC,IAAI,CAAC,WAAW,EAChB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CACtD,CAAC;QACF,IACC,kBAAkB,KAAK,SAAS;YAChC,kBAAkB,CAAC,IAAI,KAAK,QAAQ;YACpC,kBAAkB,CAAC,IAAI,KAAK,OAAO,EAClC,CAAC;YACF,kBAAkB,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;YAC5D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC3C,CAAC;QACD,MAAM,aAAa,GAAkB;YACpC,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,UAAU;SACjB,CAAC;QACF,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE/C,MAAM,EAAE,GAAqB;YAC5B,GAAG;YACH,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,EAAE,IAAI,EAAE,oBAAS,CAAC,oBAAS,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE;SACpE,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QACtC,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,4BAA4B,EAAE,KAAK,EAAE,EAC3D,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,GAAW;QACxB,MAAM,4BAA4B,GAAG,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAEvE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3D,8CAA8C;YAC9C,IAAI,4BAA4B,KAAK,SAAS,EAAE,CAAC;gBAChD,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,4BAA4B,CAAC,KAAK,EAAE,EAC1D,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;YACH,CAAC;YACD,OAAO,mBAAmB,CAAC;QAC5B,CAAC;QAED,MAAM,gBAAgB,GAAqB;YAC1C,IAAI,EAAE,QAAQ;YACd,GAAG;SACH,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAExC,MAAM,EAAE,GAAwB;YAC/B,GAAG;YACH,IAAI,EAAE,QAAQ;SACd,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;QACzC,wFAAwF;QACxF,yFAAyF;QACzF,0EAA0E;QAC1E,IAAI,4BAA4B,KAAK,SAAS,EAAE,CAAC;YAChD,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,4BAA4B,CAAC,KAAK,EAAE,EAC1D,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;OAEG;IACI,KAAK;QACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACzD,OAAO;QACR,CAAC;QAED,MAAM,YAAY,GAAiB;YAClC,IAAI,EAAE,OAAO;SACb,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAEpC,MAAM,EAAE,GAAuB;YAC9B,IAAI,EAAE,OAAO;SACb,CAAC;QACF,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC;IAED;;;;OAIG;IACI,oBAAoB,CAAC,UAA4B;QACvD,MAAM,iBAAiB,GAA6B,EAAE,CAAC;QACvD,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9D,iBAAiB,CAAC,GAAG,CAAC,GAAG,IAAA,+BAAc,EAAC,UAAU,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpF,CAAC;QACD,OAAO,iBAAiB,CAAC;IAC1B,CAAC;IAED;;;OAGG;IACI,wBAAwB,CAAC,IAAgC;QAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAC/C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAA+B,CAC1D,EAAE,CAAC;YACH,IAAA,4CAA2B,EAAC,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACxE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;IACF,CAAC;IAED;;;;;;;OAOG;IACI,kBAAkB,CAAC,EAAiB,EAAE,eAAwB;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,eAAyC,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,iBAAiB,CAAC,EAAiB;QACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,MAAM;YACP,CAAC;YACD,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBACpB,MAAM;YACP,CAAC;YACD,KAAK,KAAK,CAAC,CAAC,CAAC;gBACZ,IAAA,4CAA2B,EAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBACpE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACjC,MAAM;YACP,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,IAAA,0BAAe,EAAC,EAAE,CAAC,CAAC;YACrB,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACI,iBAAiB,CACvB,EAAiB,EACjB,KAAc,EACd,eAAwB;QAExB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,eAAqD,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;OAIG;IACI,QAAQ,CAAC,EAAW,EAAE,eAAwB;QACpD,MAAM,KAAK,GAAkB,EAAmB,CAAC;QACjD,MAAM,oBAAoB,GAAG,eAAyC,CAAC;QACvE,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC5B,qFAAqF;YACrF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;YAC5C,IAAA,iBAAM,EACL,YAAY,KAAK,SAAS;gBACzB,YAAY,CAAC,IAAI,KAAK,OAAO;gBAC7B,YAAY,KAAK,oBAAoB,EACtC,KAAK,CAAC,+BAA+B,CACrC,CAAC;YACF,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;gBAC7C,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,EACjC,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;YACH,CAAC;QACF,CAAC;aAAM,CAAC;YACP,6FAA6F;YAC7F,uDAAuD;YACvD,MAAM,iBAAiB,GAAG,IAAA,wBAAa,EACtC,IAAI,CAAC,WAAW,EAChB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAC5D,CAAC;YACF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;YACzD,IAAA,iBAAM,EACL,YAAY,KAAK,SAAS;gBACzB,CAAC,YAAY,CAAC,IAAI,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,EACrE,KAAK,CAAC,+CAA+C,CACrD,CAAC;YACF,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpC,IAAA,iBAAM,EAAC,YAAY,KAAK,oBAAoB,EAAE,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBACtF,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;gBAC9C,qFAAqF;gBACrF,IAAI,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;oBAC3D,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,EAC5C,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;gBACH,CAAC;YACF,CAAC;iBAAM,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC7C,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gBACjD,IAAA,iBAAM,EACL,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,oBAAoB,EACrE,KAAK,CAAC,6BAA6B,CACnC,CAAC;gBACF,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;gBAC/C,CAAC;gBACD,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,EAC5D,IAAI,EACJ,IAAI,CAAC,YAAY,CACjB,CAAC;YACH,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;OAGG;IACK,kBAAkB;QACzB,MAAM,eAAe,GAAG,IAAI,GAAG,EAA8B,CAAC;QAC9D,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE;YAC5B,OAAO,EAAE,CACR,EAAsB,EACtB,KAAc,EACd,eAAmD,EAClD,EAAE;gBACH,IAAI,KAAK,EAAE,CAAC;oBACX,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;oBAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;oBAC9C,IAAA,iBAAM,EACL,YAAY,KAAK,SAAS;wBACzB,YAAY,CAAC,IAAI,KAAK,OAAO;wBAC7B,YAAY,KAAK,eAAe,EACjC,KAAK,CAAC,oDAAoD,CAC1D,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACP,MAAM,YAAY,GAA8C,EAAE,CAAC;oBACnE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;wBAC/C,8EAA8E;wBAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAC1C,CAAC,KAAK,EAAE,EAAE,CACT,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC;4BAC9C,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CACjD,CAAC;wBACF,wEAAwE;wBACxE,IAAI,CAAC,aAAa,EAAE,CAAC;4BACpB,YAAY,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;wBACxD,CAAC;oBACF,CAAC;oBACD,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;oBAE3B,4FAA4F;oBAC5F,2FAA2F;oBAC3F,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,CAAC;wBAC/D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;wBAE1D,kEAAkE;wBAClE,KAAK,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,IAAI,YAAY,EAAE,CAAC;4BACnD,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,EACtB,KAAK,EACL,IAAI,CAAC,YAAY,CACjB,CAAC;wBACH,CAAC;oBACF,CAAC;gBACF,CAAC;YACF,CAAC;YACD,QAAQ,EAAE,CAAC,EAAsB,EAAE,eAAuC,EAAE,EAAE;gBAC7E,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;YACzC,CAAC;SACD,CAAC,CAAC;QACH,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE;YAC7B,OAAO,EAAE,CACR,EAAuB,EACvB,KAAc,EACd,eAAmD,EAClD,EAAE;gBACH,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;gBAEnB,IAAI,KAAK,EAAE,CAAC;oBACX,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CACnD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CACtD,CAAC;oBACF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;oBACzD,IAAA,iBAAM,EACL,YAAY,KAAK,SAAS;wBACzB,YAAY,CAAC,IAAI,KAAK,QAAQ;wBAC9B,YAAY,KAAK,eAAe,EACjC,KAAK,CAAC,qDAAqD,CAC3D,CAAC;oBACF,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;oBAE9C,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACP,MAAM,aAAa,GAAY,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;oBAClE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC/B,sGAAsG;oBACtG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;wBACpF,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,EACtB,KAAK,EACL,IAAI,CAAC,YAAY,CACjB,CAAC;oBACH,CAAC;gBACF,CAAC;YACF,CAAC;YACD,QAAQ,EAAE,CAAC,EAAuB,EAAE,eAAuC,EAAE,EAAE;gBAC9E,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;YACzC,CAAC;SACD,CAAC,CAAC;QACH,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE;YAC1B,OAAO,EAAE,CACR,EAAoB,EACpB,KAAc,EACd,eAAmD,EAClD,EAAE;gBACH,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;gBAE1B,IAAI,KAAK,EAAE,CAAC;oBACX,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CACnD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CACtD,CAAC;oBACF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;oBACzD,IAAA,iBAAM,EACL,YAAY,KAAK,SAAS,IAAI,YAAY,CAAC,IAAI,KAAK,UAAU,EAC9D,KAAK,CAAC,0DAA0D,CAChE,CAAC;oBACF,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBACnD,IAAA,iBAAM,EACL,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,eAAe,EAChE,KAAK,CAAC,kDAAkD,CACxD,CAAC;oBACF,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACvC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC;oBAC/C,CAAC;oBAED,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACP,IAAA,4CAA2B,EAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;oBACjE,MAAM,UAAU,GAAgB,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;oBACvD,MAAM,aAAa,GAAY,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;oBAClE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;oBAExC,sGAAsG;oBACtG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAC;wBACpF,IAAI,CAAC,YAAY,CAAC,IAAI,CACrB,cAAc,EACd,EAAE,GAAG,EAAE,aAAa,EAAE,EACtB,KAAK,EACL,IAAI,CAAC,YAAY,CACjB,CAAC;oBACH,CAAC;gBACF,CAAC;YACF,CAAC;YACD,QAAQ,EAAE,CAAC,EAAoB,EAAE,eAAuC,EAAE,EAAE;gBAC3E,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;YACzC,CAAC;SACD,CAAC,CAAC;QAEH,OAAO,eAAe,CAAC;IACxB,CAAC;CACD;AAxsBD,8BAwsBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { ValueType } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ISharedMapEvents } from \"./interfaces.js\";\nimport type {\n\tIMapClearOperation,\n\tIMapDeleteOperation,\n\tIMapSetOperation,\n\t// eslint-disable-next-line import-x/no-deprecated\n\tISerializableValue,\n\tISerializedValue,\n} from \"./internalInterfaces.js\";\nimport {\n\ttype ILocalValue,\n\tserializeValue,\n\tmigrateIfSharedSerializable,\n} from \"./localValues.js\";\nimport { findLast, findLastIndex } from \"./utils.js\";\n\n/**\n * Defines the means to process and resubmit a given op on a map.\n */\ninterface IMapMessageHandler {\n\t/**\n\t * Apply the given operation.\n\t * @param op - The map operation to apply\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t */\n\tprocess(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t): void;\n\n\t/**\n\t * Resubmit a previously submitted operation that was not delivered.\n\t * @param op - The map operation to resubmit\n\t * @param localOpMetadata - The metadata that was originally submitted with the message.\n\t */\n\tresubmit(op: IMapOperation, localOpMetadata: PendingLocalOpMetadata): void;\n}\n\n/**\n * Union of all possible map operations.\n */\nexport type IMapOperation = IMapSetOperation | IMapDeleteOperation | IMapClearOperation;\n\n/**\n * Defines the in-memory object structure to be used for the conversion to/from serialized.\n *\n * @remarks Directly used in\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\n * | JSON.stringify}, direct result from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}.\n */\n// eslint-disable-next-line import-x/no-deprecated\nexport type IMapDataObjectSerializable = Record<string, ISerializableValue>;\n\n/**\n * Serialized key/value data.\n */\nexport type IMapDataObjectSerialized = Record<string, ISerializedValue>;\n\ninterface PendingKeySet {\n\ttype: \"set\";\n\tvalue: ILocalValue;\n}\n\ninterface PendingKeyDelete {\n\ttype: \"delete\";\n\tkey: string;\n}\n\ninterface PendingClear {\n\ttype: \"clear\";\n}\n\ninterface PendingKeyLifetime {\n\ttype: \"lifetime\";\n\tkey: string;\n\t/**\n\t * A non-empty array of pending key sets that occurred during this lifetime. If the list\n\t * becomes empty (e.g. during processing or rollback), the lifetime no longer exists and\n\t * must be removed from the pending data.\n\t */\n\tkeySets: PendingKeySet[];\n}\n\n/**\n * A member of the pendingData array, which tracks outstanding changes and can be used to\n * compute optimistic values. Local sets are aggregated into lifetimes.\n */\ntype PendingDataEntry = PendingKeyLifetime | PendingKeyDelete | PendingClear;\n/**\n * An individual outstanding change, which will also be found in the pendingData array\n * (though the PendingKeySets will be contained within a PendingKeyLifetime there).\n */\ntype PendingLocalOpMetadata = PendingKeySet | PendingKeyDelete | PendingClear;\n\n/**\n * A SharedMap is a map-like distributed data structure.\n */\nexport class MapKernel {\n\t/**\n\t * The number of key/value pairs stored in the map.\n\t */\n\tpublic get size(): number {\n\t\tconst iterableItems = [...this.internalIterator()];\n\t\treturn iterableItems.length;\n\t}\n\n\t/**\n\t * Mapping of op types to message handlers.\n\t */\n\tprivate readonly messageHandlers: ReadonlyMap<string, IMapMessageHandler> = new Map();\n\n\t/**\n\t * The data the map is storing, but only including sequenced values (no local pending\n\t * modifications are included).\n\t */\n\tprivate readonly sequencedData = new Map<string, ILocalValue>();\n\t/**\n\t * A data structure containing all local pending modifications, which is used in combination\n\t * with the sequencedData to compute optimistic values.\n\t *\n\t * Pending sets are aggregated into \"lifetimes\", which permit correct relative iteration order\n\t * even across remote operations and rollbacks.\n\t */\n\tprivate readonly pendingData: PendingDataEntry[] = [];\n\n\t/**\n\t * Create a new shared map kernel.\n\t * @param serializer - The serializer to serialize / parse handles\n\t * @param handle - The handle of the shared object using the kernel\n\t * @param submitMessage - A callback to submit a message through the shared object\n\t * @param isAttached - To query whether the shared object should generate ops\n\t * @param valueTypes - The value types to register\n\t * @param eventEmitter - The object that will emit map events\n\t */\n\tpublic constructor(\n\t\tprivate readonly serializer: IFluidSerializer,\n\t\tprivate readonly handle: IFluidHandle,\n\t\tprivate readonly submitMessage: (op: unknown, localOpMetadata: unknown) => void,\n\t\tprivate readonly isAttached: () => boolean,\n\t\tprivate readonly eventEmitter: TypedEventEmitter<ISharedMapEvents>,\n\t) {\n\t\tthis.messageHandlers = this.getMessageHandlers();\n\t}\n\n\t/**\n\t * Get an iterator over the optimistically observable ILocalValue entries in the map. For example, excluding\n\t * sequenced entries that have pending deletes/clears.\n\t *\n\t * @remarks\n\t * There is no perfect solution here, particularly when the iterator is retained over time and the map is\n\t * modified or new ack's are received. The pendingData portion of the iteration is the most susceptible to\n\t * this problem. The implementation prioritizes (in roughly this order):\n\t * 1. Correct immediate iteration (i.e. when the map is not modified before iteration completes)\n\t * 2. Consistent iteration order before/after sequencing of pending ops; acks don't change order\n\t * 3. Consistent iteration order between synchronized clients, even if they each modified the map concurrently\n\t * 4. Remaining as close as possible to the native Map iterator behavior, e.g. live-ish view rather than snapshot\n\t *\n\t * For this reason, it's important not to internally snapshot the output of the iterator for any purpose that\n\t * does not immediately (synchronously) consume that output and dispose of it.\n\t */\n\tprivate readonly internalIterator = (): IterableIterator<[string, ILocalValue]> => {\n\t\t// We perform iteration in two steps - first by iterating over members of the sequenced data that are not\n\t\t// optimistically deleted or cleared, and then over the pending data lifetimes that have not subsequently\n\t\t// been deleted or cleared. In total, this give an ordering of members based on when they were initially\n\t\t// added to the map (even if they were later modified), similar to the native Map.\n\t\tconst sequencedDataIterator = this.sequencedData.keys();\n\t\tconst pendingDataIterator = this.pendingData.values();\n\t\tconst next = (): IteratorResult<[string, ILocalValue]> => {\n\t\t\tlet nextSequencedKey = sequencedDataIterator.next();\n\t\t\twhile (!nextSequencedKey.done) {\n\t\t\t\tconst key = nextSequencedKey.value;\n\t\t\t\t// If we have any pending deletes or clears, then we won't iterate to this key yet (if at all).\n\t\t\t\t// Either it is optimistically deleted and will not be part of the iteration, or it was\n\t\t\t\t// re-added later and we'll iterate to it when we get to the pending data.\n\t\t\t\tif (\n\t\t\t\t\t!this.pendingData.some(\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" || (entry.type === \"delete\" && entry.key === key),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tconst optimisticValue = this.getOptimisticLocalValue(key);\n\t\t\t\t\tassert(\n\t\t\t\t\t\toptimisticValue !== undefined,\n\t\t\t\t\t\t0xbf1 /* Should never iterate to a key with undefined optimisticValue */,\n\t\t\t\t\t);\n\t\t\t\t\treturn { value: [key, optimisticValue], done: false };\n\t\t\t\t}\n\t\t\t\tnextSequencedKey = sequencedDataIterator.next();\n\t\t\t}\n\n\t\t\tlet nextPending = pendingDataIterator.next();\n\t\t\twhile (!nextPending.done) {\n\t\t\t\tconst nextPendingEntry = nextPending.value;\n\t\t\t\t// A lifetime entry may need to be iterated.\n\t\t\t\tif (nextPendingEntry.type === \"lifetime\") {\n\t\t\t\t\tconst nextPendingEntryIndex = this.pendingData.indexOf(nextPendingEntry);\n\t\t\t\t\tconst mostRecentDeleteOrClearIndex = findLastIndex(\n\t\t\t\t\t\tthis.pendingData,\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" ||\n\t\t\t\t\t\t\t(entry.type === \"delete\" && entry.key === nextPendingEntry.key),\n\t\t\t\t\t);\n\t\t\t\t\t// Only iterate the pending entry now if it hasn't been deleted or cleared.\n\t\t\t\t\tif (nextPendingEntryIndex > mostRecentDeleteOrClearIndex) {\n\t\t\t\t\t\tconst latestPendingValue =\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\tnextPendingEntry.keySets[nextPendingEntry.keySets.length - 1]!;\n\t\t\t\t\t\t// Skip iterating if we would have would have already iterated it as part of the sequenced data.\n\t\t\t\t\t\t// This is not a perfect check in the case the map has changed since the iterator was created\n\t\t\t\t\t\t// (e.g. if a remote client added the same key in the meantime).\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.sequencedData.has(nextPendingEntry.key) ||\n\t\t\t\t\t\t\tmostRecentDeleteOrClearIndex !== -1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn { value: [nextPendingEntry.key, latestPendingValue.value], done: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnextPending = pendingDataIterator.next();\n\t\t\t}\n\n\t\t\treturn { value: undefined, done: true };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, ILocalValue]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t};\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic entries(): IterableIterator<[string, unknown]> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<[string, unknown]> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\t// Unpack the stored value\n\t\t\tconst [key, localValue] = nextResult.value;\n\t\t\treturn { value: [key, localValue.value], done: false };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the keys in this map.\n\t * @returns The iterator\n\t */\n\tpublic keys(): IterableIterator<string> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<string> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [key] = nextResult.value;\n\t\t\treturn { value: key, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<string> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the values in this map.\n\t * @returns The iterator\n\t */\n\tpublic values(): IterableIterator<unknown> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<unknown> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [, localValue] = nextResult.value;\n\t\t\treturn { value: localValue.value, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<unknown> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic [Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\treturn this.entries();\n\t}\n\n\t/**\n\t * Executes the given callback on each entry in the map.\n\t * @param callbackFn - Callback function\n\t */\n\tpublic forEach(\n\t\tcallbackFn: (value: unknown, key: string, map: Map<string, unknown>) => void,\n\t): void {\n\t\t// It would be better to iterate over the data without a temp map. However, we don't have a valid\n\t\t// map to pass for the third argument here (really, it should probably should be a reference to the\n\t\t// SharedMap and not the MapKernel).\n\t\tconst tempMap = new Map(this.internalIterator());\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\ttempMap.forEach((localValue, key, m) => {\n\t\t\tcallbackFn(localValue.value, key, m);\n\t\t});\n\t}\n\n\t/**\n\t * Compute the optimistic local value for a given key. This combines the sequenced data with\n\t * any pending changes that have not yet been sequenced.\n\t */\n\tprivate readonly getOptimisticLocalValue = (key: string): ILocalValue | undefined => {\n\t\tconst latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\n\t\tif (latestPendingEntry === undefined) {\n\t\t\treturn this.sequencedData.get(key);\n\t\t} else if (latestPendingEntry.type === \"lifetime\") {\n\t\t\tconst latestPendingSet =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tlatestPendingEntry.keySets[latestPendingEntry.keySets.length - 1]!;\n\t\t\treturn latestPendingSet.value;\n\t\t} else {\n\t\t\t// Delete or clear\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\t/**\n\t * {@inheritDoc ISharedMap.get}\n\t */\n\tpublic get<T = unknown>(key: string): T | undefined {\n\t\tconst localValue = this.getOptimisticLocalValue(key);\n\t\treturn localValue === undefined ? undefined : (localValue.value as T);\n\t}\n\n\t/**\n\t * Check if a key exists in the map.\n\t * @param key - The key to check\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this.getOptimisticLocalValue(key) !== undefined;\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.set}\n\t */\n\tpublic set(key: string, value: unknown): void {\n\t\t// Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.\n\t\tif (key === undefined || key === null) {\n\t\t\tthrow new Error(\"Undefined and null keys are not supported\");\n\t\t}\n\n\t\tconst localValue: ILocalValue = { value };\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.set(key, localValue);\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// A new pending key lifetime is created if:\n\t\t// 1. There isn't any pending entry for the key yet\n\t\t// 2. The most recent pending entry for the key was a deletion (as this terminates the prior lifetime)\n\t\t// 3. A clear was sent after the last pending entry for the key (which also terminates the prior lifetime)\n\t\tlet latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\t\tif (\n\t\t\tlatestPendingEntry === undefined ||\n\t\t\tlatestPendingEntry.type === \"delete\" ||\n\t\t\tlatestPendingEntry.type === \"clear\"\n\t\t) {\n\t\t\tlatestPendingEntry = { type: \"lifetime\", key, keySets: [] };\n\t\t\tthis.pendingData.push(latestPendingEntry);\n\t\t}\n\t\tconst pendingKeySet: PendingKeySet = {\n\t\t\ttype: \"set\",\n\t\t\tvalue: localValue,\n\t\t};\n\t\tlatestPendingEntry.keySets.push(pendingKeySet);\n\n\t\tconst op: IMapSetOperation = {\n\t\t\tkey,\n\t\t\ttype: \"set\",\n\t\t\tvalue: { type: ValueType[ValueType.Plain], value: localValue.value },\n\t\t};\n\t\tthis.submitMessage(op, pendingKeySet);\n\t\tthis.eventEmitter.emit(\n\t\t\t\"valueChanged\",\n\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\ttrue,\n\t\t\tthis.eventEmitter,\n\t\t);\n\t}\n\n\t/**\n\t * Delete a key from the map.\n\t * @param key - Key to delete\n\t * @returns True if the key existed and was deleted, false if it did not exist\n\t */\n\tpublic delete(key: string): boolean {\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\tif (!this.isAttached()) {\n\t\t\tconst successfullyRemoved = this.sequencedData.delete(key);\n\t\t\t// Only emit if we actually deleted something.\n\t\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn successfullyRemoved;\n\t\t}\n\n\t\tconst pendingKeyDelete: PendingKeyDelete = {\n\t\t\ttype: \"delete\",\n\t\t\tkey,\n\t\t};\n\t\tthis.pendingData.push(pendingKeyDelete);\n\n\t\tconst op: IMapDeleteOperation = {\n\t\t\tkey,\n\t\t\ttype: \"delete\",\n\t\t};\n\t\tthis.submitMessage(op, pendingKeyDelete);\n\t\t// Only emit if we locally believe we deleted something. Otherwise we still send the op\n\t\t// (permitting speculative deletion even if we don't see anything locally) but don't emit\n\t\t// a valueChanged since we in fact did not locally observe a value change.\n\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear all data from the map.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.clear();\n\t\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t\t\treturn;\n\t\t}\n\n\t\tconst pendingClear: PendingClear = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.pendingData.push(pendingClear);\n\n\t\tconst op: IMapClearOperation = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitMessage(op, pendingClear);\n\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t}\n\n\t/**\n\t * Serializes the data stored in the shared map to a JSON string\n\t * @param serializer - The serializer to use to serialize handles in its values.\n\t * @returns A JSON string containing serialized map data\n\t */\n\tpublic getSerializedStorage(serializer: IFluidSerializer): IMapDataObjectSerialized {\n\t\tconst serializedMapData: IMapDataObjectSerialized = {};\n\t\tfor (const [key, localValue] of this.sequencedData.entries()) {\n\t\t\tserializedMapData[key] = serializeValue(localValue.value, serializer, this.handle);\n\t\t}\n\t\treturn serializedMapData;\n\t}\n\n\t/**\n\t * Populate the kernel with the given map data.\n\t * @param data - A JSON string containing serialized map data\n\t */\n\tpublic populateFromSerializable(json: IMapDataObjectSerializable): void {\n\t\tfor (const [key, serializable] of Object.entries(\n\t\t\tthis.serializer.decode(json) as IMapDataObjectSerializable,\n\t\t)) {\n\t\t\tmigrateIfSharedSerializable(serializable, this.serializer, this.handle);\n\t\t\tthis.sequencedData.set(key, { value: serializable.value });\n\t\t}\n\t}\n\n\t/**\n\t * Resubmit the given op if a handler is registered.\n\t * @param op - The operation to attempt to submit\n\t * @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime\n\t * and not sent to the server. This will be sent back when this message is received back from the server. This is\n\t * also sent if we are asked to resubmit the message.\n\t * @returns True if the operation was submitted, false otherwise.\n\t */\n\tpublic tryResubmitMessage(op: IMapOperation, localOpMetadata: unknown): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.resubmit(op, localOpMetadata as PendingLocalOpMetadata);\n\t\treturn true;\n\t}\n\n\tpublic tryApplyStashedOp(op: IMapOperation): void {\n\t\tswitch (op.type) {\n\t\t\tcase \"clear\": {\n\t\t\t\tthis.clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"delete\": {\n\t\t\t\tthis.delete(op.key);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"set\": {\n\t\t\t\tmigrateIfSharedSerializable(op.value, this.serializer, this.handle);\n\t\t\t\tthis.set(op.key, op.value.value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(op);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Process the given op if a handler is registered.\n\t * @param message - The message to process\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t * @returns True if the operation was recognized and thus processed, false otherwise.\n\t *\n\t * @remarks\n\t * When this returns false and the caller doesn't handle the op itself, then the op could be from a different version of this code.\n\t * In such a case, not applying the op would result in this client becoming out of sync with clients that do handle the op\n\t * and could result in data corruption or data loss as well.\n\t * Therefore, in such cases the caller should typically throw an error, ensuring that this client treats the situation as data corruption\n\t * (since its data no longer matches what other clients think the data should be) and will avoid overriding document content or misleading the users into thinking their current state is accurate.\n\t */\n\tpublic tryProcessMessage(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.process(op, local, localOpMetadata as PendingLocalOpMetadata | undefined);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Rollback a local op\n\t * @param op - The operation to rollback\n\t * @param localOpMetadata - The local metadata associated with the op.\n\t */\n\tpublic rollback(op: unknown, localOpMetadata: unknown): void {\n\t\tconst mapOp: IMapOperation = op as IMapOperation;\n\t\tconst typedLocalOpMetadata = localOpMetadata as PendingLocalOpMetadata;\n\t\tif (mapOp.type === \"clear\") {\n\t\t\t// A pending clear will be last in the list, since it terminates all prior lifetimes.\n\t\t\tconst pendingClear = this.pendingData.pop();\n\t\t\tassert(\n\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\tpendingClear === typedLocalOpMetadata,\n\t\t\t\t0xbf2 /* Unexpected clear rollback */,\n\t\t\t);\n\t\t\tfor (const [key] of this.internalIterator()) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: undefined },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// A pending set/delete may not be last in the list, as the lifetimes' order is based on when\n\t\t\t// they were created, not when they were last modified.\n\t\t\tconst pendingEntryIndex = findLastIndex(\n\t\t\t\tthis.pendingData,\n\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === mapOp.key,\n\t\t\t);\n\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\tassert(\n\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t(pendingEntry.type === \"delete\" || pendingEntry.type === \"lifetime\"),\n\t\t\t\t0xbf3 /* Unexpected pending data for set/delete op */,\n\t\t\t);\n\t\t\tif (pendingEntry.type === \"delete\") {\n\t\t\t\tassert(pendingEntry === typedLocalOpMetadata, 0xbf4 /* Unexpected delete rollback */);\n\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t// Only emit if rolling back the delete actually results in a value becoming visible.\n\t\t\t\tif (this.getOptimisticLocalValue(mapOp.key) !== undefined) {\n\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t{ key: mapOp.key, previousValue: undefined },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (pendingEntry.type === \"lifetime\") {\n\t\t\t\tconst pendingKeySet = pendingEntry.keySets.pop();\n\t\t\t\tassert(\n\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === typedLocalOpMetadata,\n\t\t\t\t\t0xbf5 /* Unexpected set rollback */,\n\t\t\t\t);\n\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t}\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key: mapOp.key, previousValue: pendingKeySet.value.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the message handlers for the map.\n\t * @returns A map of string op names to IMapMessageHandlers for those ops\n\t */\n\tprivate getMessageHandlers(): Map<string, IMapMessageHandler> {\n\t\tconst messageHandlers = new Map<string, IMapMessageHandler>();\n\t\tmessageHandlers.set(\"clear\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapClearOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tif (local) {\n\t\t\t\t\tthis.sequencedData.clear();\n\t\t\t\t\tconst pendingClear = this.pendingData.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\t\t\tpendingClear === localOpMetadata,\n\t\t\t\t\t\t0xbf6 /* Got a local clear message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst keysToDelete: { key: string; previousValue: unknown }[] = [];\n\t\t\t\t\tfor (const [key, value] of this.sequencedData) {\n\t\t\t\t\t\t// Check if this key has pending local operations that supersede the remote op\n\t\t\t\t\t\tconst hasPendingOps = this.pendingData.some(\n\t\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\t\t(entry.type === \"delete\" && entry.key === key) ||\n\t\t\t\t\t\t\t\t(entry.type === \"lifetime\" && entry.key === key),\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Only collect keys without pending operations (i.e., actually deleted)\n\t\t\t\t\t\tif (!hasPendingOps) {\n\t\t\t\t\t\t\tkeysToDelete.push({ key, previousValue: value.value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.sequencedData.clear();\n\n\t\t\t\t\t// Only emit for remote ops, we would have already emitted for local ops. Only emit if there\n\t\t\t\t\t// is no optimistically-applied local pending clear that would supersede this remote clear.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\")) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\"clear\", local, this.eventEmitter);\n\n\t\t\t\t\t\t// Emit delete-like valueChanged events for keys that were removed\n\t\t\t\t\t\tfor (const { key, previousValue } of keysToDelete) {\n\t\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapClearOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"delete\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapDeleteOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t\t\tpendingEntry.type === \"delete\" &&\n\t\t\t\t\t\t\tpendingEntry === localOpMetadata,\n\t\t\t\t\t\t0xbf7 /* Got a local delete message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapDeleteOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"set\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapSetOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key, value } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined && pendingEntry.type === \"lifetime\",\n\t\t\t\t\t\t0xbf8 /* Couldn't match local set message to pending lifetime */,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingKeySet = pendingEntry.keySets.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === localOpMetadata,\n\t\t\t\t\t\t0xbf9 /* Got a local set message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.sequencedData.set(key, pendingKeySet.value);\n\t\t\t\t} else {\n\t\t\t\t\tmigrateIfSharedSerializable(value, this.serializer, this.handle);\n\t\t\t\t\tconst localValue: ILocalValue = { value: value.value };\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.set(key, localValue);\n\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapSetOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\n\t\treturn messageHandlers;\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/map";
8
- export declare const pkgVersion = "2.74.0-368706";
8
+ export declare const pkgVersion = "2.74.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAC7C,eAAO,MAAM,UAAU,kBAAkB,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAC7C,eAAO,MAAM,UAAU,WAAW,CAAC"}
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/map";
11
- exports.pkgVersion = "2.74.0-368706";
11
+ exports.pkgVersion = "2.74.0";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,qBAAqB,CAAC;AAChC,QAAA,UAAU,GAAG,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/map\";\nexport const pkgVersion = \"2.74.0-368706\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,qBAAqB,CAAC;AAChC,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/map\";\nexport const pkgVersion = \"2.74.0\";\n"]}
@@ -0,0 +1,27 @@
1
+ /* eslint-disable */
2
+ /**
3
+ * GENERATED FILE - DO NOT EDIT DIRECTLY.
4
+ * To regenerate: pnpm tsx scripts/generate-flat-eslint-configs.ts --typescript
5
+ */
6
+ import type { Linter } from "eslint";
7
+ import { strict } from "../../../common/build/eslint-config-fluid/flat.mts";
8
+
9
+ const config: Linter.Config[] = [
10
+ ...strict,
11
+ {
12
+ rules: {
13
+ "@typescript-eslint/no-use-before-define": "off",
14
+ "@typescript-eslint/strict-boolean-expressions": "off",
15
+ "unicorn/numeric-separators-style": "off",
16
+ "@fluid-internal/fluid/no-unchecked-record-access": "warn",
17
+ },
18
+ },
19
+ {
20
+ files: ["src/test/**"],
21
+ rules: {
22
+ "unicorn/prefer-module": "off",
23
+ },
24
+ },
25
+ ];
26
+
27
+ export default config;
@@ -1 +1 @@
1
- {"version":3,"file":"mapKernel.d.ts","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mapKernel.d.ts","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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"}
package/lib/mapKernel.js CHANGED
@@ -469,18 +469,33 @@ export class MapKernel {
469
469
  const messageHandlers = new Map();
470
470
  messageHandlers.set("clear", {
471
471
  process: (op, local, localOpMetadata) => {
472
- this.sequencedData.clear();
473
472
  if (local) {
473
+ this.sequencedData.clear();
474
474
  const pendingClear = this.pendingData.shift();
475
475
  assert(pendingClear !== undefined &&
476
476
  pendingClear.type === "clear" &&
477
477
  pendingClear === localOpMetadata, 0xbf6 /* Got a local clear message we weren't expecting */);
478
478
  }
479
479
  else {
480
+ const keysToDelete = [];
481
+ for (const [key, value] of this.sequencedData) {
482
+ // Check if this key has pending local operations that supersede the remote op
483
+ const hasPendingOps = this.pendingData.some((entry) => (entry.type === "delete" && entry.key === key) ||
484
+ (entry.type === "lifetime" && entry.key === key));
485
+ // Only collect keys without pending operations (i.e., actually deleted)
486
+ if (!hasPendingOps) {
487
+ keysToDelete.push({ key, previousValue: value.value });
488
+ }
489
+ }
490
+ this.sequencedData.clear();
480
491
  // Only emit for remote ops, we would have already emitted for local ops. Only emit if there
481
492
  // is no optimistically-applied local pending clear that would supersede this remote clear.
482
493
  if (!this.pendingData.some((entry) => entry.type === "clear")) {
483
494
  this.eventEmitter.emit("clear", local, this.eventEmitter);
495
+ // Emit delete-like valueChanged events for keys that were removed
496
+ for (const { key, previousValue } of keysToDelete) {
497
+ this.eventEmitter.emit("valueChanged", { key, previousValue }, local, this.eventEmitter);
498
+ }
484
499
  }
485
500
  }
486
501
  },
@@ -1 +1 @@
1
- {"version":3,"file":"mapKernel.js","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { ValueType } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ISharedMapEvents } from \"./interfaces.js\";\nimport type {\n\tIMapClearOperation,\n\tIMapDeleteOperation,\n\tIMapSetOperation,\n\t// eslint-disable-next-line import-x/no-deprecated\n\tISerializableValue,\n\tISerializedValue,\n} from \"./internalInterfaces.js\";\nimport {\n\ttype ILocalValue,\n\tserializeValue,\n\tmigrateIfSharedSerializable,\n} from \"./localValues.js\";\nimport { findLast, findLastIndex } from \"./utils.js\";\n\n/**\n * Defines the means to process and resubmit a given op on a map.\n */\ninterface IMapMessageHandler {\n\t/**\n\t * Apply the given operation.\n\t * @param op - The map operation to apply\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t */\n\tprocess(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t): void;\n\n\t/**\n\t * Resubmit a previously submitted operation that was not delivered.\n\t * @param op - The map operation to resubmit\n\t * @param localOpMetadata - The metadata that was originally submitted with the message.\n\t */\n\tresubmit(op: IMapOperation, localOpMetadata: PendingLocalOpMetadata): void;\n}\n\n/**\n * Union of all possible map operations.\n */\nexport type IMapOperation = IMapSetOperation | IMapDeleteOperation | IMapClearOperation;\n\n/**\n * Defines the in-memory object structure to be used for the conversion to/from serialized.\n *\n * @remarks Directly used in\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\n * | JSON.stringify}, direct result from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}.\n */\n// eslint-disable-next-line import-x/no-deprecated\nexport type IMapDataObjectSerializable = Record<string, ISerializableValue>;\n\n/**\n * Serialized key/value data.\n */\nexport type IMapDataObjectSerialized = Record<string, ISerializedValue>;\n\ninterface PendingKeySet {\n\ttype: \"set\";\n\tvalue: ILocalValue;\n}\n\ninterface PendingKeyDelete {\n\ttype: \"delete\";\n\tkey: string;\n}\n\ninterface PendingClear {\n\ttype: \"clear\";\n}\n\ninterface PendingKeyLifetime {\n\ttype: \"lifetime\";\n\tkey: string;\n\t/**\n\t * A non-empty array of pending key sets that occurred during this lifetime. If the list\n\t * becomes empty (e.g. during processing or rollback), the lifetime no longer exists and\n\t * must be removed from the pending data.\n\t */\n\tkeySets: PendingKeySet[];\n}\n\n/**\n * A member of the pendingData array, which tracks outstanding changes and can be used to\n * compute optimistic values. Local sets are aggregated into lifetimes.\n */\ntype PendingDataEntry = PendingKeyLifetime | PendingKeyDelete | PendingClear;\n/**\n * An individual outstanding change, which will also be found in the pendingData array\n * (though the PendingKeySets will be contained within a PendingKeyLifetime there).\n */\ntype PendingLocalOpMetadata = PendingKeySet | PendingKeyDelete | PendingClear;\n\n/**\n * A SharedMap is a map-like distributed data structure.\n */\nexport class MapKernel {\n\t/**\n\t * The number of key/value pairs stored in the map.\n\t */\n\tpublic get size(): number {\n\t\tconst iterableItems = [...this.internalIterator()];\n\t\treturn iterableItems.length;\n\t}\n\n\t/**\n\t * Mapping of op types to message handlers.\n\t */\n\tprivate readonly messageHandlers: ReadonlyMap<string, IMapMessageHandler> = new Map();\n\n\t/**\n\t * The data the map is storing, but only including sequenced values (no local pending\n\t * modifications are included).\n\t */\n\tprivate readonly sequencedData = new Map<string, ILocalValue>();\n\t/**\n\t * A data structure containing all local pending modifications, which is used in combination\n\t * with the sequencedData to compute optimistic values.\n\t *\n\t * Pending sets are aggregated into \"lifetimes\", which permit correct relative iteration order\n\t * even across remote operations and rollbacks.\n\t */\n\tprivate readonly pendingData: PendingDataEntry[] = [];\n\n\t/**\n\t * Create a new shared map kernel.\n\t * @param serializer - The serializer to serialize / parse handles\n\t * @param handle - The handle of the shared object using the kernel\n\t * @param submitMessage - A callback to submit a message through the shared object\n\t * @param isAttached - To query whether the shared object should generate ops\n\t * @param valueTypes - The value types to register\n\t * @param eventEmitter - The object that will emit map events\n\t */\n\tpublic constructor(\n\t\tprivate readonly serializer: IFluidSerializer,\n\t\tprivate readonly handle: IFluidHandle,\n\t\tprivate readonly submitMessage: (op: unknown, localOpMetadata: unknown) => void,\n\t\tprivate readonly isAttached: () => boolean,\n\t\tprivate readonly eventEmitter: TypedEventEmitter<ISharedMapEvents>,\n\t) {\n\t\tthis.messageHandlers = this.getMessageHandlers();\n\t}\n\n\t/**\n\t * Get an iterator over the optimistically observable ILocalValue entries in the map. For example, excluding\n\t * sequenced entries that have pending deletes/clears.\n\t *\n\t * @remarks\n\t * There is no perfect solution here, particularly when the iterator is retained over time and the map is\n\t * modified or new ack's are received. The pendingData portion of the iteration is the most susceptible to\n\t * this problem. The implementation prioritizes (in roughly this order):\n\t * 1. Correct immediate iteration (i.e. when the map is not modified before iteration completes)\n\t * 2. Consistent iteration order before/after sequencing of pending ops; acks don't change order\n\t * 3. Consistent iteration order between synchronized clients, even if they each modified the map concurrently\n\t * 4. Remaining as close as possible to the native Map iterator behavior, e.g. live-ish view rather than snapshot\n\t *\n\t * For this reason, it's important not to internally snapshot the output of the iterator for any purpose that\n\t * does not immediately (synchronously) consume that output and dispose of it.\n\t */\n\tprivate readonly internalIterator = (): IterableIterator<[string, ILocalValue]> => {\n\t\t// We perform iteration in two steps - first by iterating over members of the sequenced data that are not\n\t\t// optimistically deleted or cleared, and then over the pending data lifetimes that have not subsequently\n\t\t// been deleted or cleared. In total, this give an ordering of members based on when they were initially\n\t\t// added to the map (even if they were later modified), similar to the native Map.\n\t\tconst sequencedDataIterator = this.sequencedData.keys();\n\t\tconst pendingDataIterator = this.pendingData.values();\n\t\tconst next = (): IteratorResult<[string, ILocalValue]> => {\n\t\t\tlet nextSequencedKey = sequencedDataIterator.next();\n\t\t\twhile (!nextSequencedKey.done) {\n\t\t\t\tconst key = nextSequencedKey.value;\n\t\t\t\t// If we have any pending deletes or clears, then we won't iterate to this key yet (if at all).\n\t\t\t\t// Either it is optimistically deleted and will not be part of the iteration, or it was\n\t\t\t\t// re-added later and we'll iterate to it when we get to the pending data.\n\t\t\t\tif (\n\t\t\t\t\t!this.pendingData.some(\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" || (entry.type === \"delete\" && entry.key === key),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tconst optimisticValue = this.getOptimisticLocalValue(key);\n\t\t\t\t\tassert(\n\t\t\t\t\t\toptimisticValue !== undefined,\n\t\t\t\t\t\t0xbf1 /* Should never iterate to a key with undefined optimisticValue */,\n\t\t\t\t\t);\n\t\t\t\t\treturn { value: [key, optimisticValue], done: false };\n\t\t\t\t}\n\t\t\t\tnextSequencedKey = sequencedDataIterator.next();\n\t\t\t}\n\n\t\t\tlet nextPending = pendingDataIterator.next();\n\t\t\twhile (!nextPending.done) {\n\t\t\t\tconst nextPendingEntry = nextPending.value;\n\t\t\t\t// A lifetime entry may need to be iterated.\n\t\t\t\tif (nextPendingEntry.type === \"lifetime\") {\n\t\t\t\t\tconst nextPendingEntryIndex = this.pendingData.indexOf(nextPendingEntry);\n\t\t\t\t\tconst mostRecentDeleteOrClearIndex = findLastIndex(\n\t\t\t\t\t\tthis.pendingData,\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" ||\n\t\t\t\t\t\t\t(entry.type === \"delete\" && entry.key === nextPendingEntry.key),\n\t\t\t\t\t);\n\t\t\t\t\t// Only iterate the pending entry now if it hasn't been deleted or cleared.\n\t\t\t\t\tif (nextPendingEntryIndex > mostRecentDeleteOrClearIndex) {\n\t\t\t\t\t\tconst latestPendingValue =\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\tnextPendingEntry.keySets[nextPendingEntry.keySets.length - 1]!;\n\t\t\t\t\t\t// Skip iterating if we would have would have already iterated it as part of the sequenced data.\n\t\t\t\t\t\t// This is not a perfect check in the case the map has changed since the iterator was created\n\t\t\t\t\t\t// (e.g. if a remote client added the same key in the meantime).\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.sequencedData.has(nextPendingEntry.key) ||\n\t\t\t\t\t\t\tmostRecentDeleteOrClearIndex !== -1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn { value: [nextPendingEntry.key, latestPendingValue.value], done: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnextPending = pendingDataIterator.next();\n\t\t\t}\n\n\t\t\treturn { value: undefined, done: true };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, ILocalValue]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t};\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic entries(): IterableIterator<[string, unknown]> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<[string, unknown]> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\t// Unpack the stored value\n\t\t\tconst [key, localValue] = nextResult.value;\n\t\t\treturn { value: [key, localValue.value], done: false };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the keys in this map.\n\t * @returns The iterator\n\t */\n\tpublic keys(): IterableIterator<string> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<string> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [key] = nextResult.value;\n\t\t\treturn { value: key, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<string> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the values in this map.\n\t * @returns The iterator\n\t */\n\tpublic values(): IterableIterator<unknown> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<unknown> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [, localValue] = nextResult.value;\n\t\t\treturn { value: localValue.value, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<unknown> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic [Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\treturn this.entries();\n\t}\n\n\t/**\n\t * Executes the given callback on each entry in the map.\n\t * @param callbackFn - Callback function\n\t */\n\tpublic forEach(\n\t\tcallbackFn: (value: unknown, key: string, map: Map<string, unknown>) => void,\n\t): void {\n\t\t// It would be better to iterate over the data without a temp map. However, we don't have a valid\n\t\t// map to pass for the third argument here (really, it should probably should be a reference to the\n\t\t// SharedMap and not the MapKernel).\n\t\tconst tempMap = new Map(this.internalIterator());\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\ttempMap.forEach((localValue, key, m) => {\n\t\t\tcallbackFn(localValue.value, key, m);\n\t\t});\n\t}\n\n\t/**\n\t * Compute the optimistic local value for a given key. This combines the sequenced data with\n\t * any pending changes that have not yet been sequenced.\n\t */\n\tprivate readonly getOptimisticLocalValue = (key: string): ILocalValue | undefined => {\n\t\tconst latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\n\t\tif (latestPendingEntry === undefined) {\n\t\t\treturn this.sequencedData.get(key);\n\t\t} else if (latestPendingEntry.type === \"lifetime\") {\n\t\t\tconst latestPendingSet =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tlatestPendingEntry.keySets[latestPendingEntry.keySets.length - 1]!;\n\t\t\treturn latestPendingSet.value;\n\t\t} else {\n\t\t\t// Delete or clear\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\t/**\n\t * {@inheritDoc ISharedMap.get}\n\t */\n\tpublic get<T = unknown>(key: string): T | undefined {\n\t\tconst localValue = this.getOptimisticLocalValue(key);\n\t\treturn localValue === undefined ? undefined : (localValue.value as T);\n\t}\n\n\t/**\n\t * Check if a key exists in the map.\n\t * @param key - The key to check\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this.getOptimisticLocalValue(key) !== undefined;\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.set}\n\t */\n\tpublic set(key: string, value: unknown): void {\n\t\t// Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.\n\t\tif (key === undefined || key === null) {\n\t\t\tthrow new Error(\"Undefined and null keys are not supported\");\n\t\t}\n\n\t\tconst localValue: ILocalValue = { value };\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.set(key, localValue);\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// A new pending key lifetime is created if:\n\t\t// 1. There isn't any pending entry for the key yet\n\t\t// 2. The most recent pending entry for the key was a deletion (as this terminates the prior lifetime)\n\t\t// 3. A clear was sent after the last pending entry for the key (which also terminates the prior lifetime)\n\t\tlet latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\t\tif (\n\t\t\tlatestPendingEntry === undefined ||\n\t\t\tlatestPendingEntry.type === \"delete\" ||\n\t\t\tlatestPendingEntry.type === \"clear\"\n\t\t) {\n\t\t\tlatestPendingEntry = { type: \"lifetime\", key, keySets: [] };\n\t\t\tthis.pendingData.push(latestPendingEntry);\n\t\t}\n\t\tconst pendingKeySet: PendingKeySet = {\n\t\t\ttype: \"set\",\n\t\t\tvalue: localValue,\n\t\t};\n\t\tlatestPendingEntry.keySets.push(pendingKeySet);\n\n\t\tconst op: IMapSetOperation = {\n\t\t\tkey,\n\t\t\ttype: \"set\",\n\t\t\tvalue: { type: ValueType[ValueType.Plain], value: localValue.value },\n\t\t};\n\t\tthis.submitMessage(op, pendingKeySet);\n\t\tthis.eventEmitter.emit(\n\t\t\t\"valueChanged\",\n\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\ttrue,\n\t\t\tthis.eventEmitter,\n\t\t);\n\t}\n\n\t/**\n\t * Delete a key from the map.\n\t * @param key - Key to delete\n\t * @returns True if the key existed and was deleted, false if it did not exist\n\t */\n\tpublic delete(key: string): boolean {\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\tif (!this.isAttached()) {\n\t\t\tconst successfullyRemoved = this.sequencedData.delete(key);\n\t\t\t// Only emit if we actually deleted something.\n\t\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn successfullyRemoved;\n\t\t}\n\n\t\tconst pendingKeyDelete: PendingKeyDelete = {\n\t\t\ttype: \"delete\",\n\t\t\tkey,\n\t\t};\n\t\tthis.pendingData.push(pendingKeyDelete);\n\n\t\tconst op: IMapDeleteOperation = {\n\t\t\tkey,\n\t\t\ttype: \"delete\",\n\t\t};\n\t\tthis.submitMessage(op, pendingKeyDelete);\n\t\t// Only emit if we locally believe we deleted something. Otherwise we still send the op\n\t\t// (permitting speculative deletion even if we don't see anything locally) but don't emit\n\t\t// a valueChanged since we in fact did not locally observe a value change.\n\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear all data from the map.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.clear();\n\t\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t\t\treturn;\n\t\t}\n\n\t\tconst pendingClear: PendingClear = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.pendingData.push(pendingClear);\n\n\t\tconst op: IMapClearOperation = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitMessage(op, pendingClear);\n\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t}\n\n\t/**\n\t * Serializes the data stored in the shared map to a JSON string\n\t * @param serializer - The serializer to use to serialize handles in its values.\n\t * @returns A JSON string containing serialized map data\n\t */\n\tpublic getSerializedStorage(serializer: IFluidSerializer): IMapDataObjectSerialized {\n\t\tconst serializedMapData: IMapDataObjectSerialized = {};\n\t\tfor (const [key, localValue] of this.sequencedData.entries()) {\n\t\t\tserializedMapData[key] = serializeValue(localValue.value, serializer, this.handle);\n\t\t}\n\t\treturn serializedMapData;\n\t}\n\n\t/**\n\t * Populate the kernel with the given map data.\n\t * @param data - A JSON string containing serialized map data\n\t */\n\tpublic populateFromSerializable(json: IMapDataObjectSerializable): void {\n\t\tfor (const [key, serializable] of Object.entries(\n\t\t\tthis.serializer.decode(json) as IMapDataObjectSerializable,\n\t\t)) {\n\t\t\tmigrateIfSharedSerializable(serializable, this.serializer, this.handle);\n\t\t\tthis.sequencedData.set(key, { value: serializable.value });\n\t\t}\n\t}\n\n\t/**\n\t * Resubmit the given op if a handler is registered.\n\t * @param op - The operation to attempt to submit\n\t * @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime\n\t * and not sent to the server. This will be sent back when this message is received back from the server. This is\n\t * also sent if we are asked to resubmit the message.\n\t * @returns True if the operation was submitted, false otherwise.\n\t */\n\tpublic tryResubmitMessage(op: IMapOperation, localOpMetadata: unknown): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.resubmit(op, localOpMetadata as PendingLocalOpMetadata);\n\t\treturn true;\n\t}\n\n\tpublic tryApplyStashedOp(op: IMapOperation): void {\n\t\tswitch (op.type) {\n\t\t\tcase \"clear\": {\n\t\t\t\tthis.clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"delete\": {\n\t\t\t\tthis.delete(op.key);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"set\": {\n\t\t\t\tmigrateIfSharedSerializable(op.value, this.serializer, this.handle);\n\t\t\t\tthis.set(op.key, op.value.value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(op);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Process the given op if a handler is registered.\n\t * @param message - The message to process\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t * @returns True if the operation was recognized and thus processed, false otherwise.\n\t *\n\t * @remarks\n\t * When this returns false and the caller doesn't handle the op itself, then the op could be from a different version of this code.\n\t * In such a case, not applying the op would result in this client becoming out of sync with clients that do handle the op\n\t * and could result in data corruption or data loss as well.\n\t * Therefore, in such cases the caller should typically throw an error, ensuring that this client treats the situation as data corruption\n\t * (since its data no longer matches what other clients think the data should be) and will avoid overriding document content or misleading the users into thinking their current state is accurate.\n\t */\n\tpublic tryProcessMessage(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.process(op, local, localOpMetadata as PendingLocalOpMetadata | undefined);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Rollback a local op\n\t * @param op - The operation to rollback\n\t * @param localOpMetadata - The local metadata associated with the op.\n\t */\n\tpublic rollback(op: unknown, localOpMetadata: unknown): void {\n\t\tconst mapOp: IMapOperation = op as IMapOperation;\n\t\tconst typedLocalOpMetadata = localOpMetadata as PendingLocalOpMetadata;\n\t\tif (mapOp.type === \"clear\") {\n\t\t\t// A pending clear will be last in the list, since it terminates all prior lifetimes.\n\t\t\tconst pendingClear = this.pendingData.pop();\n\t\t\tassert(\n\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\tpendingClear === typedLocalOpMetadata,\n\t\t\t\t0xbf2 /* Unexpected clear rollback */,\n\t\t\t);\n\t\t\tfor (const [key] of this.internalIterator()) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: undefined },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// A pending set/delete may not be last in the list, as the lifetimes' order is based on when\n\t\t\t// they were created, not when they were last modified.\n\t\t\tconst pendingEntryIndex = findLastIndex(\n\t\t\t\tthis.pendingData,\n\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === mapOp.key,\n\t\t\t);\n\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\tassert(\n\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t(pendingEntry.type === \"delete\" || pendingEntry.type === \"lifetime\"),\n\t\t\t\t0xbf3 /* Unexpected pending data for set/delete op */,\n\t\t\t);\n\t\t\tif (pendingEntry.type === \"delete\") {\n\t\t\t\tassert(pendingEntry === typedLocalOpMetadata, 0xbf4 /* Unexpected delete rollback */);\n\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t// Only emit if rolling back the delete actually results in a value becoming visible.\n\t\t\t\tif (this.getOptimisticLocalValue(mapOp.key) !== undefined) {\n\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t{ key: mapOp.key, previousValue: undefined },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (pendingEntry.type === \"lifetime\") {\n\t\t\t\tconst pendingKeySet = pendingEntry.keySets.pop();\n\t\t\t\tassert(\n\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === typedLocalOpMetadata,\n\t\t\t\t\t0xbf5 /* Unexpected set rollback */,\n\t\t\t\t);\n\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t}\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key: mapOp.key, previousValue: pendingKeySet.value.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the message handlers for the map.\n\t * @returns A map of string op names to IMapMessageHandlers for those ops\n\t */\n\tprivate getMessageHandlers(): Map<string, IMapMessageHandler> {\n\t\tconst messageHandlers = new Map<string, IMapMessageHandler>();\n\t\tmessageHandlers.set(\"clear\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapClearOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tthis.sequencedData.clear();\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingClear = this.pendingData.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\t\t\tpendingClear === localOpMetadata,\n\t\t\t\t\t\t0xbf6 /* Got a local clear message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\t// Only emit for remote ops, we would have already emitted for local ops. Only emit if there\n\t\t\t\t\t// is no optimistically-applied local pending clear that would supersede this remote clear.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\")) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\"clear\", local, this.eventEmitter);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapClearOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"delete\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapDeleteOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t\t\tpendingEntry.type === \"delete\" &&\n\t\t\t\t\t\t\tpendingEntry === localOpMetadata,\n\t\t\t\t\t\t0xbf7 /* Got a local delete message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapDeleteOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"set\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapSetOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key, value } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined && pendingEntry.type === \"lifetime\",\n\t\t\t\t\t\t0xbf8 /* Couldn't match local set message to pending lifetime */,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingKeySet = pendingEntry.keySets.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === localOpMetadata,\n\t\t\t\t\t\t0xbf9 /* Got a local set message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.sequencedData.set(key, pendingKeySet.value);\n\t\t\t\t} else {\n\t\t\t\t\tmigrateIfSharedSerializable(value, this.serializer, this.handle);\n\t\t\t\t\tconst localValue: ILocalValue = { value: value.value };\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.set(key, localValue);\n\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapSetOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\n\t\treturn messageHandlers;\n\t}\n}\n"]}
1
+ {"version":3,"file":"mapKernel.js","sourceRoot":"","sources":["../src/mapKernel.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { TypedEventEmitter } from \"@fluid-internal/client-utils\";\nimport type { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { ValueType } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ISharedMapEvents } from \"./interfaces.js\";\nimport type {\n\tIMapClearOperation,\n\tIMapDeleteOperation,\n\tIMapSetOperation,\n\t// eslint-disable-next-line import-x/no-deprecated\n\tISerializableValue,\n\tISerializedValue,\n} from \"./internalInterfaces.js\";\nimport {\n\ttype ILocalValue,\n\tserializeValue,\n\tmigrateIfSharedSerializable,\n} from \"./localValues.js\";\nimport { findLast, findLastIndex } from \"./utils.js\";\n\n/**\n * Defines the means to process and resubmit a given op on a map.\n */\ninterface IMapMessageHandler {\n\t/**\n\t * Apply the given operation.\n\t * @param op - The map operation to apply\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t */\n\tprocess(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t): void;\n\n\t/**\n\t * Resubmit a previously submitted operation that was not delivered.\n\t * @param op - The map operation to resubmit\n\t * @param localOpMetadata - The metadata that was originally submitted with the message.\n\t */\n\tresubmit(op: IMapOperation, localOpMetadata: PendingLocalOpMetadata): void;\n}\n\n/**\n * Union of all possible map operations.\n */\nexport type IMapOperation = IMapSetOperation | IMapDeleteOperation | IMapClearOperation;\n\n/**\n * Defines the in-memory object structure to be used for the conversion to/from serialized.\n *\n * @remarks Directly used in\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\n * | JSON.stringify}, direct result from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}.\n */\n// eslint-disable-next-line import-x/no-deprecated\nexport type IMapDataObjectSerializable = Record<string, ISerializableValue>;\n\n/**\n * Serialized key/value data.\n */\nexport type IMapDataObjectSerialized = Record<string, ISerializedValue>;\n\ninterface PendingKeySet {\n\ttype: \"set\";\n\tvalue: ILocalValue;\n}\n\ninterface PendingKeyDelete {\n\ttype: \"delete\";\n\tkey: string;\n}\n\ninterface PendingClear {\n\ttype: \"clear\";\n}\n\ninterface PendingKeyLifetime {\n\ttype: \"lifetime\";\n\tkey: string;\n\t/**\n\t * A non-empty array of pending key sets that occurred during this lifetime. If the list\n\t * becomes empty (e.g. during processing or rollback), the lifetime no longer exists and\n\t * must be removed from the pending data.\n\t */\n\tkeySets: PendingKeySet[];\n}\n\n/**\n * A member of the pendingData array, which tracks outstanding changes and can be used to\n * compute optimistic values. Local sets are aggregated into lifetimes.\n */\ntype PendingDataEntry = PendingKeyLifetime | PendingKeyDelete | PendingClear;\n/**\n * An individual outstanding change, which will also be found in the pendingData array\n * (though the PendingKeySets will be contained within a PendingKeyLifetime there).\n */\ntype PendingLocalOpMetadata = PendingKeySet | PendingKeyDelete | PendingClear;\n\n/**\n * A SharedMap is a map-like distributed data structure.\n */\nexport class MapKernel {\n\t/**\n\t * The number of key/value pairs stored in the map.\n\t */\n\tpublic get size(): number {\n\t\tconst iterableItems = [...this.internalIterator()];\n\t\treturn iterableItems.length;\n\t}\n\n\t/**\n\t * Mapping of op types to message handlers.\n\t */\n\tprivate readonly messageHandlers: ReadonlyMap<string, IMapMessageHandler> = new Map();\n\n\t/**\n\t * The data the map is storing, but only including sequenced values (no local pending\n\t * modifications are included).\n\t */\n\tprivate readonly sequencedData = new Map<string, ILocalValue>();\n\t/**\n\t * A data structure containing all local pending modifications, which is used in combination\n\t * with the sequencedData to compute optimistic values.\n\t *\n\t * Pending sets are aggregated into \"lifetimes\", which permit correct relative iteration order\n\t * even across remote operations and rollbacks.\n\t */\n\tprivate readonly pendingData: PendingDataEntry[] = [];\n\n\t/**\n\t * Create a new shared map kernel.\n\t * @param serializer - The serializer to serialize / parse handles\n\t * @param handle - The handle of the shared object using the kernel\n\t * @param submitMessage - A callback to submit a message through the shared object\n\t * @param isAttached - To query whether the shared object should generate ops\n\t * @param valueTypes - The value types to register\n\t * @param eventEmitter - The object that will emit map events\n\t */\n\tpublic constructor(\n\t\tprivate readonly serializer: IFluidSerializer,\n\t\tprivate readonly handle: IFluidHandle,\n\t\tprivate readonly submitMessage: (op: unknown, localOpMetadata: unknown) => void,\n\t\tprivate readonly isAttached: () => boolean,\n\t\tprivate readonly eventEmitter: TypedEventEmitter<ISharedMapEvents>,\n\t) {\n\t\tthis.messageHandlers = this.getMessageHandlers();\n\t}\n\n\t/**\n\t * Get an iterator over the optimistically observable ILocalValue entries in the map. For example, excluding\n\t * sequenced entries that have pending deletes/clears.\n\t *\n\t * @remarks\n\t * There is no perfect solution here, particularly when the iterator is retained over time and the map is\n\t * modified or new ack's are received. The pendingData portion of the iteration is the most susceptible to\n\t * this problem. The implementation prioritizes (in roughly this order):\n\t * 1. Correct immediate iteration (i.e. when the map is not modified before iteration completes)\n\t * 2. Consistent iteration order before/after sequencing of pending ops; acks don't change order\n\t * 3. Consistent iteration order between synchronized clients, even if they each modified the map concurrently\n\t * 4. Remaining as close as possible to the native Map iterator behavior, e.g. live-ish view rather than snapshot\n\t *\n\t * For this reason, it's important not to internally snapshot the output of the iterator for any purpose that\n\t * does not immediately (synchronously) consume that output and dispose of it.\n\t */\n\tprivate readonly internalIterator = (): IterableIterator<[string, ILocalValue]> => {\n\t\t// We perform iteration in two steps - first by iterating over members of the sequenced data that are not\n\t\t// optimistically deleted or cleared, and then over the pending data lifetimes that have not subsequently\n\t\t// been deleted or cleared. In total, this give an ordering of members based on when they were initially\n\t\t// added to the map (even if they were later modified), similar to the native Map.\n\t\tconst sequencedDataIterator = this.sequencedData.keys();\n\t\tconst pendingDataIterator = this.pendingData.values();\n\t\tconst next = (): IteratorResult<[string, ILocalValue]> => {\n\t\t\tlet nextSequencedKey = sequencedDataIterator.next();\n\t\t\twhile (!nextSequencedKey.done) {\n\t\t\t\tconst key = nextSequencedKey.value;\n\t\t\t\t// If we have any pending deletes or clears, then we won't iterate to this key yet (if at all).\n\t\t\t\t// Either it is optimistically deleted and will not be part of the iteration, or it was\n\t\t\t\t// re-added later and we'll iterate to it when we get to the pending data.\n\t\t\t\tif (\n\t\t\t\t\t!this.pendingData.some(\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" || (entry.type === \"delete\" && entry.key === key),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tconst optimisticValue = this.getOptimisticLocalValue(key);\n\t\t\t\t\tassert(\n\t\t\t\t\t\toptimisticValue !== undefined,\n\t\t\t\t\t\t0xbf1 /* Should never iterate to a key with undefined optimisticValue */,\n\t\t\t\t\t);\n\t\t\t\t\treturn { value: [key, optimisticValue], done: false };\n\t\t\t\t}\n\t\t\t\tnextSequencedKey = sequencedDataIterator.next();\n\t\t\t}\n\n\t\t\tlet nextPending = pendingDataIterator.next();\n\t\t\twhile (!nextPending.done) {\n\t\t\t\tconst nextPendingEntry = nextPending.value;\n\t\t\t\t// A lifetime entry may need to be iterated.\n\t\t\t\tif (nextPendingEntry.type === \"lifetime\") {\n\t\t\t\t\tconst nextPendingEntryIndex = this.pendingData.indexOf(nextPendingEntry);\n\t\t\t\t\tconst mostRecentDeleteOrClearIndex = findLastIndex(\n\t\t\t\t\t\tthis.pendingData,\n\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\tentry.type === \"clear\" ||\n\t\t\t\t\t\t\t(entry.type === \"delete\" && entry.key === nextPendingEntry.key),\n\t\t\t\t\t);\n\t\t\t\t\t// Only iterate the pending entry now if it hasn't been deleted or cleared.\n\t\t\t\t\tif (nextPendingEntryIndex > mostRecentDeleteOrClearIndex) {\n\t\t\t\t\t\tconst latestPendingValue =\n\t\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\t\t\tnextPendingEntry.keySets[nextPendingEntry.keySets.length - 1]!;\n\t\t\t\t\t\t// Skip iterating if we would have would have already iterated it as part of the sequenced data.\n\t\t\t\t\t\t// This is not a perfect check in the case the map has changed since the iterator was created\n\t\t\t\t\t\t// (e.g. if a remote client added the same key in the meantime).\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!this.sequencedData.has(nextPendingEntry.key) ||\n\t\t\t\t\t\t\tmostRecentDeleteOrClearIndex !== -1\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn { value: [nextPendingEntry.key, latestPendingValue.value], done: false };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnextPending = pendingDataIterator.next();\n\t\t\t}\n\n\t\t\treturn { value: undefined, done: true };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, ILocalValue]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t};\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic entries(): IterableIterator<[string, unknown]> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<[string, unknown]> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\t// Unpack the stored value\n\t\t\tconst [key, localValue] = nextResult.value;\n\t\t\treturn { value: [key, localValue.value], done: false };\n\t\t};\n\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the keys in this map.\n\t * @returns The iterator\n\t */\n\tpublic keys(): IterableIterator<string> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<string> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [key] = nextResult.value;\n\t\t\treturn { value: key, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<string> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the values in this map.\n\t * @returns The iterator\n\t */\n\tpublic values(): IterableIterator<unknown> {\n\t\tconst internalIterator = this.internalIterator();\n\t\tconst next = (): IteratorResult<unknown> => {\n\t\t\tconst nextResult = internalIterator.next();\n\t\t\tif (nextResult.done) {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t\tconst [, localValue] = nextResult.value;\n\t\t\treturn { value: localValue.value, done: false };\n\t\t};\n\t\tconst iterator = {\n\t\t\tnext,\n\t\t\t[Symbol.iterator](): IterableIterator<unknown> {\n\t\t\t\treturn this;\n\t\t\t},\n\t\t};\n\t\treturn iterator;\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\tpublic [Symbol.iterator](): IterableIterator<[string, unknown]> {\n\t\treturn this.entries();\n\t}\n\n\t/**\n\t * Executes the given callback on each entry in the map.\n\t * @param callbackFn - Callback function\n\t */\n\tpublic forEach(\n\t\tcallbackFn: (value: unknown, key: string, map: Map<string, unknown>) => void,\n\t): void {\n\t\t// It would be better to iterate over the data without a temp map. However, we don't have a valid\n\t\t// map to pass for the third argument here (really, it should probably should be a reference to the\n\t\t// SharedMap and not the MapKernel).\n\t\tconst tempMap = new Map(this.internalIterator());\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\ttempMap.forEach((localValue, key, m) => {\n\t\t\tcallbackFn(localValue.value, key, m);\n\t\t});\n\t}\n\n\t/**\n\t * Compute the optimistic local value for a given key. This combines the sequenced data with\n\t * any pending changes that have not yet been sequenced.\n\t */\n\tprivate readonly getOptimisticLocalValue = (key: string): ILocalValue | undefined => {\n\t\tconst latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\n\t\tif (latestPendingEntry === undefined) {\n\t\t\treturn this.sequencedData.get(key);\n\t\t} else if (latestPendingEntry.type === \"lifetime\") {\n\t\t\tconst latestPendingSet =\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tlatestPendingEntry.keySets[latestPendingEntry.keySets.length - 1]!;\n\t\t\treturn latestPendingSet.value;\n\t\t} else {\n\t\t\t// Delete or clear\n\t\t\treturn undefined;\n\t\t}\n\t};\n\n\t/**\n\t * {@inheritDoc ISharedMap.get}\n\t */\n\tpublic get<T = unknown>(key: string): T | undefined {\n\t\tconst localValue = this.getOptimisticLocalValue(key);\n\t\treturn localValue === undefined ? undefined : (localValue.value as T);\n\t}\n\n\t/**\n\t * Check if a key exists in the map.\n\t * @param key - The key to check\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this.getOptimisticLocalValue(key) !== undefined;\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.set}\n\t */\n\tpublic set(key: string, value: unknown): void {\n\t\t// Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.\n\t\tif (key === undefined || key === null) {\n\t\t\tthrow new Error(\"Undefined and null keys are not supported\");\n\t\t}\n\n\t\tconst localValue: ILocalValue = { value };\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\t// If we are not attached, don't submit the op.\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.set(key, localValue);\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\t// A new pending key lifetime is created if:\n\t\t// 1. There isn't any pending entry for the key yet\n\t\t// 2. The most recent pending entry for the key was a deletion (as this terminates the prior lifetime)\n\t\t// 3. A clear was sent after the last pending entry for the key (which also terminates the prior lifetime)\n\t\tlet latestPendingEntry = findLast(\n\t\t\tthis.pendingData,\n\t\t\t(entry) => entry.type === \"clear\" || entry.key === key,\n\t\t);\n\t\tif (\n\t\t\tlatestPendingEntry === undefined ||\n\t\t\tlatestPendingEntry.type === \"delete\" ||\n\t\t\tlatestPendingEntry.type === \"clear\"\n\t\t) {\n\t\t\tlatestPendingEntry = { type: \"lifetime\", key, keySets: [] };\n\t\t\tthis.pendingData.push(latestPendingEntry);\n\t\t}\n\t\tconst pendingKeySet: PendingKeySet = {\n\t\t\ttype: \"set\",\n\t\t\tvalue: localValue,\n\t\t};\n\t\tlatestPendingEntry.keySets.push(pendingKeySet);\n\n\t\tconst op: IMapSetOperation = {\n\t\t\tkey,\n\t\t\ttype: \"set\",\n\t\t\tvalue: { type: ValueType[ValueType.Plain], value: localValue.value },\n\t\t};\n\t\tthis.submitMessage(op, pendingKeySet);\n\t\tthis.eventEmitter.emit(\n\t\t\t\"valueChanged\",\n\t\t\t{ key, previousValue: previousOptimisticLocalValue?.value },\n\t\t\ttrue,\n\t\t\tthis.eventEmitter,\n\t\t);\n\t}\n\n\t/**\n\t * Delete a key from the map.\n\t * @param key - Key to delete\n\t * @returns True if the key existed and was deleted, false if it did not exist\n\t */\n\tpublic delete(key: string): boolean {\n\t\tconst previousOptimisticLocalValue = this.getOptimisticLocalValue(key);\n\n\t\tif (!this.isAttached()) {\n\t\t\tconst successfullyRemoved = this.sequencedData.delete(key);\n\t\t\t// Only emit if we actually deleted something.\n\t\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn successfullyRemoved;\n\t\t}\n\n\t\tconst pendingKeyDelete: PendingKeyDelete = {\n\t\t\ttype: \"delete\",\n\t\t\tkey,\n\t\t};\n\t\tthis.pendingData.push(pendingKeyDelete);\n\n\t\tconst op: IMapDeleteOperation = {\n\t\t\tkey,\n\t\t\ttype: \"delete\",\n\t\t};\n\t\tthis.submitMessage(op, pendingKeyDelete);\n\t\t// Only emit if we locally believe we deleted something. Otherwise we still send the op\n\t\t// (permitting speculative deletion even if we don't see anything locally) but don't emit\n\t\t// a valueChanged since we in fact did not locally observe a value change.\n\t\tif (previousOptimisticLocalValue !== undefined) {\n\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\"valueChanged\",\n\t\t\t\t{ key, previousValue: previousOptimisticLocalValue.value },\n\t\t\t\ttrue,\n\t\t\t\tthis.eventEmitter,\n\t\t\t);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Clear all data from the map.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.isAttached()) {\n\t\t\tthis.sequencedData.clear();\n\t\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t\t\treturn;\n\t\t}\n\n\t\tconst pendingClear: PendingClear = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.pendingData.push(pendingClear);\n\n\t\tconst op: IMapClearOperation = {\n\t\t\ttype: \"clear\",\n\t\t};\n\t\tthis.submitMessage(op, pendingClear);\n\t\tthis.eventEmitter.emit(\"clear\", true, this.eventEmitter);\n\t}\n\n\t/**\n\t * Serializes the data stored in the shared map to a JSON string\n\t * @param serializer - The serializer to use to serialize handles in its values.\n\t * @returns A JSON string containing serialized map data\n\t */\n\tpublic getSerializedStorage(serializer: IFluidSerializer): IMapDataObjectSerialized {\n\t\tconst serializedMapData: IMapDataObjectSerialized = {};\n\t\tfor (const [key, localValue] of this.sequencedData.entries()) {\n\t\t\tserializedMapData[key] = serializeValue(localValue.value, serializer, this.handle);\n\t\t}\n\t\treturn serializedMapData;\n\t}\n\n\t/**\n\t * Populate the kernel with the given map data.\n\t * @param data - A JSON string containing serialized map data\n\t */\n\tpublic populateFromSerializable(json: IMapDataObjectSerializable): void {\n\t\tfor (const [key, serializable] of Object.entries(\n\t\t\tthis.serializer.decode(json) as IMapDataObjectSerializable,\n\t\t)) {\n\t\t\tmigrateIfSharedSerializable(serializable, this.serializer, this.handle);\n\t\t\tthis.sequencedData.set(key, { value: serializable.value });\n\t\t}\n\t}\n\n\t/**\n\t * Resubmit the given op if a handler is registered.\n\t * @param op - The operation to attempt to submit\n\t * @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime\n\t * and not sent to the server. This will be sent back when this message is received back from the server. This is\n\t * also sent if we are asked to resubmit the message.\n\t * @returns True if the operation was submitted, false otherwise.\n\t */\n\tpublic tryResubmitMessage(op: IMapOperation, localOpMetadata: unknown): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.resubmit(op, localOpMetadata as PendingLocalOpMetadata);\n\t\treturn true;\n\t}\n\n\tpublic tryApplyStashedOp(op: IMapOperation): void {\n\t\tswitch (op.type) {\n\t\t\tcase \"clear\": {\n\t\t\t\tthis.clear();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"delete\": {\n\t\t\t\tthis.delete(op.key);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"set\": {\n\t\t\t\tmigrateIfSharedSerializable(op.value, this.serializer, this.handle);\n\t\t\t\tthis.set(op.key, op.value.value);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tunreachableCase(op);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Process the given op if a handler is registered.\n\t * @param message - The message to process\n\t * @param local - Whether the message originated from the local client\n\t * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n\t * For messages from a remote client, this will be undefined.\n\t * @returns True if the operation was recognized and thus processed, false otherwise.\n\t *\n\t * @remarks\n\t * When this returns false and the caller doesn't handle the op itself, then the op could be from a different version of this code.\n\t * In such a case, not applying the op would result in this client becoming out of sync with clients that do handle the op\n\t * and could result in data corruption or data loss as well.\n\t * Therefore, in such cases the caller should typically throw an error, ensuring that this client treats the situation as data corruption\n\t * (since its data no longer matches what other clients think the data should be) and will avoid overriding document content or misleading the users into thinking their current state is accurate.\n\t */\n\tpublic tryProcessMessage(\n\t\top: IMapOperation,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): boolean {\n\t\tconst handler = this.messageHandlers.get(op.type);\n\t\tif (handler === undefined) {\n\t\t\treturn false;\n\t\t}\n\t\thandler.process(op, local, localOpMetadata as PendingLocalOpMetadata | undefined);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Rollback a local op\n\t * @param op - The operation to rollback\n\t * @param localOpMetadata - The local metadata associated with the op.\n\t */\n\tpublic rollback(op: unknown, localOpMetadata: unknown): void {\n\t\tconst mapOp: IMapOperation = op as IMapOperation;\n\t\tconst typedLocalOpMetadata = localOpMetadata as PendingLocalOpMetadata;\n\t\tif (mapOp.type === \"clear\") {\n\t\t\t// A pending clear will be last in the list, since it terminates all prior lifetimes.\n\t\t\tconst pendingClear = this.pendingData.pop();\n\t\t\tassert(\n\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\tpendingClear === typedLocalOpMetadata,\n\t\t\t\t0xbf2 /* Unexpected clear rollback */,\n\t\t\t);\n\t\t\tfor (const [key] of this.internalIterator()) {\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key, previousValue: undefined },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\t// A pending set/delete may not be last in the list, as the lifetimes' order is based on when\n\t\t\t// they were created, not when they were last modified.\n\t\t\tconst pendingEntryIndex = findLastIndex(\n\t\t\t\tthis.pendingData,\n\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === mapOp.key,\n\t\t\t);\n\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\tassert(\n\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t(pendingEntry.type === \"delete\" || pendingEntry.type === \"lifetime\"),\n\t\t\t\t0xbf3 /* Unexpected pending data for set/delete op */,\n\t\t\t);\n\t\t\tif (pendingEntry.type === \"delete\") {\n\t\t\t\tassert(pendingEntry === typedLocalOpMetadata, 0xbf4 /* Unexpected delete rollback */);\n\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t// Only emit if rolling back the delete actually results in a value becoming visible.\n\t\t\t\tif (this.getOptimisticLocalValue(mapOp.key) !== undefined) {\n\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t{ key: mapOp.key, previousValue: undefined },\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (pendingEntry.type === \"lifetime\") {\n\t\t\t\tconst pendingKeySet = pendingEntry.keySets.pop();\n\t\t\t\tassert(\n\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === typedLocalOpMetadata,\n\t\t\t\t\t0xbf5 /* Unexpected set rollback */,\n\t\t\t\t);\n\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t}\n\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t{ key: mapOp.key, previousValue: pendingKeySet.value.value },\n\t\t\t\t\ttrue,\n\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get the message handlers for the map.\n\t * @returns A map of string op names to IMapMessageHandlers for those ops\n\t */\n\tprivate getMessageHandlers(): Map<string, IMapMessageHandler> {\n\t\tconst messageHandlers = new Map<string, IMapMessageHandler>();\n\t\tmessageHandlers.set(\"clear\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapClearOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tif (local) {\n\t\t\t\t\tthis.sequencedData.clear();\n\t\t\t\t\tconst pendingClear = this.pendingData.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingClear !== undefined &&\n\t\t\t\t\t\t\tpendingClear.type === \"clear\" &&\n\t\t\t\t\t\t\tpendingClear === localOpMetadata,\n\t\t\t\t\t\t0xbf6 /* Got a local clear message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst keysToDelete: { key: string; previousValue: unknown }[] = [];\n\t\t\t\t\tfor (const [key, value] of this.sequencedData) {\n\t\t\t\t\t\t// Check if this key has pending local operations that supersede the remote op\n\t\t\t\t\t\tconst hasPendingOps = this.pendingData.some(\n\t\t\t\t\t\t\t(entry) =>\n\t\t\t\t\t\t\t\t(entry.type === \"delete\" && entry.key === key) ||\n\t\t\t\t\t\t\t\t(entry.type === \"lifetime\" && entry.key === key),\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Only collect keys without pending operations (i.e., actually deleted)\n\t\t\t\t\t\tif (!hasPendingOps) {\n\t\t\t\t\t\t\tkeysToDelete.push({ key, previousValue: value.value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.sequencedData.clear();\n\n\t\t\t\t\t// Only emit for remote ops, we would have already emitted for local ops. Only emit if there\n\t\t\t\t\t// is no optimistically-applied local pending clear that would supersede this remote clear.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\")) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\"clear\", local, this.eventEmitter);\n\n\t\t\t\t\t\t// Emit delete-like valueChanged events for keys that were removed\n\t\t\t\t\t\tfor (const { key, previousValue } of keysToDelete) {\n\t\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapClearOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"delete\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapDeleteOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined &&\n\t\t\t\t\t\t\tpendingEntry.type === \"delete\" &&\n\t\t\t\t\t\t\tpendingEntry === localOpMetadata,\n\t\t\t\t\t\t0xbf7 /* Got a local delete message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t} else {\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.delete(key);\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapDeleteOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\t\tmessageHandlers.set(\"set\", {\n\t\t\tprocess: (\n\t\t\t\top: IMapSetOperation,\n\t\t\t\tlocal: boolean,\n\t\t\t\tlocalOpMetadata: PendingLocalOpMetadata | undefined,\n\t\t\t) => {\n\t\t\t\tconst { key, value } = op;\n\n\t\t\t\tif (local) {\n\t\t\t\t\tconst pendingEntryIndex = this.pendingData.findIndex(\n\t\t\t\t\t\t(entry) => entry.type !== \"clear\" && entry.key === key,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEntry = this.pendingData[pendingEntryIndex];\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingEntry !== undefined && pendingEntry.type === \"lifetime\",\n\t\t\t\t\t\t0xbf8 /* Couldn't match local set message to pending lifetime */,\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingKeySet = pendingEntry.keySets.shift();\n\t\t\t\t\tassert(\n\t\t\t\t\t\tpendingKeySet !== undefined && pendingKeySet === localOpMetadata,\n\t\t\t\t\t\t0xbf9 /* Got a local set message we weren't expecting */,\n\t\t\t\t\t);\n\t\t\t\t\tif (pendingEntry.keySets.length === 0) {\n\t\t\t\t\t\tthis.pendingData.splice(pendingEntryIndex, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.sequencedData.set(key, pendingKeySet.value);\n\t\t\t\t} else {\n\t\t\t\t\tmigrateIfSharedSerializable(value, this.serializer, this.handle);\n\t\t\t\t\tconst localValue: ILocalValue = { value: value.value };\n\t\t\t\t\tconst previousValue: unknown = this.sequencedData.get(key)?.value;\n\t\t\t\t\tthis.sequencedData.set(key, localValue);\n\n\t\t\t\t\t// Suppress the event if local changes would cause the incoming change to be invisible optimistically.\n\t\t\t\t\tif (!this.pendingData.some((entry) => entry.type === \"clear\" || entry.key === key)) {\n\t\t\t\t\t\tthis.eventEmitter.emit(\n\t\t\t\t\t\t\t\"valueChanged\",\n\t\t\t\t\t\t\t{ key, previousValue },\n\t\t\t\t\t\t\tlocal,\n\t\t\t\t\t\t\tthis.eventEmitter,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tresubmit: (op: IMapSetOperation, localOpMetadata: PendingLocalOpMetadata) => {\n\t\t\t\tthis.submitMessage(op, localOpMetadata);\n\t\t\t},\n\t\t});\n\n\t\treturn messageHandlers;\n\t}\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/map";
8
- export declare const pkgVersion = "2.74.0-368706";
8
+ export declare const pkgVersion = "2.74.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAC7C,eAAO,MAAM,UAAU,kBAAkB,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAC7C,eAAO,MAAM,UAAU,WAAW,CAAC"}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/map";
8
- export const pkgVersion = "2.74.0-368706";
8
+ export const pkgVersion = "2.74.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/map\";\nexport const pkgVersion = \"2.74.0-368706\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/map\";\nexport const pkgVersion = \"2.74.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/map",
3
- "version": "2.74.0-368706",
3
+ "version": "2.74.0",
4
4
  "description": "Distributed map",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -81,32 +81,32 @@
81
81
  "temp-directory": "nyc/.nyc_output"
82
82
  },
83
83
  "dependencies": {
84
- "@fluid-internal/client-utils": "2.74.0-368706",
85
- "@fluidframework/core-interfaces": "2.74.0-368706",
86
- "@fluidframework/core-utils": "2.74.0-368706",
87
- "@fluidframework/datastore-definitions": "2.74.0-368706",
88
- "@fluidframework/driver-definitions": "2.74.0-368706",
89
- "@fluidframework/driver-utils": "2.74.0-368706",
90
- "@fluidframework/runtime-definitions": "2.74.0-368706",
91
- "@fluidframework/runtime-utils": "2.74.0-368706",
92
- "@fluidframework/shared-object-base": "2.74.0-368706",
93
- "@fluidframework/telemetry-utils": "2.74.0-368706",
84
+ "@fluid-internal/client-utils": "~2.74.0",
85
+ "@fluidframework/core-interfaces": "~2.74.0",
86
+ "@fluidframework/core-utils": "~2.74.0",
87
+ "@fluidframework/datastore-definitions": "~2.74.0",
88
+ "@fluidframework/driver-definitions": "~2.74.0",
89
+ "@fluidframework/driver-utils": "~2.74.0",
90
+ "@fluidframework/runtime-definitions": "~2.74.0",
91
+ "@fluidframework/runtime-utils": "~2.74.0",
92
+ "@fluidframework/shared-object-base": "~2.74.0",
93
+ "@fluidframework/telemetry-utils": "~2.74.0",
94
94
  "path-browserify": "^1.0.1"
95
95
  },
96
96
  "devDependencies": {
97
97
  "@arethetypeswrong/cli": "^0.17.1",
98
98
  "@biomejs/biome": "~1.9.3",
99
- "@fluid-internal/mocha-test-setup": "2.74.0-368706",
100
- "@fluid-private/stochastic-test-utils": "2.74.0-368706",
101
- "@fluid-private/test-dds-utils": "2.74.0-368706",
99
+ "@fluid-internal/mocha-test-setup": "~2.74.0",
100
+ "@fluid-private/stochastic-test-utils": "~2.74.0",
101
+ "@fluid-private/test-dds-utils": "~2.74.0",
102
102
  "@fluid-tools/benchmark": "^0.51.0",
103
- "@fluid-tools/build-cli": "^0.60.0",
103
+ "@fluid-tools/build-cli": "^0.61.0",
104
104
  "@fluidframework/build-common": "^2.0.3",
105
- "@fluidframework/build-tools": "^0.60.0",
106
- "@fluidframework/container-definitions": "2.74.0-368706",
107
- "@fluidframework/eslint-config-fluid": "2.74.0-368706",
105
+ "@fluidframework/build-tools": "^0.61.0",
106
+ "@fluidframework/container-definitions": "~2.74.0",
107
+ "@fluidframework/eslint-config-fluid": "~2.74.0",
108
108
  "@fluidframework/map-previous": "npm:@fluidframework/map@2.73.0",
109
- "@fluidframework/test-runtime-utils": "2.74.0-368706",
109
+ "@fluidframework/test-runtime-utils": "~2.74.0",
110
110
  "@microsoft/api-extractor": "7.52.11",
111
111
  "@types/mocha": "^10.0.10",
112
112
  "@types/node": "^18.19.0",
@@ -116,6 +116,7 @@
116
116
  "copyfiles": "^2.4.1",
117
117
  "cross-env": "^7.0.3",
118
118
  "eslint": "~8.57.1",
119
+ "jiti": "^2.6.1",
119
120
  "mocha": "^10.8.2",
120
121
  "mocha-multi-reporters": "^1.5.1",
121
122
  "rimraf": "^4.4.0",
package/src/mapKernel.ts CHANGED
@@ -685,8 +685,8 @@ export class MapKernel {
685
685
  local: boolean,
686
686
  localOpMetadata: PendingLocalOpMetadata | undefined,
687
687
  ) => {
688
- this.sequencedData.clear();
689
688
  if (local) {
689
+ this.sequencedData.clear();
690
690
  const pendingClear = this.pendingData.shift();
691
691
  assert(
692
692
  pendingClear !== undefined &&
@@ -695,10 +695,35 @@ export class MapKernel {
695
695
  0xbf6 /* Got a local clear message we weren't expecting */,
696
696
  );
697
697
  } else {
698
+ const keysToDelete: { key: string; previousValue: unknown }[] = [];
699
+ for (const [key, value] of this.sequencedData) {
700
+ // Check if this key has pending local operations that supersede the remote op
701
+ const hasPendingOps = this.pendingData.some(
702
+ (entry) =>
703
+ (entry.type === "delete" && entry.key === key) ||
704
+ (entry.type === "lifetime" && entry.key === key),
705
+ );
706
+ // Only collect keys without pending operations (i.e., actually deleted)
707
+ if (!hasPendingOps) {
708
+ keysToDelete.push({ key, previousValue: value.value });
709
+ }
710
+ }
711
+ this.sequencedData.clear();
712
+
698
713
  // Only emit for remote ops, we would have already emitted for local ops. Only emit if there
699
714
  // is no optimistically-applied local pending clear that would supersede this remote clear.
700
715
  if (!this.pendingData.some((entry) => entry.type === "clear")) {
701
716
  this.eventEmitter.emit("clear", local, this.eventEmitter);
717
+
718
+ // Emit delete-like valueChanged events for keys that were removed
719
+ for (const { key, previousValue } of keysToDelete) {
720
+ this.eventEmitter.emit(
721
+ "valueChanged",
722
+ { key, previousValue },
723
+ local,
724
+ this.eventEmitter,
725
+ );
726
+ }
702
727
  }
703
728
  }
704
729
  },
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/map";
9
- export const pkgVersion = "2.74.0-368706";
9
+ export const pkgVersion = "2.74.0";