@fluidframework/datastore 2.0.0-dev.3.1.0.125672 → 2.0.0-dev.4.2.0.153917

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/CHANGELOG.md +34 -0
  2. package/README.md +38 -0
  3. package/dist/channelContext.d.ts +2 -2
  4. package/dist/channelContext.d.ts.map +1 -1
  5. package/dist/channelContext.js +2 -2
  6. package/dist/channelContext.js.map +1 -1
  7. package/dist/dataStoreRuntime.d.ts +14 -9
  8. package/dist/dataStoreRuntime.d.ts.map +1 -1
  9. package/dist/dataStoreRuntime.js +47 -48
  10. package/dist/dataStoreRuntime.js.map +1 -1
  11. package/dist/packageVersion.d.ts +1 -1
  12. package/dist/packageVersion.js +1 -1
  13. package/dist/packageVersion.js.map +1 -1
  14. package/dist/remoteChannelContext.d.ts +2 -2
  15. package/dist/remoteChannelContext.d.ts.map +1 -1
  16. package/dist/remoteChannelContext.js +41 -60
  17. package/dist/remoteChannelContext.js.map +1 -1
  18. package/lib/channelContext.d.ts +2 -2
  19. package/lib/channelContext.d.ts.map +1 -1
  20. package/lib/channelContext.js +2 -2
  21. package/lib/channelContext.js.map +1 -1
  22. package/lib/dataStoreRuntime.d.ts +14 -9
  23. package/lib/dataStoreRuntime.d.ts.map +1 -1
  24. package/lib/dataStoreRuntime.js +48 -49
  25. package/lib/dataStoreRuntime.js.map +1 -1
  26. package/lib/packageVersion.d.ts +1 -1
  27. package/lib/packageVersion.js +1 -1
  28. package/lib/packageVersion.js.map +1 -1
  29. package/lib/remoteChannelContext.d.ts +2 -2
  30. package/lib/remoteChannelContext.d.ts.map +1 -1
  31. package/lib/remoteChannelContext.js +41 -60
  32. package/lib/remoteChannelContext.js.map +1 -1
  33. package/package.json +58 -59
  34. package/src/channelContext.ts +8 -1
  35. package/src/dataStoreRuntime.ts +77 -68
  36. package/src/packageVersion.ts +1 -1
  37. package/src/remoteChannelContext.ts +49 -60
@@ -1 +1 @@
1
- {"version":3,"file":"remoteChannelContext.js","sourceRoot":"","sources":["../src/remoteChannelContext.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAStE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAY5D,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAClG,OAAO,EACN,iBAAiB,EACjB,sBAAsB,EAEtB,qBAAqB,GACrB,MAAM,kBAAkB,CAAC;AAK1B,MAAM,OAAO,oBAAoB;IAchC,YACkB,OAA+B,EAC/B,gBAAwC,EACzD,cAAuC,EACvC,QAA0D,EAC1D,OAAkC,EAClC,0BAA2F,EAC1E,EAAU,EAC3B,YAA2B,EACV,QAA+B,EAChD,UAAoD,EACpD,oBAAiD,EACjD,gBAA8D,EAC7C,iBAA0B;QAZ1B,YAAO,GAAP,OAAO,CAAwB;QAC/B,qBAAgB,GAAhB,gBAAgB,CAAwB;QAKxC,OAAE,GAAF,EAAE,CAAQ;QAEV,aAAQ,GAAR,QAAQ,CAAuB;QAI/B,sBAAiB,GAAjB,iBAAiB,CAAS;QA1BpC,aAAQ,GAAG,KAAK,CAAC;QACjB,YAAO,GAA4C,EAAE,CAAC;QA2B7D,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAEtF,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAEjF,IAAI,CAAC,QAAQ,GAAG,sBAAsB,CACrC,IAAI,CAAC,EAAE,EACP,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAC/B,QAAQ,EACR,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EACtB,0BAA0B,EAC1B,cAAc,EACd,IAAI,CAAC,SAAS,EACd,YAAY,EACZ,UAAU,CACV,CAAC;QAEF,MAAM,qBAAqB,GAAG,KAAK,EAClC,QAAiB,EACjB,UAAmB,EACnB,gBAAoC,EACnC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;QAEpE,IAAI,CAAC,cAAc,GAAG,oBAAoB,CACzC,qBAAqB,EACrB,KAAK,EAAE,MAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAC1D,KAAK,IAAI,EAAE,CAAC,gBAAgB,EAAE,CAC9B,CAAC;QAEF,IAAI,CAAC,mBAAmB,GAAG,IAAI,gBAAgB,CAC9C,oBAAoB,CAAC,wBAAwB,EAC7C,IAAI,CAAC,SAAS,CACd,CAAC;IACH,CAAC;IAED,qEAAqE;IAC9D,UAAU;QAChB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE;YAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;SACnC;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC;IAEM,kBAAkB,CAAC,SAAkB,EAAE,QAAiB;QAC9D,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YACnB,OAAO;SACP;QAED,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;IAEM,cAAc,CAAC,OAAkC;QACvD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAEM,SAAS,CACf,OAAkC,EAClC,KAAc,EACd,eAAwB;QAExB,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEvD,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClB,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;SACvE;aAAM;YACN,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,2DAA2D,CAAC,CAAC;YAClF,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,4BAA4B,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;SAChF;IACF,CAAC;IAEM,QAAQ,CAAC,OAAY,EAAE,eAAwB;QACrD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAExF,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClE,CAAC;IAEM,QAAQ,CAAC,OAAY,EAAE,eAAwB;QACrD,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAExF,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClE,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,SAAS,CACrB,WAAoB,KAAK,EACzB,aAAsB,IAAI,EAC1B,gBAAoC;QAEpC,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,gBAAgB,CAAC,CAAC;IAC9E,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC9B,QAAiB,EACjB,UAAmB,EACnB,gBAAoC;QAEpC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,eAAe,GAAG,MAAM,qBAAqB,CAClD,OAAO,EACP,QAAQ,EACR,UAAU,EACV,gBAAgB,CAChB,CAAC;QACF,uCAAY,eAAe,KAAE,EAAE,EAAE,IAAI,CAAC,EAAE,IAAG;IAC5C,CAAC;IAEO,KAAK,CAAC,WAAW;QACxB,MAAM,CACL,CAAC,IAAI,CAAC,QAAQ,EACd,KAAK,CAAC,8DAA8D,CACpE,CAAC;QAEF,IAAI,UAA0C,CAAC;QAC/C,IAAI,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YAClE,UAAU,GAAG,MAAM,YAAY,CAC9B,IAAI,CAAC,QAAQ,CAAC,aAAa,EAC3B,iBAAiB,CACjB,CAAC;SACF;QAED,IAAI,OAAoC,CAAC;QACzC,8CAA8C;QAC9C,qCAAqC;QACrC,4CAA4C;QAC5C,2CAA2C;QAC3C,iDAAiD;QACjD,IAAI,UAAU,KAAK,SAAS,EAAE;YAC7B,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE;gBACzC,uEAAuE;gBACvE,MAAM,IAAI,mBAAmB,CAAC,yBAAyB,EAAE;oBACxD,SAAS,EAAE;wBACV,KAAK,EAAE,IAAI,CAAC,EAAE;wBACd,GAAG,EAAE,gBAAgB,CAAC,YAAY;qBAClC;oBACD,WAAW,EAAE;wBACZ,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE;wBAC/B,GAAG,EAAE,gBAAgB,CAAC,YAAY;qBAClC;oBACD,oBAAoB,EAAE,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;iBACjE,CAAC,CAAC;aACH;YACD,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpD,IAAI,OAAO,KAAK,SAAS,EAAE;gBAC1B,uEAAuE;gBACvE,MAAM,IAAI,mBAAmB,CAAC,iDAAiD,EAAE;oBAChF,SAAS,EAAE;wBACV,KAAK,EAAE,IAAI,CAAC,EAAE;wBACd,GAAG,EAAE,gBAAgB,CAAC,YAAY;qBAClC;oBACD,WAAW,EAAE;wBACZ,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE;wBAC/B,GAAG,EAAE,gBAAgB,CAAC,YAAY;qBAClC;oBACD,oBAAoB,EAAE,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;oBACjE,kBAAkB,EAAE,IAAI,CAAC,iBAAiB;iBAC1C,CAAC,CAAC;aACH;YACD,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;SAChC;aAAM;YACN,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,OAAO,KAAK,SAAS,EAAE;gBAC1B,uEAAuE;gBACvE,MAAM,IAAI,mBAAmB,CAAC,yCAAyC,EAAE;oBACxE,SAAS,EAAE;wBACV,KAAK,EAAE,IAAI,CAAC,EAAE;wBACd,GAAG,EAAE,gBAAgB,CAAC,YAAY;qBAClC;oBACD,WAAW,EAAE;wBACZ,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE;wBAC/B,GAAG,EAAE,gBAAgB,CAAC,YAAY;qBAClC;oBACD,oBAAoB,EAAE,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;oBACjE,kBAAkB,EAAE,UAAU,CAAC,IAAI;iBACnC,CAAC,CAAC;aACH;SACD;QAED,2DAA2D;QAC3D,IACC,UAAU,CAAC,qBAAqB,KAAK,SAAS;YAC9C,UAAU,CAAC,qBAAqB,KAAK,OAAO,CAAC,UAAU,CAAC,qBAAqB,EAC5E;YACD,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC;gBACjC,SAAS,EAAE,kCAAkC;gBAC7C,WAAW,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,gBAAgB,CAAC,YAAY,EAAE;gBAC3E,sBAAsB,EAAE;oBACvB,KAAK,EAAE,GAAG,UAAU,CAAC,qBAAqB,IAAI,UAAU,CAAC,cAAc,EAAE;oBACzE,GAAG,EAAE,gBAAgB,CAAC,YAAY;iBAClC;gBACD,kBAAkB,EAAE;oBACnB,KAAK,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,qBAAqB,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE;oBACzF,GAAG,EAAE,gBAAgB,CAAC,YAAY;iBAClC;aACD,CAAC,CAAC;SACH;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAErF,2CAA2C;QAC3C,MAAM,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACpE,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE;YACnC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,qBAAqB,CAAC,CAAC;SACvF;QACD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAExE,kBAAkB;QAClB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,2GAA2G;QAC3G,wGAAwG;QACxG,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,SAAS,CAAC,SAAkB,KAAK;QAC7C,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,iBAAiB,CAAC,SAAkB,KAAK;QACtD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAEM,gBAAgB,CAAC,UAAoB;QAC3C;;;;;WAKG;QACH,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC;;AA/QuB,6CAAwB,GAAG,IAAI,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { DataCorruptionError } from \"@fluidframework/container-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n\tIChannelFactory,\n} from \"@fluidframework/datastore-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tCreateChildSummarizerNodeFn,\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tIGarbageCollectionDetailsBase,\n\tISummarizeInternalResult,\n\tISummarizeResult,\n\tISummarizerNodeWithGC,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { ChildLogger, TelemetryDataTag, ThresholdCounter } from \"@fluidframework/telemetry-utils\";\nimport {\n\tattributesBlobKey,\n\tcreateServiceEndpoints,\n\tIChannelContext,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ChannelDeltaConnection } from \"./channelDeltaConnection\";\nimport { ChannelStorageService } from \"./channelStorageService\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\nexport class RemoteChannelContext implements IChannelContext {\n\tprivate isLoaded = false;\n\tprivate pending: ISequencedDocumentMessage[] | undefined = [];\n\tprivate channelP: Promise<IChannel> | undefined;\n\tprivate channel: IChannel | undefined;\n\tprivate readonly services: {\n\t\treadonly deltaConnection: ChannelDeltaConnection;\n\t\treadonly objectStorage: ChannelStorageService;\n\t};\n\tprivate readonly summarizerNode: ISummarizerNodeWithGC;\n\tprivate readonly subLogger: ITelemetryLogger;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\tprivate readonly dataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\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 id: string,\n\t\tbaseSnapshot: ISnapshotTree,\n\t\tprivate readonly registry: ISharedObjectRegistry,\n\t\textraBlobs: Map<string, ArrayBufferLike> | undefined,\n\t\tcreateSummarizerNode: CreateChildSummarizerNodeFn,\n\t\tgetBaseGCDetails: () => Promise<IGarbageCollectionDetailsBase>,\n\t\tprivate readonly attachMessageType?: string,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x310 /* Channel context ID cannot contain slashes */);\n\n\t\tthis.subLogger = ChildLogger.create(this.runtime.logger, \"RemoteChannelContext\");\n\n\t\tthis.services = createServiceEndpoints(\n\t\t\tthis.id,\n\t\t\tthis.dataStoreContext.connected,\n\t\t\tsubmitFn,\n\t\t\t() => dirtyFn(this.id),\n\t\t\taddedGCOutboundReferenceFn,\n\t\t\tstorageService,\n\t\t\tthis.subLogger,\n\t\t\tbaseSnapshot,\n\t\t\textraBlobs,\n\t\t);\n\n\t\tconst thisSummarizeInternal = async (\n\t\t\tfullTree: boolean,\n\t\t\ttrackState: boolean,\n\t\t\ttelemetryContext?: ITelemetryContext,\n\t\t) => this.summarizeInternal(fullTree, trackState, telemetryContext);\n\n\t\tthis.summarizerNode = createSummarizerNode(\n\t\t\tthisSummarizeInternal,\n\t\t\tasync (fullGC?: boolean) => this.getGCDataInternal(fullGC),\n\t\t\tasync () => getBaseGCDetails(),\n\t\t);\n\n\t\tthis.thresholdOpsCounter = new ThresholdCounter(\n\t\t\tRemoteChannelContext.pendingOpsCountThreshold,\n\t\t\tthis.subLogger,\n\t\t);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\tpublic getChannel(): Promise<IChannel> {\n\t\tif (this.channelP === undefined) {\n\t\t\tthis.channelP = this.loadChannel();\n\t\t}\n\n\t\treturn this.channelP;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet loaded\n\t\tif (!this.isLoaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.services.deltaConnection.setConnectionState(connected);\n\t}\n\n\tpublic applyStashedOp(message: ISequencedDocumentMessage): unknown {\n\t\tassert(this.isLoaded, 0x194 /* \"Remote channel must be loaded when rebasing op\" */);\n\t\treturn this.services.deltaConnection.applyStashedOp(message);\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tthis.summarizerNode.invalidate(message.sequenceNumber);\n\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(!local, 0x195 /* \"Remote channel must not be local when processing op\" */);\n\t\t\tassert(this.pending !== undefined, 0x23e /* \"pending is undefined\" */);\n\t\t\tthis.pending.push(message);\n\t\t\tthis.thresholdOpsCounter.sendIfMultiple(\"StorePendingOps\", this.pending.length);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x196 /* \"Remote channel must be loaded when resubmitting op\" */);\n\n\t\tthis.services.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2f0 /* \"Remote channel must be loaded when rolling back op\" */);\n\n\t\tthis.services.deltaConnection.rollback(content, localOpMetadata);\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 = true,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\treturn this.summarizerNode.summarize(fullTree, trackState, telemetryContext);\n\t}\n\n\tprivate async summarizeInternal(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeInternalResult> {\n\t\tconst channel = await this.getChannel();\n\t\tconst summarizeResult = await summarizeChannelAsync(\n\t\t\tchannel,\n\t\t\tfullTree,\n\t\t\ttrackState,\n\t\t\ttelemetryContext,\n\t\t);\n\t\treturn { ...summarizeResult, id: this.id };\n\t}\n\n\tprivate async loadChannel(): Promise<IChannel> {\n\t\tassert(\n\t\t\t!this.isLoaded,\n\t\t\t0x197 /* \"Remote channel must not already be loaded when loading\" */,\n\t\t);\n\n\t\tlet attributes: IChannelAttributes | undefined;\n\t\tif (await this.services.objectStorage.contains(attributesBlobKey)) {\n\t\t\tattributes = await readAndParse<IChannelAttributes | undefined>(\n\t\t\t\tthis.services.objectStorage,\n\t\t\t\tattributesBlobKey,\n\t\t\t);\n\t\t}\n\n\t\tlet factory: IChannelFactory | undefined;\n\t\t// this is a backward compatibility case where\n\t\t// the attach message doesn't include\n\t\t// the attributes. Since old attach messages\n\t\t// will not have attributes we need to keep\n\t\t// this as long as we support old attach messages\n\t\tif (attributes === undefined) {\n\t\t\tif (this.attachMessageType === undefined) {\n\t\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\t\tthrow new DataCorruptionError(\"channelTypeNotAvailable\", {\n\t\t\t\t\tchannelId: {\n\t\t\t\t\t\tvalue: this.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStoreId: {\n\t\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfactory = this.registry.get(this.attachMessageType);\n\t\t\tif (factory === undefined) {\n\t\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\t\tthrow new DataCorruptionError(\"channelFactoryNotRegisteredForAttachMessageType\", {\n\t\t\t\t\tchannelId: {\n\t\t\t\t\t\tvalue: this.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStoreId: {\n\t\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\t\tchannelFactoryType: this.attachMessageType,\n\t\t\t\t});\n\t\t\t}\n\t\t\tattributes = factory.attributes;\n\t\t} else {\n\t\t\tfactory = this.registry.get(attributes.type);\n\t\t\tif (factory === undefined) {\n\t\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\t\tthrow new DataCorruptionError(\"channelFactoryNotRegisteredForGivenType\", {\n\t\t\t\t\tchannelId: {\n\t\t\t\t\t\tvalue: this.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStoreId: {\n\t\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\t},\n\t\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\t\tchannelFactoryType: attributes.type,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Compare snapshot version to collaborative object version\n\t\tif (\n\t\t\tattributes.snapshotFormatVersion !== undefined &&\n\t\t\tattributes.snapshotFormatVersion !== factory.attributes.snapshotFormatVersion\n\t\t) {\n\t\t\tthis.subLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"ChannelAttributesVersionMismatch\",\n\t\t\t\tchannelType: { value: attributes.type, tag: TelemetryDataTag.CodeArtifact },\n\t\t\t\tchannelSnapshotVersion: {\n\t\t\t\t\tvalue: `${attributes.snapshotFormatVersion}@${attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tchannelCodeVersion: {\n\t\t\t\t\tvalue: `${factory.attributes.snapshotFormatVersion}@${factory.attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconst channel = await factory.load(this.runtime, this.id, this.services, attributes);\n\n\t\t// Send all pending messages to the channel\n\t\tassert(this.pending !== undefined, 0x23f /* \"pending undefined\" */);\n\t\tfor (const message of this.pending) {\n\t\t\tthis.services.deltaConnection.process(message, false, undefined /* localOpMetadata */);\n\t\t}\n\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pending.length);\n\n\t\t// Commit changes.\n\t\tthis.channel = channel;\n\t\tthis.pending = undefined;\n\t\tthis.isLoaded = true;\n\n\t\t// Because have some await between we created the service and here, the connection state might have changed\n\t\t// and we don't propagate the connection state when we are not loaded. So we have to set it again here.\n\t\tthis.services.deltaConnection.setConnectionState(this.dataStoreContext.connected);\n\t\treturn this.channel;\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.\n\t * If there is no new data in this context since the last summary, previous GC data is used.\n\t * If there is new data, the GC data is generated again (by calling getGCDataInternal).\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\treturn this.summarizerNode.getGCData(fullGC);\n\t}\n\n\t/**\n\t * Generates the data used for garbage collection. This is called when there is new data since last summary. It\n\t * loads the context and calls into the channel to get its GC data.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tprivate async getGCDataInternal(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. Update the summarizer node's\n\t\t * used routes to contain a route to this channel context.\n\t\t * Once we have GC at DDS level, this will be updated to use the passed usedRoutes. See -\n\t\t * https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t\tthis.summarizerNode.updateUsedRoutes([\"\"]);\n\t}\n}\n"]}
1
+ {"version":3,"file":"remoteChannelContext.js","sourceRoot":"","sources":["../src/remoteChannelContext.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { DataCorruptionError } from \"@fluidframework/container-utils\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport {\n\tIChannel,\n\tIChannelAttributes,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { readAndParse } from \"@fluidframework/driver-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\tCreateChildSummarizerNodeFn,\n\tIFluidDataStoreContext,\n\tIGarbageCollectionData,\n\tIExperimentalIncrementalSummaryContext,\n\tISummarizeInternalResult,\n\tISummarizeResult,\n\tISummarizerNodeWithGC,\n\tITelemetryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { ChildLogger, TelemetryDataTag, ThresholdCounter } from \"@fluidframework/telemetry-utils\";\nimport {\n\tattributesBlobKey,\n\tcreateServiceEndpoints,\n\tIChannelContext,\n\tsummarizeChannelAsync,\n} from \"./channelContext\";\nimport { ChannelDeltaConnection } from \"./channelDeltaConnection\";\nimport { ChannelStorageService } from \"./channelStorageService\";\nimport { ISharedObjectRegistry } from \"./dataStoreRuntime\";\n\nexport class RemoteChannelContext implements IChannelContext {\n\tprivate isLoaded = false;\n\tprivate pending: ISequencedDocumentMessage[] | undefined = [];\n\tprivate channelP: Promise<IChannel> | undefined;\n\tprivate channel: IChannel | undefined;\n\tprivate readonly services: {\n\t\treadonly deltaConnection: ChannelDeltaConnection;\n\t\treadonly objectStorage: ChannelStorageService;\n\t};\n\tprivate readonly summarizerNode: ISummarizerNodeWithGC;\n\tprivate readonly subLogger: ITelemetryLogger;\n\tprivate readonly thresholdOpsCounter: ThresholdCounter;\n\tprivate static readonly pendingOpsCountThreshold = 1000;\n\n\tconstructor(\n\t\tprivate readonly runtime: IFluidDataStoreRuntime,\n\t\tprivate readonly dataStoreContext: IFluidDataStoreContext,\n\t\tstorageService: IDocumentStorageService,\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 id: string,\n\t\tbaseSnapshot: ISnapshotTree,\n\t\tprivate readonly registry: ISharedObjectRegistry,\n\t\textraBlobs: Map<string, ArrayBufferLike> | undefined,\n\t\tcreateSummarizerNode: CreateChildSummarizerNodeFn,\n\t\tprivate readonly attachMessageType?: string,\n\t) {\n\t\tassert(!this.id.includes(\"/\"), 0x310 /* Channel context ID cannot contain slashes */);\n\n\t\tthis.subLogger = ChildLogger.create(this.runtime.logger, \"RemoteChannelContext\");\n\n\t\tthis.services = createServiceEndpoints(\n\t\t\tthis.id,\n\t\t\tthis.dataStoreContext.connected,\n\t\t\tsubmitFn,\n\t\t\t() => dirtyFn(this.id),\n\t\t\taddedGCOutboundReferenceFn,\n\t\t\tstorageService,\n\t\t\tthis.subLogger,\n\t\t\tbaseSnapshot,\n\t\t\textraBlobs,\n\t\t);\n\n\t\tconst thisSummarizeInternal = async (\n\t\t\tfullTree: boolean,\n\t\t\ttrackState: boolean,\n\t\t\ttelemetryContext?: ITelemetryContext,\n\t\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t\t) =>\n\t\t\tthis.summarizeInternal(\n\t\t\t\tfullTree,\n\t\t\t\ttrackState,\n\t\t\t\ttelemetryContext,\n\t\t\t\tincrementalSummaryContext,\n\t\t\t);\n\n\t\tthis.summarizerNode = createSummarizerNode(\n\t\t\tthisSummarizeInternal,\n\t\t\tasync (fullGC?: boolean) => this.getGCDataInternal(fullGC),\n\t\t);\n\n\t\tthis.thresholdOpsCounter = new ThresholdCounter(\n\t\t\tRemoteChannelContext.pendingOpsCountThreshold,\n\t\t\tthis.subLogger,\n\t\t);\n\t}\n\n\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\tpublic getChannel(): Promise<IChannel> {\n\t\tif (this.channelP === undefined) {\n\t\t\tthis.channelP = this.loadChannel();\n\t\t}\n\n\t\treturn this.channelP;\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\t// Connection events are ignored if the data store is not yet loaded\n\t\tif (!this.isLoaded) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.services.deltaConnection.setConnectionState(connected);\n\t}\n\n\tpublic applyStashedOp(message: ISequencedDocumentMessage): unknown {\n\t\tassert(this.isLoaded, 0x194 /* \"Remote channel must be loaded when rebasing op\" */);\n\t\treturn this.services.deltaConnection.applyStashedOp(message);\n\t}\n\n\tpublic processOp(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t): void {\n\t\tthis.summarizerNode.invalidate(message.sequenceNumber);\n\n\t\tif (this.isLoaded) {\n\t\t\tthis.services.deltaConnection.process(message, local, localOpMetadata);\n\t\t} else {\n\t\t\tassert(!local, 0x195 /* \"Remote channel must not be local when processing op\" */);\n\t\t\tassert(this.pending !== undefined, 0x23e /* \"pending is undefined\" */);\n\t\t\tthis.pending.push(message);\n\t\t\tthis.thresholdOpsCounter.sendIfMultiple(\"StorePendingOps\", this.pending.length);\n\t\t}\n\t}\n\n\tpublic reSubmit(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x196 /* \"Remote channel must be loaded when resubmitting op\" */);\n\n\t\tthis.services.deltaConnection.reSubmit(content, localOpMetadata);\n\t}\n\n\tpublic rollback(content: any, localOpMetadata: unknown) {\n\t\tassert(this.isLoaded, 0x2f0 /* \"Remote channel must be loaded when rolling back op\" */);\n\n\t\tthis.services.deltaConnection.rollback(content, localOpMetadata);\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 = true,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummarizeResult> {\n\t\treturn this.summarizerNode.summarize(fullTree, trackState, telemetryContext);\n\t}\n\n\tprivate async summarizeInternal(\n\t\tfullTree: boolean,\n\t\ttrackState: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): Promise<ISummarizeInternalResult> {\n\t\tconst channel = await this.getChannel();\n\t\tconst summarizeResult = await summarizeChannelAsync(\n\t\t\tchannel,\n\t\t\tfullTree,\n\t\t\ttrackState,\n\t\t\ttelemetryContext,\n\t\t\tincrementalSummaryContext,\n\t\t);\n\t\treturn { ...summarizeResult, id: this.id };\n\t}\n\n\tprivate async loadChannel(): Promise<IChannel> {\n\t\tassert(\n\t\t\t!this.isLoaded,\n\t\t\t0x197 /* \"Remote channel must not already be loaded when loading\" */,\n\t\t);\n\n\t\tlet attributes: IChannelAttributes | undefined;\n\t\tif (await this.services.objectStorage.contains(attributesBlobKey)) {\n\t\t\tattributes = await readAndParse<IChannelAttributes | undefined>(\n\t\t\t\tthis.services.objectStorage,\n\t\t\t\tattributesBlobKey,\n\t\t\t);\n\t\t}\n\n\t\t// This is a backward compatibility case where the attach message doesn't include attributes. They must\n\t\t// include attach message type.\n\t\t// Since old attach messages will not have attributes, we need to keep this as long as we support old attach\n\t\t// messages.\n\t\tconst channelFactoryType = attributes ? attributes.type : this.attachMessageType;\n\t\tif (channelFactoryType === undefined) {\n\t\t\tthrow new DataCorruptionError(\"channelTypeNotAvailable\", {\n\t\t\t\tchannelId: {\n\t\t\t\t\tvalue: this.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStoreId: {\n\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\tchannelFactoryType: this.attachMessageType,\n\t\t\t});\n\t\t}\n\t\tconst factory = this.registry.get(channelFactoryType);\n\t\tif (factory === undefined) {\n\t\t\t// TODO: dataStoreId may require a different tag from PackageData #7488\n\t\t\tthrow new DataCorruptionError(\"channelFactoryNotRegisteredForGivenType\", {\n\t\t\t\tchannelId: {\n\t\t\t\t\tvalue: this.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStoreId: {\n\t\t\t\t\tvalue: this.dataStoreContext.id,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tdataStorePackagePath: this.dataStoreContext.packagePath.join(\"/\"),\n\t\t\t\tchannelFactoryType,\n\t\t\t});\n\t\t}\n\n\t\t// This is a backward compatibility case where the attach message doesn't include attributes. Get the attributes\n\t\t// from the factory.\n\t\tattributes = attributes ?? factory.attributes;\n\n\t\t// Compare snapshot version to collaborative object version\n\t\tif (\n\t\t\tattributes.snapshotFormatVersion !== undefined &&\n\t\t\tattributes.snapshotFormatVersion !== factory.attributes.snapshotFormatVersion\n\t\t) {\n\t\t\tthis.subLogger.sendTelemetryEvent({\n\t\t\t\teventName: \"ChannelAttributesVersionMismatch\",\n\t\t\t\tchannelType: { value: attributes.type, tag: TelemetryDataTag.CodeArtifact },\n\t\t\t\tchannelSnapshotVersion: {\n\t\t\t\t\tvalue: `${attributes.snapshotFormatVersion}@${attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t\tchannelCodeVersion: {\n\t\t\t\t\tvalue: `${factory.attributes.snapshotFormatVersion}@${factory.attributes.packageVersion}`,\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tconst channel = await factory.load(this.runtime, this.id, this.services, attributes);\n\n\t\t// Send all pending messages to the channel\n\t\tassert(this.pending !== undefined, 0x23f /* \"pending undefined\" */);\n\t\tfor (const message of this.pending) {\n\t\t\tthis.services.deltaConnection.process(message, false, undefined /* localOpMetadata */);\n\t\t}\n\t\tthis.thresholdOpsCounter.send(\"ProcessPendingOps\", this.pending.length);\n\n\t\t// Commit changes.\n\t\tthis.channel = channel;\n\t\tthis.pending = undefined;\n\t\tthis.isLoaded = true;\n\n\t\t// Because have some await between we created the service and here, the connection state might have changed\n\t\t// and we don't propagate the connection state when we are not loaded. So we have to set it again here.\n\t\tthis.services.deltaConnection.setConnectionState(this.dataStoreContext.connected);\n\t\treturn this.channel;\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.\n\t * If there is no new data in this context since the last summary, previous GC data is used.\n\t * If there is new data, the GC data is generated again (by calling getGCDataInternal).\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\treturn this.summarizerNode.getGCData(fullGC);\n\t}\n\n\t/**\n\t * Generates the data used for garbage collection. This is called when there is new data since last summary. It\n\t * loads the context and calls into the channel to get its GC data.\n\t * @param fullGC - true to bypass optimizations and force full generation of GC data.\n\t */\n\tprivate async getGCDataInternal(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. Update the summarizer node's\n\t\t * used routes to contain a route to this channel context.\n\t\t * Once we have GC at DDS level, this will be updated to use the passed usedRoutes. See -\n\t\t * https://github.com/microsoft/FluidFramework/issues/4611\n\t\t */\n\t\tthis.summarizerNode.updateUsedRoutes([\"\"]);\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/datastore",
3
- "version": "2.0.0-dev.3.1.0.125672",
3
+ "version": "2.0.0-dev.4.2.0.153917",
4
4
  "description": "Fluid data store implementation",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -14,34 +14,6 @@
14
14
  "main": "dist/index.js",
15
15
  "module": "lib/index.js",
16
16
  "types": "dist/index.d.ts",
17
- "scripts": {
18
- "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
19
- "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
20
- "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
21
- "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
22
- "build:esnext": "tsc --project ./tsconfig.esnext.json",
23
- "build:full": "npm run build",
24
- "build:full:compile": "npm run build:compile",
25
- "build:genver": "gen-version",
26
- "build:test": "tsc --project ./src/test/tsconfig.json",
27
- "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
28
- "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
29
- "eslint": "eslint --format stylish src",
30
- "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
31
- "format": "npm run prettier:fix",
32
- "lint": "npm run prettier && npm run eslint",
33
- "lint:fix": "npm run prettier:fix && npm run eslint:fix",
34
- "prettier": "prettier --check . --ignore-path ../../../.prettierignore",
35
- "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
36
- "test": "npm run test:mocha",
37
- "test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
38
- "test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test --exit -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
39
- "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
40
- "tsc": "tsc",
41
- "tsc:watch": "tsc --watch",
42
- "typetests:gen": "flub generate typetests --generate --dir .",
43
- "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
44
- },
45
17
  "nyc": {
46
18
  "all": true,
47
19
  "cache-dir": "nyc/.cache",
@@ -64,50 +36,77 @@
64
36
  },
65
37
  "dependencies": {
66
38
  "@fluidframework/common-definitions": "^0.20.1",
67
- "@fluidframework/common-utils": "^1.0.0",
68
- "@fluidframework/container-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
69
- "@fluidframework/container-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
70
- "@fluidframework/core-interfaces": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
71
- "@fluidframework/datastore-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
72
- "@fluidframework/driver-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
73
- "@fluidframework/driver-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
74
- "@fluidframework/garbage-collector": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
75
- "@fluidframework/protocol-base": "^0.1038.2000",
39
+ "@fluidframework/common-utils": "^1.1.1",
40
+ "@fluidframework/container-definitions": "2.0.0-dev.4.2.0.153917",
41
+ "@fluidframework/container-utils": "2.0.0-dev.4.2.0.153917",
42
+ "@fluidframework/core-interfaces": "2.0.0-dev.4.2.0.153917",
43
+ "@fluidframework/datastore-definitions": "2.0.0-dev.4.2.0.153917",
44
+ "@fluidframework/driver-definitions": "2.0.0-dev.4.2.0.153917",
45
+ "@fluidframework/driver-utils": "2.0.0-dev.4.2.0.153917",
46
+ "@fluidframework/garbage-collector": "2.0.0-dev.4.2.0.153917",
47
+ "@fluidframework/protocol-base": "^0.1039.1000",
76
48
  "@fluidframework/protocol-definitions": "^1.1.0",
77
- "@fluidframework/runtime-definitions": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
78
- "@fluidframework/runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
79
- "@fluidframework/telemetry-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
49
+ "@fluidframework/runtime-definitions": "2.0.0-dev.4.2.0.153917",
50
+ "@fluidframework/runtime-utils": "2.0.0-dev.4.2.0.153917",
51
+ "@fluidframework/telemetry-utils": "2.0.0-dev.4.2.0.153917",
80
52
  "lodash": "^4.17.21",
81
53
  "uuid": "^8.3.1"
82
54
  },
83
55
  "devDependencies": {
84
- "@fluid-tools/build-cli": "^0.8.0",
56
+ "@fluid-tools/build-cli": "^0.15.0",
85
57
  "@fluidframework/build-common": "^1.1.0",
86
- "@fluidframework/build-tools": "^0.8.0",
87
- "@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.3.0.0",
58
+ "@fluidframework/build-tools": "^0.15.0",
59
+ "@fluidframework/datastore-previous": "npm:@fluidframework/datastore@2.0.0-internal.4.0.0",
88
60
  "@fluidframework/eslint-config-fluid": "^2.0.0",
89
- "@fluidframework/mocha-test-setup": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
90
- "@fluidframework/test-runtime-utils": ">=2.0.0-dev.3.1.0.125672 <2.0.0-dev.4.0.0",
91
- "@microsoft/api-extractor": "^7.22.2",
92
- "@rushstack/eslint-config": "^2.5.1",
61
+ "@fluidframework/mocha-test-setup": "2.0.0-dev.4.2.0.153917",
62
+ "@fluidframework/test-runtime-utils": "2.0.0-dev.4.2.0.153917",
63
+ "@microsoft/api-extractor": "^7.34.4",
93
64
  "@types/mocha": "^9.1.1",
94
- "@types/node": "^14.18.36",
65
+ "@types/node": "^14.18.38",
95
66
  "@types/uuid": "^8.3.0",
96
- "concurrently": "^6.2.0",
67
+ "concurrently": "^7.6.0",
97
68
  "copyfiles": "^2.4.1",
98
- "cross-env": "^7.0.2",
69
+ "cross-env": "^7.0.3",
99
70
  "eslint": "~8.6.0",
100
- "mocha": "^10.0.0",
101
- "nyc": "^15.0.0",
71
+ "mocha": "^10.2.0",
72
+ "mocha-json-output-reporter": "^2.0.1",
73
+ "mocha-multi-reporters": "^1.5.1",
74
+ "moment": "^2.21.0",
75
+ "nyc": "^15.1.0",
102
76
  "prettier": "~2.6.2",
103
- "rimraf": "^2.6.2",
77
+ "rimraf": "^4.4.0",
104
78
  "typescript": "~4.5.5"
105
79
  },
106
80
  "typeValidation": {
107
- "version": "2.0.0-internal.3.1.0",
108
- "previousVersionStyle": "~previousMinor",
109
- "baselineRange": ">=2.0.0-internal.3.0.0 <2.0.0-internal.3.1.0",
110
- "baselineVersion": "2.0.0-internal.3.0.0",
111
81
  "broken": {}
82
+ },
83
+ "scripts": {
84
+ "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs",
85
+ "build:commonjs": "npm run tsc && npm run typetests:gen && npm run build:test",
86
+ "build:compile": "concurrently npm:build:commonjs npm:build:esnext",
87
+ "build:docs": "api-extractor run --local --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/doc-models/* ../../../_api-extractor-temp/",
88
+ "build:esnext": "tsc --project ./tsconfig.esnext.json",
89
+ "build:full": "npm run build",
90
+ "build:full:compile": "npm run build:compile",
91
+ "build:genver": "gen-version",
92
+ "build:test": "tsc --project ./src/test/tsconfig.json",
93
+ "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
94
+ "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
95
+ "eslint": "eslint --format stylish src",
96
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
97
+ "format": "npm run prettier:fix",
98
+ "lint": "npm run prettier && npm run eslint",
99
+ "lint:fix": "npm run prettier:fix && npm run eslint:fix",
100
+ "prettier": "prettier --check . --ignore-path ../../../.prettierignore",
101
+ "prettier:fix": "prettier --write . --ignore-path ../../../.prettierignore",
102
+ "test": "npm run test:mocha",
103
+ "test:coverage": "nyc npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml",
104
+ "test:mocha": "mocha --ignore 'dist/test/types/*' --recursive dist/test --exit -r node_modules/@fluidframework/mocha-test-setup --unhandled-rejections=strict",
105
+ "test:mocha:multireport": "cross-env FLUID_TEST_MULTIREPORT=1 npm run test:mocha",
106
+ "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
107
+ "tsc": "tsc",
108
+ "tsc:watch": "tsc --watch",
109
+ "typetests:gen": "fluid-type-test-generator",
110
+ "typetests:prepare": "flub generate typetests --prepare --dir . --pin"
112
111
  }
113
- }
112
+ }
@@ -10,6 +10,7 @@ import { IDocumentStorageService } from "@fluidframework/driver-definitions";
10
10
  import { ISequencedDocumentMessage, ISnapshotTree } from "@fluidframework/protocol-definitions";
11
11
  import {
12
12
  IGarbageCollectionData,
13
+ IExperimentalIncrementalSummaryContext,
13
14
  ISummarizeResult,
14
15
  ISummaryTreeWithStats,
15
16
  ITelemetryContext,
@@ -99,8 +100,14 @@ export async function summarizeChannelAsync(
99
100
  fullTree: boolean = false,
100
101
  trackState: boolean = false,
101
102
  telemetryContext?: ITelemetryContext,
103
+ incrementalSummaryContext?: IExperimentalIncrementalSummaryContext,
102
104
  ): Promise<ISummaryTreeWithStats> {
103
- const summarizeResult = await channel.summarize(fullTree, trackState, telemetryContext);
105
+ const summarizeResult = await channel.summarize(
106
+ fullTree,
107
+ trackState,
108
+ telemetryContext,
109
+ incrementalSummaryContext,
110
+ );
104
111
 
105
112
  // Add the channel attributes to the returned result.
106
113
  addBlobToSummary(summarizeResult, attributesBlobKey, JSON.stringify(channel.attributes));
@@ -25,7 +25,15 @@ import {
25
25
  TypedEventEmitter,
26
26
  unreachableCase,
27
27
  } from "@fluidframework/common-utils";
28
- import { ChildLogger, LoggingError, raiseConnectedEvent } from "@fluidframework/telemetry-utils";
28
+ import {
29
+ ChildLogger,
30
+ generateStack,
31
+ LoggingError,
32
+ loggerToMonitoringContext,
33
+ MonitoringContext,
34
+ raiseConnectedEvent,
35
+ TelemetryDataTag,
36
+ } from "@fluidframework/telemetry-utils";
29
37
  import { buildSnapshotTree } from "@fluidframework/driver-utils";
30
38
  import {
31
39
  IClientDetails,
@@ -37,14 +45,12 @@ import {
37
45
  IQuorumClients,
38
46
  } from "@fluidframework/protocol-definitions";
39
47
  import {
40
- BindState,
41
48
  CreateSummarizerNodeSource,
42
49
  IAttachMessage,
43
50
  IEnvelope,
44
51
  IFluidDataStoreContext,
45
52
  IFluidDataStoreChannel,
46
53
  IGarbageCollectionData,
47
- IGarbageCollectionDetailsBase,
48
54
  IInboundSignalMessage,
49
55
  ISummaryTreeWithStats,
50
56
  VisibilityState,
@@ -59,7 +65,10 @@ import {
59
65
  create404Response,
60
66
  createResponseError,
61
67
  exceptionToResponse,
68
+ GCDataBuilder,
62
69
  requestFluidObject,
70
+ packagePathToTelemetryProperty,
71
+ unpackChildNodesUsedRoutes,
63
72
  } from "@fluidframework/runtime-utils";
64
73
  import {
65
74
  IChannel,
@@ -67,12 +76,6 @@ import {
67
76
  IFluidDataStoreRuntimeEvents,
68
77
  IChannelFactory,
69
78
  } from "@fluidframework/datastore-definitions";
70
- import {
71
- GCDataBuilder,
72
- removeRouteFromAllNodes,
73
- unpackChildNodesGCDetails,
74
- unpackChildNodesUsedRoutes,
75
- } from "@fluidframework/garbage-collector";
76
79
  import { v4 as uuid } from "uuid";
77
80
  import { IChannelContext, summarizeChannel } from "./channelContext";
78
81
  import {
@@ -183,7 +186,6 @@ export class FluidDataStoreRuntime
183
186
  private readonly contextsDeferred = new Map<string, Deferred<IChannelContext>>();
184
187
  private readonly pendingAttach = new Map<string, IAttachMessage>();
185
188
 
186
- private bindState: BindState;
187
189
  private readonly deferredAttached = new Deferred<void>();
188
190
  private readonly localChannelContextQueue = new Map<string, LocalChannelContextBase>();
189
191
  private readonly notBoundedChannelContextSet = new Set<string>();
@@ -198,11 +200,17 @@ export class FluidDataStoreRuntime
198
200
  public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
199
201
  private readonly quorum: IQuorumClients;
200
202
  private readonly audience: IAudience;
201
- public readonly logger: ITelemetryLogger;
203
+ private readonly mc: MonitoringContext;
204
+ public get logger(): ITelemetryLogger {
205
+ return this.mc.logger;
206
+ }
202
207
 
203
- // A map of child channel context ids to the their base GC details. This is used to initialize the GC state of the
204
- // channel contexts.
205
- private readonly channelsBaseGCDetails: LazyPromise<Map<string, IGarbageCollectionDetailsBase>>;
208
+ /**
209
+ * If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.
210
+ * So, adding a count of how many telemetry events are logged per data store context. This can be
211
+ * controlled via feature flags.
212
+ */
213
+ private localChangesTelemetryCount: number;
206
214
 
207
215
  /**
208
216
  * Invokes the given callback and expects that no ops are submitted
@@ -243,9 +251,11 @@ export class FluidDataStoreRuntime
243
251
  0x30e /* Id cannot contain slashes. DataStoreContext should have validated this. */,
244
252
  );
245
253
 
246
- this.logger = ChildLogger.create(dataStoreContext.logger, "FluidDataStoreRuntime", {
247
- all: { dataStoreId: uuid() },
248
- });
254
+ this.mc = loggerToMonitoringContext(
255
+ ChildLogger.create(dataStoreContext.logger, "FluidDataStoreRuntime", {
256
+ all: { dataStoreId: uuid() },
257
+ }),
258
+ );
249
259
 
250
260
  this.id = dataStoreContext.id;
251
261
  this.options = dataStoreContext.options;
@@ -255,11 +265,6 @@ export class FluidDataStoreRuntime
255
265
 
256
266
  const tree = dataStoreContext.baseSnapshot;
257
267
 
258
- this.channelsBaseGCDetails = new LazyPromise(async () => {
259
- const baseGCDetails = await this.dataStoreContext.getBaseGCDetails();
260
- return unpackChildNodesGCDetails(baseGCDetails);
261
- });
262
-
263
268
  // Must always receive the data store type inside of the attributes
264
269
  if (tree?.trees !== undefined) {
265
270
  Object.keys(tree.trees).forEach((path) => {
@@ -316,7 +321,6 @@ export class FluidDataStoreRuntime
316
321
  this.dataStoreContext.getCreateChildSummarizerNodeFn(path, {
317
322
  type: CreateSummarizerNodeSource.FromSummary,
318
323
  }),
319
- async () => this.getChannelBaseGCDetails(path),
320
324
  );
321
325
  }
322
326
  const deferred = new Deferred<IChannelContext>();
@@ -337,8 +341,6 @@ export class FluidDataStoreRuntime
337
341
  }
338
342
 
339
343
  this.attachListener();
340
- // If exists on storage or loaded from a snapshot, it should already be bound.
341
- this.bindState = existing ? BindState.Bound : BindState.NotBound;
342
344
  this._attachState = dataStoreContext.attachState;
343
345
 
344
346
  /**
@@ -364,6 +366,10 @@ export class FluidDataStoreRuntime
364
366
  if (existing) {
365
367
  this.deferredAttached.resolve();
366
368
  }
369
+
370
+ // By default, a data store can log maximum 10 local changes telemetry in summarizer.
371
+ this.localChangesTelemetryCount =
372
+ this.mc.config.getNumber("Fluid.Telemetry.LocalChangesTelemetryCount") ?? 10;
367
373
  }
368
374
 
369
375
  public dispose(): void {
@@ -398,7 +404,10 @@ export class FluidDataStoreRuntime
398
404
 
399
405
  return { mimeType: "fluid/object", status: 200, value: channel };
400
406
  } catch (error) {
401
- this.logger.sendErrorEvent({ eventName: "GetChannelFailedInRequest" }, error);
407
+ this.mc.logger.sendErrorEvent(
408
+ { eventName: "GetChannelFailedInRequest" },
409
+ error,
410
+ );
402
411
 
403
412
  return createResponseError(500, `Failed to get Channel: ${error}`, request);
404
413
  }
@@ -461,6 +470,9 @@ export class FluidDataStoreRuntime
461
470
  this.contextsDeferred.set(id, deferred);
462
471
  }
463
472
 
473
+ // Channels (DDS) should not be created in summarizer client.
474
+ this.identifyLocalChangeInSummarizer("DDSCreatedInSummarizer", id, type);
475
+
464
476
  assert(!!context.channel, 0x17a /* "Channel should be loaded when created!!" */);
465
477
  return context.channel;
466
478
  }
@@ -522,7 +534,7 @@ export class FluidDataStoreRuntime
522
534
  handle.attachGraph();
523
535
  });
524
536
  this.pendingHandlesToMakeVisible.clear();
525
- this.bindToContext();
537
+ this.dataStoreContext.makeLocallyVisible();
526
538
  }
527
539
 
528
540
  /**
@@ -540,12 +552,7 @@ export class FluidDataStoreRuntime
540
552
  * 2. Attaching the graph if the data store becomes attached.
541
553
  */
542
554
  public bindToContext() {
543
- if (this.bindState !== BindState.NotBound) {
544
- return;
545
- }
546
- this.bindState = BindState.Binding;
547
- this.dataStoreContext.bindToContext();
548
- this.bindState = BindState.Bound;
555
+ this.makeVisibleAndAttachGraph();
549
556
  }
550
557
 
551
558
  public bind(handle: IFluidHandle): void {
@@ -600,12 +607,7 @@ export class FluidDataStoreRuntime
600
607
  );
601
608
  this.pendingAttach.delete(id);
602
609
  } else {
603
- assert(
604
- !this.contexts.has(id),
605
- 0x17d /* `Unexpected attach channel OP,
606
- is in pendingAttach set: ${this.pendingAttach.has(id)},
607
- is local channel contexts: ${this.contexts.get(id) instanceof LocalChannelContextBase}` */,
608
- );
610
+ assert(!this.contexts.has(id), 0x17d /* "Unexpected attach channel OP" */);
609
611
 
610
612
  const flatBlobs = new Map<string, ArrayBufferLike>();
611
613
  const snapshotTree = buildSnapshotTree(
@@ -631,7 +633,6 @@ export class FluidDataStoreRuntime
631
633
  sequenceNumber: message.sequenceNumber,
632
634
  snapshot: attachMessage.snapshot,
633
635
  }),
634
- async () => this.getChannelBaseGCDetails(id),
635
636
  attachMessage.type,
636
637
  );
637
638
 
@@ -780,34 +781,6 @@ export class FluidDataStoreRuntime
780
781
  this.dataStoreContext.addedGCOutboundReference?.(srcHandle, outboundHandle);
781
782
  }
782
783
 
783
- /**
784
- * Returns the base GC details for the channel with the given id. This is used to initialize its GC state.
785
- * @param channelId - The id of the channel context that is asked for the initial GC details.
786
- * @returns the requested channel's base GC details.
787
- */
788
- private async getChannelBaseGCDetails(
789
- channelId: string,
790
- ): Promise<IGarbageCollectionDetailsBase> {
791
- let channelBaseGCDetails = (await this.channelsBaseGCDetails).get(channelId);
792
- if (channelBaseGCDetails === undefined) {
793
- channelBaseGCDetails = {};
794
- } else if (channelBaseGCDetails.gcData?.gcNodes !== undefined) {
795
- // Note: if the child channel has an explicit handle route to its parent, it will be removed here and
796
- // expected to be added back by the parent when getGCData is called.
797
- removeRouteFromAllNodes(channelBaseGCDetails.gcData.gcNodes, this.absolutePath);
798
- }
799
-
800
- // Currently, channel context's are always considered used. So, it there are no used routes for it, we still
801
- // need to mark it as used. Add self-route (empty string) to the channel context's used routes.
802
- if (
803
- channelBaseGCDetails.usedRoutes === undefined ||
804
- channelBaseGCDetails.usedRoutes.length === 0
805
- ) {
806
- channelBaseGCDetails.usedRoutes = [""];
807
- }
808
- return channelBaseGCDetails;
809
- }
810
-
811
784
  /**
812
785
  * Returns a summary at the current sequence number.
813
786
  * @param fullTree - true to bypass optimizations and force a full summary tree
@@ -1109,6 +1082,42 @@ export class FluidDataStoreRuntime
1109
1082
  throw new LoggingError("Runtime is closed");
1110
1083
  }
1111
1084
  }
1085
+
1086
+ /**
1087
+ * Summarizer client should not have local changes. These changes can become part of the summary and can break
1088
+ * eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas
1089
+ * other clients that are up-to-date till seq# 100 may not have them yet.
1090
+ */
1091
+ private identifyLocalChangeInSummarizer(
1092
+ eventName: string,
1093
+ channelId: string,
1094
+ channelType: string,
1095
+ ) {
1096
+ if (this.clientDetails.type !== "summarizer" || this.localChangesTelemetryCount <= 0) {
1097
+ return;
1098
+ }
1099
+
1100
+ // Log a telemetry if there are local changes in the summarizer. This will give us data on how often
1101
+ // this is happening and which data stores do this. The eventual goal is to disallow local changes
1102
+ // in the summarizer and the data will help us plan this.
1103
+ this.mc.logger.sendTelemetryEvent({
1104
+ eventName,
1105
+ channelType,
1106
+ channelId: {
1107
+ value: channelId,
1108
+ tag: TelemetryDataTag.CodeArtifact,
1109
+ },
1110
+ fluidDataStoreId: {
1111
+ value: this.id,
1112
+ tag: TelemetryDataTag.CodeArtifact,
1113
+ },
1114
+ fluidDataStorePackagePath: packagePathToTelemetryProperty(
1115
+ this.dataStoreContext.packagePath,
1116
+ ),
1117
+ stack: generateStack(),
1118
+ });
1119
+ this.localChangesTelemetryCount--;
1120
+ }
1112
1121
  }
1113
1122
 
1114
1123
  /**
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/datastore";
9
- export const pkgVersion = "2.0.0-dev.3.1.0.125672";
9
+ export const pkgVersion = "2.0.0-dev.4.2.0.153917";