@fluidframework/datastore 0.58.2001 → 0.59.1000-61898

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/dataStoreRuntime.d.ts +17 -5
  2. package/dist/dataStoreRuntime.d.ts.map +1 -1
  3. package/dist/dataStoreRuntime.js +106 -57
  4. package/dist/dataStoreRuntime.js.map +1 -1
  5. package/dist/fluidHandle.d.ts +8 -4
  6. package/dist/fluidHandle.d.ts.map +1 -1
  7. package/dist/fluidHandle.js +28 -20
  8. package/dist/fluidHandle.js.map +1 -1
  9. package/dist/localChannelContext.d.ts +2 -2
  10. package/dist/localChannelContext.d.ts.map +1 -1
  11. package/dist/localChannelContext.js +9 -9
  12. package/dist/localChannelContext.js.map +1 -1
  13. package/dist/packageVersion.d.ts +1 -1
  14. package/dist/packageVersion.d.ts.map +1 -1
  15. package/dist/packageVersion.js +1 -1
  16. package/dist/packageVersion.js.map +1 -1
  17. package/lib/dataStoreRuntime.d.ts +17 -5
  18. package/lib/dataStoreRuntime.d.ts.map +1 -1
  19. package/lib/dataStoreRuntime.js +107 -58
  20. package/lib/dataStoreRuntime.js.map +1 -1
  21. package/lib/fluidHandle.d.ts +8 -4
  22. package/lib/fluidHandle.d.ts.map +1 -1
  23. package/lib/fluidHandle.js +28 -20
  24. package/lib/fluidHandle.js.map +1 -1
  25. package/lib/localChannelContext.d.ts +2 -2
  26. package/lib/localChannelContext.d.ts.map +1 -1
  27. package/lib/localChannelContext.js +9 -9
  28. package/lib/localChannelContext.js.map +1 -1
  29. package/lib/packageVersion.d.ts +1 -1
  30. package/lib/packageVersion.d.ts.map +1 -1
  31. package/lib/packageVersion.js +1 -1
  32. package/lib/packageVersion.js.map +1 -1
  33. package/package.json +28 -17
  34. package/src/dataStoreRuntime.ts +123 -64
  35. package/src/fluidHandle.ts +31 -24
  36. package/src/localChannelContext.ts +9 -9
  37. package/src/packageVersion.ts +1 -1
@@ -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\n// eslint-disable-next-line import/no-internal-modules\nimport cloneDeep from \"lodash/cloneDeep\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n IChannel,\n IFluidDataStoreRuntime,\n IChannelFactory,\n IChannelAttributes,\n} from \"@fluidframework/datastore-definitions\";\nimport {\n IFluidDataStoreContext,\n IGarbageCollectionData,\n ISummarizeResult,\n} from \"@fluidframework/runtime-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { DataProcessingError } from \"@fluidframework/container-utils\";\nimport { assert, Lazy } from \"@fluidframework/common-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n createServiceEndpoints,\n IChannelContext,\n summarizeChannel,\n summarizeChannelAsync,\n} from \"./channelContext\";\nimport { ChannelDeltaConnection } from \"./channelDeltaConnection\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\nimport { ChannelStorageService } from \"./channelStorageService\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n public channel: IChannel | undefined;\n private attached = false;\n protected readonly pending: ISequencedDocumentMessage[] = [];\n protected factory: IChannelFactory | undefined;\n constructor(\n protected readonly id: string,\n protected readonly registry: ISharedObjectRegistry,\n protected readonly runtime: IFluidDataStoreRuntime,\n private readonly servicesGetter: () => Lazy<{\n readonly deltaConnection: ChannelDeltaConnection,\n readonly objectStorage: ChannelStorageService,\n }>,\n ) {\n }\n\n public async getChannel(): Promise<IChannel> {\n assert(this.channel !== undefined, 0x207 /* \"Channel should be defined\" */);\n return this.channel;\n }\n\n public get isLoaded(): boolean {\n return this.channel !== undefined;\n }\n\n public setConnectionState(connected: boolean, clientId?: string) {\n // Connection events are ignored if the data store is not yet attached or loaded\n if (this.attached && this.isLoaded) {\n this.servicesGetter().value.deltaConnection.setConnectionState(connected);\n }\n }\n\n public processOp(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n assert(this.attached, 0x188 /* \"Local channel must be attached when processing op\" */);\n\n // A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n // delay loading. So after the container is attached and some other client joins which start generating\n // ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n if (this.isLoaded) {\n this.servicesGetter().value.deltaConnection.process(message, local, localOpMetadata);\n } else {\n assert(local === false,\n 0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */);\n this.pending.push(message);\n }\n }\n\n public reSubmit(content: any, localOpMetadata: unknown) {\n assert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n assert(this.attached, 0x18b /* \"Local channel must be attached when resubmitting op\" */);\n this.servicesGetter().value.deltaConnection.reSubmit(content, localOpMetadata);\n }\n\n public applyStashedOp() {\n throw new Error(\"no stashed ops on local channel\");\n }\n\n /**\n * Returns a summary at the current sequence number.\n * @param fullTree - true to bypass optimizations and force a full summary tree\n * @param trackState - This tells whether we should track state from this summary.\n */\n public async summarize(fullTree: boolean = false, trackState: boolean = false): Promise<ISummarizeResult> {\n assert(this.isLoaded && this.channel !== undefined, 0x18c /* \"Channel should be loaded to summarize\" */);\n return summarizeChannelAsync(this.channel, fullTree, trackState);\n }\n\n public getAttachSummary(): ISummarizeResult {\n assert(this.isLoaded && this.channel !== undefined, 0x18d /* \"Channel should be loaded to take snapshot\" */);\n return summarizeChannel(this.channel, true /* fullTree */, false /* trackState */);\n }\n\n public markAttached(): void {\n if (this.attached) {\n throw new Error(\"Channel is already attached\");\n }\n\n if (this.isLoaded) {\n assert(!!this.channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n this.channel.connect(this.servicesGetter().value);\n }\n this.attached = true;\n }\n\n /**\n * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n * the context has loaded.\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n assert(this.isLoaded && this.channel !== undefined, 0x193 /* \"Channel should be loaded to run GC\" */);\n return this.channel.getGCData(fullGC);\n }\n\n public updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number) {\n /**\n * Currently, DDSs are always considered referenced and are not garbage collected.\n * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n */\n }\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n private readonly services: Lazy<{\n readonly deltaConnection: ChannelDeltaConnection,\n readonly objectStorage: ChannelStorageService,\n }>;\n\n private readonly dirtyFn: () => void;\n\n constructor(\n id: string,\n registry: ISharedObjectRegistry,\n runtime: IFluidDataStoreRuntime,\n dataStoreContext: IFluidDataStoreContext,\n storageService: IDocumentStorageService,\n logger: ITelemetryLogger,\n submitFn: (content: any, localOpMetadata: unknown) => void,\n dirtyFn: (address: string) => void,\n addedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n private readonly snapshotTree: ISnapshotTree,\n ) {\n super(id, registry, runtime, () => this.services);\n const blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n const clonedSnapshotTree = cloneDeep(this.snapshotTree);\n // 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n // This is for older snapshot which is generated by loader <=0.47 version which still contains\n // the contents within blobs. After a couple of revisions we can remove it.\n if (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n this.sanitizeSnapshot(clonedSnapshotTree);\n }\n\n this.services = new Lazy(() => {\n return createServiceEndpoints(\n this.id,\n dataStoreContext.connected,\n submitFn,\n this.dirtyFn,\n addedGCOutboundReferenceFn,\n storageService,\n logger,\n clonedSnapshotTree,\n blobMap,\n );\n });\n this.dirtyFn = () => { dirtyFn(id); };\n }\n\n public async getChannel(): Promise<IChannel> {\n if (this.channel === undefined) {\n this.channel = await this.loadChannel()\n .catch((err) => {\n throw DataProcessingError.wrapIfUnrecognized(\n err, \"rehydratedLocalChannelContextFailedToLoadChannel\", undefined);\n });\n }\n return this.channel;\n }\n\n private async loadChannel(): Promise<IChannel> {\n assert(!this.isLoaded, 0x18e /* \"Channel must not already be loaded when loading\" */);\n assert(await this.services.value.objectStorage.contains(\".attributes\"),\n 0x190 /* \".attributes blob should be present\" */);\n const attributes = await readAndParse<IChannelAttributes>(\n this.services.value.objectStorage,\n \".attributes\");\n\n assert(this.factory === undefined, 0x208 /* \"Factory should be undefined before loading\" */);\n this.factory = this.registry.get(attributes.type);\n if (this.factory === undefined) {\n throw new Error(`Channel Factory ${attributes.type} not registered`);\n }\n // Services will be assigned during this load.\n const channel = await this.factory.load(\n this.runtime,\n this.id,\n this.services.value,\n attributes);\n\n // Commit changes.\n this.channel = channel;\n\n // Send all pending messages to the channel\n for (const message of this.pending) {\n this.services.value.deltaConnection.process(message, false, undefined /* localOpMetadata */);\n }\n return this.channel;\n }\n\n private isSnapshotInOldFormatAndCollectBlobs(\n snapshotTree: ISnapshotTree,\n blobMap: Map<string, ArrayBufferLike>,\n ): boolean {\n let sanitize = false;\n const blobsContents: {[path: string]: ArrayBufferLike} = (snapshotTree as any).blobsContents;\n Object.entries(blobsContents).forEach(([key, value]) => {\n blobMap.set(key, value);\n if (snapshotTree.blobs[key] !== undefined) {\n sanitize = true;\n }\n });\n for (const value of Object.values(snapshotTree.trees)) {\n sanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n }\n return sanitize;\n }\n\n private sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n const blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n for (const [blobName, blobId] of blobMapInitial.entries()) {\n const blobValue = blobMapInitial.get(blobId);\n if (blobValue === undefined) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete snapshotTree.blobs[blobName];\n }\n }\n for (const value of Object.values(snapshotTree.trees)) {\n this.sanitizeSnapshot(value);\n }\n }\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n private readonly services: Lazy<{\n readonly deltaConnection: ChannelDeltaConnection,\n readonly objectStorage: ChannelStorageService,\n }>;\n private readonly dirtyFn: () => void;\n constructor(\n id: string,\n registry: ISharedObjectRegistry,\n type: string,\n runtime: IFluidDataStoreRuntime,\n dataStoreContext: IFluidDataStoreContext,\n storageService: IDocumentStorageService,\n logger: ITelemetryLogger,\n submitFn: (content: any, localOpMetadata: unknown) => void,\n dirtyFn: (address: string) => void,\n addedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n ) {\n super(id, registry, runtime, () => this.services);\n assert(type !== undefined, 0x209 /* \"Factory Type should be defined\" */);\n this.factory = registry.get(type);\n if (this.factory === undefined) {\n throw new Error(`Channel Factory ${type} not registered`);\n }\n this.channel = this.factory.create(runtime, id);\n this.services = new Lazy(() => {\n return createServiceEndpoints(\n this.id,\n dataStoreContext.connected,\n submitFn,\n this.dirtyFn,\n addedGCOutboundReferenceFn,\n storageService,\n logger,\n );\n });\n this.dirtyFn = () => { dirtyFn(id); };\n }\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\n// eslint-disable-next-line import/no-internal-modules\nimport cloneDeep from \"lodash/cloneDeep\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n IChannel,\n IFluidDataStoreRuntime,\n IChannelFactory,\n IChannelAttributes,\n} from \"@fluidframework/datastore-definitions\";\nimport {\n IFluidDataStoreContext,\n IGarbageCollectionData,\n ISummarizeResult,\n} from \"@fluidframework/runtime-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { DataProcessingError } from \"@fluidframework/container-utils\";\nimport { assert, Lazy } from \"@fluidframework/common-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n createServiceEndpoints,\n IChannelContext,\n summarizeChannel,\n summarizeChannelAsync,\n} from \"./channelContext\";\nimport { ChannelDeltaConnection } from \"./channelDeltaConnection\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\nimport { ChannelStorageService } from \"./channelStorageService\";\n\n/**\n * Channel context for a locally created channel\n */\nexport abstract class LocalChannelContextBase implements IChannelContext {\n public channel: IChannel | undefined;\n private globallyVisible = false;\n protected readonly pending: ISequencedDocumentMessage[] = [];\n protected factory: IChannelFactory | undefined;\n constructor(\n protected readonly id: string,\n protected readonly registry: ISharedObjectRegistry,\n protected readonly runtime: IFluidDataStoreRuntime,\n private readonly servicesGetter: () => Lazy<{\n readonly deltaConnection: ChannelDeltaConnection,\n readonly objectStorage: ChannelStorageService,\n }>,\n ) {\n }\n\n public async getChannel(): Promise<IChannel> {\n assert(this.channel !== undefined, 0x207 /* \"Channel should be defined\" */);\n return this.channel;\n }\n\n public get isLoaded(): boolean {\n return this.channel !== undefined;\n }\n\n public setConnectionState(connected: boolean, clientId?: string) {\n // Connection events are ignored if the data store is not yet globallyVisible or loaded\n if (this.globallyVisible && this.isLoaded) {\n this.servicesGetter().value.deltaConnection.setConnectionState(connected);\n }\n }\n\n public processOp(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void {\n assert(this.globallyVisible, 0x2d3 /* \"Local channel must be globally visible when processing op\" */);\n\n // A local channel may not be loaded in case where we rehydrate the container from a snapshot because of\n // delay loading. So after the container is attached and some other client joins which start generating\n // ops for this channel. So not loaded local channel can still receive ops and we store them to process later.\n if (this.isLoaded) {\n this.servicesGetter().value.deltaConnection.process(message, local, localOpMetadata);\n } else {\n assert(local === false,\n 0x189 /* \"Should always be remote because a local dds shouldn't generate ops before loading\" */);\n this.pending.push(message);\n }\n }\n\n public reSubmit(content: any, localOpMetadata: unknown) {\n assert(this.isLoaded, 0x18a /* \"Channel should be loaded to resubmit ops\" */);\n assert(this.globallyVisible, 0x2d4 /* \"Local channel must be globally visible when resubmitting op\" */);\n this.servicesGetter().value.deltaConnection.reSubmit(content, localOpMetadata);\n }\n\n public applyStashedOp() {\n throw new Error(\"no stashed ops on local channel\");\n }\n\n /**\n * Returns a summary at the current sequence number.\n * @param fullTree - true to bypass optimizations and force a full summary tree\n * @param trackState - This tells whether we should track state from this summary.\n */\n public async summarize(fullTree: boolean = false, trackState: boolean = false): Promise<ISummarizeResult> {\n assert(this.isLoaded && this.channel !== undefined, 0x18c /* \"Channel should be loaded to summarize\" */);\n return summarizeChannelAsync(this.channel, fullTree, trackState);\n }\n\n public getAttachSummary(): ISummarizeResult {\n assert(this.isLoaded && this.channel !== undefined, 0x18d /* \"Channel should be loaded to take snapshot\" */);\n return summarizeChannel(this.channel, true /* fullTree */, false /* trackState */);\n }\n\n public makeVisible(): void {\n if (this.globallyVisible) {\n throw new Error(\"Channel is already globally visible\");\n }\n\n if (this.isLoaded) {\n assert(!!this.channel, 0x192 /* \"Channel should be there if loaded!!\" */);\n this.channel.connect(this.servicesGetter().value);\n }\n this.globallyVisible = true;\n }\n\n /**\n * Returns the data used for garbage collection. This includes a list of GC nodes that represent this context.\n * Each node has a set of outbound routes to other GC nodes in the document. This should be called only after\n * the context has loaded.\n * @param fullGC - true to bypass optimizations and force full generation of GC data.\n */\n public async getGCData(fullGC: boolean = false): Promise<IGarbageCollectionData> {\n assert(this.isLoaded && this.channel !== undefined, 0x193 /* \"Channel should be loaded to run GC\" */);\n return this.channel.getGCData(fullGC);\n }\n\n public updateUsedRoutes(usedRoutes: string[], gcTimestamp?: number) {\n /**\n * Currently, DDSs are always considered referenced and are not garbage collected.\n * Once we have GC at DDS level, this channel context's used routes will be updated as per the passed\n * value. See - https://github.com/microsoft/FluidFramework/issues/4611\n */\n }\n}\n\nexport class RehydratedLocalChannelContext extends LocalChannelContextBase {\n private readonly services: Lazy<{\n readonly deltaConnection: ChannelDeltaConnection,\n readonly objectStorage: ChannelStorageService,\n }>;\n\n private readonly dirtyFn: () => void;\n\n constructor(\n id: string,\n registry: ISharedObjectRegistry,\n runtime: IFluidDataStoreRuntime,\n dataStoreContext: IFluidDataStoreContext,\n storageService: IDocumentStorageService,\n logger: ITelemetryLogger,\n submitFn: (content: any, localOpMetadata: unknown) => void,\n dirtyFn: (address: string) => void,\n addedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n private readonly snapshotTree: ISnapshotTree,\n ) {\n super(id, registry, runtime, () => this.services);\n const blobMap: Map<string, ArrayBufferLike> = new Map<string, ArrayBufferLike>();\n const clonedSnapshotTree = cloneDeep(this.snapshotTree);\n // 0.47 back-compat Need to sanitize if snapshotTree.blobs still contains blob contents too.\n // This is for older snapshot which is generated by loader <=0.47 version which still contains\n // the contents within blobs. After a couple of revisions we can remove it.\n if (this.isSnapshotInOldFormatAndCollectBlobs(clonedSnapshotTree, blobMap)) {\n this.sanitizeSnapshot(clonedSnapshotTree);\n }\n\n this.services = new Lazy(() => {\n return createServiceEndpoints(\n this.id,\n dataStoreContext.connected,\n submitFn,\n this.dirtyFn,\n addedGCOutboundReferenceFn,\n storageService,\n logger,\n clonedSnapshotTree,\n blobMap,\n );\n });\n this.dirtyFn = () => { dirtyFn(id); };\n }\n\n public async getChannel(): Promise<IChannel> {\n if (this.channel === undefined) {\n this.channel = await this.loadChannel()\n .catch((err) => {\n throw DataProcessingError.wrapIfUnrecognized(\n err, \"rehydratedLocalChannelContextFailedToLoadChannel\", undefined);\n });\n }\n return this.channel;\n }\n\n private async loadChannel(): Promise<IChannel> {\n assert(!this.isLoaded, 0x18e /* \"Channel must not already be loaded when loading\" */);\n assert(await this.services.value.objectStorage.contains(\".attributes\"),\n 0x190 /* \".attributes blob should be present\" */);\n const attributes = await readAndParse<IChannelAttributes>(\n this.services.value.objectStorage,\n \".attributes\");\n\n assert(this.factory === undefined, 0x208 /* \"Factory should be undefined before loading\" */);\n this.factory = this.registry.get(attributes.type);\n if (this.factory === undefined) {\n throw new Error(`Channel Factory ${attributes.type} not registered`);\n }\n // Services will be assigned during this load.\n const channel = await this.factory.load(\n this.runtime,\n this.id,\n this.services.value,\n attributes);\n\n // Commit changes.\n this.channel = channel;\n\n // Send all pending messages to the channel\n for (const message of this.pending) {\n this.services.value.deltaConnection.process(message, false, undefined /* localOpMetadata */);\n }\n return this.channel;\n }\n\n private isSnapshotInOldFormatAndCollectBlobs(\n snapshotTree: ISnapshotTree,\n blobMap: Map<string, ArrayBufferLike>,\n ): boolean {\n let sanitize = false;\n const blobsContents: {[path: string]: ArrayBufferLike} = (snapshotTree as any).blobsContents;\n Object.entries(blobsContents).forEach(([key, value]) => {\n blobMap.set(key, value);\n if (snapshotTree.blobs[key] !== undefined) {\n sanitize = true;\n }\n });\n for (const value of Object.values(snapshotTree.trees)) {\n sanitize = sanitize || this.isSnapshotInOldFormatAndCollectBlobs(value, blobMap);\n }\n return sanitize;\n }\n\n private sanitizeSnapshot(snapshotTree: ISnapshotTree) {\n const blobMapInitial = new Map(Object.entries(snapshotTree.blobs));\n for (const [blobName, blobId] of blobMapInitial.entries()) {\n const blobValue = blobMapInitial.get(blobId);\n if (blobValue === undefined) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete snapshotTree.blobs[blobName];\n }\n }\n for (const value of Object.values(snapshotTree.trees)) {\n this.sanitizeSnapshot(value);\n }\n }\n}\n\nexport class LocalChannelContext extends LocalChannelContextBase {\n private readonly services: Lazy<{\n readonly deltaConnection: ChannelDeltaConnection,\n readonly objectStorage: ChannelStorageService,\n }>;\n private readonly dirtyFn: () => void;\n constructor(\n id: string,\n registry: ISharedObjectRegistry,\n type: string,\n runtime: IFluidDataStoreRuntime,\n dataStoreContext: IFluidDataStoreContext,\n storageService: IDocumentStorageService,\n logger: ITelemetryLogger,\n submitFn: (content: any, localOpMetadata: unknown) => void,\n dirtyFn: (address: string) => void,\n addedGCOutboundReferenceFn: (srcHandle: IFluidHandle, outboundHandle: IFluidHandle) => void,\n ) {\n super(id, registry, runtime, () => this.services);\n assert(type !== undefined, 0x209 /* \"Factory Type should be defined\" */);\n this.factory = registry.get(type);\n if (this.factory === undefined) {\n throw new Error(`Channel Factory ${type} not registered`);\n }\n this.channel = this.factory.create(runtime, id);\n this.services = new Lazy(() => {\n return createServiceEndpoints(\n this.id,\n dataStoreContext.connected,\n submitFn,\n this.dirtyFn,\n addedGCOutboundReferenceFn,\n storageService,\n logger,\n );\n });\n this.dirtyFn = () => { dirtyFn(id); };\n }\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/datastore";
8
- export declare const pkgVersion = "0.58.2001";
8
+ export declare const pkgVersion = "0.59.1000-61898";
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,8BAA8B,CAAC;AACnD,eAAO,MAAM,UAAU,cAAc,CAAC"}
1
+ {"version":3,"file":"packageVersion.d.ts","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,8BAA8B,CAAC;AACnD,eAAO,MAAM,UAAU,oBAAoB,CAAC"}
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/datastore";
11
- exports.pkgVersion = "0.58.2001";
11
+ exports.pkgVersion = "0.59.1000-61898";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,2BAA2B,CAAC;AACtC,QAAA,UAAU,GAAG,WAAW,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/datastore\";\nexport const pkgVersion = \"0.58.2001\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,2BAA2B,CAAC;AACtC,QAAA,UAAU,GAAG,iBAAiB,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/datastore\";\nexport const pkgVersion = \"0.59.1000-61898\";\n"]}
@@ -7,7 +7,7 @@ import { IFluidHandle, IFluidHandleContext, IRequest, IResponse } from "@fluidfr
7
7
  import { IAudience, IDeltaManager, AttachState, ILoaderOptions } from "@fluidframework/container-definitions";
8
8
  import { TypedEventEmitter } from "@fluidframework/common-utils";
9
9
  import { IClientDetails, IDocumentMessage, ISequencedDocumentMessage, IQuorumClients } from "@fluidframework/protocol-definitions";
10
- import { IFluidDataStoreContext, IFluidDataStoreChannel, IGarbageCollectionData, IInboundSignalMessage, ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
10
+ import { IFluidDataStoreContext, IFluidDataStoreChannel, IGarbageCollectionData, IInboundSignalMessage, ISummaryTreeWithStats, VisibilityState } from "@fluidframework/runtime-definitions";
11
11
  import { IChannel, IFluidDataStoreRuntime, IFluidDataStoreRuntimeEvents, IChannelFactory } from "@fluidframework/datastore-definitions";
12
12
  export declare enum DataStoreMessageType {
13
13
  Attach = "attach",
@@ -47,12 +47,12 @@ export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataS
47
47
  private readonly contextsDeferred;
48
48
  private readonly pendingAttach;
49
49
  private bindState;
50
- private graphAttachState;
51
50
  private readonly deferredAttached;
52
51
  private readonly localChannelContextQueue;
53
52
  private readonly notBoundedChannelContextSet;
54
- private boundhandles;
55
53
  private _attachState;
54
+ visibilityState: VisibilityState;
55
+ private readonly pendingHandlesToMakeVisible;
56
56
  readonly id: string;
57
57
  readonly options: ILoaderOptions;
58
58
  readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
@@ -72,6 +72,18 @@ export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataS
72
72
  * @param channel - channel to be registered.
73
73
  */
74
74
  bindChannel(channel: IChannel): void;
75
+ /**
76
+ * This function is called when a data store becomes root. It does the following:
77
+ * 1. Marks the data store locally visible in the container.
78
+ * 2. Attaches the graph of all the handles bound to it.
79
+ * 3. Calls into the data store context to mark it visible in the container too. If the container is globally
80
+ * visible, it will mark us globally visible. Otherwise, it will mark us globally visible when it becomes
81
+ * globally visible.
82
+ */
83
+ makeVisibleAndAttachGraph(): void;
84
+ /**
85
+ * This function is called when a handle to this data store is added to a visible DDS.
86
+ */
75
87
  attachGraph(): void;
76
88
  /**
77
89
  * Binds this runtime to the container
@@ -106,8 +118,8 @@ export declare class FluidDataStoreRuntime extends TypedEventEmitter<IFluidDataS
106
118
  * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the
107
119
  * document. It does the following:
108
120
  * 1. Calls into each child context to get its GC data.
109
- * 2. Prefixs the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
110
- * idenfied as belonging to the child.
121
+ * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
122
+ * identified as belonging to the child.
111
123
  * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent
112
124
  * the GC data of this channel.
113
125
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
@@ -1 +1 @@
1
- {"version":3,"file":"dataStoreRuntime.d.ts","sourceRoot":"","sources":["../src/dataStoreRuntime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dataStoreRuntime.d.ts","sourceRoot":"","sources":["../src/dataStoreRuntime.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ import { assert, Deferred, LazyPromise, TypedEventEmitter, unreachableCase, } fr
8
8
  import { ChildLogger, raiseConnectedEvent, } from "@fluidframework/telemetry-utils";
9
9
  import { buildSnapshotTree } from "@fluidframework/driver-utils";
10
10
  import { SummaryType, } from "@fluidframework/protocol-definitions";
11
- import { CreateSummarizerNodeSource, } from "@fluidframework/runtime-definitions";
11
+ import { CreateSummarizerNodeSource, VisibilityState, } from "@fluidframework/runtime-definitions";
12
12
  import { convertSnapshotTreeToSummaryTree, convertSummaryTreeToITree, generateHandleContextPath, RequestParser, SummaryTreeBuilder, create404Response, createResponseError, exceptionToResponse, } from "@fluidframework/runtime-utils";
13
13
  import { GCDataBuilder, unpackChildNodesGCDetails, unpackChildNodesUsedRoutes, } from "@fluidframework/garbage-collector";
14
14
  import { v4 as uuid } from "uuid";
@@ -33,13 +33,12 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
33
33
  this.contexts = new Map();
34
34
  this.contextsDeferred = new Map();
35
35
  this.pendingAttach = new Map();
36
- // For new data stores, this is used to break the recursion while attaching the graph. The graph must be attached
37
- // before the data store can move to Attached state (see _attachState) and become live.
38
- // For existing data stores, the graph is always attached.
39
- this.graphAttachState = AttachState.Detached;
40
36
  this.deferredAttached = new Deferred();
41
37
  this.localChannelContextQueue = new Map();
42
38
  this.notBoundedChannelContextSet = new Set();
39
+ // A list of handles that are bound when the data store is not visible. We have to make them visible when the data
40
+ // store becomes visible.
41
+ this.pendingHandlesToMakeVisible = new Set();
43
42
  this.logger = ChildLogger.create(dataStoreContext.logger, "FluidDataStoreRuntime", { all: { dataStoreId: uuid() } });
44
43
  this.id = dataStoreContext.id;
45
44
  this.options = dataStoreContext.options;
@@ -66,11 +65,11 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
66
65
  if (dataStoreContext.isLocalDataStore) {
67
66
  channelContext = new RehydratedLocalChannelContext(path, this.sharedObjectRegistry, this, this.dataStoreContext, this.dataStoreContext.storage, this.logger, (content, localOpMetadata) => this.submitChannelOp(path, content, localOpMetadata), (address) => this.setChannelDirty(address), (srcHandle, outboundHandle) => this.addedGCOutboundReference(srcHandle, outboundHandle), tree.trees[path]);
68
67
  // This is the case of rehydrating a detached container from snapshot. Now due to delay loading of
69
- // data store, if the data store is loaded after the container is attached, then we missed marking
70
- // the channel as attached. So mark it now. Otherwise add it to local channel context queue, so
71
- // that it can be mark attached later with the data store.
68
+ // data store, if the data store is loaded after the container is attached, then we missed making
69
+ // the channel visible. So do it now. Otherwise, add it to local channel context queue, so
70
+ // that it can be make it visible later with the data store.
72
71
  if (dataStoreContext.attachState !== AttachState.Detached) {
73
- channelContext.markAttached();
72
+ channelContext.makeVisible();
74
73
  }
75
74
  else {
76
75
  this.localChannelContextQueue.set(path, channelContext);
@@ -86,9 +85,24 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
86
85
  });
87
86
  }
88
87
  this.attachListener();
89
- // If exists on storage or loaded from a snapshot, it should already be binded.
88
+ // If exists on storage or loaded from a snapshot, it should already be bound.
90
89
  this.bindState = existing ? BindState.Bound : BindState.NotBound;
91
90
  this._attachState = dataStoreContext.attachState;
91
+ /**
92
+ * If existing flag is false, this is a new data store and is not visible. The existing flag can be true in two
93
+ * conditions:
94
+ * 1. It's a local data store that is created when a detached container is rehydrated. In this case, the data
95
+ * store is locally visible because the snapshot it is loaded from contains locally visible data stores only.
96
+ * 2. It's a remote data store that is created when an attached container is loaded is loaded from snapshot or
97
+ * when an attach op comes in. In both these cases, the data store is already globally visible.
98
+ */
99
+ if (existing) {
100
+ this.visibilityState = dataStoreContext.attachState === AttachState.Detached
101
+ ? VisibilityState.LocallyVisible : VisibilityState.GloballyVisible;
102
+ }
103
+ else {
104
+ this.visibilityState = VisibilityState.NotVisible;
105
+ }
92
106
  // If it's existing we know it has been attached.
93
107
  if (existing) {
94
108
  this.deferredAttached.resolve();
@@ -212,34 +226,43 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
212
226
  this.attachChannel(channel);
213
227
  return;
214
228
  }
215
- else {
216
- this.bind(channel.handle);
217
- // If our data store is local then add the channel to the queue
218
- if (!this.localChannelContextQueue.has(channel.id)) {
219
- this.localChannelContextQueue.set(channel.id, this.contexts.get(channel.id));
220
- }
229
+ /**
230
+ * If this channel is already waiting to be made visible, do nothing. This can happen during attachGraph() when
231
+ * a channel's graph is attached. It calls bindToContext on the shared object which will end up back here.
232
+ */
233
+ if (this.pendingHandlesToMakeVisible.has(channel.handle)) {
234
+ return;
235
+ }
236
+ this.bind(channel.handle);
237
+ // If our data store is local then add the channel to the queue
238
+ if (!this.localChannelContextQueue.has(channel.id)) {
239
+ this.localChannelContextQueue.set(channel.id, this.contexts.get(channel.id));
221
240
  }
222
241
  }
223
- attachGraph() {
224
- if (this.graphAttachState !== AttachState.Detached) {
242
+ /**
243
+ * This function is called when a data store becomes root. It does the following:
244
+ * 1. Marks the data store locally visible in the container.
245
+ * 2. Attaches the graph of all the handles bound to it.
246
+ * 3. Calls into the data store context to mark it visible in the container too. If the container is globally
247
+ * visible, it will mark us globally visible. Otherwise, it will mark us globally visible when it becomes
248
+ * globally visible.
249
+ */
250
+ makeVisibleAndAttachGraph() {
251
+ if (this.visibilityState !== VisibilityState.NotVisible) {
225
252
  return;
226
253
  }
227
- this.graphAttachState = AttachState.Attaching;
228
- if (this.boundhandles !== undefined) {
229
- this.boundhandles.forEach((handle) => {
230
- handle.attachGraph();
231
- });
232
- this.boundhandles = undefined;
233
- }
234
- // Flush the queue to set any pre-existing channels to local
235
- this.localChannelContextQueue.forEach((channel) => {
236
- // When we are attaching the data store we don't need to send attach for the registered services.
237
- // This is because they will be captured as part of the Attach data store snapshot
238
- channel.markAttached();
254
+ this.visibilityState = VisibilityState.LocallyVisible;
255
+ this.pendingHandlesToMakeVisible.forEach((handle) => {
256
+ handle.attachGraph();
239
257
  });
240
- this.localChannelContextQueue.clear();
258
+ this.pendingHandlesToMakeVisible.clear();
241
259
  this.bindToContext();
242
- this.graphAttachState = AttachState.Attached;
260
+ }
261
+ /**
262
+ * This function is called when a handle to this data store is added to a visible DDS.
263
+ */
264
+ attachGraph() {
265
+ this.makeVisibleAndAttachGraph();
243
266
  }
244
267
  /**
245
268
  * Binds this runtime to the container
@@ -256,16 +279,12 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
256
279
  this.bindState = BindState.Bound;
257
280
  }
258
281
  bind(handle) {
259
- // If the data store is already attached or its graph is already in attaching or attached state,
260
- // then attach the incoming handle too.
261
- if (this.isAttached || this.graphAttachState !== AttachState.Detached) {
282
+ // If visible, attach the incoming handle's graph. Else, this will be done when we become visible.
283
+ if (this.visibilityState !== VisibilityState.NotVisible) {
262
284
  handle.attachGraph();
263
285
  return;
264
286
  }
265
- if (this.boundhandles === undefined) {
266
- this.boundhandles = new Set();
267
- }
268
- this.boundhandles.add(handle);
287
+ this.pendingHandlesToMakeVisible.add(handle);
269
288
  }
270
289
  setConnectionState(connected, clientId) {
271
290
  this.verifyNotClosed();
@@ -376,8 +395,8 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
376
395
  * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the
377
396
  * document. It does the following:
378
397
  * 1. Calls into each child context to get its GC data.
379
- * 2. Prefixs the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
380
- * idenfied as belonging to the child.
398
+ * 2. Prefixes the child context's id to the GC nodes in the child's GC data. This makes sure that the node can be
399
+ * identified as belonging to the child.
381
400
  * 3. Adds a GC node for this channel to the nodes received from the children. All these nodes together represent
382
401
  * the GC data of this channel.
383
402
  * @param fullGC - true to bypass optimizations and force full generation of GC data.
@@ -475,7 +494,24 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
475
494
  return summaryBuilder.getSummaryTree();
476
495
  }
477
496
  getAttachSummary() {
497
+ /**
498
+ * back-compat 0.59.1000 - getAttachSummary() is called when making a data store globally visible (previously
499
+ * attaching state). Ideally, attachGraph() should have already be called making it locally visible. However,
500
+ * before visibility state was added, this may not have been the case and getAttachSummary() could be called:
501
+ * 1) Before attaching the data store - When a detached container is attached.
502
+ * 2) After attaching the data store - When a data store is created and bound in an attached container.
503
+ *
504
+ * The basic idea is that all local object should become locally visible before they are globally visible.
505
+ */
478
506
  this.attachGraph();
507
+ /**
508
+ * This assert cannot be added now due to back-compat. To be uncommented when the following issue is fixed -
509
+ * https://github.com/microsoft/FluidFramework/issues/9688.
510
+ *
511
+ * assert(this.visibilityState === VisibilityState.LocallyVisible,
512
+ * "The data store should be locally visible when generating attach summary",
513
+ * );
514
+ */
479
515
  const summaryBuilder = new SummaryTreeBuilder();
480
516
  // Craft the .attributes file for each shared object
481
517
  for (const [contextId, context] of this.contexts) {
@@ -524,22 +560,19 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
524
560
  }
525
561
  channel.handle.attachGraph();
526
562
  assert(this.isAttached, 0x182 /* "Data store should be attached to attach the channel." */);
527
- // Get the object snapshot only if the data store is Bound and its graph is attached too,
528
- // because if the graph is attaching, then it would get included in the data store snapshot.
529
- if (this.bindState === BindState.Bound && this.graphAttachState === AttachState.Attached) {
530
- const summarizeResult = summarizeChannel(channel, true /* fullTree */, false /* trackState */);
531
- // Attach message needs the summary in ITree format. Convert the ISummaryTree into an ITree.
532
- const snapshot = convertSummaryTreeToITree(summarizeResult.summary);
533
- const message = {
534
- id: channel.id,
535
- snapshot,
536
- type: channel.attributes.type,
537
- };
538
- this.pendingAttach.set(channel.id, message);
539
- this.submit(DataStoreMessageType.Attach, message);
540
- }
563
+ assert(this.visibilityState === VisibilityState.GloballyVisible, 0x2d0 /* "Data store should be globally visible to attach channels." */);
564
+ const summarizeResult = summarizeChannel(channel, true /* fullTree */, false /* trackState */);
565
+ // Attach message needs the summary in ITree format. Convert the ISummaryTree into an ITree.
566
+ const snapshot = convertSummaryTreeToITree(summarizeResult.summary);
567
+ const message = {
568
+ id: channel.id,
569
+ snapshot,
570
+ type: channel.attributes.type,
571
+ };
572
+ this.pendingAttach.set(channel.id, message);
573
+ this.submit(DataStoreMessageType.Attach, message);
541
574
  const context = this.contexts.get(channel.id);
542
- context.markAttached();
575
+ context.makeVisible();
543
576
  }
544
577
  submitChannelOp(address, contents, localOpMetadata) {
545
578
  const envelope = { address, contents };
@@ -599,14 +632,30 @@ export class FluidDataStoreRuntime extends TypedEventEmitter {
599
632
  attachListener() {
600
633
  this.setMaxListeners(Number.MAX_SAFE_INTEGER);
601
634
  this.dataStoreContext.once("attaching", () => {
602
- assert(this.bindState !== BindState.NotBound, 0x186 /* "Data store attaching should not occur if it is not bound" */);
635
+ /**
636
+ * back-compat 0.59.1000 - Ideally, attachGraph() should have already been called making the data store
637
+ * locally visible. However, before visibility state was added, this may not have been the case and data
638
+ * store can move to "attaching" state in 2 scenarios:
639
+ * 1) Before attachGraph() is called - When a data store is created and bound in an attached container.
640
+ * 2) After attachGraph() is called - When a detached container is attached.
641
+ *
642
+ * The basic idea is that all local object should become locally visible before they are globally visible.
643
+ */
644
+ this.attachGraph();
603
645
  this._attachState = AttachState.Attaching;
646
+ assert(this.visibilityState === VisibilityState.LocallyVisible, 0x2d1 /* "Data store should be locally visible before it can become globally visible." */);
647
+ // Mark the data store globally visible and make its child channels visible as well.
648
+ this.visibilityState = VisibilityState.GloballyVisible;
649
+ this.localChannelContextQueue.forEach((channel) => {
650
+ channel.makeVisible();
651
+ });
652
+ this.localChannelContextQueue.clear();
604
653
  // This promise resolution will be moved to attached event once we fix the scheduler.
605
654
  this.deferredAttached.resolve();
606
655
  this.emit("attaching");
607
656
  });
608
657
  this.dataStoreContext.once("attached", () => {
609
- assert(this.bindState === BindState.Bound, 0x187 /* "Data store should only be attached after it is bound" */);
658
+ assert(this.visibilityState === VisibilityState.GloballyVisible, 0x2d2 /* "Data store should be globally visible when its attached." */);
610
659
  this._attachState = AttachState.Attached;
611
660
  this.emit("attached");
612
661
  });