@fluidframework/map 2.0.0-internal.2.2.0 → 2.0.0-internal.2.3.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.
Files changed (59) hide show
  1. package/.eslintrc.js +4 -1
  2. package/dist/directory.d.ts +5 -4
  3. package/dist/directory.d.ts.map +1 -1
  4. package/dist/directory.js +26 -11
  5. package/dist/directory.js.map +1 -1
  6. package/dist/interfaces.d.ts +3 -4
  7. package/dist/interfaces.d.ts.map +1 -1
  8. package/dist/interfaces.js.map +1 -1
  9. package/dist/internalInterfaces.d.ts +39 -0
  10. package/dist/internalInterfaces.d.ts.map +1 -1
  11. package/dist/internalInterfaces.js.map +1 -1
  12. package/dist/localValues.d.ts +12 -3
  13. package/dist/localValues.d.ts.map +1 -1
  14. package/dist/localValues.js +10 -0
  15. package/dist/localValues.js.map +1 -1
  16. package/dist/map.d.ts +4 -4
  17. package/dist/map.d.ts.map +1 -1
  18. package/dist/map.js +11 -0
  19. package/dist/map.js.map +1 -1
  20. package/dist/mapKernel.d.ts +5 -5
  21. package/dist/mapKernel.d.ts.map +1 -1
  22. package/dist/mapKernel.js +25 -11
  23. package/dist/mapKernel.js.map +1 -1
  24. package/dist/packageVersion.d.ts +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/lib/directory.d.ts +5 -4
  28. package/lib/directory.d.ts.map +1 -1
  29. package/lib/directory.js +26 -11
  30. package/lib/directory.js.map +1 -1
  31. package/lib/interfaces.d.ts +3 -4
  32. package/lib/interfaces.d.ts.map +1 -1
  33. package/lib/interfaces.js.map +1 -1
  34. package/lib/internalInterfaces.d.ts +39 -0
  35. package/lib/internalInterfaces.d.ts.map +1 -1
  36. package/lib/internalInterfaces.js.map +1 -1
  37. package/lib/localValues.d.ts +12 -3
  38. package/lib/localValues.d.ts.map +1 -1
  39. package/lib/localValues.js +10 -0
  40. package/lib/localValues.js.map +1 -1
  41. package/lib/map.d.ts +4 -4
  42. package/lib/map.d.ts.map +1 -1
  43. package/lib/map.js +11 -0
  44. package/lib/map.js.map +1 -1
  45. package/lib/mapKernel.d.ts +5 -5
  46. package/lib/mapKernel.d.ts.map +1 -1
  47. package/lib/mapKernel.js +25 -11
  48. package/lib/mapKernel.js.map +1 -1
  49. package/lib/packageVersion.d.ts +1 -1
  50. package/lib/packageVersion.js +1 -1
  51. package/lib/packageVersion.js.map +1 -1
  52. package/package.json +17 -16
  53. package/src/directory.ts +85 -54
  54. package/src/interfaces.ts +19 -9
  55. package/src/internalInterfaces.ts +45 -0
  56. package/src/localValues.ts +18 -7
  57. package/src/map.ts +28 -17
  58. package/src/mapKernel.ts +50 -32
  59. package/src/packageVersion.ts +1 -1
package/lib/mapKernel.js CHANGED
@@ -5,6 +5,7 @@
5
5
  import { ValueType } from "@fluidframework/shared-object-base";
6
6
  import { assert } from "@fluidframework/common-utils";
7
7
  import { LocalValueMaker, makeSerializable, } from "./localValues";
8
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
8
9
  function isMapKeyLocalOpMetadata(metadata) {
9
10
  return metadata !== undefined && typeof metadata.pendingMessageId === "number" &&
10
11
  (metadata.type === "add" || metadata.type === "edit");
@@ -16,6 +17,7 @@ function isMapLocalOpMetadata(metadata) {
16
17
  return metadata !== undefined && typeof metadata.pendingMessageId === "number" &&
17
18
  (metadata.type === "add" || metadata.type === "edit" || metadata.type === "clear");
18
19
  }
20
+ /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */
19
21
  function createClearLocalOpMetadata(op, pendingClearMessageId, previousMap) {
20
22
  const localMetadata = {
21
23
  type: "clear",
@@ -88,6 +90,8 @@ export class MapKernel {
88
90
  * Get an iterator over the entries in this map.
89
91
  * @returns The iterator
90
92
  */
93
+ // TODO: Use `unknown` instead (breaking change).
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
95
  entries() {
92
96
  const localEntriesIterator = this.data.entries();
93
97
  const iterator = {
@@ -108,6 +112,8 @@ export class MapKernel {
108
112
  * Get an iterator over the values in this map.
109
113
  * @returns The iterator
110
114
  */
115
+ // TODO: Use `unknown` instead (breaking change).
116
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
117
  values() {
112
118
  const localValuesIterator = this.data.values();
113
119
  const iterator = {
@@ -128,6 +134,8 @@ export class MapKernel {
128
134
  * Get an iterator over the entries in this map.
129
135
  * @returns The iterator
130
136
  */
137
+ // TODO: Use `unknown` instead (breaking change).
138
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
139
  [Symbol.iterator]() {
132
140
  return this.entries();
133
141
  }
@@ -136,6 +144,7 @@ export class MapKernel {
136
144
  * @param callbackFn - Callback function
137
145
  */
138
146
  forEach(callbackFn) {
147
+ // eslint-disable-next-line unicorn/no-array-for-each
139
148
  this.data.forEach((localValue, key, m) => {
140
149
  callbackFn(localValue.value, key, m);
141
150
  });
@@ -143,6 +152,8 @@ export class MapKernel {
143
152
  /**
144
153
  * {@inheritDoc ISharedMap.get}
145
154
  */
155
+ // TODO: Use `unknown` instead (breaking change).
156
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
146
157
  get(key) {
147
158
  const localValue = this.data.get(key);
148
159
  return localValue === undefined ? undefined : localValue.value;
@@ -221,16 +232,16 @@ export class MapKernel {
221
232
  */
222
233
  getSerializedStorage(serializer) {
223
234
  const serializableMapData = {};
224
- this.data.forEach((localValue, key) => {
235
+ for (const [key, localValue] of this.data.entries()) {
225
236
  serializableMapData[key] = localValue.makeSerialized(serializer, this.handle);
226
- });
237
+ }
227
238
  return serializableMapData;
228
239
  }
229
240
  getSerializableStorage(serializer) {
230
241
  const serializableMapData = {};
231
- this.data.forEach((localValue, key) => {
242
+ for (const [key, localValue] of this.data.entries()) {
232
243
  serializableMapData[key] = makeSerializable(localValue, serializer, this.handle);
233
- });
244
+ }
234
245
  return serializableMapData;
235
246
  }
236
247
  serialize(serializer) {
@@ -291,11 +302,13 @@ export class MapKernel {
291
302
  handler.process(op, local, localOpMetadata);
292
303
  return true;
293
304
  }
305
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
294
306
  /**
295
307
  * Rollback a local op
296
308
  * @param op - The operation to rollback
297
309
  * @param localOpMetadata - The local metadata associated with the op.
298
310
  */
311
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
299
312
  rollback(op, localOpMetadata) {
300
313
  if (!isMapLocalOpMetadata(localOpMetadata)) {
301
314
  throw new Error("Invalid localOpMetadata");
@@ -304,9 +317,9 @@ export class MapKernel {
304
317
  if (localOpMetadata.previousMap === undefined) {
305
318
  throw new Error("Cannot rollback without previous map");
306
319
  }
307
- localOpMetadata.previousMap.forEach((localValue, key) => {
320
+ for (const [key, localValue] of localOpMetadata.previousMap.entries()) {
308
321
  this.setCore(key, localValue, true);
309
- });
322
+ }
310
323
  const lastPendingClearId = this.pendingClearMessageIds.pop();
311
324
  if (lastPendingClearId === undefined || lastPendingClearId !== localOpMetadata.pendingMessageId) {
312
325
  throw new Error("Rollback op does match last clear");
@@ -335,6 +348,7 @@ export class MapKernel {
335
348
  throw new Error("Unsupported op for rollback");
336
349
  }
337
350
  }
351
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access */
338
352
  /**
339
353
  * Set implementation used for both locally sourced sets as well as incoming remote sets.
340
354
  * @param key - The key being set
@@ -379,14 +393,14 @@ export class MapKernel {
379
393
  // Assuming the pendingKeys is small and the map is large
380
394
  // we will get the value for the pendingKeys and clear the map
381
395
  const temp = new Map();
382
- this.pendingKeys.forEach((value, key) => {
396
+ for (const key of this.pendingKeys.keys()) {
383
397
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
384
398
  temp.set(key, this.data.get(key));
385
- });
399
+ }
386
400
  this.clearCore(false);
387
- temp.forEach((value, key) => {
401
+ for (const [key, value] of temp.entries()) {
388
402
  this.setCore(key, value, true);
389
- });
403
+ }
390
404
  }
391
405
  /**
392
406
  * The remote ISerializableValue we're receiving (either as a result of a load or an incoming set op) will
@@ -456,7 +470,7 @@ export class MapKernel {
456
470
  assert(pendingClearMessageId === localOpMetadata.pendingMessageId, 0x2fb /* pendingMessageId does not match */);
457
471
  return;
458
472
  }
459
- if (this.pendingKeys.size !== 0) {
473
+ if (this.pendingKeys.size > 0) {
460
474
  this.clearExceptPendingKeys();
461
475
  return;
462
476
  }
@@ -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 { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { IFluidSerializer, ValueType } from \"@fluidframework/shared-object-base\";\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n ISerializableValue,\n ISerializedValue,\n ISharedMapEvents,\n} from \"./interfaces\";\nimport {\n IMapSetOperation,\n IMapDeleteOperation,\n IMapClearOperation,\n IMapKeyEditLocalOpMetadata,\n IMapKeyAddLocalOpMetadata,\n IMapClearLocalOpMetadata,\n} from \"./internalInterfaces\";\nimport {\n ILocalValue,\n LocalValueMaker,\n makeSerializable,\n} from \"./localValues\";\n\n/**\n * Defines the means to process and submit a given op on a map.\n */\ninterface IMapMessageHandler {\n /**\n * Apply the given operation.\n * @param op - The map operation to apply\n * @param local - Whether the message originated from the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n */\n process(\n op: IMapOperation,\n local: boolean,\n localOpMetadata: MapLocalOpMetadata,\n ): void;\n\n /**\n * Communicate the operation to remote clients.\n * @param op - The map operation to submit\n * @param localOpMetadata - The metadata to be submitted with the message.\n */\n submit(op: IMapOperation, localOpMetadata: MapLocalOpMetadata): void;\n\n applyStashedOp(op: IMapOperation): MapLocalOpMetadata;\n}\n\n/**\n * Map key operations are one of several types.\n */\nexport type IMapKeyOperation = IMapSetOperation | IMapDeleteOperation;\n\n/**\n * Description of a map delta operation\n */\nexport type IMapOperation = IMapKeyOperation | 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 */\nexport interface IMapDataObjectSerializable {\n [key: string]: ISerializableValue;\n}\n\n/**\n * Serialized key/value data.\n */\nexport interface IMapDataObjectSerialized {\n [key: string]: ISerializedValue;\n}\n\ntype MapKeyLocalOpMetadata = IMapKeyEditLocalOpMetadata | IMapKeyAddLocalOpMetadata;\ntype MapLocalOpMetadata = IMapClearLocalOpMetadata | MapKeyLocalOpMetadata;\n\nfunction isMapKeyLocalOpMetadata(metadata: any): metadata is MapKeyLocalOpMetadata {\n return metadata !== undefined && typeof metadata.pendingMessageId === \"number\" &&\n (metadata.type === \"add\" || metadata.type === \"edit\");\n}\n\nfunction isClearLocalOpMetadata(metadata: any): metadata is IMapClearLocalOpMetadata {\n return metadata !== undefined && metadata.type === \"clear\" && typeof metadata.pendingMessageId === \"number\";\n}\n\nfunction isMapLocalOpMetadata(metadata: any): metadata is MapLocalOpMetadata {\n return metadata !== undefined && typeof metadata.pendingMessageId === \"number\" &&\n (metadata.type === \"add\" || metadata.type === \"edit\" || metadata.type === \"clear\");\n}\n\nfunction createClearLocalOpMetadata(op: IMapClearOperation,\n pendingClearMessageId: number, previousMap?: Map<string, ILocalValue>): IMapClearLocalOpMetadata {\n const localMetadata: IMapClearLocalOpMetadata = {\n type: \"clear\",\n pendingMessageId: pendingClearMessageId, previousMap,\n };\n return localMetadata;\n}\n\nfunction createKeyLocalOpMetadata(op: IMapKeyOperation,\n pendingMessageId: number, previousValue?: ILocalValue): MapKeyLocalOpMetadata {\n const localMetadata: MapKeyLocalOpMetadata = previousValue ?\n { type: \"edit\", pendingMessageId, previousValue } :\n { type: \"add\", pendingMessageId };\n return localMetadata;\n}\n\n/**\n * A SharedMap is a map-like distributed data structure.\n */\nexport class MapKernel {\n /**\n * The number of key/value pairs stored in the map.\n */\n public get size(): number {\n return this.data.size;\n }\n\n /**\n * Mapping of op types to message handlers.\n */\n private readonly messageHandlers: ReadonlyMap<string, IMapMessageHandler> = new Map();\n\n /**\n * The in-memory data the map is storing.\n */\n private readonly data = new Map<string, ILocalValue>();\n\n /**\n * Keys that have been modified locally but not yet ack'd from the server.\n */\n private readonly pendingKeys: Map<string, number[]> = new Map();\n\n /**\n * This is used to assign a unique id to every outgoing operation and helps in tracking unack'd ops.\n */\n private pendingMessageId: number = -1;\n\n /**\n * The pending ids of any clears that have been performed locally but not yet ack'd from the server\n */\n private readonly pendingClearMessageIds: number[] = [];\n\n /**\n * Object to create encapsulations of the values stored in the map.\n */\n private readonly localValueMaker: LocalValueMaker;\n\n /**\n * Create a new shared map kernel.\n * @param serializer - The serializer to serialize / parse handles\n * @param handle - The handle of the shared object using the kernel\n * @param submitMessage - A callback to submit a message through the shared object\n * @param isAttached - To query whether the shared object should generate ops\n * @param valueTypes - The value types to register\n * @param eventEmitter - The object that will emit map events\n */\n constructor(\n private readonly serializer: IFluidSerializer,\n private readonly handle: IFluidHandle,\n private readonly submitMessage: (op: any, localOpMetadata: unknown) => void,\n private readonly isAttached: () => boolean,\n private readonly eventEmitter: TypedEventEmitter<ISharedMapEvents>,\n ) {\n this.localValueMaker = new LocalValueMaker(serializer);\n this.messageHandlers = this.getMessageHandlers();\n }\n\n /**\n * Get an iterator over the keys in this map.\n * @returns The iterator\n */\n public keys(): IterableIterator<string> {\n return this.data.keys();\n }\n\n /**\n * Get an iterator over the entries in this map.\n * @returns The iterator\n */\n public entries(): IterableIterator<[string, any]> {\n const localEntriesIterator = this.data.entries();\n const iterator = {\n next(): IteratorResult<[string, any]> {\n const nextVal = localEntriesIterator.next();\n return nextVal.done\n ? { value: undefined, done: true }\n // Unpack the stored value\n : { value: [nextVal.value[0], nextVal.value[1].value], done: false };\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the values in this map.\n * @returns The iterator\n */\n public values(): IterableIterator<any> {\n const localValuesIterator = this.data.values();\n const iterator = {\n next(): IteratorResult<any> {\n const nextVal = localValuesIterator.next();\n return nextVal.done\n ? { value: undefined, done: true }\n // Unpack the stored value\n : { value: nextVal.value.value, done: false };\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the entries in this map.\n * @returns The iterator\n */\n public [Symbol.iterator](): IterableIterator<[string, any]> {\n return this.entries();\n }\n\n /**\n * Executes the given callback on each entry in the map.\n * @param callbackFn - Callback function\n */\n public forEach(callbackFn: (value: any, key: string, map: Map<string, any>) => void): void {\n this.data.forEach((localValue, key, m) => {\n callbackFn(localValue.value, key, m);\n });\n }\n\n /**\n * {@inheritDoc ISharedMap.get}\n */\n public get<T = any>(key: string): T | undefined {\n const localValue = this.data.get(key);\n return localValue === undefined ? undefined : localValue.value as T;\n }\n\n /**\n * Check if a key exists in the map.\n * @param key - The key to check\n * @returns True if the key exists, false otherwise\n */\n public has(key: string): boolean {\n return this.data.has(key);\n }\n\n /**\n * {@inheritDoc ISharedMap.set}\n */\n public set(key: string, value: any) {\n // Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.\n if (key === undefined || key === null) {\n throw new Error(\"Undefined and null keys are not supported\");\n }\n\n // Create a local value and serialize it.\n const localValue = this.localValueMaker.fromInMemory(value);\n const serializableValue = makeSerializable(\n localValue,\n this.serializer,\n this.handle);\n\n // Set the value locally.\n const previousValue = this.setCore(\n key,\n localValue,\n true,\n );\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: IMapSetOperation = {\n key,\n type: \"set\",\n value: serializableValue,\n };\n this.submitMapKeyMessage(op, previousValue);\n }\n\n /**\n * Delete a key from the map.\n * @param key - Key to delete\n * @returns True if the key existed and was deleted, false if it did not exist\n */\n public delete(key: string): boolean {\n // Delete the key locally first.\n const previousValue = this.deleteCore(key, true);\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return previousValue !== undefined;\n }\n\n const op: IMapDeleteOperation = {\n key,\n type: \"delete\",\n };\n this.submitMapKeyMessage(op, previousValue);\n\n return previousValue !== undefined;\n }\n\n /**\n * Clear all data from the map.\n */\n public clear(): void {\n const copy = this.isAttached() ? new Map<string, ILocalValue>(this.data) : undefined;\n\n // Clear the data locally first.\n this.clearCore(true);\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: IMapClearOperation = {\n type: \"clear\",\n };\n this.submitMapClearMessage(op, copy);\n }\n\n /**\n * Serializes the data stored in the shared map to a JSON string\n * @param serializer - The serializer to use to serialize handles in its values.\n * @returns A JSON string containing serialized map data\n */\n public getSerializedStorage(serializer: IFluidSerializer): IMapDataObjectSerialized {\n const serializableMapData: IMapDataObjectSerialized = {};\n this.data.forEach((localValue, key) => {\n serializableMapData[key] = localValue.makeSerialized(serializer, this.handle);\n });\n return serializableMapData;\n }\n\n public getSerializableStorage(serializer: IFluidSerializer): IMapDataObjectSerializable {\n const serializableMapData: IMapDataObjectSerializable = {};\n this.data.forEach((localValue, key) => {\n serializableMapData[key] = makeSerializable(localValue, serializer, this.handle);\n });\n return serializableMapData;\n }\n\n public serialize(serializer: IFluidSerializer): string {\n return JSON.stringify(this.getSerializableStorage(serializer));\n }\n\n /**\n * Populate the kernel with the given map data.\n * @param data - A JSON string containing serialized map data\n */\n public populateFromSerializable(json: IMapDataObjectSerializable): void {\n for (const [key, serializable] of Object.entries(json)) {\n const localValue = {\n key,\n value: this.makeLocal(key, serializable),\n };\n\n this.data.set(localValue.key, localValue.value);\n }\n }\n\n public populate(json: string): void {\n this.populateFromSerializable(JSON.parse(json) as IMapDataObjectSerializable);\n }\n\n /**\n * Submit the given op if a handler is registered.\n * @param op - The operation to attempt to submit\n * @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime\n * and not sent to the server. This will be sent back when this message is received back from the server. This is\n * also sent if we are asked to resubmit the message.\n * @returns True if the operation was submitted, false otherwise.\n */\n public trySubmitMessage(op: any, localOpMetadata: unknown): boolean {\n const handler = this.messageHandlers.get(op.type);\n if (handler === undefined) {\n return false;\n }\n handler.submit(op as IMapOperation, localOpMetadata as MapLocalOpMetadata);\n return true;\n }\n\n public tryApplyStashedOp(op: any): unknown {\n const handler = this.messageHandlers.get(op.type);\n if (handler === undefined) {\n throw new Error(\"no apply stashed op handler\");\n }\n return handler.applyStashedOp(op as IMapOperation);\n }\n\n /**\n * Process the given op if a handler is registered.\n * @param op - The message to process\n * @param local - Whether the message originated from the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n * @returns True if the operation was processed, false otherwise.\n */\n public tryProcessMessage(\n op: IMapOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): boolean {\n const handler = this.messageHandlers.get(op.type);\n if (handler === undefined) {\n return false;\n }\n handler.process(op, local, localOpMetadata as MapLocalOpMetadata);\n return true;\n }\n\n /**\n * Rollback a local op\n * @param op - The operation to rollback\n * @param localOpMetadata - The local metadata associated with the op.\n */\n public rollback(op: any, localOpMetadata: unknown) {\n if (!isMapLocalOpMetadata(localOpMetadata)) {\n throw new Error(\"Invalid localOpMetadata\");\n }\n\n if (op.type === \"clear\" && localOpMetadata.type === \"clear\") {\n if (localOpMetadata.previousMap === undefined) {\n throw new Error(\"Cannot rollback without previous map\");\n }\n localOpMetadata.previousMap.forEach((localValue, key) => {\n this.setCore(key, localValue, true);\n });\n\n const lastPendingClearId = this.pendingClearMessageIds.pop();\n if (lastPendingClearId === undefined || lastPendingClearId !== localOpMetadata.pendingMessageId) {\n throw new Error(\"Rollback op does match last clear\");\n }\n } else if (op.type === \"delete\" || op.type === \"set\") {\n if (localOpMetadata.type === \"add\") {\n this.deleteCore(op.key, true);\n } else if (localOpMetadata.type === \"edit\" && localOpMetadata.previousValue !== undefined) {\n this.setCore(op.key, localOpMetadata.previousValue, true);\n } else {\n throw new Error(\"Cannot rollback without previous value\");\n }\n\n const pendingMessageIds = this.pendingKeys.get(op.key);\n const lastPendingMessageId = pendingMessageIds?.pop();\n if (!pendingMessageIds || lastPendingMessageId !== localOpMetadata.pendingMessageId) {\n throw new Error(\"Rollback op does not match last pending\");\n }\n if (pendingMessageIds.length === 0) {\n this.pendingKeys.delete(op.key);\n }\n } else {\n throw new Error(\"Unsupported op for rollback\");\n }\n }\n\n /**\n * Set implementation used for both locally sourced sets as well as incoming remote sets.\n * @param key - The key being set\n * @param value - The value being set\n * @param local - Whether the message originated from the local client\n * @returns Previous local value of the key, if any\n */\n private setCore(key: string, value: ILocalValue, local: boolean): ILocalValue | undefined {\n const previousLocalValue = this.data.get(key);\n const previousValue = previousLocalValue?.value;\n this.data.set(key, value);\n this.eventEmitter.emit(\"valueChanged\", { key, previousValue }, local, this.eventEmitter);\n return previousLocalValue;\n }\n\n /**\n * Clear implementation used for both locally sourced clears as well as incoming remote clears.\n * @param local - Whether the message originated from the local client\n */\n private clearCore(local: boolean): void {\n this.data.clear();\n this.eventEmitter.emit(\"clear\", local, this.eventEmitter);\n }\n\n /**\n * Delete implementation used for both locally sourced deletes as well as incoming remote deletes.\n * @param key - The key being deleted\n * @param local - Whether the message originated from the local client\n * @returns Previous local value of the key if it existed, undefined if it did not exist\n */\n private deleteCore(key: string, local: boolean): ILocalValue | undefined {\n const previousLocalValue = this.data.get(key);\n const previousValue = previousLocalValue?.value;\n const successfullyRemoved = this.data.delete(key);\n if (successfullyRemoved) {\n this.eventEmitter.emit(\"valueChanged\", { key, previousValue }, local, this.eventEmitter);\n }\n return previousLocalValue;\n }\n\n /**\n * Clear all keys in memory in response to a remote clear, but retain keys we have modified but not yet been ack'd.\n */\n private clearExceptPendingKeys(): void {\n // Assuming the pendingKeys is small and the map is large\n // we will get the value for the pendingKeys and clear the map\n const temp = new Map<string, ILocalValue>();\n this.pendingKeys.forEach((value, key) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n temp.set(key, this.data.get(key)!);\n });\n this.clearCore(false);\n temp.forEach((value, key) => {\n this.setCore(key, value, true);\n });\n }\n\n /**\n * The remote ISerializableValue we're receiving (either as a result of a load or an incoming set op) will\n * have the information we need to create a real object, but will not be the real object yet. For example,\n * we might know it's a map and the map's ID but not have the actual map or its data yet. makeLocal's\n * job is to convert that information into a real object for local usage.\n * @param key - The key that the caller intends to store the local value into (used for ops later). But\n * doesn't actually store the local value into that key. So better not lie!\n * @param serializable - The remote information that we can convert into a real object\n * @returns The local value that was produced\n */\n private makeLocal(key: string, serializable: ISerializableValue): ILocalValue {\n if (serializable.type === ValueType[ValueType.Plain] || serializable.type === ValueType[ValueType.Shared]) {\n return this.localValueMaker.fromSerializable(serializable);\n } else {\n throw new Error(\"Unknown local value type\");\n }\n }\n\n /**\n * If our local operations that have not yet been ack'd will eventually overwrite an incoming operation, we should\n * not process the incoming operation.\n * @param op - Operation to check\n * @param local - Whether the message originated from the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n * @returns True if the operation should be processed, false otherwise\n */\n private needProcessKeyOperation(\n op: IMapKeyOperation,\n local: boolean,\n localOpMetadata: MapLocalOpMetadata,\n ): boolean {\n if (this.pendingClearMessageIds.length > 0) {\n if (local) {\n assert(localOpMetadata !== undefined && isMapKeyLocalOpMetadata(localOpMetadata) &&\n localOpMetadata.pendingMessageId < this.pendingClearMessageIds[0],\n 0x013 /* \"Received out of order op when there is an unackd clear message\" */);\n }\n // If we have an unack'd clear, we can ignore all ops.\n return false;\n }\n\n const pendingKeyMessageId = this.pendingKeys.get(op.key);\n if (pendingKeyMessageId !== undefined) {\n // Found an unack'd op. Clear it from the map if the pendingMessageId in the map matches this message's\n // and don't process the op.\n if (local) {\n assert(localOpMetadata !== undefined && isMapKeyLocalOpMetadata(localOpMetadata),\n 0x014 /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageIds = this.pendingKeys.get(op.key);\n assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId,\n 0x2fa /* Unexpected pending message received */);\n pendingMessageIds.shift();\n if (pendingMessageIds.length === 0) {\n this.pendingKeys.delete(op.key);\n }\n }\n return false;\n }\n\n // If we don't have a NACK op on the key, we need to process the remote ops.\n return !local;\n }\n\n /**\n * Get the message handlers for the map.\n * @returns A map of string op names to IMapMessageHandlers for those ops\n */\n private getMessageHandlers() {\n const messageHandlers = new Map<string, IMapMessageHandler>();\n messageHandlers.set(\n \"clear\",\n {\n process: (op: IMapClearOperation, local, localOpMetadata) => {\n if (local) {\n assert(isClearLocalOpMetadata(localOpMetadata),\n 0x015 /* \"pendingMessageId is missing from the local client's clear operation\" */);\n const pendingClearMessageId = this.pendingClearMessageIds.shift();\n assert(pendingClearMessageId === localOpMetadata.pendingMessageId,\n 0x2fb /* pendingMessageId does not match */);\n return;\n }\n if (this.pendingKeys.size !== 0) {\n this.clearExceptPendingKeys();\n return;\n }\n this.clearCore(local);\n },\n submit: (op: IMapClearOperation, localOpMetadata: IMapClearLocalOpMetadata) => {\n assert(isClearLocalOpMetadata(localOpMetadata), 0x2fc /* Invalid localOpMetadata for clear */);\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const pendingClearMessageId = this.pendingClearMessageIds.shift();\n assert(pendingClearMessageId === localOpMetadata.pendingMessageId,\n 0x2fd /* pendingMessageId does not match */);\n this.submitMapClearMessage(op, localOpMetadata.previousMap);\n },\n applyStashedOp: (op: IMapClearOperation) => {\n const copy = new Map<string, ILocalValue>(this.data);\n this.clearCore(true);\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n return createClearLocalOpMetadata(op, this.getMapClearMessageId(), copy);\n },\n });\n messageHandlers.set(\n \"delete\",\n {\n process: (op: IMapDeleteOperation, local, localOpMetadata) => {\n if (!this.needProcessKeyOperation(op, local, localOpMetadata)) {\n return;\n }\n this.deleteCore(op.key, local);\n },\n submit: (op: IMapDeleteOperation, localOpMetadata: MapKeyLocalOpMetadata) => {\n this.resubmitMapKeyMessage(op, localOpMetadata);\n },\n applyStashedOp: (op: IMapDeleteOperation) => {\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const previousValue = this.deleteCore(op.key, true);\n return createKeyLocalOpMetadata(op, this.getMapKeyMessageId(op), previousValue);\n },\n });\n messageHandlers.set(\n \"set\",\n {\n process: (op: IMapSetOperation, local, localOpMetadata) => {\n if (!this.needProcessKeyOperation(op, local, localOpMetadata)) {\n return;\n }\n\n // needProcessKeyOperation should have returned false if local is true\n const context = this.makeLocal(op.key, op.value);\n this.setCore(op.key, context, local);\n },\n submit: (op: IMapSetOperation, localOpMetadata: MapKeyLocalOpMetadata) => {\n this.resubmitMapKeyMessage(op, localOpMetadata);\n },\n applyStashedOp: (op: IMapSetOperation) => {\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const context = this.makeLocal(op.key, op.value);\n const previousValue = this.setCore(op.key, context, true);\n return createKeyLocalOpMetadata(op, this.getMapKeyMessageId(op), previousValue);\n },\n });\n\n return messageHandlers;\n }\n\n private getMapClearMessageId(): number {\n const pendingMessageId = ++this.pendingMessageId;\n this.pendingClearMessageIds.push(pendingMessageId);\n return pendingMessageId;\n }\n\n /**\n * Submit a clear message to remote clients.\n * @param op - The clear message\n */\n private submitMapClearMessage(op: IMapClearOperation, previousMap?: Map<string, ILocalValue>): void {\n const metadata = createClearLocalOpMetadata(op, this.getMapClearMessageId(), previousMap);\n this.submitMessage(op, metadata);\n }\n\n private getMapKeyMessageId(op: IMapKeyOperation): number {\n const pendingMessageId = ++this.pendingMessageId;\n const pendingMessageIds = this.pendingKeys.get(op.key);\n if (pendingMessageIds !== undefined) {\n pendingMessageIds.push(pendingMessageId);\n } else {\n this.pendingKeys.set(op.key, [pendingMessageId]);\n }\n return pendingMessageId;\n }\n\n /**\n * Submit a map key message to remote clients.\n * @param op - The map key message\n * @param previousValue - The value of the key before this op\n */\n private submitMapKeyMessage(op: IMapKeyOperation, previousValue?: ILocalValue): void {\n const localMetadata = createKeyLocalOpMetadata(op, this.getMapKeyMessageId(op), previousValue);\n this.submitMessage(op, localMetadata);\n }\n\n /**\n * Submit a map key message to remote clients based on a previous submit.\n * @param op - The map key message\n * @param localOpMetadata - Metadata from the previous submit\n */\n private resubmitMapKeyMessage(op: IMapKeyOperation, localOpMetadata: MapLocalOpMetadata): void {\n assert(isMapKeyLocalOpMetadata(localOpMetadata), 0x2fe /* Invalid localOpMetadata in submit */);\n\n // clear the old pending message id\n const pendingMessageIds = this.pendingKeys.get(op.key);\n assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId,\n 0x2ff /* Unexpected pending message received */);\n pendingMessageIds.shift();\n if (pendingMessageIds.length === 0) {\n this.pendingKeys.delete(op.key);\n }\n\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const pendingMessageId = this.getMapKeyMessageId(op);\n const localMetadata = localOpMetadata.type === \"edit\" ?\n { type: \"edit\", pendingMessageId, previousValue: localOpMetadata.previousValue } :\n { type: \"add\", pendingMessageId };\n this.submitMessage(op, localMetadata);\n }\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 { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { IFluidSerializer, ValueType } from \"@fluidframework/shared-object-base\";\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n ISerializableValue,\n ISerializedValue,\n ISharedMapEvents,\n} from \"./interfaces\";\nimport {\n IMapSetOperation,\n IMapDeleteOperation,\n IMapClearOperation,\n IMapKeyEditLocalOpMetadata,\n IMapKeyAddLocalOpMetadata,\n IMapClearLocalOpMetadata,\n} from \"./internalInterfaces\";\nimport {\n ILocalValue,\n LocalValueMaker,\n makeSerializable,\n} from \"./localValues\";\n\n/**\n * Defines the means to process and submit a given op on a map.\n */\ninterface IMapMessageHandler {\n /**\n * Apply the given operation.\n * @param op - The map operation to apply\n * @param local - Whether the message originated from the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n */\n process(\n op: IMapOperation,\n local: boolean,\n localOpMetadata: MapLocalOpMetadata,\n ): void;\n\n /**\n * Communicate the operation to remote clients.\n * @param op - The map operation to submit\n * @param localOpMetadata - The metadata to be submitted with the message.\n */\n submit(op: IMapOperation, localOpMetadata: MapLocalOpMetadata): void;\n\n applyStashedOp(op: IMapOperation): MapLocalOpMetadata;\n}\n\n/**\n * Map key operations are one of several types.\n */\nexport type IMapKeyOperation = IMapSetOperation | IMapDeleteOperation;\n\n/**\n * Description of a map delta operation\n */\nexport type IMapOperation = IMapKeyOperation | 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 */\nexport interface IMapDataObjectSerializable {\n [key: string]: ISerializableValue;\n}\n\n/**\n * Serialized key/value data.\n */\nexport interface IMapDataObjectSerialized {\n [key: string]: ISerializedValue;\n}\n\ntype MapKeyLocalOpMetadata = IMapKeyEditLocalOpMetadata | IMapKeyAddLocalOpMetadata;\ntype MapLocalOpMetadata = IMapClearLocalOpMetadata | MapKeyLocalOpMetadata;\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n\nfunction isMapKeyLocalOpMetadata(metadata: any): metadata is MapKeyLocalOpMetadata {\n return metadata !== undefined && typeof metadata.pendingMessageId === \"number\" &&\n (metadata.type === \"add\" || metadata.type === \"edit\");\n}\n\nfunction isClearLocalOpMetadata(metadata: any): metadata is IMapClearLocalOpMetadata {\n return metadata !== undefined && metadata.type === \"clear\" && typeof metadata.pendingMessageId === \"number\";\n}\n\nfunction isMapLocalOpMetadata(metadata: any): metadata is MapLocalOpMetadata {\n return metadata !== undefined && typeof metadata.pendingMessageId === \"number\" &&\n (metadata.type === \"add\" || metadata.type === \"edit\" || metadata.type === \"clear\");\n}\n\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n\nfunction createClearLocalOpMetadata(op: IMapClearOperation,\n pendingClearMessageId: number, previousMap?: Map<string, ILocalValue>): IMapClearLocalOpMetadata {\n const localMetadata: IMapClearLocalOpMetadata = {\n type: \"clear\",\n pendingMessageId: pendingClearMessageId, previousMap,\n };\n return localMetadata;\n}\n\nfunction createKeyLocalOpMetadata(op: IMapKeyOperation,\n pendingMessageId: number, previousValue?: ILocalValue): MapKeyLocalOpMetadata {\n const localMetadata: MapKeyLocalOpMetadata = previousValue ?\n { type: \"edit\", pendingMessageId, previousValue } :\n { type: \"add\", pendingMessageId };\n return localMetadata;\n}\n\n/**\n * A SharedMap is a map-like distributed data structure.\n */\nexport class MapKernel {\n /**\n * The number of key/value pairs stored in the map.\n */\n public get size(): number {\n return this.data.size;\n }\n\n /**\n * Mapping of op types to message handlers.\n */\n private readonly messageHandlers: ReadonlyMap<string, IMapMessageHandler> = new Map();\n\n /**\n * The in-memory data the map is storing.\n */\n private readonly data = new Map<string, ILocalValue>();\n\n /**\n * Keys that have been modified locally but not yet ack'd from the server.\n */\n private readonly pendingKeys: Map<string, number[]> = new Map();\n\n /**\n * This is used to assign a unique id to every outgoing operation and helps in tracking unack'd ops.\n */\n private pendingMessageId: number = -1;\n\n /**\n * The pending ids of any clears that have been performed locally but not yet ack'd from the server\n */\n private readonly pendingClearMessageIds: number[] = [];\n\n /**\n * Object to create encapsulations of the values stored in the map.\n */\n private readonly localValueMaker: LocalValueMaker;\n\n /**\n * Create a new shared map kernel.\n * @param serializer - The serializer to serialize / parse handles\n * @param handle - The handle of the shared object using the kernel\n * @param submitMessage - A callback to submit a message through the shared object\n * @param isAttached - To query whether the shared object should generate ops\n * @param valueTypes - The value types to register\n * @param eventEmitter - The object that will emit map events\n */\n public constructor(\n private readonly serializer: IFluidSerializer,\n private readonly handle: IFluidHandle,\n private readonly submitMessage: (op: unknown, localOpMetadata: unknown) => void,\n private readonly isAttached: () => boolean,\n private readonly eventEmitter: TypedEventEmitter<ISharedMapEvents>,\n ) {\n this.localValueMaker = new LocalValueMaker(serializer);\n this.messageHandlers = this.getMessageHandlers();\n }\n\n /**\n * Get an iterator over the keys in this map.\n * @returns The iterator\n */\n public keys(): IterableIterator<string> {\n return this.data.keys();\n }\n\n /**\n * Get an iterator over the entries in this map.\n * @returns The iterator\n */\n // TODO: Use `unknown` instead (breaking change).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public entries(): IterableIterator<[string, any]> {\n const localEntriesIterator = this.data.entries();\n const iterator = {\n next(): IteratorResult<[string, unknown]> {\n const nextVal = localEntriesIterator.next();\n return nextVal.done\n ? { value: undefined, done: true }\n // Unpack the stored value\n : { value: [nextVal.value[0], nextVal.value[1].value], done: false };\n },\n [Symbol.iterator](): IterableIterator<[string, unknown]> {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the values in this map.\n * @returns The iterator\n */\n // TODO: Use `unknown` instead (breaking change).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public values(): IterableIterator<any> {\n const localValuesIterator = this.data.values();\n const iterator = {\n next(): IteratorResult<unknown> {\n const nextVal = localValuesIterator.next();\n return nextVal.done\n ? { value: undefined, done: true }\n // Unpack the stored value\n : { value: nextVal.value.value as unknown, done: false };\n },\n [Symbol.iterator](): IterableIterator<unknown> {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the entries in this map.\n * @returns The iterator\n */\n // TODO: Use `unknown` instead (breaking change).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public [Symbol.iterator](): IterableIterator<[string, any]> {\n return this.entries();\n }\n\n /**\n * Executes the given callback on each entry in the map.\n * @param callbackFn - Callback function\n */\n public forEach(callbackFn: (value: unknown, key: string, map: Map<string, unknown>) => void): void {\n // eslint-disable-next-line unicorn/no-array-for-each\n this.data.forEach((localValue, key, m) => {\n callbackFn(localValue.value, key, m);\n });\n }\n\n /**\n * {@inheritDoc ISharedMap.get}\n */\n // TODO: Use `unknown` instead (breaking change).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n public get<T = any>(key: string): T | undefined {\n const localValue = this.data.get(key);\n return localValue === undefined ? undefined : localValue.value as T;\n }\n\n /**\n * Check if a key exists in the map.\n * @param key - The key to check\n * @returns True if the key exists, false otherwise\n */\n public has(key: string): boolean {\n return this.data.has(key);\n }\n\n /**\n * {@inheritDoc ISharedMap.set}\n */\n public set(key: string, value: unknown): void {\n // Undefined/null keys can't be serialized to JSON in the manner we currently snapshot.\n if (key === undefined || key === null) {\n throw new Error(\"Undefined and null keys are not supported\");\n }\n\n // Create a local value and serialize it.\n const localValue = this.localValueMaker.fromInMemory(value);\n const serializableValue = makeSerializable(\n localValue,\n this.serializer,\n this.handle);\n\n // Set the value locally.\n const previousValue = this.setCore(\n key,\n localValue,\n true,\n );\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: IMapSetOperation = {\n key,\n type: \"set\",\n value: serializableValue,\n };\n this.submitMapKeyMessage(op, previousValue);\n }\n\n /**\n * Delete a key from the map.\n * @param key - Key to delete\n * @returns True if the key existed and was deleted, false if it did not exist\n */\n public delete(key: string): boolean {\n // Delete the key locally first.\n const previousValue = this.deleteCore(key, true);\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return previousValue !== undefined;\n }\n\n const op: IMapDeleteOperation = {\n key,\n type: \"delete\",\n };\n this.submitMapKeyMessage(op, previousValue);\n\n return previousValue !== undefined;\n }\n\n /**\n * Clear all data from the map.\n */\n public clear(): void {\n const copy = this.isAttached() ? new Map<string, ILocalValue>(this.data) : undefined;\n\n // Clear the data locally first.\n this.clearCore(true);\n\n // If we are not attached, don't submit the op.\n if (!this.isAttached()) {\n return;\n }\n\n const op: IMapClearOperation = {\n type: \"clear\",\n };\n this.submitMapClearMessage(op, copy);\n }\n\n /**\n * Serializes the data stored in the shared map to a JSON string\n * @param serializer - The serializer to use to serialize handles in its values.\n * @returns A JSON string containing serialized map data\n */\n public getSerializedStorage(serializer: IFluidSerializer): IMapDataObjectSerialized {\n const serializableMapData: IMapDataObjectSerialized = {};\n for (const [key, localValue] of this.data.entries()) {\n serializableMapData[key] = localValue.makeSerialized(serializer, this.handle);\n }\n return serializableMapData;\n }\n\n public getSerializableStorage(serializer: IFluidSerializer): IMapDataObjectSerializable {\n const serializableMapData: IMapDataObjectSerializable = {};\n for (const [key, localValue] of this.data.entries()) {\n serializableMapData[key] = makeSerializable(localValue, serializer, this.handle);\n }\n return serializableMapData;\n }\n\n public serialize(serializer: IFluidSerializer): string {\n return JSON.stringify(this.getSerializableStorage(serializer));\n }\n\n /**\n * Populate the kernel with the given map data.\n * @param data - A JSON string containing serialized map data\n */\n public populateFromSerializable(json: IMapDataObjectSerializable): void {\n for (const [key, serializable] of Object.entries(json)) {\n const localValue = {\n key,\n value: this.makeLocal(key, serializable),\n };\n\n this.data.set(localValue.key, localValue.value);\n }\n }\n\n public populate(json: string): void {\n this.populateFromSerializable(JSON.parse(json) as IMapDataObjectSerializable);\n }\n\n /**\n * Submit the given op if a handler is registered.\n * @param op - The operation to attempt to submit\n * @param localOpMetadata - The local metadata associated with the op. This is kept locally by the runtime\n * and not sent to the server. This will be sent back when this message is received back from the server. This is\n * also sent if we are asked to resubmit the message.\n * @returns True if the operation was submitted, false otherwise.\n */\n public trySubmitMessage(op: IMapOperation, localOpMetadata: unknown): boolean {\n const handler = this.messageHandlers.get(op.type);\n if (handler === undefined) {\n return false;\n }\n handler.submit(op, localOpMetadata as MapLocalOpMetadata);\n return true;\n }\n\n public tryApplyStashedOp(op: IMapOperation): unknown {\n const handler = this.messageHandlers.get(op.type);\n if (handler === undefined) {\n throw new Error(\"no apply stashed op handler\");\n }\n return handler.applyStashedOp(op);\n }\n\n /**\n * Process the given op if a handler is registered.\n * @param op - The message to process\n * @param local - Whether the message originated from the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n * @returns True if the operation was processed, false otherwise.\n */\n public tryProcessMessage(\n op: IMapOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): boolean {\n const handler = this.messageHandlers.get(op.type);\n if (handler === undefined) {\n return false;\n }\n handler.process(op, local, localOpMetadata as MapLocalOpMetadata);\n return true;\n }\n\n /* eslint-disable @typescript-eslint/no-unsafe-member-access */\n\n /**\n * Rollback a local op\n * @param op - The operation to rollback\n * @param localOpMetadata - The local metadata associated with the op.\n */\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n public rollback(op: any, localOpMetadata: unknown): void {\n if (!isMapLocalOpMetadata(localOpMetadata)) {\n throw new Error(\"Invalid localOpMetadata\");\n }\n\n if (op.type === \"clear\" && localOpMetadata.type === \"clear\") {\n if (localOpMetadata.previousMap === undefined) {\n throw new Error(\"Cannot rollback without previous map\");\n }\n for (const [key, localValue] of localOpMetadata.previousMap.entries()) {\n this.setCore(key, localValue, true);\n }\n\n const lastPendingClearId = this.pendingClearMessageIds.pop();\n if (lastPendingClearId === undefined || lastPendingClearId !== localOpMetadata.pendingMessageId) {\n throw new Error(\"Rollback op does match last clear\");\n }\n } else if (op.type === \"delete\" || op.type === \"set\") {\n if (localOpMetadata.type === \"add\") {\n this.deleteCore(op.key as string, true);\n } else if (localOpMetadata.type === \"edit\" && localOpMetadata.previousValue !== undefined) {\n this.setCore(op.key as string, localOpMetadata.previousValue, true);\n } else {\n throw new Error(\"Cannot rollback without previous value\");\n }\n\n const pendingMessageIds = this.pendingKeys.get(op.key as string);\n const lastPendingMessageId = pendingMessageIds?.pop();\n if (!pendingMessageIds || lastPendingMessageId !== localOpMetadata.pendingMessageId) {\n throw new Error(\"Rollback op does not match last pending\");\n }\n if (pendingMessageIds.length === 0) {\n this.pendingKeys.delete(op.key as string);\n }\n } else {\n throw new Error(\"Unsupported op for rollback\");\n }\n }\n\n /* eslint-enable @typescript-eslint/no-unsafe-member-access */\n\n /**\n * Set implementation used for both locally sourced sets as well as incoming remote sets.\n * @param key - The key being set\n * @param value - The value being set\n * @param local - Whether the message originated from the local client\n * @returns Previous local value of the key, if any\n */\n private setCore(key: string, value: ILocalValue, local: boolean): ILocalValue | undefined {\n const previousLocalValue = this.data.get(key);\n const previousValue: unknown = previousLocalValue?.value;\n this.data.set(key, value);\n this.eventEmitter.emit(\"valueChanged\", { key, previousValue }, local, this.eventEmitter);\n return previousLocalValue;\n }\n\n /**\n * Clear implementation used for both locally sourced clears as well as incoming remote clears.\n * @param local - Whether the message originated from the local client\n */\n private clearCore(local: boolean): void {\n this.data.clear();\n this.eventEmitter.emit(\"clear\", local, this.eventEmitter);\n }\n\n /**\n * Delete implementation used for both locally sourced deletes as well as incoming remote deletes.\n * @param key - The key being deleted\n * @param local - Whether the message originated from the local client\n * @returns Previous local value of the key if it existed, undefined if it did not exist\n */\n private deleteCore(key: string, local: boolean): ILocalValue | undefined {\n const previousLocalValue = this.data.get(key);\n const previousValue: unknown = previousLocalValue?.value;\n const successfullyRemoved = this.data.delete(key);\n if (successfullyRemoved) {\n this.eventEmitter.emit(\"valueChanged\", { key, previousValue }, local, this.eventEmitter);\n }\n return previousLocalValue;\n }\n\n /**\n * Clear all keys in memory in response to a remote clear, but retain keys we have modified but not yet been ack'd.\n */\n private clearExceptPendingKeys(): void {\n // Assuming the pendingKeys is small and the map is large\n // we will get the value for the pendingKeys and clear the map\n const temp = new Map<string, ILocalValue>();\n for (const key of this.pendingKeys.keys()) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n temp.set(key, this.data.get(key)!);\n }\n this.clearCore(false);\n for (const [key, value] of temp.entries()) {\n this.setCore(key, value, true);\n }\n }\n\n /**\n * The remote ISerializableValue we're receiving (either as a result of a load or an incoming set op) will\n * have the information we need to create a real object, but will not be the real object yet. For example,\n * we might know it's a map and the map's ID but not have the actual map or its data yet. makeLocal's\n * job is to convert that information into a real object for local usage.\n * @param key - The key that the caller intends to store the local value into (used for ops later). But\n * doesn't actually store the local value into that key. So better not lie!\n * @param serializable - The remote information that we can convert into a real object\n * @returns The local value that was produced\n */\n private makeLocal(key: string, serializable: ISerializableValue): ILocalValue {\n if (serializable.type === ValueType[ValueType.Plain] || serializable.type === ValueType[ValueType.Shared]) {\n return this.localValueMaker.fromSerializable(serializable);\n } else {\n throw new Error(\"Unknown local value type\");\n }\n }\n\n /**\n * If our local operations that have not yet been ack'd will eventually overwrite an incoming operation, we should\n * not process the incoming operation.\n * @param op - Operation to check\n * @param local - Whether the message originated from the local client\n * @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.\n * For messages from a remote client, this will be undefined.\n * @returns True if the operation should be processed, false otherwise\n */\n private needProcessKeyOperation(\n op: IMapKeyOperation,\n local: boolean,\n localOpMetadata: MapLocalOpMetadata,\n ): boolean {\n if (this.pendingClearMessageIds.length > 0) {\n if (local) {\n assert(localOpMetadata !== undefined && isMapKeyLocalOpMetadata(localOpMetadata) &&\n localOpMetadata.pendingMessageId < this.pendingClearMessageIds[0],\n 0x013 /* \"Received out of order op when there is an unackd clear message\" */);\n }\n // If we have an unack'd clear, we can ignore all ops.\n return false;\n }\n\n const pendingKeyMessageId = this.pendingKeys.get(op.key);\n if (pendingKeyMessageId !== undefined) {\n // Found an unack'd op. Clear it from the map if the pendingMessageId in the map matches this message's\n // and don't process the op.\n if (local) {\n assert(localOpMetadata !== undefined && isMapKeyLocalOpMetadata(localOpMetadata),\n 0x014 /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageIds = this.pendingKeys.get(op.key);\n assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId,\n 0x2fa /* Unexpected pending message received */);\n pendingMessageIds.shift();\n if (pendingMessageIds.length === 0) {\n this.pendingKeys.delete(op.key);\n }\n }\n return false;\n }\n\n // If we don't have a NACK op on the key, we need to process the remote ops.\n return !local;\n }\n\n /**\n * Get the message handlers for the map.\n * @returns A map of string op names to IMapMessageHandlers for those ops\n */\n private getMessageHandlers(): Map<string, IMapMessageHandler> {\n const messageHandlers = new Map<string, IMapMessageHandler>();\n messageHandlers.set(\n \"clear\",\n {\n process: (op: IMapClearOperation, local, localOpMetadata) => {\n if (local) {\n assert(isClearLocalOpMetadata(localOpMetadata),\n 0x015 /* \"pendingMessageId is missing from the local client's clear operation\" */);\n const pendingClearMessageId = this.pendingClearMessageIds.shift();\n assert(pendingClearMessageId === localOpMetadata.pendingMessageId,\n 0x2fb /* pendingMessageId does not match */);\n return;\n }\n if (this.pendingKeys.size > 0) {\n this.clearExceptPendingKeys();\n return;\n }\n this.clearCore(local);\n },\n submit: (op: IMapClearOperation, localOpMetadata: IMapClearLocalOpMetadata) => {\n assert(isClearLocalOpMetadata(localOpMetadata), 0x2fc /* Invalid localOpMetadata for clear */);\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const pendingClearMessageId = this.pendingClearMessageIds.shift();\n assert(pendingClearMessageId === localOpMetadata.pendingMessageId,\n 0x2fd /* pendingMessageId does not match */);\n this.submitMapClearMessage(op, localOpMetadata.previousMap);\n },\n applyStashedOp: (op: IMapClearOperation) => {\n const copy = new Map<string, ILocalValue>(this.data);\n this.clearCore(true);\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n return createClearLocalOpMetadata(op, this.getMapClearMessageId(), copy);\n },\n });\n messageHandlers.set(\n \"delete\",\n {\n process: (op: IMapDeleteOperation, local, localOpMetadata) => {\n if (!this.needProcessKeyOperation(op, local, localOpMetadata)) {\n return;\n }\n this.deleteCore(op.key, local);\n },\n submit: (op: IMapDeleteOperation, localOpMetadata: MapKeyLocalOpMetadata) => {\n this.resubmitMapKeyMessage(op, localOpMetadata);\n },\n applyStashedOp: (op: IMapDeleteOperation) => {\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const previousValue = this.deleteCore(op.key, true);\n return createKeyLocalOpMetadata(op, this.getMapKeyMessageId(op), previousValue);\n },\n });\n messageHandlers.set(\n \"set\",\n {\n process: (op: IMapSetOperation, local, localOpMetadata) => {\n if (!this.needProcessKeyOperation(op, local, localOpMetadata)) {\n return;\n }\n\n // needProcessKeyOperation should have returned false if local is true\n const context = this.makeLocal(op.key, op.value);\n this.setCore(op.key, context, local);\n },\n submit: (op: IMapSetOperation, localOpMetadata: MapKeyLocalOpMetadata) => {\n this.resubmitMapKeyMessage(op, localOpMetadata);\n },\n applyStashedOp: (op: IMapSetOperation) => {\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const context = this.makeLocal(op.key, op.value);\n const previousValue = this.setCore(op.key, context, true);\n return createKeyLocalOpMetadata(op, this.getMapKeyMessageId(op), previousValue);\n },\n });\n\n return messageHandlers;\n }\n\n private getMapClearMessageId(): number {\n const pendingMessageId = ++this.pendingMessageId;\n this.pendingClearMessageIds.push(pendingMessageId);\n return pendingMessageId;\n }\n\n /**\n * Submit a clear message to remote clients.\n * @param op - The clear message\n */\n private submitMapClearMessage(op: IMapClearOperation, previousMap?: Map<string, ILocalValue>): void {\n const metadata = createClearLocalOpMetadata(op, this.getMapClearMessageId(), previousMap);\n this.submitMessage(op, metadata);\n }\n\n private getMapKeyMessageId(op: IMapKeyOperation): number {\n const pendingMessageId = ++this.pendingMessageId;\n const pendingMessageIds = this.pendingKeys.get(op.key);\n if (pendingMessageIds !== undefined) {\n pendingMessageIds.push(pendingMessageId);\n } else {\n this.pendingKeys.set(op.key, [pendingMessageId]);\n }\n return pendingMessageId;\n }\n\n /**\n * Submit a map key message to remote clients.\n * @param op - The map key message\n * @param previousValue - The value of the key before this op\n */\n private submitMapKeyMessage(op: IMapKeyOperation, previousValue?: ILocalValue): void {\n const localMetadata = createKeyLocalOpMetadata(op, this.getMapKeyMessageId(op), previousValue);\n this.submitMessage(op, localMetadata);\n }\n\n /**\n * Submit a map key message to remote clients based on a previous submit.\n * @param op - The map key message\n * @param localOpMetadata - Metadata from the previous submit\n */\n private resubmitMapKeyMessage(op: IMapKeyOperation, localOpMetadata: MapLocalOpMetadata): void {\n assert(isMapKeyLocalOpMetadata(localOpMetadata), 0x2fe /* Invalid localOpMetadata in submit */);\n\n // clear the old pending message id\n const pendingMessageIds = this.pendingKeys.get(op.key);\n assert(pendingMessageIds !== undefined && pendingMessageIds[0] === localOpMetadata.pendingMessageId,\n 0x2ff /* Unexpected pending message received */);\n pendingMessageIds.shift();\n if (pendingMessageIds.length === 0) {\n this.pendingKeys.delete(op.key);\n }\n\n // We don't reuse the metadata pendingMessageId but send a new one on each submit.\n const pendingMessageId = this.getMapKeyMessageId(op);\n const localMetadata = localOpMetadata.type === \"edit\" ?\n { type: \"edit\", pendingMessageId, previousValue: localOpMetadata.previousValue } :\n { type: \"add\", pendingMessageId };\n this.submitMessage(op, localMetadata);\n }\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.0.0-internal.2.2.0";
8
+ export declare const pkgVersion = "2.0.0-internal.2.3.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -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.0.0-internal.2.2.0";
8
+ export const pkgVersion = "2.0.0-internal.2.3.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,sBAAsB,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.0.0-internal.2.2.0\";\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,sBAAsB,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.0.0-internal.2.3.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/map",
3
- "version": "2.0.0-internal.2.2.0",
3
+ "version": "2.0.0-internal.2.3.0",
4
4
  "description": "Distributed map",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -67,30 +67,31 @@
67
67
  "dependencies": {
68
68
  "@fluidframework/common-definitions": "^0.20.1",
69
69
  "@fluidframework/common-utils": "^1.0.0",
70
- "@fluidframework/container-utils": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
71
- "@fluidframework/core-interfaces": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
72
- "@fluidframework/datastore-definitions": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
73
- "@fluidframework/driver-utils": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
70
+ "@fluidframework/container-utils": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
71
+ "@fluidframework/core-interfaces": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
72
+ "@fluidframework/datastore-definitions": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
73
+ "@fluidframework/driver-utils": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
74
74
  "@fluidframework/protocol-definitions": "^1.1.0",
75
- "@fluidframework/runtime-definitions": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
76
- "@fluidframework/runtime-utils": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
77
- "@fluidframework/shared-object-base": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
75
+ "@fluidframework/runtime-definitions": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
76
+ "@fluidframework/runtime-utils": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
77
+ "@fluidframework/shared-object-base": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
78
78
  "path-browserify": "^1.0.1"
79
79
  },
80
80
  "devDependencies": {
81
- "@fluid-internal/test-dds-utils": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
81
+ "@fluid-internal/test-dds-utils": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
82
82
  "@fluid-tools/benchmark": "^0.45.0",
83
83
  "@fluid-tools/build-cli": "^0.7.0",
84
84
  "@fluidframework/build-common": "^1.1.0",
85
85
  "@fluidframework/build-tools": "^0.7.0",
86
- "@fluidframework/eslint-config-fluid": "^1.2.0",
87
- "@fluidframework/map-previous": "npm:@fluidframework/map@2.0.0-internal.2.1.0",
88
- "@fluidframework/mocha-test-setup": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
89
- "@fluidframework/test-runtime-utils": ">=2.0.0-internal.2.2.0 <2.0.0-internal.3.0.0",
86
+ "@fluidframework/eslint-config-fluid": "^2.0.0",
87
+ "@fluidframework/map-previous": "npm:@fluidframework/map@2.0.0-internal.2.2.0",
88
+ "@fluidframework/mocha-test-setup": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
89
+ "@fluidframework/test-runtime-utils": ">=2.0.0-internal.2.3.0 <2.0.0-internal.3.0.0",
90
90
  "@microsoft/api-extractor": "^7.22.2",
91
91
  "@rushstack/eslint-config": "^2.5.1",
92
92
  "@types/mocha": "^9.1.1",
93
93
  "@types/node": "^14.18.0",
94
+ "@types/path-browserify": "^1.0.0",
94
95
  "concurrently": "^6.2.0",
95
96
  "copyfiles": "^2.4.1",
96
97
  "cross-env": "^7.0.2",
@@ -102,9 +103,9 @@
102
103
  "typescript": "~4.5.5"
103
104
  },
104
105
  "typeValidation": {
105
- "version": "2.0.0-internal.2.2.0",
106
- "baselineRange": ">=2.0.0-internal.2.1.0 <2.0.0-internal.2.2.0",
107
- "baselineVersion": "2.0.0-internal.2.1.0",
106
+ "version": "2.0.0-internal.2.3.0",
107
+ "baselineRange": ">=2.0.0-internal.2.2.0 <2.0.0-internal.2.3.0",
108
+ "baselineVersion": "2.0.0-internal.2.2.0",
108
109
  "broken": {}
109
110
  }
110
111
  }