@fluidframework/map 2.70.0-361248 → 2.70.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/directory.d.ts +16 -15
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +47 -40
- package/dist/directory.js.map +1 -1
- package/dist/map.d.ts +4 -4
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +10 -4
- package/dist/map.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/lib/directory.d.ts +16 -15
- package/lib/directory.d.ts.map +1 -1
- package/lib/directory.js +48 -41
- package/lib/directory.js.map +1 -1
- package/lib/map.d.ts +4 -4
- package/lib/map.d.ts.map +1 -1
- package/lib/map.js +11 -5
- package/lib/map.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/package.json +16 -16
- package/src/directory.ts +97 -49
- package/src/map.ts +18 -11
- package/src/packageVersion.ts +1 -1
package/lib/map.d.ts
CHANGED
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import type { IChannelAttributes, IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions/internal";
|
|
6
|
-
import {
|
|
7
|
-
import type { ISummaryTreeWithStats, ITelemetryContext } from "@fluidframework/runtime-definitions/internal";
|
|
6
|
+
import type { ISummaryTreeWithStats, ITelemetryContext, IRuntimeMessageCollection } from "@fluidframework/runtime-definitions/internal";
|
|
8
7
|
import type { IFluidSerializer } from "@fluidframework/shared-object-base/internal";
|
|
9
8
|
import { SharedObject } from "@fluidframework/shared-object-base/internal";
|
|
10
9
|
import type { ISharedMap, ISharedMapEvents } from "./interfaces.js";
|
|
@@ -102,9 +101,10 @@ export declare class SharedMap extends SharedObject<ISharedMapEvents> implements
|
|
|
102
101
|
*/
|
|
103
102
|
protected applyStashedOp(content: unknown): void;
|
|
104
103
|
/**
|
|
105
|
-
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.
|
|
104
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.processMessagesCore}
|
|
106
105
|
*/
|
|
107
|
-
protected
|
|
106
|
+
protected processMessagesCore(messagesCollection: IRuntimeMessageCollection): void;
|
|
107
|
+
private processMessage;
|
|
108
108
|
/**
|
|
109
109
|
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}
|
|
110
110
|
*/
|
package/lib/map.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;
|
|
1
|
+
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACX,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACtB,MAAM,gDAAgD,CAAC;AAGxD,OAAO,KAAK,EACX,qBAAqB,EACrB,iBAAiB,EACjB,yBAAyB,EAGzB,MAAM,8CAA8C,CAAC;AAEtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAE3E,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAcpE;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY,CAAC,gBAAgB,CAAE,YAAW,UAAU;IAClF;;OAEG;IACH,SAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM,CAAe;IAE3D;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IAEnC;;;;;;OAMG;gBAEF,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB;IAY/B;;;OAGG;IACI,IAAI,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIvC;;;OAGG;IAGI,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAIjD;;;OAGG;IAGI,MAAM,IAAI,gBAAgB,CAAC,GAAG,CAAC;IAItC;;;OAGG;IAGI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAI3D;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;OAGG;IAGI,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,IAAI;IAK1F;;OAEG;IAGI,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAI/C;;;;OAIG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAK7C;;;;OAIG;IACI,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAInC;;OAEG;IACI,KAAK,IAAI,IAAI;IAIpB;;OAEG;IACH,SAAS,CAAC,aAAa,CACtB,UAAU,EAAE,gBAAgB,EAC5B,gBAAgB,CAAC,EAAE,iBAAiB,GAClC,qBAAqB;IAqExB;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxE;;OAEG;IACH,SAAS,CAAC,YAAY,IAAI,IAAI;IAE9B;;OAEG;cACgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;IAIjF;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIhD;;OAEG;cACgB,mBAAmB,CAAC,kBAAkB,EAAE,yBAAyB,GAAG,IAAI;IAO3F,OAAO,CAAC,cAAc;IAkBtB;;OAEG;cACgB,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,IAAI;CAG7E"}
|
package/lib/map.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
var _a;
|
|
6
6
|
import { assert } from "@fluidframework/core-utils/internal";
|
|
7
|
-
import { MessageType
|
|
7
|
+
import { MessageType } from "@fluidframework/driver-definitions/internal";
|
|
8
8
|
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
9
9
|
import { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
|
|
10
10
|
import { SharedObject } from "@fluidframework/shared-object-base/internal";
|
|
@@ -214,12 +214,18 @@ export class SharedMap extends SharedObject {
|
|
|
214
214
|
this.kernel.tryApplyStashedOp(content);
|
|
215
215
|
}
|
|
216
216
|
/**
|
|
217
|
-
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.
|
|
217
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.processMessagesCore}
|
|
218
218
|
*/
|
|
219
|
-
|
|
219
|
+
processMessagesCore(messagesCollection) {
|
|
220
|
+
const { envelope, local, messagesContent } = messagesCollection;
|
|
221
|
+
for (const messageContent of messagesContent) {
|
|
222
|
+
this.processMessage(envelope, messageContent, local);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
processMessage(messageEnvelope, messageContent, local) {
|
|
220
226
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
221
|
-
if (
|
|
222
|
-
assert(this.kernel.tryProcessMessage(
|
|
227
|
+
if (messageEnvelope.type === MessageType.Operation) {
|
|
228
|
+
assert(this.kernel.tryProcessMessage(messageContent.contents, local, messageContent.localOpMetadata), 0xab2 /* Map received an unrecognized op, possibly from a newer version */);
|
|
223
229
|
}
|
|
224
230
|
}
|
|
225
231
|
/**
|
package/lib/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","sourceRoot":"","sources":["../src/map.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 } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport {\n\tMessageType,\n\ttype ISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { SharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ISharedMap, ISharedMapEvents } from \"./interfaces.js\";\nimport {\n\ttype IMapDataObjectSerializable,\n\ttype IMapOperation,\n\tMapKernel,\n} from \"./mapKernel.js\";\n\ninterface IMapSerializationFormat {\n\tblobs?: string[];\n\tcontent: IMapDataObjectSerializable;\n}\n\nconst snapshotFileName = \"header\";\n\n/**\n * {@inheritDoc ISharedMap}\n */\nexport class SharedMap extends SharedObject<ISharedMapEvents> implements ISharedMap {\n\t/**\n\t * String representation for the class.\n\t */\n\tpublic readonly [Symbol.toStringTag]: string = \"SharedMap\";\n\n\t/**\n\t * MapKernel which manages actual map operations.\n\t */\n\tprivate readonly kernel: MapKernel;\n\n\t/**\n\t * Do not call the constructor. Instead, you should use the {@link SharedMap.create | create method}.\n\t *\n\t * @param id - String identifier.\n\t * @param runtime - Data store runtime.\n\t * @param attributes - The attributes for the map.\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"fluid_map_\");\n\t\tthis.kernel = new MapKernel(\n\t\t\tthis.serializer,\n\t\t\tthis.handle,\n\t\t\t(op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata),\n\t\t\t() => this.isAttached(),\n\t\t\tthis,\n\t\t);\n\t}\n\n\t/**\n\t * Get an iterator over the keys in this map.\n\t * @returns The iterator\n\t */\n\tpublic keys(): IterableIterator<string> {\n\t\treturn this.kernel.keys();\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic entries(): IterableIterator<[string, any]> {\n\t\treturn this.kernel.entries();\n\t}\n\n\t/**\n\t * Get an iterator over the values in this map.\n\t * @returns The iterator\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic values(): IterableIterator<any> {\n\t\treturn this.kernel.values();\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic [Symbol.iterator](): IterableIterator<[string, any]> {\n\t\treturn this.kernel.entries();\n\t}\n\n\t/**\n\t * The number of key/value pairs stored in the map.\n\t */\n\tpublic get size(): number {\n\t\treturn this.kernel.size;\n\t}\n\n\t/**\n\t * Executes the given callback on each entry in the map.\n\t * @param callbackFn - Callback function\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic forEach(callbackFn: (value: any, key: string, map: Map<string, any>) => void): void {\n\t\t// eslint-disable-next-line unicorn/no-array-for-each, unicorn/no-array-callback-reference\n\t\tthis.kernel.forEach(callbackFn);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.get}\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic get<T = any>(key: string): T | undefined {\n\t\treturn this.kernel.get<T>(key);\n\t}\n\n\t/**\n\t * Check if a key exists in the map.\n\t * @param key - The key to check\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this.kernel.has(key);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.set}\n\t */\n\tpublic set(key: string, value: unknown): this {\n\t\tthis.kernel.set(key, value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Delete a key from the map.\n\t * @param key - Key to delete\n\t * @returns True if the key existed and was deleted, false if it did not exist\n\t */\n\tpublic delete(key: string): boolean {\n\t\treturn this.kernel.delete(key);\n\t}\n\n\t/**\n\t * Clear all data from the map.\n\t */\n\tpublic clear(): void {\n\t\tthis.kernel.clear();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummaryTreeWithStats {\n\t\tlet currentSize = 0;\n\t\tlet counter = 0;\n\t\tlet headerBlob: IMapDataObjectSerializable = {};\n\t\tconst blobs: string[] = [];\n\n\t\tconst builder = new SummaryTreeBuilder();\n\n\t\tconst data = this.kernel.getSerializedStorage(serializer);\n\n\t\t// If single property exceeds this size, it goes into its own blob\n\t\tconst MinValueSizeSeparateSnapshotBlob = 8 * 1024;\n\n\t\t// Maximum blob size for multiple map properties\n\t\t// Should be bigger than MinValueSizeSeparateSnapshotBlob\n\t\tconst MaxSnapshotBlobSize = 16 * 1024;\n\n\t\t// Partitioning algorithm:\n\t\t// 1) Split large (over MinValueSizeSeparateSnapshotBlob = 8K) properties into their own blobs.\n\t\t// Naming (across snapshots) of such blob does not have to be stable across snapshots,\n\t\t// As de-duping process (in driver) should not care about paths, only content.\n\t\t// 2) Split remaining properties into blobs of MaxSnapshotBlobSize (16K) size.\n\t\t// This process does not produce stable partitioning. This means\n\t\t// modification (including addition / deletion) of property can shift properties across blobs\n\t\t// and result in non-incremental snapshot.\n\t\t// This can be improved in the future, without being format breaking change, as loading sequence\n\t\t// loads all blobs at once and partitioning schema has no impact on that process.\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {\n\t\t\t\tconst blobName = `blob${counter}`;\n\t\t\t\tcounter++;\n\t\t\t\tblobs.push(blobName);\n\t\t\t\tconst content: IMapDataObjectSerializable = {\n\t\t\t\t\t[key]: {\n\t\t\t\t\t\ttype: value.type,\n\t\t\t\t\t\tvalue: JSON.parse(value.value) as unknown,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tbuilder.addBlob(blobName, JSON.stringify(content));\n\t\t\t} else {\n\t\t\t\tcurrentSize += value.type.length + 21; // Approximation cost of property header\n\t\t\t\tif (value.value) {\n\t\t\t\t\tcurrentSize += value.value.length;\n\t\t\t\t}\n\n\t\t\t\tif (currentSize > MaxSnapshotBlobSize) {\n\t\t\t\t\tconst blobName = `blob${counter}`;\n\t\t\t\t\tcounter++;\n\t\t\t\t\tblobs.push(blobName);\n\t\t\t\t\tbuilder.addBlob(blobName, JSON.stringify(headerBlob));\n\t\t\t\t\theaderBlob = {};\n\t\t\t\t\tcurrentSize = 0;\n\t\t\t\t}\n\t\t\t\theaderBlob[key] = {\n\t\t\t\t\ttype: value.type,\n\t\t\t\t\tvalue: value.value === undefined ? undefined : (JSON.parse(value.value) as unknown),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst header: IMapSerializationFormat = {\n\t\t\tblobs,\n\t\t\tcontent: headerBlob,\n\t\t};\n\t\tbuilder.addBlob(snapshotFileName, JSON.stringify(header));\n\n\t\treturn builder.getSummaryTree();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst json = await readAndParse<object>(storage, snapshotFileName);\n\t\tconst newFormat = json as IMapSerializationFormat;\n\t\tif (Array.isArray(newFormat.blobs)) {\n\t\t\tthis.kernel.populateFromSerializable(newFormat.content);\n\t\t\tconst blobContents = await Promise.all(\n\t\t\t\tnewFormat.blobs.map(async (blobName) =>\n\t\t\t\t\treadAndParse<IMapDataObjectSerializable>(storage, blobName),\n\t\t\t\t),\n\t\t\t);\n\t\t\tfor (const blobContent of blobContents) {\n\t\t\t\tthis.kernel.populateFromSerializable(blobContent);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.kernel.populateFromSerializable(json as IMapDataObjectSerializable);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}\n\t */\n\tprotected override reSubmitCore(content: unknown, localOpMetadata: unknown): void {\n\t\tthis.kernel.tryResubmitMessage(content as IMapOperation, localOpMetadata);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}\n\t */\n\tprotected applyStashedOp(content: unknown): void {\n\t\tthis.kernel.tryApplyStashedOp(content as IMapOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n\t\tif (message.type === MessageType.Operation) {\n\t\t\tassert(\n\t\t\t\tthis.kernel.tryProcessMessage(\n\t\t\t\t\tmessage.contents as IMapOperation,\n\t\t\t\t\tlocal,\n\t\t\t\t\tlocalOpMetadata,\n\t\t\t\t),\n\t\t\t\t0xab2 /* Map received an unrecognized op, possibly from a newer version */,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}\n\t */\n\tprotected override rollback(content: unknown, localOpMetadata: unknown): void {\n\t\tthis.kernel.rollback(content, localOpMetadata);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../src/map.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 } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n} from \"@fluidframework/datastore-definitions/internal\";\nimport { MessageType } from \"@fluidframework/driver-definitions/internal\";\nimport { readAndParse } from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n\tIRuntimeMessageCollection,\n\tIRuntimeMessagesContent,\n\tISequencedMessageEnvelope,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils/internal\";\nimport type { IFluidSerializer } from \"@fluidframework/shared-object-base/internal\";\nimport { SharedObject } from \"@fluidframework/shared-object-base/internal\";\n\nimport type { ISharedMap, ISharedMapEvents } from \"./interfaces.js\";\nimport {\n\ttype IMapDataObjectSerializable,\n\ttype IMapOperation,\n\tMapKernel,\n} from \"./mapKernel.js\";\n\ninterface IMapSerializationFormat {\n\tblobs?: string[];\n\tcontent: IMapDataObjectSerializable;\n}\n\nconst snapshotFileName = \"header\";\n\n/**\n * {@inheritDoc ISharedMap}\n */\nexport class SharedMap extends SharedObject<ISharedMapEvents> implements ISharedMap {\n\t/**\n\t * String representation for the class.\n\t */\n\tpublic readonly [Symbol.toStringTag]: string = \"SharedMap\";\n\n\t/**\n\t * MapKernel which manages actual map operations.\n\t */\n\tprivate readonly kernel: MapKernel;\n\n\t/**\n\t * Do not call the constructor. Instead, you should use the {@link SharedMap.create | create method}.\n\t *\n\t * @param id - String identifier.\n\t * @param runtime - Data store runtime.\n\t * @param attributes - The attributes for the map.\n\t */\n\tpublic constructor(\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t) {\n\t\tsuper(id, runtime, attributes, \"fluid_map_\");\n\t\tthis.kernel = new MapKernel(\n\t\t\tthis.serializer,\n\t\t\tthis.handle,\n\t\t\t(op, localOpMetadata) => this.submitLocalMessage(op, localOpMetadata),\n\t\t\t() => this.isAttached(),\n\t\t\tthis,\n\t\t);\n\t}\n\n\t/**\n\t * Get an iterator over the keys in this map.\n\t * @returns The iterator\n\t */\n\tpublic keys(): IterableIterator<string> {\n\t\treturn this.kernel.keys();\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic entries(): IterableIterator<[string, any]> {\n\t\treturn this.kernel.entries();\n\t}\n\n\t/**\n\t * Get an iterator over the values in this map.\n\t * @returns The iterator\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic values(): IterableIterator<any> {\n\t\treturn this.kernel.values();\n\t}\n\n\t/**\n\t * Get an iterator over the entries in this map.\n\t * @returns The iterator\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic [Symbol.iterator](): IterableIterator<[string, any]> {\n\t\treturn this.kernel.entries();\n\t}\n\n\t/**\n\t * The number of key/value pairs stored in the map.\n\t */\n\tpublic get size(): number {\n\t\treturn this.kernel.size;\n\t}\n\n\t/**\n\t * Executes the given callback on each entry in the map.\n\t * @param callbackFn - Callback function\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic forEach(callbackFn: (value: any, key: string, map: Map<string, any>) => void): void {\n\t\t// eslint-disable-next-line unicorn/no-array-for-each, unicorn/no-array-callback-reference\n\t\tthis.kernel.forEach(callbackFn);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.get}\n\t */\n\t// TODO: Use `unknown` instead (breaking change).\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpublic get<T = any>(key: string): T | undefined {\n\t\treturn this.kernel.get<T>(key);\n\t}\n\n\t/**\n\t * Check if a key exists in the map.\n\t * @param key - The key to check\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this.kernel.has(key);\n\t}\n\n\t/**\n\t * {@inheritDoc ISharedMap.set}\n\t */\n\tpublic set(key: string, value: unknown): this {\n\t\tthis.kernel.set(key, value);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Delete a key from the map.\n\t * @param key - Key to delete\n\t * @returns True if the key existed and was deleted, false if it did not exist\n\t */\n\tpublic delete(key: string): boolean {\n\t\treturn this.kernel.delete(key);\n\t}\n\n\t/**\n\t * Clear all data from the map.\n\t */\n\tpublic clear(): void {\n\t\tthis.kernel.clear();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): ISummaryTreeWithStats {\n\t\tlet currentSize = 0;\n\t\tlet counter = 0;\n\t\tlet headerBlob: IMapDataObjectSerializable = {};\n\t\tconst blobs: string[] = [];\n\n\t\tconst builder = new SummaryTreeBuilder();\n\n\t\tconst data = this.kernel.getSerializedStorage(serializer);\n\n\t\t// If single property exceeds this size, it goes into its own blob\n\t\tconst MinValueSizeSeparateSnapshotBlob = 8 * 1024;\n\n\t\t// Maximum blob size for multiple map properties\n\t\t// Should be bigger than MinValueSizeSeparateSnapshotBlob\n\t\tconst MaxSnapshotBlobSize = 16 * 1024;\n\n\t\t// Partitioning algorithm:\n\t\t// 1) Split large (over MinValueSizeSeparateSnapshotBlob = 8K) properties into their own blobs.\n\t\t// Naming (across snapshots) of such blob does not have to be stable across snapshots,\n\t\t// As de-duping process (in driver) should not care about paths, only content.\n\t\t// 2) Split remaining properties into blobs of MaxSnapshotBlobSize (16K) size.\n\t\t// This process does not produce stable partitioning. This means\n\t\t// modification (including addition / deletion) of property can shift properties across blobs\n\t\t// and result in non-incremental snapshot.\n\t\t// This can be improved in the future, without being format breaking change, as loading sequence\n\t\t// loads all blobs at once and partitioning schema has no impact on that process.\n\t\tfor (const [key, value] of Object.entries(data)) {\n\t\t\tif (value.value && value.value.length >= MinValueSizeSeparateSnapshotBlob) {\n\t\t\t\tconst blobName = `blob${counter}`;\n\t\t\t\tcounter++;\n\t\t\t\tblobs.push(blobName);\n\t\t\t\tconst content: IMapDataObjectSerializable = {\n\t\t\t\t\t[key]: {\n\t\t\t\t\t\ttype: value.type,\n\t\t\t\t\t\tvalue: JSON.parse(value.value) as unknown,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tbuilder.addBlob(blobName, JSON.stringify(content));\n\t\t\t} else {\n\t\t\t\tcurrentSize += value.type.length + 21; // Approximation cost of property header\n\t\t\t\tif (value.value) {\n\t\t\t\t\tcurrentSize += value.value.length;\n\t\t\t\t}\n\n\t\t\t\tif (currentSize > MaxSnapshotBlobSize) {\n\t\t\t\t\tconst blobName = `blob${counter}`;\n\t\t\t\t\tcounter++;\n\t\t\t\t\tblobs.push(blobName);\n\t\t\t\t\tbuilder.addBlob(blobName, JSON.stringify(headerBlob));\n\t\t\t\t\theaderBlob = {};\n\t\t\t\t\tcurrentSize = 0;\n\t\t\t\t}\n\t\t\t\theaderBlob[key] = {\n\t\t\t\t\ttype: value.type,\n\t\t\t\t\tvalue: value.value === undefined ? undefined : (JSON.parse(value.value) as unknown),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tconst header: IMapSerializationFormat = {\n\t\t\tblobs,\n\t\t\tcontent: headerBlob,\n\t\t};\n\t\tbuilder.addBlob(snapshotFileName, JSON.stringify(header));\n\n\t\treturn builder.getSummaryTree();\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst json = await readAndParse<object>(storage, snapshotFileName);\n\t\tconst newFormat = json as IMapSerializationFormat;\n\t\tif (Array.isArray(newFormat.blobs)) {\n\t\t\tthis.kernel.populateFromSerializable(newFormat.content);\n\t\t\tconst blobContents = await Promise.all(\n\t\t\t\tnewFormat.blobs.map(async (blobName) =>\n\t\t\t\t\treadAndParse<IMapDataObjectSerializable>(storage, blobName),\n\t\t\t\t),\n\t\t\t);\n\t\t\tfor (const blobContent of blobContents) {\n\t\t\t\tthis.kernel.populateFromSerializable(blobContent);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.kernel.populateFromSerializable(json as IMapDataObjectSerializable);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.reSubmitCore}\n\t */\n\tprotected override reSubmitCore(content: unknown, localOpMetadata: unknown): void {\n\t\tthis.kernel.tryResubmitMessage(content as IMapOperation, localOpMetadata);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObjectCore.applyStashedOp}\n\t */\n\tprotected applyStashedOp(content: unknown): void {\n\t\tthis.kernel.tryApplyStashedOp(content as IMapOperation);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processMessagesCore}\n\t */\n\tprotected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {\n\t\tconst { envelope, local, messagesContent } = messagesCollection;\n\t\tfor (const messageContent of messagesContent) {\n\t\t\tthis.processMessage(envelope, messageContent, local);\n\t\t}\n\t}\n\n\tprivate processMessage(\n\t\tmessageEnvelope: ISequencedMessageEnvelope,\n\t\tmessageContent: IRuntimeMessagesContent,\n\t\tlocal: boolean,\n\t): void {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n\t\tif (messageEnvelope.type === MessageType.Operation) {\n\t\t\tassert(\n\t\t\t\tthis.kernel.tryProcessMessage(\n\t\t\t\t\tmessageContent.contents as IMapOperation,\n\t\t\t\t\tlocal,\n\t\t\t\t\tmessageContent.localOpMetadata,\n\t\t\t\t),\n\t\t\t\t0xab2 /* Map received an unrecognized op, possibly from a newer version */,\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.rollback}\n\t */\n\tprotected override rollback(content: unknown, localOpMetadata: unknown): void {\n\t\tthis.kernel.rollback(content, localOpMetadata);\n\t}\n}\n"]}
|
package/lib/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/map";
|
|
8
|
-
export declare const pkgVersion = "2.70.0
|
|
8
|
+
export declare const pkgVersion = "2.70.0";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAC7C,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,wBAAwB,CAAC;AAC7C,eAAO,MAAM,UAAU,WAAW,CAAC"}
|
package/lib/packageVersion.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,qBAAqB,CAAC;AAC7C,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/map\";\nexport const pkgVersion = \"2.70.0\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/map",
|
|
3
|
-
"version": "2.70.0
|
|
3
|
+
"version": "2.70.0",
|
|
4
4
|
"description": "Distributed map",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -81,32 +81,32 @@
|
|
|
81
81
|
"temp-directory": "nyc/.nyc_output"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@fluid-internal/client-utils": "2.70.0
|
|
85
|
-
"@fluidframework/core-interfaces": "2.70.0
|
|
86
|
-
"@fluidframework/core-utils": "2.70.0
|
|
87
|
-
"@fluidframework/datastore-definitions": "2.70.0
|
|
88
|
-
"@fluidframework/driver-definitions": "2.70.0
|
|
89
|
-
"@fluidframework/driver-utils": "2.70.0
|
|
90
|
-
"@fluidframework/runtime-definitions": "2.70.0
|
|
91
|
-
"@fluidframework/runtime-utils": "2.70.0
|
|
92
|
-
"@fluidframework/shared-object-base": "2.70.0
|
|
93
|
-
"@fluidframework/telemetry-utils": "2.70.0
|
|
84
|
+
"@fluid-internal/client-utils": "~2.70.0",
|
|
85
|
+
"@fluidframework/core-interfaces": "~2.70.0",
|
|
86
|
+
"@fluidframework/core-utils": "~2.70.0",
|
|
87
|
+
"@fluidframework/datastore-definitions": "~2.70.0",
|
|
88
|
+
"@fluidframework/driver-definitions": "~2.70.0",
|
|
89
|
+
"@fluidframework/driver-utils": "~2.70.0",
|
|
90
|
+
"@fluidframework/runtime-definitions": "~2.70.0",
|
|
91
|
+
"@fluidframework/runtime-utils": "~2.70.0",
|
|
92
|
+
"@fluidframework/shared-object-base": "~2.70.0",
|
|
93
|
+
"@fluidframework/telemetry-utils": "~2.70.0",
|
|
94
94
|
"path-browserify": "^1.0.1"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
97
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
98
98
|
"@biomejs/biome": "~1.9.3",
|
|
99
|
-
"@fluid-internal/mocha-test-setup": "2.70.0
|
|
100
|
-
"@fluid-private/stochastic-test-utils": "2.70.0
|
|
101
|
-
"@fluid-private/test-dds-utils": "2.70.0
|
|
99
|
+
"@fluid-internal/mocha-test-setup": "~2.70.0",
|
|
100
|
+
"@fluid-private/stochastic-test-utils": "~2.70.0",
|
|
101
|
+
"@fluid-private/test-dds-utils": "~2.70.0",
|
|
102
102
|
"@fluid-tools/benchmark": "^0.51.0",
|
|
103
103
|
"@fluid-tools/build-cli": "^0.58.3",
|
|
104
104
|
"@fluidframework/build-common": "^2.0.3",
|
|
105
105
|
"@fluidframework/build-tools": "^0.58.3",
|
|
106
|
-
"@fluidframework/container-definitions": "2.70.0
|
|
106
|
+
"@fluidframework/container-definitions": "~2.70.0",
|
|
107
107
|
"@fluidframework/eslint-config-fluid": "^6.1.0",
|
|
108
108
|
"@fluidframework/map-previous": "npm:@fluidframework/map@2.63.0",
|
|
109
|
-
"@fluidframework/test-runtime-utils": "2.70.0
|
|
109
|
+
"@fluidframework/test-runtime-utils": "~2.70.0",
|
|
110
110
|
"@microsoft/api-extractor": "7.52.11",
|
|
111
111
|
"@types/mocha": "^10.0.10",
|
|
112
112
|
"@types/node": "^18.19.0",
|
package/src/directory.ts
CHANGED
|
@@ -10,14 +10,14 @@ import type {
|
|
|
10
10
|
IFluidDataStoreRuntime,
|
|
11
11
|
IChannelStorageService,
|
|
12
12
|
} from "@fluidframework/datastore-definitions/internal";
|
|
13
|
-
import {
|
|
14
|
-
MessageType,
|
|
15
|
-
type ISequencedDocumentMessage,
|
|
16
|
-
} from "@fluidframework/driver-definitions/internal";
|
|
13
|
+
import { MessageType } from "@fluidframework/driver-definitions/internal";
|
|
17
14
|
import { readAndParse } from "@fluidframework/driver-utils/internal";
|
|
18
15
|
import type {
|
|
19
16
|
ISummaryTreeWithStats,
|
|
20
17
|
ITelemetryContext,
|
|
18
|
+
IRuntimeMessageCollection,
|
|
19
|
+
IRuntimeMessagesContent,
|
|
20
|
+
ISequencedMessageEnvelope,
|
|
21
21
|
} from "@fluidframework/runtime-definitions/internal";
|
|
22
22
|
import { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
|
|
23
23
|
import type { IFluidSerializer } from "@fluidframework/shared-object-base/internal";
|
|
@@ -63,17 +63,19 @@ const snapshotFileName = "header";
|
|
|
63
63
|
interface IDirectoryMessageHandler {
|
|
64
64
|
/**
|
|
65
65
|
* Apply the given operation.
|
|
66
|
-
* @param
|
|
66
|
+
* @param msgEnvelope - The envelope of the message from the server to apply.
|
|
67
67
|
* @param op - The directory operation to apply
|
|
68
68
|
* @param local - Whether the message originated from the local client
|
|
69
69
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
70
70
|
* For messages from a remote client, this will be undefined.
|
|
71
|
+
* @param clientSequenceNumber - The client sequence number of the message.
|
|
71
72
|
*/
|
|
72
73
|
process(
|
|
73
|
-
|
|
74
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
74
75
|
op: IDirectoryOperation,
|
|
75
76
|
local: boolean,
|
|
76
77
|
localOpMetadata: DirectoryLocalOpMetadata | undefined,
|
|
78
|
+
clientSequenceNumber: number,
|
|
77
79
|
): void;
|
|
78
80
|
|
|
79
81
|
/**
|
|
@@ -785,22 +787,35 @@ export class SharedDirectory
|
|
|
785
787
|
}
|
|
786
788
|
|
|
787
789
|
/**
|
|
788
|
-
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.
|
|
790
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.processMessagesCore}
|
|
789
791
|
*/
|
|
790
|
-
protected
|
|
791
|
-
|
|
792
|
+
protected override processMessagesCore(messagesCollection: IRuntimeMessageCollection): void {
|
|
793
|
+
const { envelope, local, messagesContent } = messagesCollection;
|
|
794
|
+
for (const messageContent of messagesContent) {
|
|
795
|
+
this.processMessage(envelope, messageContent, local);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
private processMessage(
|
|
800
|
+
messageEnvelope: ISequencedMessageEnvelope,
|
|
801
|
+
messageContent: IRuntimeMessagesContent,
|
|
792
802
|
local: boolean,
|
|
793
|
-
localOpMetadata: DirectoryLocalOpMetadata | undefined,
|
|
794
803
|
): void {
|
|
795
804
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
|
|
796
|
-
if (
|
|
797
|
-
const op: IDirectoryOperation =
|
|
805
|
+
if (messageEnvelope.type === MessageType.Operation) {
|
|
806
|
+
const op: IDirectoryOperation = messageContent.contents as IDirectoryOperation;
|
|
798
807
|
const handler = this.messageHandlers.get(op.type);
|
|
799
808
|
assert(
|
|
800
809
|
handler !== undefined,
|
|
801
810
|
0x00e /* "Missing message handler for message type: op may be from a newer version */,
|
|
802
811
|
);
|
|
803
|
-
handler.process(
|
|
812
|
+
handler.process(
|
|
813
|
+
messageEnvelope,
|
|
814
|
+
op,
|
|
815
|
+
local,
|
|
816
|
+
messageContent.localOpMetadata as DirectoryLocalOpMetadata | undefined,
|
|
817
|
+
messageContent.clientSequenceNumber,
|
|
818
|
+
);
|
|
804
819
|
}
|
|
805
820
|
}
|
|
806
821
|
|
|
@@ -838,14 +853,15 @@ export class SharedDirectory
|
|
|
838
853
|
// the op was originally targeting.
|
|
839
854
|
this.messageHandlers.set("clear", {
|
|
840
855
|
process: (
|
|
841
|
-
|
|
856
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
842
857
|
op: IDirectoryClearOperation,
|
|
843
858
|
local: boolean,
|
|
844
859
|
localOpMetadata: ClearLocalOpMetadata | undefined,
|
|
860
|
+
clientSequenceNumber: number,
|
|
845
861
|
) => {
|
|
846
862
|
const subdir = this.getSequencedWorkingDirectory(op.path) as SubDirectory | undefined;
|
|
847
863
|
if (subdir !== undefined && !subdir?.disposed) {
|
|
848
|
-
subdir.processClearMessage(
|
|
864
|
+
subdir.processClearMessage(msgEnvelope, op, local, localOpMetadata);
|
|
849
865
|
}
|
|
850
866
|
},
|
|
851
867
|
resubmit: (op: IDirectoryClearOperation, localOpMetadata: ClearLocalOpMetadata) => {
|
|
@@ -857,14 +873,15 @@ export class SharedDirectory
|
|
|
857
873
|
});
|
|
858
874
|
this.messageHandlers.set("delete", {
|
|
859
875
|
process: (
|
|
860
|
-
|
|
876
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
861
877
|
op: IDirectoryDeleteOperation,
|
|
862
878
|
local: boolean,
|
|
863
879
|
localOpMetadata: EditLocalOpMetadata | undefined,
|
|
880
|
+
clientSequenceNumber: number,
|
|
864
881
|
) => {
|
|
865
882
|
const subdir = this.getSequencedWorkingDirectory(op.path) as SubDirectory | undefined;
|
|
866
883
|
if (subdir !== undefined && !subdir?.disposed) {
|
|
867
|
-
subdir.processDeleteMessage(
|
|
884
|
+
subdir.processDeleteMessage(msgEnvelope, op, local, localOpMetadata);
|
|
868
885
|
}
|
|
869
886
|
},
|
|
870
887
|
resubmit: (op: IDirectoryDeleteOperation, localOpMetadata: EditLocalOpMetadata) => {
|
|
@@ -876,16 +893,17 @@ export class SharedDirectory
|
|
|
876
893
|
});
|
|
877
894
|
this.messageHandlers.set("set", {
|
|
878
895
|
process: (
|
|
879
|
-
|
|
896
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
880
897
|
op: IDirectorySetOperation,
|
|
881
898
|
local: boolean,
|
|
882
899
|
localOpMetadata: EditLocalOpMetadata | undefined,
|
|
900
|
+
clientSequenceNumber: number,
|
|
883
901
|
) => {
|
|
884
902
|
const subdir = this.getSequencedWorkingDirectory(op.path) as SubDirectory | undefined;
|
|
885
903
|
if (subdir !== undefined && !subdir?.disposed) {
|
|
886
904
|
migrateIfSharedSerializable(op.value, this.serializer, this.handle);
|
|
887
905
|
const localValue: unknown = local ? undefined : op.value.value;
|
|
888
|
-
subdir.processSetMessage(
|
|
906
|
+
subdir.processSetMessage(msgEnvelope, op, localValue, local, localOpMetadata);
|
|
889
907
|
}
|
|
890
908
|
},
|
|
891
909
|
resubmit: (op: IDirectorySetOperation, localOpMetadata: EditLocalOpMetadata) => {
|
|
@@ -898,16 +916,23 @@ export class SharedDirectory
|
|
|
898
916
|
|
|
899
917
|
this.messageHandlers.set("createSubDirectory", {
|
|
900
918
|
process: (
|
|
901
|
-
|
|
919
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
902
920
|
op: IDirectoryCreateSubDirectoryOperation,
|
|
903
921
|
local: boolean,
|
|
904
922
|
localOpMetadata: SubDirLocalOpMetadata | undefined,
|
|
923
|
+
clientSequenceNumber: number,
|
|
905
924
|
) => {
|
|
906
925
|
const parentSubdir = this.getSequencedWorkingDirectory(op.path) as
|
|
907
926
|
| SubDirectory
|
|
908
927
|
| undefined;
|
|
909
928
|
if (parentSubdir !== undefined && !parentSubdir?.disposed) {
|
|
910
|
-
parentSubdir.processCreateSubDirectoryMessage(
|
|
929
|
+
parentSubdir.processCreateSubDirectoryMessage(
|
|
930
|
+
msgEnvelope,
|
|
931
|
+
op,
|
|
932
|
+
local,
|
|
933
|
+
localOpMetadata,
|
|
934
|
+
clientSequenceNumber,
|
|
935
|
+
);
|
|
911
936
|
}
|
|
912
937
|
},
|
|
913
938
|
resubmit: (
|
|
@@ -924,7 +949,7 @@ export class SharedDirectory
|
|
|
924
949
|
|
|
925
950
|
this.messageHandlers.set("deleteSubDirectory", {
|
|
926
951
|
process: (
|
|
927
|
-
|
|
952
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
928
953
|
op: IDirectoryDeleteSubDirectoryOperation,
|
|
929
954
|
local: boolean,
|
|
930
955
|
localOpMetadata: SubDirLocalOpMetadata | undefined,
|
|
@@ -933,7 +958,12 @@ export class SharedDirectory
|
|
|
933
958
|
| SubDirectory
|
|
934
959
|
| undefined;
|
|
935
960
|
if (parentSubdir !== undefined && !parentSubdir?.disposed) {
|
|
936
|
-
parentSubdir.processDeleteSubDirectoryMessage(
|
|
961
|
+
parentSubdir.processDeleteSubDirectoryMessage(
|
|
962
|
+
msgEnvelope,
|
|
963
|
+
op,
|
|
964
|
+
local,
|
|
965
|
+
localOpMetadata,
|
|
966
|
+
);
|
|
937
967
|
}
|
|
938
968
|
},
|
|
939
969
|
resubmit: (
|
|
@@ -1834,20 +1864,22 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
1834
1864
|
|
|
1835
1865
|
/**
|
|
1836
1866
|
* Process a clear operation.
|
|
1837
|
-
* @param
|
|
1867
|
+
* @param msgEnvelope - The envelope of the message from the server to apply.
|
|
1838
1868
|
* @param op - The op to process
|
|
1839
1869
|
* @param local - Whether the message originated from the local client
|
|
1840
1870
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
1841
1871
|
* For messages from a remote client, this will be undefined.
|
|
1842
1872
|
*/
|
|
1843
1873
|
public processClearMessage(
|
|
1844
|
-
|
|
1874
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
1845
1875
|
op: IDirectoryClearOperation,
|
|
1846
1876
|
local: boolean,
|
|
1847
1877
|
localOpMetadata: ClearLocalOpMetadata | undefined,
|
|
1848
1878
|
): void {
|
|
1849
1879
|
this.throwIfDisposed();
|
|
1850
|
-
if (
|
|
1880
|
+
if (
|
|
1881
|
+
!this.isMessageForCurrentInstanceOfSubDirectory(msgEnvelope, localOpMetadata?.subdir)
|
|
1882
|
+
) {
|
|
1851
1883
|
return;
|
|
1852
1884
|
}
|
|
1853
1885
|
|
|
@@ -1894,20 +1926,22 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
1894
1926
|
|
|
1895
1927
|
/**
|
|
1896
1928
|
* Process a delete operation.
|
|
1897
|
-
* @param
|
|
1929
|
+
* @param msgEnvelope - The envelope of the message from the server to apply.
|
|
1898
1930
|
* @param op - The op to process
|
|
1899
1931
|
* @param local - Whether the message originated from the local client
|
|
1900
1932
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
1901
1933
|
* For messages from a remote client, this will be undefined.
|
|
1902
1934
|
*/
|
|
1903
1935
|
public processDeleteMessage(
|
|
1904
|
-
|
|
1936
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
1905
1937
|
op: IDirectoryDeleteOperation,
|
|
1906
1938
|
local: boolean,
|
|
1907
1939
|
localOpMetadata: EditLocalOpMetadata | undefined,
|
|
1908
1940
|
): void {
|
|
1909
1941
|
this.throwIfDisposed();
|
|
1910
|
-
if (
|
|
1942
|
+
if (
|
|
1943
|
+
!this.isMessageForCurrentInstanceOfSubDirectory(msgEnvelope, localOpMetadata?.subdir)
|
|
1944
|
+
) {
|
|
1911
1945
|
return;
|
|
1912
1946
|
}
|
|
1913
1947
|
if (local) {
|
|
@@ -1946,21 +1980,23 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
1946
1980
|
|
|
1947
1981
|
/**
|
|
1948
1982
|
* Process a set operation.
|
|
1949
|
-
* @param
|
|
1983
|
+
* @param msgEnvelope - The envelope of the message from the server to apply.
|
|
1950
1984
|
* @param op - The op to process
|
|
1951
1985
|
* @param local - Whether the message originated from the local client
|
|
1952
1986
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
1953
1987
|
* For messages from a remote client, this will be undefined.
|
|
1954
1988
|
*/
|
|
1955
1989
|
public processSetMessage(
|
|
1956
|
-
|
|
1990
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
1957
1991
|
op: IDirectorySetOperation,
|
|
1958
1992
|
value: unknown,
|
|
1959
1993
|
local: boolean,
|
|
1960
1994
|
localOpMetadata: EditLocalOpMetadata | undefined,
|
|
1961
1995
|
): void {
|
|
1962
1996
|
this.throwIfDisposed();
|
|
1963
|
-
if (
|
|
1997
|
+
if (
|
|
1998
|
+
!this.isMessageForCurrentInstanceOfSubDirectory(msgEnvelope, localOpMetadata?.subdir)
|
|
1999
|
+
) {
|
|
1964
2000
|
return;
|
|
1965
2001
|
}
|
|
1966
2002
|
|
|
@@ -2003,24 +2039,31 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
2003
2039
|
|
|
2004
2040
|
/**
|
|
2005
2041
|
* Process a create subdirectory operation.
|
|
2006
|
-
* @param
|
|
2042
|
+
* @param msgEnvelope - The envelope of the message from the server to apply.
|
|
2007
2043
|
* @param op - The op to process
|
|
2008
2044
|
* @param local - Whether the message originated from the local client
|
|
2009
2045
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
2010
2046
|
* For messages from a remote client, this will be undefined.
|
|
2047
|
+
* @param clientSequenceNumber - The client sequence number of the message.
|
|
2011
2048
|
*/
|
|
2012
2049
|
public processCreateSubDirectoryMessage(
|
|
2013
|
-
|
|
2050
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
2014
2051
|
op: IDirectoryCreateSubDirectoryOperation,
|
|
2015
2052
|
local: boolean,
|
|
2016
2053
|
localOpMetadata: SubDirLocalOpMetadata | undefined,
|
|
2054
|
+
clientSequenceNumber: number,
|
|
2017
2055
|
): void {
|
|
2018
2056
|
this.throwIfDisposed();
|
|
2019
2057
|
|
|
2020
|
-
if (
|
|
2058
|
+
if (
|
|
2059
|
+
!this.isMessageForCurrentInstanceOfSubDirectory(
|
|
2060
|
+
msgEnvelope,
|
|
2061
|
+
localOpMetadata?.parentSubdir,
|
|
2062
|
+
)
|
|
2063
|
+
) {
|
|
2021
2064
|
return;
|
|
2022
2065
|
}
|
|
2023
|
-
assertNonNullClientId(
|
|
2066
|
+
assertNonNullClientId(msgEnvelope.clientId);
|
|
2024
2067
|
|
|
2025
2068
|
let subDir: SubDirectory | undefined;
|
|
2026
2069
|
if (local) {
|
|
@@ -2053,8 +2096,8 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
2053
2096
|
if (subDir === undefined) {
|
|
2054
2097
|
const absolutePath = posix.join(this.absolutePath, op.subdirName);
|
|
2055
2098
|
subDir = new SubDirectory(
|
|
2056
|
-
{ seq:
|
|
2057
|
-
new Set([
|
|
2099
|
+
{ seq: msgEnvelope.sequenceNumber, clientSeq: clientSequenceNumber },
|
|
2100
|
+
new Set([msgEnvelope.clientId]),
|
|
2058
2101
|
this.directory,
|
|
2059
2102
|
this.runtime,
|
|
2060
2103
|
this.serializer,
|
|
@@ -2067,7 +2110,7 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
2067
2110
|
if (subDir.disposed) {
|
|
2068
2111
|
this.undisposeSubdirectoryTree(subDir);
|
|
2069
2112
|
}
|
|
2070
|
-
subDir.clientIds.add(
|
|
2113
|
+
subDir.clientIds.add(msgEnvelope.clientId);
|
|
2071
2114
|
}
|
|
2072
2115
|
this.registerEventsOnSubDirectory(subDir, op.subdirName);
|
|
2073
2116
|
this._sequencedSubdirectories.set(op.subdirName, subDir);
|
|
@@ -2082,30 +2125,35 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
2082
2125
|
// then later recreated.
|
|
2083
2126
|
if (
|
|
2084
2127
|
this.seqData.seq !== -1 &&
|
|
2085
|
-
this.seqData.seq <=
|
|
2128
|
+
this.seqData.seq <= msgEnvelope.sequenceNumber &&
|
|
2086
2129
|
subDir.seqData.seq === -1
|
|
2087
2130
|
) {
|
|
2088
|
-
subDir.seqData.seq =
|
|
2089
|
-
subDir.seqData.clientSeq =
|
|
2131
|
+
subDir.seqData.seq = msgEnvelope.sequenceNumber;
|
|
2132
|
+
subDir.seqData.clientSeq = clientSequenceNumber;
|
|
2090
2133
|
}
|
|
2091
2134
|
}
|
|
2092
2135
|
|
|
2093
2136
|
/**
|
|
2094
2137
|
* Process a delete subdirectory operation.
|
|
2095
|
-
* @param
|
|
2138
|
+
* @param msgEnvelope - The envelope of the message from the server to apply.
|
|
2096
2139
|
* @param op - The op to process
|
|
2097
2140
|
* @param local - Whether the message originated from the local client
|
|
2098
2141
|
* @param localOpMetadata - For local client messages, this is the metadata that was submitted with the message.
|
|
2099
2142
|
* For messages from a remote client, this will be undefined.
|
|
2100
2143
|
*/
|
|
2101
2144
|
public processDeleteSubDirectoryMessage(
|
|
2102
|
-
|
|
2145
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
2103
2146
|
op: IDirectoryDeleteSubDirectoryOperation,
|
|
2104
2147
|
local: boolean,
|
|
2105
2148
|
localOpMetadata: SubDirLocalOpMetadata | undefined,
|
|
2106
2149
|
): void {
|
|
2107
2150
|
this.throwIfDisposed();
|
|
2108
|
-
if (
|
|
2151
|
+
if (
|
|
2152
|
+
!this.isMessageForCurrentInstanceOfSubDirectory(
|
|
2153
|
+
msgEnvelope,
|
|
2154
|
+
localOpMetadata?.parentSubdir,
|
|
2155
|
+
)
|
|
2156
|
+
) {
|
|
2109
2157
|
return;
|
|
2110
2158
|
}
|
|
2111
2159
|
|
|
@@ -2517,11 +2565,11 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
2517
2565
|
/**
|
|
2518
2566
|
* This return true if the message is for the current instance of this sub directory. As the sub directory
|
|
2519
2567
|
* can be deleted and created again, then this finds if the message is for current instance of directory or not.
|
|
2520
|
-
* @param
|
|
2568
|
+
* @param msgEnvelope - message envelope for the directory
|
|
2521
2569
|
* @param targetSubdir - subdirectory instance we are targeting from local op metadata (if a local op)
|
|
2522
2570
|
*/
|
|
2523
2571
|
private isMessageForCurrentInstanceOfSubDirectory(
|
|
2524
|
-
|
|
2572
|
+
msgEnvelope: ISequencedMessageEnvelope,
|
|
2525
2573
|
targetSubdir?: SubDirectory | undefined,
|
|
2526
2574
|
): boolean {
|
|
2527
2575
|
// The message must be from this instance of the directory (if a local op) AND one of the following must be true:
|
|
@@ -2530,9 +2578,9 @@ class SubDirectory extends TypedEventEmitter<IDirectoryEvents> implements IDirec
|
|
|
2530
2578
|
// 3. This directory was already live (known to other clients) and the op was created after the directory was created.
|
|
2531
2579
|
return (
|
|
2532
2580
|
(targetSubdir === undefined || targetSubdir === this) &&
|
|
2533
|
-
((
|
|
2581
|
+
((msgEnvelope.clientId !== null && this.clientIds.has(msgEnvelope.clientId)) ||
|
|
2534
2582
|
this.clientIds.has("detached") ||
|
|
2535
|
-
(this.seqData.seq !== -1 && this.seqData.seq <=
|
|
2583
|
+
(this.seqData.seq !== -1 && this.seqData.seq <= msgEnvelope.referenceSequenceNumber))
|
|
2536
2584
|
);
|
|
2537
2585
|
}
|
|
2538
2586
|
|