@fluidframework/map 0.59.4002 → 1.0.2

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/.eslintrc.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  module.exports = {
7
7
  "extends": [
8
- "@fluidframework/eslint-config-fluid"
8
+ require.resolve("@fluidframework/eslint-config-fluid")
9
9
  ],
10
10
  "parserOptions": {
11
11
  "project": ["./tsconfig.json", "./src/test/tsconfig.json"]
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
6
6
  import { IChannelAttributes, IFluidDataStoreRuntime, IChannelStorageService, IChannelServices, IChannelFactory } from "@fluidframework/datastore-definitions";
7
- import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
7
+ import { ISummaryTreeWithStats, ITelemetryContext } from "@fluidframework/runtime-definitions";
8
8
  import { IFluidSerializer, SharedObject } from "@fluidframework/shared-object-base";
9
9
  import { IDirectory, ISerializableValue, ISharedDirectory, ISharedDirectoryEvents } from "./interfaces";
10
10
  import { LocalValueMaker } from "./localValues";
@@ -300,7 +300,7 @@ export declare class SharedDirectory extends SharedObject<ISharedDirectoryEvents
300
300
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}
301
301
  * @internal
302
302
  */
303
- protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats;
303
+ protected summarizeCore(serializer: IFluidSerializer, telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
304
304
  /**
305
305
  * Submits an operation
306
306
  * @param op - Op to submit
@@ -359,6 +359,7 @@ export declare class SharedDirectory extends SharedObject<ISharedDirectoryEvents
359
359
  * @internal
360
360
  */
361
361
  protected applyStashedOp(): void;
362
+ private serializeDirectory;
362
363
  }
363
364
  export {};
364
365
  //# sourceMappingURL=directory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../src/directory.ts"],"names":[],"mappings":"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"}
package/dist/directory.js CHANGED
@@ -38,61 +38,6 @@ const packageVersion_1 = require("./packageVersion");
38
38
  // We standardize on using posix slashes everywhere.
39
39
  const posix = path.posix;
40
40
  const snapshotFileName = "header";
41
- function serializeDirectory(root, serializer) {
42
- const MinValueSizeSeparateSnapshotBlob = 8 * 1024;
43
- const builder = new runtime_utils_1.SummaryTreeBuilder();
44
- let counter = 0;
45
- const blobs = [];
46
- const stack = [];
47
- const content = {};
48
- stack.push([root, content]);
49
- while (stack.length > 0) {
50
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
51
- const [currentSubDir, currentSubDirObject] = stack.pop();
52
- for (const [key, value] of currentSubDir.getSerializedStorage(serializer)) {
53
- if (!currentSubDirObject.storage) {
54
- currentSubDirObject.storage = {};
55
- }
56
- const result = {
57
- type: value.type,
58
- value: value.value && JSON.parse(value.value),
59
- };
60
- if (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {
61
- const extraContent = {};
62
- let largeContent = extraContent;
63
- if (currentSubDir.absolutePath !== posix.sep) {
64
- for (const dir of currentSubDir.absolutePath.substr(1).split(posix.sep)) {
65
- const subDataObject = {};
66
- largeContent.subdirectories = { [dir]: subDataObject };
67
- largeContent = subDataObject;
68
- }
69
- }
70
- largeContent.storage = { [key]: result };
71
- const blobName = `blob${counter}`;
72
- counter++;
73
- blobs.push(blobName);
74
- builder.addBlob(blobName, JSON.stringify(extraContent));
75
- }
76
- else {
77
- currentSubDirObject.storage[key] = result;
78
- }
79
- }
80
- for (const [subdirName, subdir] of currentSubDir.subdirectories()) {
81
- if (!currentSubDirObject.subdirectories) {
82
- currentSubDirObject.subdirectories = {};
83
- }
84
- const subDataObject = {};
85
- currentSubDirObject.subdirectories[subdirName] = subDataObject;
86
- stack.push([subdir, subDataObject]);
87
- }
88
- }
89
- const newFormat = {
90
- blobs,
91
- content,
92
- };
93
- builder.addBlob(snapshotFileName, JSON.stringify(newFormat));
94
- return builder.getSummaryTree();
95
- }
96
41
  /**
97
42
  * The factory that defines the directory.
98
43
  * @sealed
@@ -163,7 +108,7 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
163
108
  * @param type - Type identifier
164
109
  */
165
110
  constructor(id, runtime, attributes) {
166
- super(id, runtime, attributes);
111
+ super(id, runtime, attributes, "fluid_directory_");
167
112
  /**
168
113
  * String representation for the class.
169
114
  */
@@ -353,8 +298,8 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
353
298
  * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}
354
299
  * @internal
355
300
  */
356
- summarizeCore(serializer) {
357
- return serializeDirectory(this.root, serializer);
301
+ summarizeCore(serializer, telemetryContext) {
302
+ return this.serializeDirectory(this.root, serializer);
358
303
  }
359
304
  /**
360
305
  * Submits an operation
@@ -550,6 +495,62 @@ class SharedDirectory extends shared_object_base_1.SharedObject {
550
495
  applyStashedOp() {
551
496
  throw new Error("not implemented");
552
497
  }
498
+ serializeDirectory(root, serializer, telemetryContext) {
499
+ const MinValueSizeSeparateSnapshotBlob = 8 * 1024;
500
+ const builder = new runtime_utils_1.SummaryTreeBuilder();
501
+ let counter = 0;
502
+ const blobs = [];
503
+ const stack = [];
504
+ const content = {};
505
+ stack.push([root, content]);
506
+ while (stack.length > 0) {
507
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
508
+ const [currentSubDir, currentSubDirObject] = stack.pop();
509
+ for (const [key, value] of currentSubDir.getSerializedStorage(serializer)) {
510
+ if (!currentSubDirObject.storage) {
511
+ currentSubDirObject.storage = {};
512
+ }
513
+ const result = {
514
+ type: value.type,
515
+ // eslint-disable-next-line @typescript-eslint/ban-types
516
+ value: value.value && JSON.parse(value.value),
517
+ };
518
+ if (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {
519
+ const extraContent = {};
520
+ let largeContent = extraContent;
521
+ if (currentSubDir.absolutePath !== posix.sep) {
522
+ for (const dir of currentSubDir.absolutePath.substr(1).split(posix.sep)) {
523
+ const subDataObject = {};
524
+ largeContent.subdirectories = { [dir]: subDataObject };
525
+ largeContent = subDataObject;
526
+ }
527
+ }
528
+ largeContent.storage = { [key]: result };
529
+ const blobName = `blob${counter}`;
530
+ counter++;
531
+ blobs.push(blobName);
532
+ builder.addBlob(blobName, JSON.stringify(extraContent));
533
+ }
534
+ else {
535
+ currentSubDirObject.storage[key] = result;
536
+ }
537
+ }
538
+ for (const [subdirName, subdir] of currentSubDir.subdirectories()) {
539
+ if (!currentSubDirObject.subdirectories) {
540
+ currentSubDirObject.subdirectories = {};
541
+ }
542
+ const subDataObject = {};
543
+ currentSubDirObject.subdirectories[subdirName] = subDataObject;
544
+ stack.push([subdir, subDataObject]);
545
+ }
546
+ }
547
+ const newFormat = {
548
+ blobs,
549
+ content,
550
+ };
551
+ builder.addBlob(snapshotFileName, JSON.stringify(newFormat));
552
+ return builder.getSummaryTree();
553
+ }
553
554
  }
554
555
  exports.SharedDirectory = SharedDirectory;
555
556
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"directory.js","sourceRoot":"","sources":["../src/directory.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 { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport {\n ISequencedDocumentMessage,\n MessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n IChannelServices,\n IChannelFactory,\n} from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { IFluidSerializer, SharedObject, ValueType } from \"@fluidframework/shared-object-base\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport * as path from \"path-browserify\";\nimport {\n IDirectory,\n IDirectoryEvents,\n IDirectoryValueChanged,\n ISerializableValue,\n ISerializedValue,\n ISharedDirectory,\n ISharedDirectoryEvents,\n IValueChanged,\n} from \"./interfaces\";\nimport {\n ILocalValue,\n LocalValueMaker,\n makeSerializable,\n} from \"./localValues\";\nimport { pkgVersion } from \"./packageVersion\";\n\n// We use path-browserify since this code can run safely on the server or the browser.\n// We standardize on using posix slashes everywhere.\nconst posix: typeof import(\"path\").posix = path.posix;\n\nconst snapshotFileName = \"header\";\n\n/**\n * Defines the means to process and submit a given op on a directory.\n */\ninterface IDirectoryMessageHandler {\n /**\n * Apply the given operation.\n * @param op - The directory 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: IDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void;\n\n /**\n * Communicate the operation to remote clients.\n * @param op - The directory operation to submit\n * @param localOpMetadata - The metadata to be submitted with the message.\n */\n submit(op: IDirectoryOperation, localOpMetadata: unknown): void;\n}\n\n/**\n * Operation indicating a value should be set for a key.\n */\ninterface IDirectorySetOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"set\";\n\n /**\n * Directory key being modified.\n */\n key: string;\n\n /**\n * Absolute path of the directory where the modified key is located.\n */\n path: string;\n\n /**\n * Value to be set on the key.\n */\n value: ISerializableValue;\n}\n\n/**\n * Operation indicating a key should be deleted from the directory.\n */\ninterface IDirectoryDeleteOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"delete\";\n\n /**\n * Directory key being modified.\n */\n key: string;\n\n /**\n * Absolute path of the directory where the modified key is located.\n */\n path: string;\n}\n\n/**\n * An operation on a specific key within a directory\n */\ntype IDirectoryKeyOperation = IDirectorySetOperation | IDirectoryDeleteOperation;\n\n/**\n * Operation indicating the directory should be cleared.\n */\ninterface IDirectoryClearOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"clear\";\n\n /**\n * Absolute path of the directory being cleared.\n */\n path: string;\n}\n\n/**\n * An operation on one or more of the keys within a directory\n */\ntype IDirectoryStorageOperation = IDirectoryKeyOperation | IDirectoryClearOperation;\n\n/**\n * Operation indicating a subdirectory should be created.\n */\ninterface IDirectoryCreateSubDirectoryOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"createSubDirectory\";\n\n /**\n * Absolute path of the directory that will contain the new subdirectory.\n */\n path: string;\n\n /**\n * Name of the new subdirectory.\n */\n subdirName: string;\n}\n\n/**\n * Operation indicating a subdirectory should be deleted.\n */\ninterface IDirectoryDeleteSubDirectoryOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"deleteSubDirectory\";\n\n /**\n * Absolute path of the directory that contains the directory to be deleted.\n */\n path: string;\n\n /**\n * Name of the subdirectory to be deleted.\n */\n subdirName: string;\n}\n\n/**\n * An operation on the subdirectories within a directory\n */\ntype IDirectorySubDirectoryOperation = IDirectoryCreateSubDirectoryOperation | IDirectoryDeleteSubDirectoryOperation;\n\n/**\n * Any operation on a directory\n */\nexport type IDirectoryOperation = IDirectoryStorageOperation | IDirectorySubDirectoryOperation;\n\n/**\n * Defines the in-memory object structure to be used for the conversion to/from serialized.\n * @privateRemarks\n * Directly used in JSON.stringify, direct result from JSON.parse.\n */\nexport interface IDirectoryDataObject {\n storage?: { [key: string]: ISerializableValue; };\n subdirectories?: { [subdirName: string]: IDirectoryDataObject; };\n}\n\nexport interface IDirectoryNewStorageFormat {\n blobs: string[];\n content: IDirectoryDataObject;\n}\n\nfunction serializeDirectory(root: SubDirectory, serializer: IFluidSerializer): ISummaryTreeWithStats {\n const MinValueSizeSeparateSnapshotBlob = 8 * 1024;\n\n const builder = new SummaryTreeBuilder();\n let counter = 0;\n const blobs: string[] = [];\n\n const stack: [SubDirectory, IDirectoryDataObject][] = [];\n const content: IDirectoryDataObject = {};\n stack.push([root, content]);\n\n while (stack.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const [currentSubDir, currentSubDirObject] = stack.pop()!;\n for (const [key, value] of currentSubDir.getSerializedStorage(serializer)) {\n if (!currentSubDirObject.storage) {\n currentSubDirObject.storage = {};\n }\n const result: ISerializableValue = {\n type: value.type,\n value: value.value && JSON.parse(value.value) as object,\n };\n if (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {\n const extraContent: IDirectoryDataObject = {};\n let largeContent = extraContent;\n if (currentSubDir.absolutePath !== posix.sep) {\n for (const dir of currentSubDir.absolutePath.substr(1).split(posix.sep)) {\n const subDataObject: IDirectoryDataObject = {};\n largeContent.subdirectories = { [dir]: subDataObject };\n largeContent = subDataObject;\n }\n }\n largeContent.storage = { [key]: result };\n const blobName = `blob${counter}`;\n counter++;\n blobs.push(blobName);\n builder.addBlob(blobName, JSON.stringify(extraContent));\n } else {\n currentSubDirObject.storage[key] = result;\n }\n }\n\n for (const [subdirName, subdir] of currentSubDir.subdirectories()) {\n if (!currentSubDirObject.subdirectories) {\n currentSubDirObject.subdirectories = {};\n }\n const subDataObject: IDirectoryDataObject = {};\n currentSubDirObject.subdirectories[subdirName] = subDataObject;\n stack.push([subdir as SubDirectory, subDataObject]);\n }\n }\n\n const newFormat: IDirectoryNewStorageFormat = {\n blobs,\n content,\n };\n builder.addBlob(snapshotFileName, JSON.stringify(newFormat));\n\n return builder.getSummaryTree();\n}\n\n/**\n * The factory that defines the directory.\n * @sealed\n */\nexport class DirectoryFactory {\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n */\n public static readonly Type = \"https://graph.microsoft.com/types/directory\";\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n */\n public static readonly Attributes: IChannelAttributes = {\n type: DirectoryFactory.Type,\n snapshotFormatVersion: \"0.1\",\n packageVersion: pkgVersion,\n };\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n */\n public get type() {\n return DirectoryFactory.Type;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n */\n public get attributes() {\n return DirectoryFactory.Attributes;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n */\n public async load(\n runtime: IFluidDataStoreRuntime,\n id: string,\n services: IChannelServices,\n attributes: IChannelAttributes): Promise<ISharedDirectory> {\n const directory = new SharedDirectory(id, runtime, attributes);\n await directory.load(services);\n\n return directory;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}\n */\n public create(runtime: IFluidDataStoreRuntime, id: string): ISharedDirectory {\n const directory = new SharedDirectory(id, runtime, DirectoryFactory.Attributes);\n directory.initializeLocal();\n\n return directory;\n }\n}\n\n/**\n * SharedDirectory provides a hierarchical organization of map-like data structures as SubDirectories.\n * The values stored within can be accessed like a map, and the hierarchy can be navigated using path syntax.\n * SubDirectories can be retrieved for use as working directories.\n *\n * @example\n * ```ts\n * mySharedDirectory.createSubDirectory(\"a\").createSubDirectory(\"b\").createSubDirectory(\"c\").set(\"foo\", val1);\n * const mySubDir = mySharedDirectory.getWorkingDirectory(\"/a/b/c\");\n * mySubDir.get(\"foo\"); // returns val1\n * ```\n *\n * @sealed\n */\nexport class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implements ISharedDirectory {\n /**\n * Create a new shared directory\n *\n * @param runtime - Data store runtime the new shared directory belongs to\n * @param id - Optional name of the shared directory\n * @returns Newly create shared directory (but not attached yet)\n */\n public static create(runtime: IFluidDataStoreRuntime, id?: string): SharedDirectory {\n return runtime.createChannel(id, DirectoryFactory.Type) as SharedDirectory;\n }\n\n /**\n * Get a factory for SharedDirectory to register with the data store.\n *\n * @returns A factory that creates and load SharedDirectory\n */\n public static getFactory(): IChannelFactory {\n return new DirectoryFactory();\n }\n\n /**\n * String representation for the class.\n */\n public [Symbol.toStringTag]: string = \"SharedDirectory\";\n\n /**\n * {@inheritDoc IDirectory.absolutePath}\n */\n public get absolutePath(): string {\n return this.root.absolutePath;\n }\n\n /**\n * @internal\n */\n public readonly localValueMaker: LocalValueMaker;\n\n /**\n * Root of the SharedDirectory, most operations on the SharedDirectory itself act on the root.\n */\n private readonly root: SubDirectory = new SubDirectory(this, this.runtime, this.serializer, posix.sep);\n\n /**\n * Mapping of op types to message handlers.\n */\n private readonly messageHandlers: Map<string, IDirectoryMessageHandler> = new Map();\n\n /**\n * Constructs a new shared directory. If the object is non-local an id and service interfaces will\n * be provided.\n * @param id - String identifier for the SharedDirectory\n * @param runtime - Data store runtime\n * @param type - Type identifier\n */\n constructor(\n id: string,\n runtime: IFluidDataStoreRuntime,\n attributes: IChannelAttributes,\n ) {\n super(id, runtime, attributes);\n this.localValueMaker = new LocalValueMaker(this.serializer);\n this.setMessageHandlers();\n // Mirror the containedValueChanged op on the SharedDirectory\n this.root.on(\n \"containedValueChanged\",\n (changed: IValueChanged, local: boolean) => {\n this.emit(\"containedValueChanged\", changed, local, this);\n },\n );\n this.root.on(\n \"subDirectoryCreated\",\n (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryCreated\", relativePath, local, this);\n },\n );\n this.root.on(\n \"subDirectoryDeleted\",\n (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryDeleted\", relativePath, local, this);\n },\n );\n }\n\n /**\n * {@inheritDoc IDirectory.get}\n */\n public get<T = any>(key: string): T | undefined {\n return this.root.get<T>(key);\n }\n\n /**\n * {@inheritDoc IDirectory.set}\n */\n public set<T = any>(key: string, value: T): this {\n this.root.set(key, value);\n return this;\n }\n\n public dispose(error?: Error): void {\n this.root.dispose(error);\n }\n\n public get disposed(): boolean {\n return this.root.disposed;\n }\n\n /**\n * Deletes the given key from within this IDirectory.\n * @param key - The 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 return this.root.delete(key);\n }\n\n /**\n * Deletes all keys from within this IDirectory.\n */\n public clear(): void {\n this.root.clear();\n }\n\n /**\n * Checks whether the given key exists in this IDirectory.\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.root.has(key);\n }\n\n /**\n * The number of entries under this IDirectory.\n */\n public get size(): number {\n return this.root.size;\n }\n\n /**\n * Issue a callback on each entry under this IDirectory.\n * @param callback - Callback to issue\n */\n public forEach(callback: (value: any, key: string, map: Map<string, any>) => void): void {\n this.root.forEach(callback);\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public [Symbol.iterator](): IterableIterator<[string, any]> {\n return this.root[Symbol.iterator]();\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public entries(): IterableIterator<[string, any]> {\n return this.root.entries();\n }\n\n /**\n * {@inheritDoc IDirectory.countSubDirectory}\n */\n public countSubDirectory(): number {\n return this.root.countSubDirectory();\n }\n\n /**\n * Get an iterator over the keys under this IDirectory.\n * @returns The iterator\n */\n public keys(): IterableIterator<string> {\n return this.root.keys();\n }\n\n /**\n * Get an iterator over the values under this IDirectory.\n * @returns The iterator\n */\n public values(): IterableIterator<any> {\n return this.root.values();\n }\n\n /**\n * {@inheritDoc IDirectory.createSubDirectory}\n */\n public createSubDirectory(subdirName: string): IDirectory {\n return this.root.createSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.getSubDirectory}\n */\n public getSubDirectory(subdirName: string): IDirectory | undefined {\n return this.root.getSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.hasSubDirectory}\n */\n public hasSubDirectory(subdirName: string): boolean {\n return this.root.hasSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.deleteSubDirectory}\n */\n public deleteSubDirectory(subdirName: string): boolean {\n return this.root.deleteSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.subdirectories}\n */\n public subdirectories(): IterableIterator<[string, IDirectory]> {\n return this.root.subdirectories();\n }\n\n /**\n * {@inheritDoc IDirectory.getWorkingDirectory}\n */\n public getWorkingDirectory(relativePath: string): IDirectory | undefined {\n const absolutePath = this.makeAbsolute(relativePath);\n if (absolutePath === posix.sep) {\n return this.root;\n }\n\n let currentSubDir = this.root;\n const subdirs = absolutePath.substr(1).split(posix.sep);\n for (const subdir of subdirs) {\n currentSubDir = currentSubDir.getSubDirectory(subdir) as SubDirectory;\n if (!currentSubDir) {\n return undefined;\n }\n }\n return currentSubDir;\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n * @internal\n */\n protected summarizeCore(serializer: IFluidSerializer): ISummaryTreeWithStats {\n return serializeDirectory(this.root, serializer);\n }\n\n /**\n * Submits an operation\n * @param op - Op to submit\n * @param localOpMetadata - The local metadata associated with the op. We send a unique id that is used to track\n * this op while it has not been ack'd. This will be sent when we receive this op back from the server.\n * @internal\n */\n public submitDirectoryMessage(op: IDirectoryOperation, localOpMetadata: unknown) {\n this.submitLocalMessage(op, localOpMetadata);\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n * @internal\n */\n protected onDisconnect() {}\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}\n * @internal\n */\n protected reSubmitCore(content: any, localOpMetadata: unknown) {\n const message = content as IDirectoryOperation;\n const handler = this.messageHandlers.get(message.type);\n assert(handler !== undefined, 0x00d /* Missing message handler for message type */);\n handler.submit(message, localOpMetadata);\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n * @internal\n */\n protected async loadCore(storage: IChannelStorageService) {\n const data = await readAndParse(storage, snapshotFileName);\n const newFormat = data as IDirectoryNewStorageFormat;\n if (Array.isArray(newFormat.blobs)) {\n // New storage format\n this.populate(newFormat.content);\n await Promise.all(newFormat.blobs.map(async (value) => {\n const dataExtra = await readAndParse(storage, value);\n this.populate(dataExtra as IDirectoryDataObject);\n }));\n } else {\n // Old storage format\n this.populate(data as IDirectoryDataObject);\n }\n }\n\n /**\n * Populate the directory with the given directory data.\n * @param data - A JSON string containing serialized directory data\n * @internal\n */\n protected populate(data: IDirectoryDataObject) {\n const stack: [SubDirectory, IDirectoryDataObject][] = [];\n stack.push([this.root, data]);\n while (stack.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const [currentSubDir, currentSubDirObject] = stack.pop()!;\n if (currentSubDirObject.subdirectories) {\n for (const [subdirName, subdirObject] of Object.entries(currentSubDirObject.subdirectories)) {\n let newSubDir = currentSubDir.getSubDirectory(subdirName) as SubDirectory;\n if (!newSubDir) {\n newSubDir = new SubDirectory(\n this,\n this.runtime,\n this.serializer,\n posix.join(currentSubDir.absolutePath, subdirName),\n );\n currentSubDir.populateSubDirectory(subdirName, newSubDir);\n }\n stack.push([newSubDir, subdirObject]);\n }\n }\n\n if (currentSubDirObject.storage) {\n for (const [key, serializable] of Object.entries(currentSubDirObject.storage)) {\n const localValue = this.makeLocal(\n key,\n currentSubDir.absolutePath,\n serializable,\n );\n currentSubDir.populateStorage(key, localValue);\n }\n }\n }\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n * @internal\n */\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n if (message.type === MessageType.Operation) {\n const op: IDirectoryOperation = message.contents as IDirectoryOperation;\n const handler = this.messageHandlers.get(op.type);\n assert(handler !== undefined, 0x00e /* Missing message handler for message type */);\n handler.process(op, local, localOpMetadata);\n }\n }\n\n /**\n * Converts the given relative path to absolute against the root.\n * @param relativePath - The path to convert\n */\n private makeAbsolute(relativePath: string): string {\n return posix.resolve(posix.sep, relativePath);\n }\n\n /**\n * The remote ISerializableValue we're receiving (either as a result of a snapshot load or an incoming set op)\n * will 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 ID but not have the actual map or its data yet. makeLocal's job\n * is to convert that information into a real object for local usage.\n * @param key - Key of element being converted\n * @param absolutePath - Path of element being converted\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(\n key: string,\n absolutePath: string,\n serializable: ISerializableValue,\n ): ILocalValue {\n assert(\n serializable.type === ValueType[ValueType.Plain] || serializable.type === ValueType[ValueType.Shared],\n 0x1e4 /* \"Unexpected serializable type\" */,\n );\n return this.localValueMaker.fromSerializable(serializable);\n }\n\n /**\n * Set the message handlers for the directory.\n */\n private setMessageHandlers(): void {\n this.messageHandlers.set(\n \"clear\",\n {\n process: (op: IDirectoryClearOperation, local, localOpMetadata) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n subdir.processClearMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryClearOperation, localOpMetadata: unknown) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n // We don't reuse the metadata but send a new one on each submit.\n subdir.submitClearMessage(op);\n }\n },\n },\n );\n this.messageHandlers.set(\n \"delete\",\n {\n process: (op: IDirectoryDeleteOperation, local, localOpMetadata) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n subdir.processDeleteMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryDeleteOperation, localOpMetadata: unknown) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n // We don't reuse the metadata but send a new one on each submit.\n subdir.submitKeyMessage(op);\n }\n },\n },\n );\n this.messageHandlers.set(\n \"set\",\n {\n process: (op: IDirectorySetOperation, local, localOpMetadata) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n const context = local ? undefined : this.makeLocal(op.key, op.path, op.value);\n subdir.processSetMessage(op, context, local, localOpMetadata);\n }\n },\n submit: (op: IDirectorySetOperation, localOpMetadata: unknown) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n // We don't reuse the metadata but send a new one on each submit.\n subdir.submitKeyMessage(op);\n }\n },\n },\n );\n\n this.messageHandlers.set(\n \"createSubDirectory\",\n {\n process: (op: IDirectoryCreateSubDirectoryOperation, local, localOpMetadata) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n parentSubdir.processCreateSubDirectoryMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryCreateSubDirectoryOperation, localOpMetadata: unknown) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n // We don't reuse the metadata but send a new one on each submit.\n parentSubdir.submitSubDirectoryMessage(op);\n }\n },\n },\n );\n\n this.messageHandlers.set(\n \"deleteSubDirectory\",\n {\n process: (op: IDirectoryDeleteSubDirectoryOperation, local, localOpMetadata) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n parentSubdir.processDeleteSubDirectoryMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryDeleteSubDirectoryOperation, localOpMetadata: unknown) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n // We don't reuse the metadata but send a new one on each submit.\n parentSubdir.submitSubDirectoryMessage(op);\n }\n },\n },\n );\n }\n\n /**\n * @internal\n */\n protected applyStashedOp() {\n throw new Error(\"not implemented\");\n }\n}\n\n/**\n * Node of the directory tree.\n * @sealed\n */\nclass SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirectory {\n /**\n * Tells if the sub directory is disposed or not.\n */\n private _disposed = false;\n\n /**\n * String representation for the class.\n */\n public [Symbol.toStringTag]: string = \"SubDirectory\";\n\n /**\n * The in-memory data the directory is storing.\n */\n private readonly _storage: Map<string, ILocalValue> = new Map();\n\n /**\n * The subdirectories the directory is holding.\n */\n private readonly _subdirectories: Map<string, SubDirectory> = new Map();\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 * Subdirectories that have been modified locally but not yet ack'd from the server.\n */\n private readonly pendingSubDirectories: 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 * If a clear has been performed locally but not yet ack'd from the server, then this stores the pending id\n * of that clear operation. Otherwise, is -1.\n */\n private pendingClearMessageId: number = -1;\n\n /**\n * Constructor.\n * @param directory - Reference back to the SharedDirectory to perform operations\n * @param runtime - The data store runtime this directory is associated with\n * @param serializer - The serializer to serialize / parse handles\n * @param absolutePath - The absolute path of this IDirectory\n */\n constructor(\n private readonly directory: SharedDirectory,\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly serializer: IFluidSerializer,\n public readonly absolutePath: string,\n ) {\n super();\n }\n\n public dispose(error?: Error): void {\n this._disposed = true;\n this.emit(\"disposed\", this);\n }\n\n public get disposed(): boolean {\n return this._disposed;\n }\n\n private throwIfDisposed() {\n if (this._disposed) {\n throw new UsageError(\"Cannot access Disposed subDirectory\");\n }\n }\n\n /**\n * Checks whether the given key exists in this IDirectory.\n * @param key - The key to check\n * @returns True if the key exists, false otherwise\n */\n public has(key: string): boolean {\n this.throwIfDisposed();\n return this._storage.has(key);\n }\n\n /**\n * {@inheritDoc IDirectory.get}\n */\n public get<T = any>(key: string): T | undefined {\n this.throwIfDisposed();\n return this._storage.get(key)?.value as T | undefined;\n }\n\n /**\n * {@inheritDoc IDirectory.set}\n */\n public set<T = any>(key: string, value: T): this {\n this.throwIfDisposed();\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.directory.localValueMaker.fromInMemory(value);\n const serializableValue = makeSerializable(\n localValue,\n this.serializer,\n this.directory.handle);\n\n // Set the value locally.\n this.setCore(\n key,\n localValue,\n true,\n );\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return this;\n }\n\n const op: IDirectorySetOperation = {\n key,\n path: this.absolutePath,\n type: \"set\",\n value: serializableValue,\n };\n this.submitKeyMessage(op);\n return this;\n }\n\n /**\n * {@inheritDoc IDirectory.countSubDirectory}\n */\n public countSubDirectory(): number {\n return this._subdirectories.size;\n }\n\n /**\n * {@inheritDoc IDirectory.createSubDirectory}\n */\n public createSubDirectory(subdirName: string): IDirectory {\n this.throwIfDisposed();\n // Undefined/null subdirectory names can't be serialized to JSON in the manner we currently snapshot.\n if (subdirName === undefined || subdirName === null) {\n throw new Error(\"SubDirectory name may not be undefined or null\");\n }\n\n if (subdirName.includes(posix.sep)) {\n throw new Error(`SubDirectory name may not contain ${posix.sep}`);\n }\n\n // Create the sub directory locally first.\n this.createSubDirectoryCore(subdirName, true);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const subDir: IDirectory = this._subdirectories.get(subdirName)!;\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return subDir;\n }\n\n const op: IDirectoryCreateSubDirectoryOperation = {\n path: this.absolutePath,\n subdirName,\n type: \"createSubDirectory\",\n };\n this.submitSubDirectoryMessage(op);\n\n return subDir;\n }\n\n /**\n * {@inheritDoc IDirectory.getSubDirectory}\n */\n public getSubDirectory(subdirName: string): IDirectory | undefined {\n this.throwIfDisposed();\n return this._subdirectories.get(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.hasSubDirectory}\n */\n public hasSubDirectory(subdirName: string): boolean {\n this.throwIfDisposed();\n return this._subdirectories.has(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.deleteSubDirectory}\n */\n public deleteSubDirectory(subdirName: string): boolean {\n this.throwIfDisposed();\n // Delete the sub directory locally first.\n const successfullyRemoved = this.deleteSubDirectoryCore(subdirName, true);\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return successfullyRemoved;\n }\n\n const op: IDirectoryDeleteSubDirectoryOperation = {\n path: this.absolutePath,\n subdirName,\n type: \"deleteSubDirectory\",\n };\n\n this.submitSubDirectoryMessage(op);\n return successfullyRemoved;\n }\n\n /**\n * {@inheritDoc IDirectory.subdirectories}\n */\n public subdirectories(): IterableIterator<[string, IDirectory]> {\n this.throwIfDisposed();\n return this._subdirectories.entries();\n }\n\n /**\n * {@inheritDoc IDirectory.getWorkingDirectory}\n */\n public getWorkingDirectory(relativePath: string): IDirectory | undefined {\n this.throwIfDisposed();\n return this.directory.getWorkingDirectory(this.makeAbsolute(relativePath));\n }\n\n /**\n * Deletes the given key from within this IDirectory.\n * @param key - The 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 this.throwIfDisposed();\n // Delete the key locally first.\n const successfullyRemoved = this.deleteCore(key, true);\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return successfullyRemoved;\n }\n\n const op: IDirectoryDeleteOperation = {\n key,\n path: this.absolutePath,\n type: \"delete\",\n };\n\n this.submitKeyMessage(op);\n return successfullyRemoved;\n }\n\n /**\n * Deletes all keys from within this IDirectory.\n */\n public clear(): void {\n this.throwIfDisposed();\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.directory.isAttached()) {\n return;\n }\n\n const op: IDirectoryClearOperation = {\n path: this.absolutePath,\n type: \"clear\",\n };\n this.submitClearMessage(op);\n }\n\n /**\n * Issue a callback on each entry under this IDirectory.\n * @param callback - Callback to issue\n */\n public forEach(callback: (value: any, key: string, map: Map<string, any>) => void): void {\n this.throwIfDisposed();\n this._storage.forEach((localValue, key, map) => {\n callback(localValue.value, key, map);\n });\n }\n\n /**\n * The number of entries under this IDirectory.\n */\n public get size(): number {\n this.throwIfDisposed();\n return this._storage.size;\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public entries(): IterableIterator<[string, any]> {\n this.throwIfDisposed();\n const localEntriesIterator = this._storage.entries();\n const iterator = {\n next(): IteratorResult<[string, any]> {\n const nextVal = localEntriesIterator.next();\n if (nextVal.done) {\n return { value: undefined, done: true };\n } else {\n // Unpack the stored value\n return { value: [nextVal.value[0], nextVal.value[1].value], done: false };\n }\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the keys under this IDirectory.\n * @returns The iterator\n */\n public keys(): IterableIterator<string> {\n this.throwIfDisposed();\n return this._storage.keys();\n }\n\n /**\n * Get an iterator over the values under this IDirectory.\n * @returns The iterator\n */\n public values(): IterableIterator<any> {\n this.throwIfDisposed();\n const localValuesIterator = this._storage.values();\n const iterator = {\n next(): IteratorResult<any> {\n const nextVal = localValuesIterator.next();\n if (nextVal.done) {\n return { value: undefined, done: true };\n } else {\n // Unpack the stored value\n return { value: nextVal.value.value, done: false };\n }\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public [Symbol.iterator](): IterableIterator<[string, any]> {\n this.throwIfDisposed();\n return this.entries();\n }\n\n /**\n * Process a clear operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processClearMessage(\n op: IDirectoryClearOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (local) {\n assert(localOpMetadata !== undefined,\n 0x00f /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageId = localOpMetadata as number;\n if (this.pendingClearMessageId === pendingMessageId) {\n this.pendingClearMessageId = -1;\n }\n return;\n }\n this.clearExceptPendingKeys();\n this.directory.emit(\"clear\", local, this.directory);\n }\n\n /**\n * Process a delete operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processDeleteMessage(\n op: IDirectoryDeleteOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessStorageOperation(op, local, localOpMetadata)) {\n return;\n }\n this.deleteCore(op.key, local);\n }\n\n /**\n * Process a set operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processSetMessage(\n op: IDirectorySetOperation,\n context: ILocalValue | undefined,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessStorageOperation(op, local, localOpMetadata)) {\n return;\n }\n\n // needProcessStorageOperation should have returned false if local is true\n // so we can assume context is not undefined\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.setCore(op.key, context!, local);\n }\n\n /**\n * Process a create subdirectory operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processCreateSubDirectoryMessage(\n op: IDirectoryCreateSubDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessSubDirectoryOperations(op, local, localOpMetadata)) {\n return;\n }\n this.createSubDirectoryCore(op.subdirName, local);\n }\n\n /**\n * Process a delete subdirectory operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processDeleteSubDirectoryMessage(\n op: IDirectoryDeleteSubDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessSubDirectoryOperations(op, local, localOpMetadata)) {\n return;\n }\n this.deleteSubDirectoryCore(op.subdirName, local);\n }\n\n /**\n * Submit a clear operation.\n * @param op - The operation\n * @internal\n */\n public submitClearMessage(op: IDirectoryClearOperation): void {\n this.throwIfDisposed();\n const pendingMessageId = ++this.pendingMessageId;\n this.directory.submitDirectoryMessage(op, pendingMessageId);\n this.pendingClearMessageId = pendingMessageId;\n }\n\n /**\n * Submit a key operation.\n * @param op - The operation\n * @internal\n */\n public submitKeyMessage(op: IDirectoryKeyOperation): void {\n this.throwIfDisposed();\n const pendingMessageId = ++this.pendingMessageId;\n this.directory.submitDirectoryMessage(op, pendingMessageId);\n this.pendingKeys.set(op.key, pendingMessageId);\n }\n\n /**\n * Submit a subdirectory operation.\n * @param op - The operation\n * @internal\n */\n public submitSubDirectoryMessage(op: IDirectorySubDirectoryOperation): void {\n this.throwIfDisposed();\n const pendingMessageId = ++this.pendingMessageId;\n this.directory.submitDirectoryMessage(op, pendingMessageId);\n this.pendingSubDirectories.set(op.subdirName, pendingMessageId);\n }\n\n /**\n * Get the storage of this subdirectory in a serializable format, to be used in snapshotting.\n * @param serializer - The serializer to use to serialize handles in its values.\n * @returns The JSONable string representing the storage of this subdirectory\n * @internal\n */\n public *getSerializedStorage(serializer: IFluidSerializer) {\n this.throwIfDisposed();\n for (const [key, localValue] of this._storage) {\n const value = localValue.makeSerialized(serializer, this.directory.handle);\n const res: [string, ISerializedValue] = [key, value];\n yield res;\n }\n }\n\n /**\n * Populate a key value in this subdirectory's storage, to be used when loading from snapshot.\n * @param key - The key to populate\n * @param localValue - The local value to populate into it\n * @internal\n */\n public populateStorage(key: string, localValue: ILocalValue): void {\n this.throwIfDisposed();\n this._storage.set(key, localValue);\n }\n\n /**\n * Populate a subdirectory into this subdirectory, to be used when loading from snapshot.\n * @param subdirName - The name of the subdirectory to add\n * @param newSubDir - The new subdirectory to add\n * @internal\n */\n public populateSubDirectory(subdirName: string, newSubDir: SubDirectory): void {\n this.throwIfDisposed();\n this._subdirectories.set(subdirName, newSubDir);\n }\n\n /**\n * Retrieve the local value at the given key. This is used to get value type information stashed on the local\n * value so op handlers can be retrieved\n * @param key - The key to retrieve from\n * @returns The local value\n * @internal\n */\n public getLocalValue<T extends ILocalValue = ILocalValue>(key: string): T {\n this.throwIfDisposed();\n return this._storage.get(key) as T;\n }\n\n /**\n * Converts the given relative path into an absolute path.\n * @param path - Relative path to convert\n * @returns The equivalent absolute path\n */\n private makeAbsolute(relativePath: string): string {\n return posix.resolve(this.absolutePath, relativePath);\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 message - The message\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 needProcessStorageOperation(\n op: IDirectoryKeyOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): boolean {\n if (this.pendingClearMessageId !== -1) {\n if (local) {\n assert(localOpMetadata !== undefined && localOpMetadata as number < this.pendingClearMessageId,\n 0x010 /* \"Received out of order storage op when there is an unackd clear message\" */);\n }\n // If I have a NACK clear, we can ignore all ops.\n return false;\n }\n\n if (this.pendingKeys.has(op.key)) {\n // Found an NACK op, clear it from the directory if the latest sequence number in the directory\n // match the message's and don't process the op.\n if (local) {\n assert(localOpMetadata !== undefined,\n 0x011 /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageId = localOpMetadata as number;\n const pendingKeyMessageId = this.pendingKeys.get(op.key);\n if (pendingKeyMessageId === pendingMessageId) {\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 * 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 message - The message\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 needProcessSubDirectoryOperations(\n op: IDirectorySubDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): boolean {\n if (this.pendingSubDirectories.has(op.subdirName)) {\n if (local) {\n assert(localOpMetadata !== undefined,\n 0x012 /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageId = localOpMetadata as number;\n const pendingSubDirectoryMessageId = this.pendingSubDirectories.get(op.subdirName);\n if (pendingSubDirectoryMessageId === pendingMessageId) {\n this.pendingSubDirectories.delete(op.subdirName);\n }\n }\n return false;\n }\n\n return !local;\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() {\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, map) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n temp.set(key, this._storage.get(key)!);\n });\n this._storage.clear();\n temp.forEach((value, key, map) => {\n this._storage.set(key, value);\n });\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 * @param op - The message if from a remote clear, or null if from a local clear\n */\n private clearCore(local: boolean) {\n this._storage.clear();\n this.directory.emit(\"clear\", local, this.directory);\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 * @param op - The message if from a remote delete, or null if from a local delete\n * @returns True if the key existed and was deleted, false if it did not exist\n */\n private deleteCore(key: string, local: boolean) {\n const previousValue = this.get(key);\n const successfullyRemoved = this._storage.delete(key);\n if (successfullyRemoved) {\n const event: IDirectoryValueChanged = { key, path: this.absolutePath, previousValue };\n this.directory.emit(\"valueChanged\", event, local, this.directory);\n const containedEvent: IValueChanged = { key, previousValue };\n this.emit(\"containedValueChanged\", containedEvent, local, this);\n }\n return successfullyRemoved;\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 * @param op - The message if from a remote set, or null if from a local set\n */\n private setCore(key: string, value: ILocalValue, local: boolean) {\n const previousValue = this.get(key);\n this._storage.set(key, value);\n const event: IDirectoryValueChanged = { key, path: this.absolutePath, previousValue };\n this.directory.emit(\"valueChanged\", event, local, this.directory);\n const containedEvent: IValueChanged = { key, previousValue };\n this.emit(\"containedValueChanged\", containedEvent, local, this);\n }\n\n /**\n * Create subdirectory implementation used for both locally sourced creation as well as incoming remote creation.\n * @param subdirName - The name of the subdirectory being created\n * @param local - Whether the message originated from the local client\n */\n private createSubDirectoryCore(subdirName: string, local: boolean) {\n if (!this._subdirectories.has(subdirName)) {\n const absolutePath = posix.join(this.absolutePath, subdirName);\n const subDir = new SubDirectory(this.directory, this.runtime, this.serializer, absolutePath);\n this.registerEventsOnSubDirectory(subDir, subdirName);\n this._subdirectories.set(subdirName, subDir);\n this.emit(\"subDirectoryCreated\", subdirName, local, this);\n }\n }\n\n private registerEventsOnSubDirectory(subDirectory: SubDirectory, subDirName: string) {\n subDirectory.on(\"subDirectoryCreated\", (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryCreated\", posix.join(subDirName, relativePath), local, this);\n });\n subDirectory.on(\"subDirectoryDeleted\", (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryDeleted\", posix.join(subDirName, relativePath), local, this);\n });\n }\n\n /**\n * Delete subdirectory implementation used for both locally sourced creation as well as incoming remote creation.\n * @param subdirName - The name of the subdirectory being deleted\n * @param local - Whether the message originated from the local client\n * @param op - The message if from a remote delete, or null if from a local delete\n */\n private deleteSubDirectoryCore(subdirName: string, local: boolean) {\n const previousValue = this.getSubDirectory(subdirName);\n // This should make the subdirectory structure unreachable so it can be GC'd and won't appear in snapshots\n // Might want to consider cleaning out the structure more exhaustively though?\n const successfullyRemoved = this._subdirectories.delete(subdirName);\n if (previousValue !== undefined) {\n this.disposeSubDirectoryTree(previousValue);\n this.emit(\"subDirectoryDeleted\", subdirName, local, this);\n }\n return successfullyRemoved;\n }\n\n private disposeSubDirectoryTree(directory: IDirectory | undefined) {\n if (!directory) {\n return;\n }\n // Dispose the subdirectory tree. This will dispose the subdirectories from bottom to top.\n const subDirectories = directory.subdirectories();\n for (const [_, subDirectory] of subDirectories) {\n this.disposeSubDirectoryTree(subDirectory);\n }\n if (typeof directory.dispose === \"function\") {\n directory.dispose();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"directory.js","sourceRoot":"","sources":["../src/directory.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 { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport {\n ISequencedDocumentMessage,\n MessageType,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n IChannelServices,\n IChannelFactory,\n} from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTreeWithStats, ITelemetryContext } from \"@fluidframework/runtime-definitions\";\nimport { IFluidSerializer, SharedObject, ValueType } from \"@fluidframework/shared-object-base\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport * as path from \"path-browserify\";\nimport {\n IDirectory,\n IDirectoryEvents,\n IDirectoryValueChanged,\n ISerializableValue,\n ISerializedValue,\n ISharedDirectory,\n ISharedDirectoryEvents,\n IValueChanged,\n} from \"./interfaces\";\nimport {\n ILocalValue,\n LocalValueMaker,\n makeSerializable,\n} from \"./localValues\";\nimport { pkgVersion } from \"./packageVersion\";\n\n// We use path-browserify since this code can run safely on the server or the browser.\n// We standardize on using posix slashes everywhere.\nconst posix: typeof import(\"path\").posix = path.posix;\n\nconst snapshotFileName = \"header\";\n\n/**\n * Defines the means to process and submit a given op on a directory.\n */\ninterface IDirectoryMessageHandler {\n /**\n * Apply the given operation.\n * @param op - The directory 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: IDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void;\n\n /**\n * Communicate the operation to remote clients.\n * @param op - The directory operation to submit\n * @param localOpMetadata - The metadata to be submitted with the message.\n */\n submit(op: IDirectoryOperation, localOpMetadata: unknown): void;\n}\n\n/**\n * Operation indicating a value should be set for a key.\n */\ninterface IDirectorySetOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"set\";\n\n /**\n * Directory key being modified.\n */\n key: string;\n\n /**\n * Absolute path of the directory where the modified key is located.\n */\n path: string;\n\n /**\n * Value to be set on the key.\n */\n value: ISerializableValue;\n}\n\n/**\n * Operation indicating a key should be deleted from the directory.\n */\ninterface IDirectoryDeleteOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"delete\";\n\n /**\n * Directory key being modified.\n */\n key: string;\n\n /**\n * Absolute path of the directory where the modified key is located.\n */\n path: string;\n}\n\n/**\n * An operation on a specific key within a directory\n */\ntype IDirectoryKeyOperation = IDirectorySetOperation | IDirectoryDeleteOperation;\n\n/**\n * Operation indicating the directory should be cleared.\n */\ninterface IDirectoryClearOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"clear\";\n\n /**\n * Absolute path of the directory being cleared.\n */\n path: string;\n}\n\n/**\n * An operation on one or more of the keys within a directory\n */\ntype IDirectoryStorageOperation = IDirectoryKeyOperation | IDirectoryClearOperation;\n\n/**\n * Operation indicating a subdirectory should be created.\n */\ninterface IDirectoryCreateSubDirectoryOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"createSubDirectory\";\n\n /**\n * Absolute path of the directory that will contain the new subdirectory.\n */\n path: string;\n\n /**\n * Name of the new subdirectory.\n */\n subdirName: string;\n}\n\n/**\n * Operation indicating a subdirectory should be deleted.\n */\ninterface IDirectoryDeleteSubDirectoryOperation {\n /**\n * String identifier of the operation type.\n */\n type: \"deleteSubDirectory\";\n\n /**\n * Absolute path of the directory that contains the directory to be deleted.\n */\n path: string;\n\n /**\n * Name of the subdirectory to be deleted.\n */\n subdirName: string;\n}\n\n/**\n * An operation on the subdirectories within a directory\n */\ntype IDirectorySubDirectoryOperation = IDirectoryCreateSubDirectoryOperation | IDirectoryDeleteSubDirectoryOperation;\n\n/**\n * Any operation on a directory\n */\nexport type IDirectoryOperation = IDirectoryStorageOperation | IDirectorySubDirectoryOperation;\n\n/**\n * Defines the in-memory object structure to be used for the conversion to/from serialized.\n * @privateRemarks\n * Directly used in JSON.stringify, direct result from JSON.parse.\n */\nexport interface IDirectoryDataObject {\n storage?: { [key: string]: ISerializableValue; };\n subdirectories?: { [subdirName: string]: IDirectoryDataObject; };\n}\n\nexport interface IDirectoryNewStorageFormat {\n blobs: string[];\n content: IDirectoryDataObject;\n}\n\n/**\n * The factory that defines the directory.\n * @sealed\n */\nexport class DirectoryFactory {\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n */\n public static readonly Type = \"https://graph.microsoft.com/types/directory\";\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n */\n public static readonly Attributes: IChannelAttributes = {\n type: DirectoryFactory.Type,\n snapshotFormatVersion: \"0.1\",\n packageVersion: pkgVersion,\n };\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.\"type\"}\n */\n public get type() {\n return DirectoryFactory.Type;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.attributes}\n */\n public get attributes() {\n return DirectoryFactory.Attributes;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n */\n public async load(\n runtime: IFluidDataStoreRuntime,\n id: string,\n services: IChannelServices,\n attributes: IChannelAttributes): Promise<ISharedDirectory> {\n const directory = new SharedDirectory(id, runtime, attributes);\n await directory.load(services);\n\n return directory;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.create}\n */\n public create(runtime: IFluidDataStoreRuntime, id: string): ISharedDirectory {\n const directory = new SharedDirectory(id, runtime, DirectoryFactory.Attributes);\n directory.initializeLocal();\n\n return directory;\n }\n}\n\n/**\n * SharedDirectory provides a hierarchical organization of map-like data structures as SubDirectories.\n * The values stored within can be accessed like a map, and the hierarchy can be navigated using path syntax.\n * SubDirectories can be retrieved for use as working directories.\n *\n * @example\n * ```ts\n * mySharedDirectory.createSubDirectory(\"a\").createSubDirectory(\"b\").createSubDirectory(\"c\").set(\"foo\", val1);\n * const mySubDir = mySharedDirectory.getWorkingDirectory(\"/a/b/c\");\n * mySubDir.get(\"foo\"); // returns val1\n * ```\n *\n * @sealed\n */\nexport class SharedDirectory extends SharedObject<ISharedDirectoryEvents> implements ISharedDirectory {\n /**\n * Create a new shared directory\n *\n * @param runtime - Data store runtime the new shared directory belongs to\n * @param id - Optional name of the shared directory\n * @returns Newly create shared directory (but not attached yet)\n */\n public static create(runtime: IFluidDataStoreRuntime, id?: string): SharedDirectory {\n return runtime.createChannel(id, DirectoryFactory.Type) as SharedDirectory;\n }\n\n /**\n * Get a factory for SharedDirectory to register with the data store.\n *\n * @returns A factory that creates and load SharedDirectory\n */\n public static getFactory(): IChannelFactory {\n return new DirectoryFactory();\n }\n\n /**\n * String representation for the class.\n */\n public [Symbol.toStringTag]: string = \"SharedDirectory\";\n\n /**\n * {@inheritDoc IDirectory.absolutePath}\n */\n public get absolutePath(): string {\n return this.root.absolutePath;\n }\n\n /**\n * @internal\n */\n public readonly localValueMaker: LocalValueMaker;\n\n /**\n * Root of the SharedDirectory, most operations on the SharedDirectory itself act on the root.\n */\n private readonly root: SubDirectory = new SubDirectory(this, this.runtime, this.serializer, posix.sep);\n\n /**\n * Mapping of op types to message handlers.\n */\n private readonly messageHandlers: Map<string, IDirectoryMessageHandler> = new Map();\n\n /**\n * Constructs a new shared directory. If the object is non-local an id and service interfaces will\n * be provided.\n * @param id - String identifier for the SharedDirectory\n * @param runtime - Data store runtime\n * @param type - Type identifier\n */\n constructor(\n id: string,\n runtime: IFluidDataStoreRuntime,\n attributes: IChannelAttributes,\n ) {\n super(id, runtime, attributes, \"fluid_directory_\");\n this.localValueMaker = new LocalValueMaker(this.serializer);\n this.setMessageHandlers();\n // Mirror the containedValueChanged op on the SharedDirectory\n this.root.on(\n \"containedValueChanged\",\n (changed: IValueChanged, local: boolean) => {\n this.emit(\"containedValueChanged\", changed, local, this);\n },\n );\n this.root.on(\n \"subDirectoryCreated\",\n (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryCreated\", relativePath, local, this);\n },\n );\n this.root.on(\n \"subDirectoryDeleted\",\n (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryDeleted\", relativePath, local, this);\n },\n );\n }\n\n /**\n * {@inheritDoc IDirectory.get}\n */\n public get<T = any>(key: string): T | undefined {\n return this.root.get<T>(key);\n }\n\n /**\n * {@inheritDoc IDirectory.set}\n */\n public set<T = any>(key: string, value: T): this {\n this.root.set(key, value);\n return this;\n }\n\n public dispose(error?: Error): void {\n this.root.dispose(error);\n }\n\n public get disposed(): boolean {\n return this.root.disposed;\n }\n\n /**\n * Deletes the given key from within this IDirectory.\n * @param key - The 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 return this.root.delete(key);\n }\n\n /**\n * Deletes all keys from within this IDirectory.\n */\n public clear(): void {\n this.root.clear();\n }\n\n /**\n * Checks whether the given key exists in this IDirectory.\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.root.has(key);\n }\n\n /**\n * The number of entries under this IDirectory.\n */\n public get size(): number {\n return this.root.size;\n }\n\n /**\n * Issue a callback on each entry under this IDirectory.\n * @param callback - Callback to issue\n */\n public forEach(callback: (value: any, key: string, map: Map<string, any>) => void): void {\n this.root.forEach(callback);\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public [Symbol.iterator](): IterableIterator<[string, any]> {\n return this.root[Symbol.iterator]();\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public entries(): IterableIterator<[string, any]> {\n return this.root.entries();\n }\n\n /**\n * {@inheritDoc IDirectory.countSubDirectory}\n */\n public countSubDirectory(): number {\n return this.root.countSubDirectory();\n }\n\n /**\n * Get an iterator over the keys under this IDirectory.\n * @returns The iterator\n */\n public keys(): IterableIterator<string> {\n return this.root.keys();\n }\n\n /**\n * Get an iterator over the values under this IDirectory.\n * @returns The iterator\n */\n public values(): IterableIterator<any> {\n return this.root.values();\n }\n\n /**\n * {@inheritDoc IDirectory.createSubDirectory}\n */\n public createSubDirectory(subdirName: string): IDirectory {\n return this.root.createSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.getSubDirectory}\n */\n public getSubDirectory(subdirName: string): IDirectory | undefined {\n return this.root.getSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.hasSubDirectory}\n */\n public hasSubDirectory(subdirName: string): boolean {\n return this.root.hasSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.deleteSubDirectory}\n */\n public deleteSubDirectory(subdirName: string): boolean {\n return this.root.deleteSubDirectory(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.subdirectories}\n */\n public subdirectories(): IterableIterator<[string, IDirectory]> {\n return this.root.subdirectories();\n }\n\n /**\n * {@inheritDoc IDirectory.getWorkingDirectory}\n */\n public getWorkingDirectory(relativePath: string): IDirectory | undefined {\n const absolutePath = this.makeAbsolute(relativePath);\n if (absolutePath === posix.sep) {\n return this.root;\n }\n\n let currentSubDir = this.root;\n const subdirs = absolutePath.substr(1).split(posix.sep);\n for (const subdir of subdirs) {\n currentSubDir = currentSubDir.getSubDirectory(subdir) as SubDirectory;\n if (!currentSubDir) {\n return undefined;\n }\n }\n return currentSubDir;\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n * @internal\n */\n protected summarizeCore(\n serializer: IFluidSerializer,\n telemetryContext?: ITelemetryContext,\n ): ISummaryTreeWithStats {\n return this.serializeDirectory(this.root, serializer);\n }\n\n /**\n * Submits an operation\n * @param op - Op to submit\n * @param localOpMetadata - The local metadata associated with the op. We send a unique id that is used to track\n * this op while it has not been ack'd. This will be sent when we receive this op back from the server.\n * @internal\n */\n public submitDirectoryMessage(op: IDirectoryOperation, localOpMetadata: unknown) {\n this.submitLocalMessage(op, localOpMetadata);\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n * @internal\n */\n protected onDisconnect() {}\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}\n * @internal\n */\n protected reSubmitCore(content: any, localOpMetadata: unknown) {\n const message = content as IDirectoryOperation;\n const handler = this.messageHandlers.get(message.type);\n assert(handler !== undefined, 0x00d /* Missing message handler for message type */);\n handler.submit(message, localOpMetadata);\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n * @internal\n */\n protected async loadCore(storage: IChannelStorageService) {\n const data = await readAndParse(storage, snapshotFileName);\n const newFormat = data as IDirectoryNewStorageFormat;\n if (Array.isArray(newFormat.blobs)) {\n // New storage format\n this.populate(newFormat.content);\n await Promise.all(newFormat.blobs.map(async (value) => {\n const dataExtra = await readAndParse(storage, value);\n this.populate(dataExtra as IDirectoryDataObject);\n }));\n } else {\n // Old storage format\n this.populate(data as IDirectoryDataObject);\n }\n }\n\n /**\n * Populate the directory with the given directory data.\n * @param data - A JSON string containing serialized directory data\n * @internal\n */\n protected populate(data: IDirectoryDataObject) {\n const stack: [SubDirectory, IDirectoryDataObject][] = [];\n stack.push([this.root, data]);\n while (stack.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const [currentSubDir, currentSubDirObject] = stack.pop()!;\n if (currentSubDirObject.subdirectories) {\n for (const [subdirName, subdirObject] of Object.entries(currentSubDirObject.subdirectories)) {\n let newSubDir = currentSubDir.getSubDirectory(subdirName) as SubDirectory;\n if (!newSubDir) {\n newSubDir = new SubDirectory(\n this,\n this.runtime,\n this.serializer,\n posix.join(currentSubDir.absolutePath, subdirName),\n );\n currentSubDir.populateSubDirectory(subdirName, newSubDir);\n }\n stack.push([newSubDir, subdirObject]);\n }\n }\n\n if (currentSubDirObject.storage) {\n for (const [key, serializable] of Object.entries(currentSubDirObject.storage)) {\n const localValue = this.makeLocal(\n key,\n currentSubDir.absolutePath,\n serializable,\n );\n currentSubDir.populateStorage(key, localValue);\n }\n }\n }\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n * @internal\n */\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n if (message.type === MessageType.Operation) {\n const op: IDirectoryOperation = message.contents as IDirectoryOperation;\n const handler = this.messageHandlers.get(op.type);\n assert(handler !== undefined, 0x00e /* Missing message handler for message type */);\n handler.process(op, local, localOpMetadata);\n }\n }\n\n /**\n * Converts the given relative path to absolute against the root.\n * @param relativePath - The path to convert\n */\n private makeAbsolute(relativePath: string): string {\n return posix.resolve(posix.sep, relativePath);\n }\n\n /**\n * The remote ISerializableValue we're receiving (either as a result of a snapshot load or an incoming set op)\n * will 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 ID but not have the actual map or its data yet. makeLocal's job\n * is to convert that information into a real object for local usage.\n * @param key - Key of element being converted\n * @param absolutePath - Path of element being converted\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(\n key: string,\n absolutePath: string,\n serializable: ISerializableValue,\n ): ILocalValue {\n assert(\n serializable.type === ValueType[ValueType.Plain] || serializable.type === ValueType[ValueType.Shared],\n 0x1e4 /* \"Unexpected serializable type\" */,\n );\n return this.localValueMaker.fromSerializable(serializable);\n }\n\n /**\n * Set the message handlers for the directory.\n */\n private setMessageHandlers(): void {\n this.messageHandlers.set(\n \"clear\",\n {\n process: (op: IDirectoryClearOperation, local, localOpMetadata) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n subdir.processClearMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryClearOperation, localOpMetadata: unknown) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n // We don't reuse the metadata but send a new one on each submit.\n subdir.submitClearMessage(op);\n }\n },\n },\n );\n this.messageHandlers.set(\n \"delete\",\n {\n process: (op: IDirectoryDeleteOperation, local, localOpMetadata) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n subdir.processDeleteMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryDeleteOperation, localOpMetadata: unknown) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n // We don't reuse the metadata but send a new one on each submit.\n subdir.submitKeyMessage(op);\n }\n },\n },\n );\n this.messageHandlers.set(\n \"set\",\n {\n process: (op: IDirectorySetOperation, local, localOpMetadata) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n const context = local ? undefined : this.makeLocal(op.key, op.path, op.value);\n subdir.processSetMessage(op, context, local, localOpMetadata);\n }\n },\n submit: (op: IDirectorySetOperation, localOpMetadata: unknown) => {\n const subdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (subdir) {\n // We don't reuse the metadata but send a new one on each submit.\n subdir.submitKeyMessage(op);\n }\n },\n },\n );\n\n this.messageHandlers.set(\n \"createSubDirectory\",\n {\n process: (op: IDirectoryCreateSubDirectoryOperation, local, localOpMetadata) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n parentSubdir.processCreateSubDirectoryMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryCreateSubDirectoryOperation, localOpMetadata: unknown) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n // We don't reuse the metadata but send a new one on each submit.\n parentSubdir.submitSubDirectoryMessage(op);\n }\n },\n },\n );\n\n this.messageHandlers.set(\n \"deleteSubDirectory\",\n {\n process: (op: IDirectoryDeleteSubDirectoryOperation, local, localOpMetadata) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n parentSubdir.processDeleteSubDirectoryMessage(op, local, localOpMetadata);\n }\n },\n submit: (op: IDirectoryDeleteSubDirectoryOperation, localOpMetadata: unknown) => {\n const parentSubdir = this.getWorkingDirectory(op.path) as SubDirectory | undefined;\n if (parentSubdir) {\n // We don't reuse the metadata but send a new one on each submit.\n parentSubdir.submitSubDirectoryMessage(op);\n }\n },\n },\n );\n }\n\n /**\n * @internal\n */\n protected applyStashedOp() {\n throw new Error(\"not implemented\");\n }\n\n private serializeDirectory(\n root: SubDirectory,\n serializer: IFluidSerializer,\n telemetryContext?: ITelemetryContext,\n ): ISummaryTreeWithStats {\n const MinValueSizeSeparateSnapshotBlob = 8 * 1024;\n\n const builder = new SummaryTreeBuilder();\n let counter = 0;\n const blobs: string[] = [];\n\n const stack: [SubDirectory, IDirectoryDataObject][] = [];\n const content: IDirectoryDataObject = {};\n stack.push([root, content]);\n\n while (stack.length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const [currentSubDir, currentSubDirObject] = stack.pop()!;\n for (const [key, value] of currentSubDir.getSerializedStorage(serializer)) {\n if (!currentSubDirObject.storage) {\n currentSubDirObject.storage = {};\n }\n const result: ISerializableValue = {\n type: value.type,\n // eslint-disable-next-line @typescript-eslint/ban-types\n value: value.value && JSON.parse(value.value) as object,\n };\n if (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {\n const extraContent: IDirectoryDataObject = {};\n let largeContent = extraContent;\n if (currentSubDir.absolutePath !== posix.sep) {\n for (const dir of currentSubDir.absolutePath.substr(1).split(posix.sep)) {\n const subDataObject: IDirectoryDataObject = {};\n largeContent.subdirectories = { [dir]: subDataObject };\n largeContent = subDataObject;\n }\n }\n largeContent.storage = { [key]: result };\n const blobName = `blob${counter}`;\n counter++;\n blobs.push(blobName);\n builder.addBlob(blobName, JSON.stringify(extraContent));\n } else {\n currentSubDirObject.storage[key] = result;\n }\n }\n\n for (const [subdirName, subdir] of currentSubDir.subdirectories()) {\n if (!currentSubDirObject.subdirectories) {\n currentSubDirObject.subdirectories = {};\n }\n const subDataObject: IDirectoryDataObject = {};\n currentSubDirObject.subdirectories[subdirName] = subDataObject;\n stack.push([subdir as SubDirectory, subDataObject]);\n }\n }\n\n const newFormat: IDirectoryNewStorageFormat = {\n blobs,\n content,\n };\n builder.addBlob(snapshotFileName, JSON.stringify(newFormat));\n\n return builder.getSummaryTree();\n }\n}\n\n/**\n * Node of the directory tree.\n * @sealed\n */\nclass SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirectory {\n /**\n * Tells if the sub directory is disposed or not.\n */\n private _disposed = false;\n\n /**\n * String representation for the class.\n */\n public [Symbol.toStringTag]: string = \"SubDirectory\";\n\n /**\n * The in-memory data the directory is storing.\n */\n private readonly _storage: Map<string, ILocalValue> = new Map();\n\n /**\n * The subdirectories the directory is holding.\n */\n private readonly _subdirectories: Map<string, SubDirectory> = new Map();\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 * Subdirectories that have been modified locally but not yet ack'd from the server.\n */\n private readonly pendingSubDirectories: 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 * If a clear has been performed locally but not yet ack'd from the server, then this stores the pending id\n * of that clear operation. Otherwise, is -1.\n */\n private pendingClearMessageId: number = -1;\n\n /**\n * Constructor.\n * @param directory - Reference back to the SharedDirectory to perform operations\n * @param runtime - The data store runtime this directory is associated with\n * @param serializer - The serializer to serialize / parse handles\n * @param absolutePath - The absolute path of this IDirectory\n */\n constructor(\n private readonly directory: SharedDirectory,\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly serializer: IFluidSerializer,\n public readonly absolutePath: string,\n ) {\n super();\n }\n\n public dispose(error?: Error): void {\n this._disposed = true;\n this.emit(\"disposed\", this);\n }\n\n public get disposed(): boolean {\n return this._disposed;\n }\n\n private throwIfDisposed() {\n if (this._disposed) {\n throw new UsageError(\"Cannot access Disposed subDirectory\");\n }\n }\n\n /**\n * Checks whether the given key exists in this IDirectory.\n * @param key - The key to check\n * @returns True if the key exists, false otherwise\n */\n public has(key: string): boolean {\n this.throwIfDisposed();\n return this._storage.has(key);\n }\n\n /**\n * {@inheritDoc IDirectory.get}\n */\n public get<T = any>(key: string): T | undefined {\n this.throwIfDisposed();\n return this._storage.get(key)?.value as T | undefined;\n }\n\n /**\n * {@inheritDoc IDirectory.set}\n */\n public set<T = any>(key: string, value: T): this {\n this.throwIfDisposed();\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.directory.localValueMaker.fromInMemory(value);\n const serializableValue = makeSerializable(\n localValue,\n this.serializer,\n this.directory.handle);\n\n // Set the value locally.\n this.setCore(\n key,\n localValue,\n true,\n );\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return this;\n }\n\n const op: IDirectorySetOperation = {\n key,\n path: this.absolutePath,\n type: \"set\",\n value: serializableValue,\n };\n this.submitKeyMessage(op);\n return this;\n }\n\n /**\n * {@inheritDoc IDirectory.countSubDirectory}\n */\n public countSubDirectory(): number {\n return this._subdirectories.size;\n }\n\n /**\n * {@inheritDoc IDirectory.createSubDirectory}\n */\n public createSubDirectory(subdirName: string): IDirectory {\n this.throwIfDisposed();\n // Undefined/null subdirectory names can't be serialized to JSON in the manner we currently snapshot.\n if (subdirName === undefined || subdirName === null) {\n throw new Error(\"SubDirectory name may not be undefined or null\");\n }\n\n if (subdirName.includes(posix.sep)) {\n throw new Error(`SubDirectory name may not contain ${posix.sep}`);\n }\n\n // Create the sub directory locally first.\n this.createSubDirectoryCore(subdirName, true);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const subDir: IDirectory = this._subdirectories.get(subdirName)!;\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return subDir;\n }\n\n const op: IDirectoryCreateSubDirectoryOperation = {\n path: this.absolutePath,\n subdirName,\n type: \"createSubDirectory\",\n };\n this.submitSubDirectoryMessage(op);\n\n return subDir;\n }\n\n /**\n * {@inheritDoc IDirectory.getSubDirectory}\n */\n public getSubDirectory(subdirName: string): IDirectory | undefined {\n this.throwIfDisposed();\n return this._subdirectories.get(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.hasSubDirectory}\n */\n public hasSubDirectory(subdirName: string): boolean {\n this.throwIfDisposed();\n return this._subdirectories.has(subdirName);\n }\n\n /**\n * {@inheritDoc IDirectory.deleteSubDirectory}\n */\n public deleteSubDirectory(subdirName: string): boolean {\n this.throwIfDisposed();\n // Delete the sub directory locally first.\n const successfullyRemoved = this.deleteSubDirectoryCore(subdirName, true);\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return successfullyRemoved;\n }\n\n const op: IDirectoryDeleteSubDirectoryOperation = {\n path: this.absolutePath,\n subdirName,\n type: \"deleteSubDirectory\",\n };\n\n this.submitSubDirectoryMessage(op);\n return successfullyRemoved;\n }\n\n /**\n * {@inheritDoc IDirectory.subdirectories}\n */\n public subdirectories(): IterableIterator<[string, IDirectory]> {\n this.throwIfDisposed();\n return this._subdirectories.entries();\n }\n\n /**\n * {@inheritDoc IDirectory.getWorkingDirectory}\n */\n public getWorkingDirectory(relativePath: string): IDirectory | undefined {\n this.throwIfDisposed();\n return this.directory.getWorkingDirectory(this.makeAbsolute(relativePath));\n }\n\n /**\n * Deletes the given key from within this IDirectory.\n * @param key - The 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 this.throwIfDisposed();\n // Delete the key locally first.\n const successfullyRemoved = this.deleteCore(key, true);\n\n // If we are not attached, don't submit the op.\n if (!this.directory.isAttached()) {\n return successfullyRemoved;\n }\n\n const op: IDirectoryDeleteOperation = {\n key,\n path: this.absolutePath,\n type: \"delete\",\n };\n\n this.submitKeyMessage(op);\n return successfullyRemoved;\n }\n\n /**\n * Deletes all keys from within this IDirectory.\n */\n public clear(): void {\n this.throwIfDisposed();\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.directory.isAttached()) {\n return;\n }\n\n const op: IDirectoryClearOperation = {\n path: this.absolutePath,\n type: \"clear\",\n };\n this.submitClearMessage(op);\n }\n\n /**\n * Issue a callback on each entry under this IDirectory.\n * @param callback - Callback to issue\n */\n public forEach(callback: (value: any, key: string, map: Map<string, any>) => void): void {\n this.throwIfDisposed();\n this._storage.forEach((localValue, key, map) => {\n callback(localValue.value, key, map);\n });\n }\n\n /**\n * The number of entries under this IDirectory.\n */\n public get size(): number {\n this.throwIfDisposed();\n return this._storage.size;\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public entries(): IterableIterator<[string, any]> {\n this.throwIfDisposed();\n const localEntriesIterator = this._storage.entries();\n const iterator = {\n next(): IteratorResult<[string, any]> {\n const nextVal = localEntriesIterator.next();\n if (nextVal.done) {\n return { value: undefined, done: true };\n } else {\n // Unpack the stored value\n return { value: [nextVal.value[0], nextVal.value[1].value], done: false };\n }\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the keys under this IDirectory.\n * @returns The iterator\n */\n public keys(): IterableIterator<string> {\n this.throwIfDisposed();\n return this._storage.keys();\n }\n\n /**\n * Get an iterator over the values under this IDirectory.\n * @returns The iterator\n */\n public values(): IterableIterator<any> {\n this.throwIfDisposed();\n const localValuesIterator = this._storage.values();\n const iterator = {\n next(): IteratorResult<any> {\n const nextVal = localValuesIterator.next();\n if (nextVal.done) {\n return { value: undefined, done: true };\n } else {\n // Unpack the stored value\n return { value: nextVal.value.value, done: false };\n }\n },\n [Symbol.iterator]() {\n return this;\n },\n };\n return iterator;\n }\n\n /**\n * Get an iterator over the entries under this IDirectory.\n * @returns The iterator\n */\n public [Symbol.iterator](): IterableIterator<[string, any]> {\n this.throwIfDisposed();\n return this.entries();\n }\n\n /**\n * Process a clear operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processClearMessage(\n op: IDirectoryClearOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (local) {\n assert(localOpMetadata !== undefined,\n 0x00f /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageId = localOpMetadata as number;\n if (this.pendingClearMessageId === pendingMessageId) {\n this.pendingClearMessageId = -1;\n }\n return;\n }\n this.clearExceptPendingKeys();\n this.directory.emit(\"clear\", local, this.directory);\n }\n\n /**\n * Process a delete operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processDeleteMessage(\n op: IDirectoryDeleteOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessStorageOperation(op, local, localOpMetadata)) {\n return;\n }\n this.deleteCore(op.key, local);\n }\n\n /**\n * Process a set operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processSetMessage(\n op: IDirectorySetOperation,\n context: ILocalValue | undefined,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessStorageOperation(op, local, localOpMetadata)) {\n return;\n }\n\n // needProcessStorageOperation should have returned false if local is true\n // so we can assume context is not undefined\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.setCore(op.key, context!, local);\n }\n\n /**\n * Process a create subdirectory operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processCreateSubDirectoryMessage(\n op: IDirectoryCreateSubDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessSubDirectoryOperations(op, local, localOpMetadata)) {\n return;\n }\n this.createSubDirectoryCore(op.subdirName, local);\n }\n\n /**\n * Process a delete subdirectory operation.\n * @param op - The op to process\n * @param local - Whether the message originated from the local client\n * @param message - The message\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 * @internal\n */\n public processDeleteSubDirectoryMessage(\n op: IDirectoryDeleteSubDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): void {\n this.throwIfDisposed();\n if (!this.needProcessSubDirectoryOperations(op, local, localOpMetadata)) {\n return;\n }\n this.deleteSubDirectoryCore(op.subdirName, local);\n }\n\n /**\n * Submit a clear operation.\n * @param op - The operation\n * @internal\n */\n public submitClearMessage(op: IDirectoryClearOperation): void {\n this.throwIfDisposed();\n const pendingMessageId = ++this.pendingMessageId;\n this.directory.submitDirectoryMessage(op, pendingMessageId);\n this.pendingClearMessageId = pendingMessageId;\n }\n\n /**\n * Submit a key operation.\n * @param op - The operation\n * @internal\n */\n public submitKeyMessage(op: IDirectoryKeyOperation): void {\n this.throwIfDisposed();\n const pendingMessageId = ++this.pendingMessageId;\n this.directory.submitDirectoryMessage(op, pendingMessageId);\n this.pendingKeys.set(op.key, pendingMessageId);\n }\n\n /**\n * Submit a subdirectory operation.\n * @param op - The operation\n * @internal\n */\n public submitSubDirectoryMessage(op: IDirectorySubDirectoryOperation): void {\n this.throwIfDisposed();\n const pendingMessageId = ++this.pendingMessageId;\n this.directory.submitDirectoryMessage(op, pendingMessageId);\n this.pendingSubDirectories.set(op.subdirName, pendingMessageId);\n }\n\n /**\n * Get the storage of this subdirectory in a serializable format, to be used in snapshotting.\n * @param serializer - The serializer to use to serialize handles in its values.\n * @returns The JSONable string representing the storage of this subdirectory\n * @internal\n */\n public *getSerializedStorage(serializer: IFluidSerializer) {\n this.throwIfDisposed();\n for (const [key, localValue] of this._storage) {\n const value = localValue.makeSerialized(serializer, this.directory.handle);\n const res: [string, ISerializedValue] = [key, value];\n yield res;\n }\n }\n\n /**\n * Populate a key value in this subdirectory's storage, to be used when loading from snapshot.\n * @param key - The key to populate\n * @param localValue - The local value to populate into it\n * @internal\n */\n public populateStorage(key: string, localValue: ILocalValue): void {\n this.throwIfDisposed();\n this._storage.set(key, localValue);\n }\n\n /**\n * Populate a subdirectory into this subdirectory, to be used when loading from snapshot.\n * @param subdirName - The name of the subdirectory to add\n * @param newSubDir - The new subdirectory to add\n * @internal\n */\n public populateSubDirectory(subdirName: string, newSubDir: SubDirectory): void {\n this.throwIfDisposed();\n this._subdirectories.set(subdirName, newSubDir);\n }\n\n /**\n * Retrieve the local value at the given key. This is used to get value type information stashed on the local\n * value so op handlers can be retrieved\n * @param key - The key to retrieve from\n * @returns The local value\n * @internal\n */\n public getLocalValue<T extends ILocalValue = ILocalValue>(key: string): T {\n this.throwIfDisposed();\n return this._storage.get(key) as T;\n }\n\n /**\n * Converts the given relative path into an absolute path.\n * @param path - Relative path to convert\n * @returns The equivalent absolute path\n */\n private makeAbsolute(relativePath: string): string {\n return posix.resolve(this.absolutePath, relativePath);\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 message - The message\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 needProcessStorageOperation(\n op: IDirectoryKeyOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): boolean {\n if (this.pendingClearMessageId !== -1) {\n if (local) {\n assert(localOpMetadata !== undefined && localOpMetadata as number < this.pendingClearMessageId,\n 0x010 /* \"Received out of order storage op when there is an unackd clear message\" */);\n }\n // If I have a NACK clear, we can ignore all ops.\n return false;\n }\n\n if (this.pendingKeys.has(op.key)) {\n // Found an NACK op, clear it from the directory if the latest sequence number in the directory\n // match the message's and don't process the op.\n if (local) {\n assert(localOpMetadata !== undefined,\n 0x011 /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageId = localOpMetadata as number;\n const pendingKeyMessageId = this.pendingKeys.get(op.key);\n if (pendingKeyMessageId === pendingMessageId) {\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 * 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 message - The message\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 needProcessSubDirectoryOperations(\n op: IDirectorySubDirectoryOperation,\n local: boolean,\n localOpMetadata: unknown,\n ): boolean {\n if (this.pendingSubDirectories.has(op.subdirName)) {\n if (local) {\n assert(localOpMetadata !== undefined,\n 0x012 /* pendingMessageId is missing from the local client's operation */);\n const pendingMessageId = localOpMetadata as number;\n const pendingSubDirectoryMessageId = this.pendingSubDirectories.get(op.subdirName);\n if (pendingSubDirectoryMessageId === pendingMessageId) {\n this.pendingSubDirectories.delete(op.subdirName);\n }\n }\n return false;\n }\n\n return !local;\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() {\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, map) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n temp.set(key, this._storage.get(key)!);\n });\n this._storage.clear();\n temp.forEach((value, key, map) => {\n this._storage.set(key, value);\n });\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 * @param op - The message if from a remote clear, or null if from a local clear\n */\n private clearCore(local: boolean) {\n this._storage.clear();\n this.directory.emit(\"clear\", local, this.directory);\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 * @param op - The message if from a remote delete, or null if from a local delete\n * @returns True if the key existed and was deleted, false if it did not exist\n */\n private deleteCore(key: string, local: boolean) {\n const previousValue = this.get(key);\n const successfullyRemoved = this._storage.delete(key);\n if (successfullyRemoved) {\n const event: IDirectoryValueChanged = { key, path: this.absolutePath, previousValue };\n this.directory.emit(\"valueChanged\", event, local, this.directory);\n const containedEvent: IValueChanged = { key, previousValue };\n this.emit(\"containedValueChanged\", containedEvent, local, this);\n }\n return successfullyRemoved;\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 * @param op - The message if from a remote set, or null if from a local set\n */\n private setCore(key: string, value: ILocalValue, local: boolean) {\n const previousValue = this.get(key);\n this._storage.set(key, value);\n const event: IDirectoryValueChanged = { key, path: this.absolutePath, previousValue };\n this.directory.emit(\"valueChanged\", event, local, this.directory);\n const containedEvent: IValueChanged = { key, previousValue };\n this.emit(\"containedValueChanged\", containedEvent, local, this);\n }\n\n /**\n * Create subdirectory implementation used for both locally sourced creation as well as incoming remote creation.\n * @param subdirName - The name of the subdirectory being created\n * @param local - Whether the message originated from the local client\n */\n private createSubDirectoryCore(subdirName: string, local: boolean) {\n if (!this._subdirectories.has(subdirName)) {\n const absolutePath = posix.join(this.absolutePath, subdirName);\n const subDir = new SubDirectory(this.directory, this.runtime, this.serializer, absolutePath);\n this.registerEventsOnSubDirectory(subDir, subdirName);\n this._subdirectories.set(subdirName, subDir);\n this.emit(\"subDirectoryCreated\", subdirName, local, this);\n }\n }\n\n private registerEventsOnSubDirectory(subDirectory: SubDirectory, subDirName: string) {\n subDirectory.on(\"subDirectoryCreated\", (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryCreated\", posix.join(subDirName, relativePath), local, this);\n });\n subDirectory.on(\"subDirectoryDeleted\", (relativePath: string, local: boolean) => {\n this.emit(\"subDirectoryDeleted\", posix.join(subDirName, relativePath), local, this);\n });\n }\n\n /**\n * Delete subdirectory implementation used for both locally sourced creation as well as incoming remote creation.\n * @param subdirName - The name of the subdirectory being deleted\n * @param local - Whether the message originated from the local client\n * @param op - The message if from a remote delete, or null if from a local delete\n */\n private deleteSubDirectoryCore(subdirName: string, local: boolean) {\n const previousValue = this.getSubDirectory(subdirName);\n // This should make the subdirectory structure unreachable so it can be GC'd and won't appear in snapshots\n // Might want to consider cleaning out the structure more exhaustively though?\n const successfullyRemoved = this._subdirectories.delete(subdirName);\n if (previousValue !== undefined) {\n this.disposeSubDirectoryTree(previousValue);\n this.emit(\"subDirectoryDeleted\", subdirName, local, this);\n }\n return successfullyRemoved;\n }\n\n private disposeSubDirectoryTree(directory: IDirectory | undefined) {\n if (!directory) {\n return;\n }\n // Dispose the subdirectory tree. This will dispose the subdirectories from bottom to top.\n const subDirectories = directory.subdirectories();\n for (const [_, subDirectory] of subDirectories) {\n this.disposeSubDirectoryTree(subDirectory);\n }\n if (typeof directory.dispose === \"function\") {\n directory.dispose();\n }\n }\n}\n"]}