@fluidframework/datastore 2.0.0-rc.1.0.7 → 2.0.0-rc.1.0.8
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/dist/localChannelContext.d.ts.map +1 -1
- package/dist/localChannelContext.js +17 -5
- package/dist/localChannelContext.js.map +1 -1
- package/lib/localChannelContext.d.mts.map +1 -1
- package/lib/localChannelContext.mjs +17 -2
- package/lib/localChannelContext.mjs.map +1 -1
- package/package.json +13 -14
- package/src/localChannelContext.ts +18 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localChannelContext.d.ts","sourceRoot":"","sources":["../src/localChannelContext.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuB,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAChG,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,EACN,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAU,IAAI,EAAe,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"localChannelContext.d.ts","sourceRoot":"","sources":["../src/localChannelContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,10 @@
|
|
|
3
3
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
-
};
|
|
9
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
7
|
exports.LocalChannelContext = exports.RehydratedLocalChannelContext = exports.LocalChannelContextBase = void 0;
|
|
11
8
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
12
9
|
const core_utils_1 = require("@fluidframework/core-utils");
|
|
13
|
-
const structured_clone_1 = __importDefault(require("@ungap/structured-clone"));
|
|
14
10
|
const channelContext_1 = require("./channelContext");
|
|
15
11
|
/**
|
|
16
12
|
* Channel context for a locally created channel
|
|
@@ -130,7 +126,7 @@ class RehydratedLocalChannelContext extends LocalChannelContextBase {
|
|
|
130
126
|
constructor(id, registry, runtime, dataStoreContext, storageService, logger, submitFn, dirtyFn, addedGCOutboundReferenceFn, snapshotTree) {
|
|
131
127
|
super(id, runtime, new core_utils_1.Lazy(() => {
|
|
132
128
|
const blobMap = new Map();
|
|
133
|
-
const clonedSnapshotTree = (
|
|
129
|
+
const clonedSnapshotTree = cloneSnapshotTree(this.snapshotTree);
|
|
134
130
|
// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.
|
|
135
131
|
// This is for older snapshot which is generated by loader <=0.47 version which still contains
|
|
136
132
|
// the contents within blobs. After a couple of revisions we can remove it.
|
|
@@ -201,4 +197,20 @@ class LocalChannelContext extends LocalChannelContextBase {
|
|
|
201
197
|
}
|
|
202
198
|
}
|
|
203
199
|
exports.LocalChannelContext = LocalChannelContext;
|
|
200
|
+
/**
|
|
201
|
+
* Deep clones a snapshot tree.
|
|
202
|
+
*
|
|
203
|
+
* TODO: Investigate replacing this with a deep clone utility.
|
|
204
|
+
* This is a temporary solution to avoid issues with lodash deepClone and ungap structuredClone.
|
|
205
|
+
* Using lodash caused a significant bundle size regression. structuredClone cannot be used since
|
|
206
|
+
* it does not support ArrayBuffer data types, and ISnapshotTree can contain blobContents properties,
|
|
207
|
+
* which are ArrayBuffer data types.
|
|
208
|
+
*/
|
|
209
|
+
function cloneSnapshotTree(tree) {
|
|
210
|
+
const clone = { ...tree, blobs: { ...tree.blobs }, trees: {} };
|
|
211
|
+
for (const [k, v] of Object.entries(tree.trees)) {
|
|
212
|
+
clone.trees[k] = cloneSnapshotTree(v);
|
|
213
|
+
}
|
|
214
|
+
return clone;
|
|
215
|
+
}
|
|
204
216
|
//# sourceMappingURL=localChannelContext.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localChannelContext.js","sourceRoot":"","sources":["../src/localChannelContext.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 { DataProcessingError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport {\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/core-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport structuredClone from \"@ungap/structured-clone\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannel,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n\tprivate globallyVisible = false;\n\tprotected readonly pending: ISequencedDocumentMessage[] = [];\n\tconstructor(\n\t\tprotected readonly id: string,\n\t\tprotected readonly runtime: IFluidDataStoreRuntime,\n\t\tprotected readonly services: Lazy<ChannelServiceEndpoints>,\n\t\tprivate readonly channelP: Promise<IChannel>,\n\t\tprivate _channel?: IChannel,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x30f /* Channel context ID cannot contain slashes */);\n\t}\n\n\tpublic async getChannel(): Promise<IChannel> {\n\t\tif (this._channel === undefined) {\n\t\t\treturn this.channelP.then((c) => (this._channel = c));\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tpublic get isLoaded(): boolean {\n\t\treturn this._channel !== undefined;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet globallyVisible or loaded\n\t\tif (this.globallyVisible && this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.setConnectionState(connected);\n\t\t}\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d3 /* \"Local channel must be globally visible when processing op\" */,\n\t\t);\n\n\t\t// A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n\t\t// delay loading. So after the container is attached and some other client joins which start generating\n\t\t// ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tlocal === false,\n\t\t\t\t0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */,\n\t\t\t);\n\t\t\tthis.pending.push(message);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2ee /* \"Channel should be loaded to rollback ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2ef /* \"Local channel must be globally visible when rolling back op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp() {\n\t\tthrow new Error(\"no stashed ops on local channel\");\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = false,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\tconst channel = await this.getChannel();\n\t\treturn summarizeChannelAsync(channel, fullTree, trackState, telemetryContext);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach summary to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummarizeResult {\n\t\tassert(\n\t\t\tthis._channel !== undefined,\n\t\t\t0x18d /* \"Channel should be loaded to take snapshot\" */,\n\t\t);\n\t\treturn summarizeChannel(\n\t\t\tthis._channel,\n\t\t\ttrue /* fullTree */,\n\t\t\tfalse /* trackState */,\n\t\t\ttelemetryContext,\n\t\t);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach GC data (set of outbound routes in the initial state)\n\t * to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tassert(this._channel !== undefined, \"Local Channel should be loaded before being attached\");\n\n\t\t// We need the GC Data to detect references added in this attach op\n\t\treturn this._channel.getGCData(/* fullGC: */ true);\n\t}\n\n\tpublic makeVisible(): void {\n\t\tif (this.globallyVisible) {\n\t\t\tthrow new Error(\"Channel is already globally visible\");\n\t\t}\n\n\t\tif (this.isLoaded) {\n\t\t\tassert(!!this._channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n\t\t\tthis._channel.connect(this.services.value);\n\t\t}\n\t\tthis.globallyVisible = true;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n\t * the context has loaded.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected.\n\t\t * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n\t\t * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t}\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly snapshotTree: ISnapshotTree,\n\t) {\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\tconst blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n\t\t\t\tconst clonedSnapshotTree = structuredClone(this.snapshotTree);\n\t\t\t\t// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n\t\t\t\t// This is for older snapshot which is generated by loader <=0.47 version which still contains\n\t\t\t\t// the contents within blobs. After a couple of revisions we can remove it.\n\t\t\t\tif (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n\t\t\t\t\tthis.sanitizeSnapshot(clonedSnapshotTree);\n\t\t\t\t}\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t\tclonedSnapshotTree,\n\t\t\t\t\tblobMap,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tnew LazyPromise<IChannel>(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\t\t\tdataStoreContext,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t);\n\t\t\t\t\tconst channel = await loadChannel(\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tfactory,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t);\n\t\t\t\t\t// Send all pending messages to the channel\n\t\t\t\t\tfor (const message of this.pending) {\n\t\t\t\t\t\tthis.services.value.deltaConnection.process(\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn channel;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t\"rehydratedLocalChannelContextFailedToLoadChannel\",\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n\n\tprivate isSnapshotInOldFormatAndCollectBlobs(\n\t\tsnapshotTree: ISnapshotTreeWithBlobContents,\n\t\tblobMap: Map<string, ArrayBufferLike>,\n\t): boolean {\n\t\tlet sanitize = false;\n\t\tconst blobsContents = snapshotTree.blobsContents;\n\t\tif (blobsContents !== undefined) {\n\t\t\tObject.entries(blobsContents).forEach(([key, value]) => {\n\t\t\t\tblobMap.set(key, value);\n\t\t\t\tif (snapshotTree.blobs[key] !== undefined) {\n\t\t\t\t\tsanitize = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tsanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n\t\t}\n\t\treturn sanitize;\n\t}\n\n\tprivate sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n\t\tconst blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n\t\tfor (const [blobName, blobId] of blobMapInitial.entries()) {\n\t\t\tconst blobValue = blobMapInitial.get(blobId);\n\t\t\tif (blobValue === undefined) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete snapshotTree.blobs[blobName];\n\t\t\t}\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tthis.sanitizeSnapshot(value);\n\t\t}\n\t}\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tpublic readonly channel: IChannel,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t) {\n\t\tsuper(\n\t\t\tchannel.id,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tPromise.resolve(channel),\n\t\t\tchannel,\n\t\t);\n\t\tthis.channel = channel;\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(channel.id);\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localChannelContext.js","sourceRoot":"","sources":["../src/localChannelContext.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 { DataProcessingError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport {\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/core-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannel,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n\tprivate globallyVisible = false;\n\tprotected readonly pending: ISequencedDocumentMessage[] = [];\n\tconstructor(\n\t\tprotected readonly id: string,\n\t\tprotected readonly runtime: IFluidDataStoreRuntime,\n\t\tprotected readonly services: Lazy<ChannelServiceEndpoints>,\n\t\tprivate readonly channelP: Promise<IChannel>,\n\t\tprivate _channel?: IChannel,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x30f /* Channel context ID cannot contain slashes */);\n\t}\n\n\tpublic async getChannel(): Promise<IChannel> {\n\t\tif (this._channel === undefined) {\n\t\t\treturn this.channelP.then((c) => (this._channel = c));\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tpublic get isLoaded(): boolean {\n\t\treturn this._channel !== undefined;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet globallyVisible or loaded\n\t\tif (this.globallyVisible && this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.setConnectionState(connected);\n\t\t}\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d3 /* \"Local channel must be globally visible when processing op\" */,\n\t\t);\n\n\t\t// A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n\t\t// delay loading. So after the container is attached and some other client joins which start generating\n\t\t// ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tlocal === false,\n\t\t\t\t0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */,\n\t\t\t);\n\t\t\tthis.pending.push(message);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2ee /* \"Channel should be loaded to rollback ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2ef /* \"Local channel must be globally visible when rolling back op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp() {\n\t\tthrow new Error(\"no stashed ops on local channel\");\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = false,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\tconst channel = await this.getChannel();\n\t\treturn summarizeChannelAsync(channel, fullTree, trackState, telemetryContext);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach summary to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummarizeResult {\n\t\tassert(\n\t\t\tthis._channel !== undefined,\n\t\t\t0x18d /* \"Channel should be loaded to take snapshot\" */,\n\t\t);\n\t\treturn summarizeChannel(\n\t\t\tthis._channel,\n\t\t\ttrue /* fullTree */,\n\t\t\tfalse /* trackState */,\n\t\t\ttelemetryContext,\n\t\t);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach GC data (set of outbound routes in the initial state)\n\t * to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tassert(this._channel !== undefined, \"Local Channel should be loaded before being attached\");\n\n\t\t// We need the GC Data to detect references added in this attach op\n\t\treturn this._channel.getGCData(/* fullGC: */ true);\n\t}\n\n\tpublic makeVisible(): void {\n\t\tif (this.globallyVisible) {\n\t\t\tthrow new Error(\"Channel is already globally visible\");\n\t\t}\n\n\t\tif (this.isLoaded) {\n\t\t\tassert(!!this._channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n\t\t\tthis._channel.connect(this.services.value);\n\t\t}\n\t\tthis.globallyVisible = true;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n\t * the context has loaded.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected.\n\t\t * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n\t\t * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t}\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly snapshotTree: ISnapshotTree,\n\t) {\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\tconst blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n\t\t\t\tconst clonedSnapshotTree = cloneSnapshotTree(this.snapshotTree);\n\t\t\t\t// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n\t\t\t\t// This is for older snapshot which is generated by loader <=0.47 version which still contains\n\t\t\t\t// the contents within blobs. After a couple of revisions we can remove it.\n\t\t\t\tif (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n\t\t\t\t\tthis.sanitizeSnapshot(clonedSnapshotTree);\n\t\t\t\t}\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t\tclonedSnapshotTree,\n\t\t\t\t\tblobMap,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tnew LazyPromise<IChannel>(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\t\t\tdataStoreContext,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t);\n\t\t\t\t\tconst channel = await loadChannel(\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tfactory,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t);\n\t\t\t\t\t// Send all pending messages to the channel\n\t\t\t\t\tfor (const message of this.pending) {\n\t\t\t\t\t\tthis.services.value.deltaConnection.process(\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn channel;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t\"rehydratedLocalChannelContextFailedToLoadChannel\",\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n\n\tprivate isSnapshotInOldFormatAndCollectBlobs(\n\t\tsnapshotTree: ISnapshotTreeWithBlobContents,\n\t\tblobMap: Map<string, ArrayBufferLike>,\n\t): boolean {\n\t\tlet sanitize = false;\n\t\tconst blobsContents = snapshotTree.blobsContents;\n\t\tif (blobsContents !== undefined) {\n\t\t\tObject.entries(blobsContents).forEach(([key, value]) => {\n\t\t\t\tblobMap.set(key, value);\n\t\t\t\tif (snapshotTree.blobs[key] !== undefined) {\n\t\t\t\t\tsanitize = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tsanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n\t\t}\n\t\treturn sanitize;\n\t}\n\n\tprivate sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n\t\tconst blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n\t\tfor (const [blobName, blobId] of blobMapInitial.entries()) {\n\t\t\tconst blobValue = blobMapInitial.get(blobId);\n\t\t\tif (blobValue === undefined) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete snapshotTree.blobs[blobName];\n\t\t\t}\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tthis.sanitizeSnapshot(value);\n\t\t}\n\t}\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tpublic readonly channel: IChannel,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t) {\n\t\tsuper(\n\t\t\tchannel.id,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tPromise.resolve(channel),\n\t\t\tchannel,\n\t\t);\n\t\tthis.channel = channel;\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(channel.id);\n\t\t};\n\t}\n}\n\n/**\n * Deep clones a snapshot tree.\n *\n * TODO: Investigate replacing this with a deep clone utility.\n * This is a temporary solution to avoid issues with lodash deepClone and ungap structuredClone.\n * Using lodash caused a significant bundle size regression. structuredClone cannot be used since\n * it does not support ArrayBuffer data types, and ISnapshotTree can contain blobContents properties,\n * which are ArrayBuffer data types.\n */\nfunction cloneSnapshotTree(tree: ISnapshotTree): ISnapshotTree {\n\tconst clone = { ...tree, blobs: { ...tree.blobs }, trees: {} };\n\tfor (const [k, v] of Object.entries(tree.trees)) {\n\t\tclone.trees[k] = cloneSnapshotTree(v);\n\t}\n\treturn clone;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localChannelContext.d.mts","sourceRoot":"","sources":["../src/localChannelContext.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAEI,EAAuB,mBAAmB,EAAE,MAAM,iCAAiC;OACnF,EAAE,uBAAuB,EAAE,MAAM,oCAAoC;OACrE,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,sCAAsC;OACxF,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,uCAAuC;OACjF,EACN,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,qCAAqC;OACrC,EAAU,IAAI,EAAe,MAAM,4BAA4B;OAC/D,EAAE,YAAY,EAAE,MAAM,iCAAiC;
|
|
1
|
+
{"version":3,"file":"localChannelContext.d.mts","sourceRoot":"","sources":["../src/localChannelContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { DataProcessingError } from "@fluidframework/telemetry-utils";
|
|
6
6
|
import { assert, Lazy, LazyPromise } from "@fluidframework/core-utils";
|
|
7
|
-
import structuredClone from "@ungap/structured-clone";
|
|
8
7
|
import { createChannelServiceEndpoints, loadChannel, loadChannelFactoryAndAttributes, summarizeChannel, summarizeChannelAsync, } from "./channelContext.mjs";
|
|
9
8
|
/**
|
|
10
9
|
* Channel context for a locally created channel
|
|
@@ -123,7 +122,7 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
|
|
|
123
122
|
constructor(id, registry, runtime, dataStoreContext, storageService, logger, submitFn, dirtyFn, addedGCOutboundReferenceFn, snapshotTree) {
|
|
124
123
|
super(id, runtime, new Lazy(() => {
|
|
125
124
|
const blobMap = new Map();
|
|
126
|
-
const clonedSnapshotTree =
|
|
125
|
+
const clonedSnapshotTree = cloneSnapshotTree(this.snapshotTree);
|
|
127
126
|
// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.
|
|
128
127
|
// This is for older snapshot which is generated by loader <=0.47 version which still contains
|
|
129
128
|
// the contents within blobs. After a couple of revisions we can remove it.
|
|
@@ -192,4 +191,20 @@ export class LocalChannelContext extends LocalChannelContextBase {
|
|
|
192
191
|
};
|
|
193
192
|
}
|
|
194
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Deep clones a snapshot tree.
|
|
196
|
+
*
|
|
197
|
+
* TODO: Investigate replacing this with a deep clone utility.
|
|
198
|
+
* This is a temporary solution to avoid issues with lodash deepClone and ungap structuredClone.
|
|
199
|
+
* Using lodash caused a significant bundle size regression. structuredClone cannot be used since
|
|
200
|
+
* it does not support ArrayBuffer data types, and ISnapshotTree can contain blobContents properties,
|
|
201
|
+
* which are ArrayBuffer data types.
|
|
202
|
+
*/
|
|
203
|
+
function cloneSnapshotTree(tree) {
|
|
204
|
+
const clone = { ...tree, blobs: { ...tree.blobs }, trees: {} };
|
|
205
|
+
for (const [k, v] of Object.entries(tree.trees)) {
|
|
206
|
+
clone.trees[k] = cloneSnapshotTree(v);
|
|
207
|
+
}
|
|
208
|
+
return clone;
|
|
209
|
+
}
|
|
195
210
|
//# sourceMappingURL=localChannelContext.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localChannelContext.mjs","sourceRoot":"","sources":["../src/localChannelContext.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 { DataProcessingError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport {\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/core-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport structuredClone from \"@ungap/structured-clone\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannel,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n\tprivate globallyVisible = false;\n\tprotected readonly pending: ISequencedDocumentMessage[] = [];\n\tconstructor(\n\t\tprotected readonly id: string,\n\t\tprotected readonly runtime: IFluidDataStoreRuntime,\n\t\tprotected readonly services: Lazy<ChannelServiceEndpoints>,\n\t\tprivate readonly channelP: Promise<IChannel>,\n\t\tprivate _channel?: IChannel,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x30f /* Channel context ID cannot contain slashes */);\n\t}\n\n\tpublic async getChannel(): Promise<IChannel> {\n\t\tif (this._channel === undefined) {\n\t\t\treturn this.channelP.then((c) => (this._channel = c));\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tpublic get isLoaded(): boolean {\n\t\treturn this._channel !== undefined;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet globallyVisible or loaded\n\t\tif (this.globallyVisible && this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.setConnectionState(connected);\n\t\t}\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d3 /* \"Local channel must be globally visible when processing op\" */,\n\t\t);\n\n\t\t// A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n\t\t// delay loading. So after the container is attached and some other client joins which start generating\n\t\t// ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tlocal === false,\n\t\t\t\t0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */,\n\t\t\t);\n\t\t\tthis.pending.push(message);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2ee /* \"Channel should be loaded to rollback ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2ef /* \"Local channel must be globally visible when rolling back op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp() {\n\t\tthrow new Error(\"no stashed ops on local channel\");\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = false,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\tconst channel = await this.getChannel();\n\t\treturn summarizeChannelAsync(channel, fullTree, trackState, telemetryContext);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach summary to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummarizeResult {\n\t\tassert(\n\t\t\tthis._channel !== undefined,\n\t\t\t0x18d /* \"Channel should be loaded to take snapshot\" */,\n\t\t);\n\t\treturn summarizeChannel(\n\t\t\tthis._channel,\n\t\t\ttrue /* fullTree */,\n\t\t\tfalse /* trackState */,\n\t\t\ttelemetryContext,\n\t\t);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach GC data (set of outbound routes in the initial state)\n\t * to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tassert(this._channel !== undefined, \"Local Channel should be loaded before being attached\");\n\n\t\t// We need the GC Data to detect references added in this attach op\n\t\treturn this._channel.getGCData(/* fullGC: */ true);\n\t}\n\n\tpublic makeVisible(): void {\n\t\tif (this.globallyVisible) {\n\t\t\tthrow new Error(\"Channel is already globally visible\");\n\t\t}\n\n\t\tif (this.isLoaded) {\n\t\t\tassert(!!this._channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n\t\t\tthis._channel.connect(this.services.value);\n\t\t}\n\t\tthis.globallyVisible = true;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n\t * the context has loaded.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected.\n\t\t * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n\t\t * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t}\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly snapshotTree: ISnapshotTree,\n\t) {\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\tconst blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n\t\t\t\tconst clonedSnapshotTree = structuredClone(this.snapshotTree);\n\t\t\t\t// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n\t\t\t\t// This is for older snapshot which is generated by loader <=0.47 version which still contains\n\t\t\t\t// the contents within blobs. After a couple of revisions we can remove it.\n\t\t\t\tif (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n\t\t\t\t\tthis.sanitizeSnapshot(clonedSnapshotTree);\n\t\t\t\t}\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t\tclonedSnapshotTree,\n\t\t\t\t\tblobMap,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tnew LazyPromise<IChannel>(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\t\t\tdataStoreContext,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t);\n\t\t\t\t\tconst channel = await loadChannel(\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tfactory,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t);\n\t\t\t\t\t// Send all pending messages to the channel\n\t\t\t\t\tfor (const message of this.pending) {\n\t\t\t\t\t\tthis.services.value.deltaConnection.process(\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn channel;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t\"rehydratedLocalChannelContextFailedToLoadChannel\",\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n\n\tprivate isSnapshotInOldFormatAndCollectBlobs(\n\t\tsnapshotTree: ISnapshotTreeWithBlobContents,\n\t\tblobMap: Map<string, ArrayBufferLike>,\n\t): boolean {\n\t\tlet sanitize = false;\n\t\tconst blobsContents = snapshotTree.blobsContents;\n\t\tif (blobsContents !== undefined) {\n\t\t\tObject.entries(blobsContents).forEach(([key, value]) => {\n\t\t\t\tblobMap.set(key, value);\n\t\t\t\tif (snapshotTree.blobs[key] !== undefined) {\n\t\t\t\t\tsanitize = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tsanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n\t\t}\n\t\treturn sanitize;\n\t}\n\n\tprivate sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n\t\tconst blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n\t\tfor (const [blobName, blobId] of blobMapInitial.entries()) {\n\t\t\tconst blobValue = blobMapInitial.get(blobId);\n\t\t\tif (blobValue === undefined) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete snapshotTree.blobs[blobName];\n\t\t\t}\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tthis.sanitizeSnapshot(value);\n\t\t}\n\t}\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tpublic readonly channel: IChannel,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t) {\n\t\tsuper(\n\t\t\tchannel.id,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tPromise.resolve(channel),\n\t\t\tchannel,\n\t\t);\n\t\tthis.channel = channel;\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(channel.id);\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"localChannelContext.mjs","sourceRoot":"","sources":["../src/localChannelContext.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 { DataProcessingError, ITelemetryLoggerExt } from \"@fluidframework/telemetry-utils\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { IChannel, IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions\";\nimport {\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { assert, Lazy, LazyPromise } from \"@fluidframework/core-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport {\n\tChannelServiceEndpoints,\n\tcreateChannelServiceEndpoints,\n\tIChannelContext,\n\tloadChannel,\n\tloadChannelFactoryAndAttributes,\n\tsummarizeChannel,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n\tprivate globallyVisible = false;\n\tprotected readonly pending: ISequencedDocumentMessage[] = [];\n\tconstructor(\n\t\tprotected readonly id: string,\n\t\tprotected readonly runtime: IFluidDataStoreRuntime,\n\t\tprotected readonly services: Lazy<ChannelServiceEndpoints>,\n\t\tprivate readonly channelP: Promise<IChannel>,\n\t\tprivate _channel?: IChannel,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x30f /* Channel context ID cannot contain slashes */);\n\t}\n\n\tpublic async getChannel(): Promise<IChannel> {\n\t\tif (this._channel === undefined) {\n\t\t\treturn this.channelP.then((c) => (this._channel = c));\n\t\t}\n\t\treturn this.channelP;\n\t}\n\n\tpublic get isLoaded(): boolean {\n\t\treturn this._channel !== undefined;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet globallyVisible or loaded\n\t\tif (this.globallyVisible && this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.setConnectionState(connected);\n\t\t}\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d3 /* \"Local channel must be globally visible when processing op\" */,\n\t\t);\n\n\t\t// A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n\t\t// delay loading. So after the container is attached and some other client joins which start generating\n\t\t// ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.value.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tlocal === false,\n\t\t\t\t0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */,\n\t\t\t);\n\t\t\tthis.pending.push(message);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2ee /* \"Channel should be loaded to rollback ops\" */);\n\t\tassert(\n\t\t\tthis.globallyVisible,\n\t\t\t0x2ef /* \"Local channel must be globally visible when rolling back op\" */,\n\t\t);\n\t\tthis.services.value.deltaConnection.rollback(content, localOpMetadata);\n\t}\n\n\tpublic applyStashedOp() {\n\t\tthrow new Error(\"no stashed ops on local channel\");\n\t}\n\n\t/**\n\t * Returns a summary at the current sequence number.\n\t * @param fullTree - true to bypass optimizations and force a full summary tree\n\t * @param trackState - This tells whether we should track state from this summary.\n\t * @param telemetryContext - summary data passed through the layers for telemetry purposes\n\t */\n\tpublic async summarize(\n\t\tfullTree: boolean = false,\n\t\ttrackState: boolean = false,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\tconst channel = await this.getChannel();\n\t\treturn summarizeChannelAsync(channel, fullTree, trackState, telemetryContext);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach summary to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachSummary(telemetryContext?: ITelemetryContext): ISummarizeResult {\n\t\tassert(\n\t\t\tthis._channel !== undefined,\n\t\t\t0x18d /* \"Channel should be loaded to take snapshot\" */,\n\t\t);\n\t\treturn summarizeChannel(\n\t\t\tthis._channel,\n\t\t\ttrue /* fullTree */,\n\t\t\tfalse /* trackState */,\n\t\t\ttelemetryContext,\n\t\t);\n\t}\n\n\t/**\n\t * For crafting the DataStore attach op. Only to be called when the channel is loaded (if applicable).\n\t *\n\t * Synchronously generates the channel's attach GC data (set of outbound routes in the initial state)\n\t * to be joined with the same from the DataStore's other channels\n\t */\n\tpublic getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData {\n\t\tassert(this._channel !== undefined, \"Local Channel should be loaded before being attached\");\n\n\t\t// We need the GC Data to detect references added in this attach op\n\t\treturn this._channel.getGCData(/* fullGC: */ true);\n\t}\n\n\tpublic makeVisible(): void {\n\t\tif (this.globallyVisible) {\n\t\t\tthrow new Error(\"Channel is already globally visible\");\n\t\t}\n\n\t\tif (this.isLoaded) {\n\t\t\tassert(!!this._channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n\t\t\tthis._channel.connect(this.services.value);\n\t\t}\n\t\tthis.globallyVisible = true;\n\t}\n\n\t/**\n\t * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n\t * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n\t * the context has loaded.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tpublic async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n\t\tconst channel = await this.getChannel();\n\t\treturn channel.getGCData(fullGC);\n\t}\n\n\tpublic updateUsedRoutes(usedRoutes: string[]) {\n\t\t/**\n\t\t * Currently, DDSes are always considered referenced and are not garbage collected.\n\t\t * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n\t\t * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t}\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tid: string,\n\t\tregistry: ISharedObjectRegistry,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t\tprivate readonly snapshotTree: ISnapshotTree,\n\t) {\n\t\tsuper(\n\t\t\tid,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\tconst blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n\t\t\t\tconst clonedSnapshotTree = cloneSnapshotTree(this.snapshotTree);\n\t\t\t\t// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n\t\t\t\t// This is for older snapshot which is generated by loader <=0.47 version which still contains\n\t\t\t\t// the contents within blobs. After a couple of revisions we can remove it.\n\t\t\t\tif (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n\t\t\t\t\tthis.sanitizeSnapshot(clonedSnapshotTree);\n\t\t\t\t}\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t\tclonedSnapshotTree,\n\t\t\t\t\tblobMap,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tnew LazyPromise<IChannel>(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst { attributes, factory } = await loadChannelFactoryAndAttributes(\n\t\t\t\t\t\tdataStoreContext,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t\tregistry,\n\t\t\t\t\t);\n\t\t\t\t\tconst channel = await loadChannel(\n\t\t\t\t\t\truntime,\n\t\t\t\t\t\tattributes,\n\t\t\t\t\t\tfactory,\n\t\t\t\t\t\tthis.services.value,\n\t\t\t\t\t\tlogger,\n\t\t\t\t\t\tthis.id,\n\t\t\t\t\t);\n\t\t\t\t\t// Send all pending messages to the channel\n\t\t\t\t\tfor (const message of this.pending) {\n\t\t\t\t\t\tthis.services.value.deltaConnection.process(\n\t\t\t\t\t\t\tmessage,\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\tundefined /* localOpMetadata */,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn channel;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tthrow DataProcessingError.wrapIfUnrecognized(\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t\"rehydratedLocalChannelContextFailedToLoadChannel\",\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(id);\n\t\t};\n\t}\n\n\tprivate isSnapshotInOldFormatAndCollectBlobs(\n\t\tsnapshotTree: ISnapshotTreeWithBlobContents,\n\t\tblobMap: Map<string, ArrayBufferLike>,\n\t): boolean {\n\t\tlet sanitize = false;\n\t\tconst blobsContents = snapshotTree.blobsContents;\n\t\tif (blobsContents !== undefined) {\n\t\t\tObject.entries(blobsContents).forEach(([key, value]) => {\n\t\t\t\tblobMap.set(key, value);\n\t\t\t\tif (snapshotTree.blobs[key] !== undefined) {\n\t\t\t\t\tsanitize = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tsanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n\t\t}\n\t\treturn sanitize;\n\t}\n\n\tprivate sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n\t\tconst blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n\t\tfor (const [blobName, blobId] of blobMapInitial.entries()) {\n\t\t\tconst blobValue = blobMapInitial.get(blobId);\n\t\t\tif (blobValue === undefined) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete snapshotTree.blobs[blobName];\n\t\t\t}\n\t\t}\n\t\tfor (const value of Object.values(snapshotTree.trees)) {\n\t\t\tthis.sanitizeSnapshot(value);\n\t\t}\n\t}\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n\tprivate readonly dirtyFn: () => void;\n\tconstructor(\n\t\tpublic readonly channel: IChannel,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tdataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\n\t\tlogger: ITelemetryLoggerExt,\n\t\tsubmitFn: (content: any, localOpMetadata: unknown) => void,\n\t\tdirtyFn: (address: string) => void,\n\t\taddedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n\t) {\n\t\tsuper(\n\t\t\tchannel.id,\n\t\t\truntime,\n\t\t\tnew Lazy(() => {\n\t\t\t\treturn createChannelServiceEndpoints(\n\t\t\t\t\tdataStoreContext.connected,\n\t\t\t\t\tsubmitFn,\n\t\t\t\t\tthis.dirtyFn,\n\t\t\t\t\taddedGCOutboundReferenceFn,\n\t\t\t\t\tstorageService,\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\t\t\t}),\n\t\t\tPromise.resolve(channel),\n\t\t\tchannel,\n\t\t);\n\t\tthis.channel = channel;\n\n\t\tthis.dirtyFn = () => {\n\t\t\tdirtyFn(channel.id);\n\t\t};\n\t}\n}\n\n/**\n * Deep clones a snapshot tree.\n *\n * TODO: Investigate replacing this with a deep clone utility.\n * This is a temporary solution to avoid issues with lodash deepClone and ungap structuredClone.\n * Using lodash caused a significant bundle size regression. structuredClone cannot be used since\n * it does not support ArrayBuffer data types, and ISnapshotTree can contain blobContents properties,\n * which are ArrayBuffer data types.\n */\nfunction cloneSnapshotTree(tree: ISnapshotTree): ISnapshotTree {\n\tconst clone = { ...tree, blobs: { ...tree.blobs }, trees: {} };\n\tfor (const [k, v] of Object.entries(tree.trees)) {\n\t\tclone.trees[k] = cloneSnapshotTree(v);\n\t}\n\treturn clone;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/datastore",
|
|
3
|
-
"version": "2.0.0-rc.1.0.
|
|
3
|
+
"version": "2.0.0-rc.1.0.8",
|
|
4
4
|
"description": "Fluid data store implementation",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -87,18 +87,17 @@
|
|
|
87
87
|
"temp-directory": "nyc/.nyc_output"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@fluid-internal/client-utils": ">=2.0.0-rc.1.0.
|
|
91
|
-
"@fluidframework/container-definitions": ">=2.0.0-rc.1.0.
|
|
92
|
-
"@fluidframework/core-interfaces": ">=2.0.0-rc.1.0.
|
|
93
|
-
"@fluidframework/core-utils": ">=2.0.0-rc.1.0.
|
|
94
|
-
"@fluidframework/datastore-definitions": ">=2.0.0-rc.1.0.
|
|
95
|
-
"@fluidframework/driver-definitions": ">=2.0.0-rc.1.0.
|
|
96
|
-
"@fluidframework/driver-utils": ">=2.0.0-rc.1.0.
|
|
90
|
+
"@fluid-internal/client-utils": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
91
|
+
"@fluidframework/container-definitions": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
92
|
+
"@fluidframework/core-interfaces": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
93
|
+
"@fluidframework/core-utils": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
94
|
+
"@fluidframework/datastore-definitions": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
95
|
+
"@fluidframework/driver-definitions": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
96
|
+
"@fluidframework/driver-utils": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
97
97
|
"@fluidframework/protocol-definitions": "^3.1.0",
|
|
98
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-rc.1.0.
|
|
99
|
-
"@fluidframework/runtime-utils": ">=2.0.0-rc.1.0.
|
|
100
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-rc.1.0.
|
|
101
|
-
"@ungap/structured-clone": "^1.2.0",
|
|
98
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
99
|
+
"@fluidframework/runtime-utils": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
100
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
102
101
|
"uuid": "^9.0.0"
|
|
103
102
|
},
|
|
104
103
|
"devDependencies": {
|
|
@@ -108,8 +107,8 @@
|
|
|
108
107
|
"@fluidframework/build-tools": "^0.29.0",
|
|
109
108
|
"@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.8.0.0",
|
|
110
109
|
"@fluidframework/eslint-config-fluid": "^3.2.0",
|
|
111
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-rc.1.0.
|
|
112
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.1.0.
|
|
110
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
111
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.1.0.8 <2.0.0-rc.1.1.0",
|
|
113
112
|
"@microsoft/api-extractor": "^7.38.3",
|
|
114
113
|
"@types/mocha": "^9.1.1",
|
|
115
114
|
"@types/node": "^18.19.0",
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
import { assert, Lazy, LazyPromise } from "@fluidframework/core-utils";
|
|
17
17
|
import { IFluidHandle } from "@fluidframework/core-interfaces";
|
|
18
18
|
import { ISnapshotTreeWithBlobContents } from "@fluidframework/container-definitions";
|
|
19
|
-
import structuredClone from "@ungap/structured-clone";
|
|
20
19
|
import {
|
|
21
20
|
ChannelServiceEndpoints,
|
|
22
21
|
createChannelServiceEndpoints,
|
|
@@ -204,7 +203,7 @@ export class RehydratedLocalChannelContext extends LocalChannelContextBase {
|
|
|
204
203
|
runtime,
|
|
205
204
|
new Lazy(() => {
|
|
206
205
|
const blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();
|
|
207
|
-
const clonedSnapshotTree =
|
|
206
|
+
const clonedSnapshotTree = cloneSnapshotTree(this.snapshotTree);
|
|
208
207
|
// 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.
|
|
209
208
|
// This is for older snapshot which is generated by loader <=0.47 version which still contains
|
|
210
209
|
// the contents within blobs. After a couple of revisions we can remove it.
|
|
@@ -332,3 +331,20 @@ export class LocalChannelContext extends LocalChannelContextBase {
|
|
|
332
331
|
};
|
|
333
332
|
}
|
|
334
333
|
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Deep clones a snapshot tree.
|
|
337
|
+
*
|
|
338
|
+
* TODO: Investigate replacing this with a deep clone utility.
|
|
339
|
+
* This is a temporary solution to avoid issues with lodash deepClone and ungap structuredClone.
|
|
340
|
+
* Using lodash caused a significant bundle size regression. structuredClone cannot be used since
|
|
341
|
+
* it does not support ArrayBuffer data types, and ISnapshotTree can contain blobContents properties,
|
|
342
|
+
* which are ArrayBuffer data types.
|
|
343
|
+
*/
|
|
344
|
+
function cloneSnapshotTree(tree: ISnapshotTree): ISnapshotTree {
|
|
345
|
+
const clone = { ...tree, blobs: { ...tree.blobs }, trees: {} };
|
|
346
|
+
for (const [k, v] of Object.entries(tree.trees)) {
|
|
347
|
+
clone.trees[k] = cloneSnapshotTree(v);
|
|
348
|
+
}
|
|
349
|
+
return clone;
|
|
350
|
+
}
|