@fluidframework/ordered-collection 0.54.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  module.exports = {
7
7
  "extends": [
8
- "@fluidframework/eslint-config-fluid/eslint7"
8
+ "@fluidframework/eslint-config-fluid"
9
9
  ],
10
10
  "parserOptions": {
11
11
  "project": ["./tsconfig.json", "./src/test/tsconfig.json"]
@@ -2,10 +2,10 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IFluidSerializer } from "@fluidframework/core-interfaces";
6
- import { ISequencedDocumentMessage, ITree } from "@fluidframework/protocol-definitions";
5
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
7
6
  import { IChannelAttributes, IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
8
- import { SharedObject } from "@fluidframework/shared-object-base";
7
+ import { IFluidSerializer, SharedObject } from "@fluidframework/shared-object-base";
8
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
9
9
  import { ConsensusCallback, IConsensusOrderedCollection, IOrderedCollection, IConsensusOrderedCollectionEvents } from "./interfaces";
10
10
  /**
11
11
  * Implementation of a consensus collection shared object
@@ -40,7 +40,7 @@ export declare class ConsensusOrderedCollection<T = any> extends SharedObject<IC
40
40
  * Wait for a value to be available and acquire it from the consensus collection
41
41
  */
42
42
  waitAndAcquire(callback: ConsensusCallback<T>): Promise<void>;
43
- protected snapshotCore(serializer: IFluidSerializer): ITree;
43
+ protected summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats;
44
44
  protected isActive(): boolean;
45
45
  protected complete(acquireId: string): Promise<void>;
46
46
  protected completeCore(acquireId: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"consensusOrderedCollection.d.ts","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAEH,yBAAyB,EACzB,KAAK,EAGR,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EACH,iBAAiB,EAEjB,2BAA2B,EAC3B,kBAAkB,EAClB,iCAAiC,EACpC,MAAM,cAAc,CAAC;AA6DtB;;;;;;;;GAQG;AACH,qBAAa,0BAA0B,CAAC,CAAC,GAAG,GAAG,CAC3C,SAAQ,YAAY,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAE,YAAW,2BAA2B,CAAC,CAAC,CAAC;IAchG,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbzB;;OAEG;IACH,OAAO,CAAC,WAAW,CAAiC;IAEpD;;;OAGG;IACH,SAAS,aACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB,EACb,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAchD;;OAEG;IACU,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzC;;;OAGG;IACU,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBtE;;OAEG;IACU,cAAc,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,GAAG,KAAK;IAgC3D,SAAS,CAAC,QAAQ;cAIF,QAAQ,CAAC,SAAS,EAAE,MAAM;IAe1C,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM;IASxC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM;IAiBnC,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM;IAUvC;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxE,SAAS,CAAC,YAAY;IAItB,SAAS,CAAC,YAAY;IAQtB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO;YA+BpF,MAAM;IAapB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,WAAW;YAgBL,eAAe;IAY7B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAKxB,SAAS,CAAC,cAAc;CAG3B"}
1
+ {"version":3,"file":"consensusOrderedCollection.d.ts","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,OAAO,EACH,iBAAiB,EAEjB,2BAA2B,EAC3B,kBAAkB,EAClB,iCAAiC,EACpC,MAAM,cAAc,CAAC;AA6DtB;;;;;;;;GAQG;AACH,qBAAa,0BAA0B,CAAC,CAAC,GAAG,GAAG,CAC3C,SAAQ,YAAY,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAE,YAAW,2BAA2B,CAAC,CAAC,CAAC;IAchG,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbzB;;OAEG;IACH,OAAO,CAAC,WAAW,CAAiC;IAEpD;;;OAGG;IACH,SAAS,aACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB,EACb,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAchD;;OAEG;IACU,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzC;;;OAGG;IACU,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBtE;;OAEG;IACU,cAAc,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,GAAG,qBAAqB;IAa/F,SAAS,CAAC,QAAQ;cAIF,QAAQ,CAAC,SAAS,EAAE,MAAM;IAe1C,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM;IASxC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM;IAiBnC,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM;IAUvC;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxE,SAAS,CAAC,YAAY;IAItB,SAAS,CAAC,YAAY;IAQtB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO;YA+BpF,MAAM;IAapB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,WAAW;YAgBL,eAAe;IAY7B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAKxB,SAAS,CAAC,cAAc;CAG3B"}
@@ -8,6 +8,7 @@ exports.ConsensusOrderedCollection = void 0;
8
8
  const common_utils_1 = require("@fluidframework/common-utils");
9
9
  const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
10
10
  const shared_object_base_1 = require("@fluidframework/shared-object-base");
11
+ const runtime_utils_1 = require("@fluidframework/runtime-utils");
11
12
  const uuid_1 = require("uuid");
12
13
  const interfaces_1 = require("./interfaces");
13
14
  const snapshotFileNameData = "header";
@@ -95,33 +96,16 @@ class ConsensusOrderedCollection extends shared_object_base_1.SharedObject {
95
96
  }
96
97
  } while (!(await this.acquire(callback)));
97
98
  }
98
- snapshotCore(serializer) {
99
+ summarizeCore(serializer, fullTree) {
99
100
  // If we are transitioning from unattached to attached mode,
100
101
  // then we are losing all checked out work!
101
102
  this.removeClient(idForLocalUnattachedClient);
102
- const tree = {
103
- entries: [
104
- {
105
- mode: protocol_definitions_1.FileMode.File,
106
- path: snapshotFileNameData,
107
- type: protocol_definitions_1.TreeEntry.Blob,
108
- value: {
109
- contents: this.serializeValue(this.data.asArray(), serializer),
110
- encoding: "utf-8",
111
- },
112
- },
113
- ],
114
- };
115
- tree.entries.push({
116
- mode: protocol_definitions_1.FileMode.File,
117
- path: snapshotFileNameTracking,
118
- type: protocol_definitions_1.TreeEntry.Blob,
119
- value: {
120
- contents: this.serializeValue(Array.from(this.jobTracking.entries()), serializer),
121
- encoding: "utf-8",
122
- },
123
- });
124
- return tree;
103
+ const builder = new runtime_utils_1.SummaryTreeBuilder();
104
+ let blobContent = this.serializeValue(this.data.asArray(), serializer);
105
+ builder.addBlob(snapshotFileNameData, blobContent);
106
+ blobContent = this.serializeValue(Array.from(this.jobTracking.entries()), serializer);
107
+ builder.addBlob(snapshotFileNameTracking, blobContent);
108
+ return builder.getSummaryTree();
125
109
  }
126
110
  isActive() {
127
111
  return this.runtime.connected && this.runtime.deltaManager.active;
@@ -1 +1 @@
1
- {"version":3,"file":"consensusOrderedCollection.js","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert , bufferToString, unreachableCase } from \"@fluidframework/common-utils\";\nimport { IFluidSerializer } from \"@fluidframework/core-interfaces\";\nimport {\n FileMode,\n ISequencedDocumentMessage,\n ITree,\n MessageType,\n TreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { SharedObject } from \"@fluidframework/shared-object-base\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n ConsensusCallback,\n ConsensusResult,\n IConsensusOrderedCollection,\n IOrderedCollection,\n IConsensusOrderedCollectionEvents,\n} from \"./interfaces\";\n\nconst snapshotFileNameData = \"header\";\nconst snapshotFileNameTracking = \"jobTracking\";\n\ninterface IConsensusOrderedCollectionValue<T> {\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n readonly acquireId: string;\n\n // The actual value\n readonly value: T;\n}\n\n/**\n * An operation for consensus ordered collection\n */\ninterface IConsensusOrderedCollectionAddOperation {\n opName: \"add\";\n // serialized value\n value: string;\n}\n\ninterface IConsensusOrderedCollectionAcquireOperation {\n opName: \"acquire\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionCompleteOperation {\n opName: \"complete\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionReleaseOperation {\n opName: \"release\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ntype IConsensusOrderedCollectionOperation =\n IConsensusOrderedCollectionAddOperation |\n IConsensusOrderedCollectionAcquireOperation |\n IConsensusOrderedCollectionCompleteOperation |\n IConsensusOrderedCollectionReleaseOperation;\n\n/** The type of the resolve function to call after the local operation is ack'd */\ntype PendingResolve<T> = (value: IConsensusOrderedCollectionValue<T> | undefined) => void;\n\n/**\n * For job tracking, we need to keep track of which client \"owns\" a given value.\n * Key is the acquireId from when it was acquired\n * Value is the acquired value, and the id of the client who acquired it, or undefined for unattached client\n */\ntype JobTrackingInfo<T> = Map<string, { value: T, clientId: string | undefined }>;\nconst idForLocalUnattachedClient = undefined;\n\n/**\n * Implementation of a consensus collection shared object\n *\n * Implements the shared object's communication, and the semantics around the\n * release/complete mechanism following acquire.\n *\n * Generally not used directly. A derived type will pass in a backing data type\n * IOrderedCollection that will define the deterministic add/acquire order and snapshot ability.\n */\nexport class ConsensusOrderedCollection<T = any>\n extends SharedObject<IConsensusOrderedCollectionEvents<T>> implements IConsensusOrderedCollection<T> {\n /**\n * The set of values that have been acquired but not yet completed or released\n */\n private jobTracking: JobTrackingInfo<T> = new Map();\n\n /**\n * Constructs a new consensus collection. If the object is non-local an id and service interfaces will\n * be provided\n */\n protected constructor(\n id: string,\n runtime: IFluidDataStoreRuntime,\n attributes: IChannelAttributes,\n private readonly data: IOrderedCollection<T>,\n ) {\n super(id, runtime, attributes);\n\n // We can't simply call this.removeClient(this.runtime.clientId) in on runtime disconnected,\n // because other clients may disconnect concurrently.\n // Disconnect order matters because it defines the order items go back to the queue.\n // So we put items back to queue only when we process our own removeMember event.\n runtime.getQuorum().on(\"removeMember\", (clientId: string) => {\n assert(!!clientId, 0x067 /* \"Missing clientId for removal!\" */);\n this.removeClient(clientId);\n });\n }\n\n /**\n * Add a value to the consensus collection.\n */\n public async add(value: T): Promise<void> {\n const valueSer = this.serializeValue(value, this.serializer);\n\n if (!this.isAttached()) {\n // For the case where this is not attached yet, explicitly JSON\n // clone the value to match the behavior of going thru the wire.\n const addValue = this.deserializeValue(valueSer, this.serializer) as T;\n this.addCore(addValue);\n return;\n }\n\n await this.submit<IConsensusOrderedCollectionAddOperation>({\n opName: \"add\",\n value: valueSer,\n });\n }\n\n /**\n * Remove a value from the consensus collection. If the collection is empty, returns false.\n * Otherwise calls callback with the value\n */\n public async acquire(callback: ConsensusCallback<T>): Promise<boolean> {\n const result = await this.acquireInternal();\n if (result === undefined) {\n return false;\n }\n\n const res = await callback(result.value);\n\n switch (res) {\n case ConsensusResult.Complete:\n await this.complete(result.acquireId);\n break;\n case ConsensusResult.Release:\n this.release(result.acquireId);\n this.emit(\"localRelease\", result.value, true /* intentional */);\n break;\n default: unreachableCase(res);\n }\n\n return true;\n }\n\n /**\n * Wait for a value to be available and acquire it from the consensus collection\n */\n public async waitAndAcquire(callback: ConsensusCallback<T>): Promise<void> {\n do {\n if (this.data.size() === 0) {\n // Wait for new entry before trying to acquire again\n await this.newAckBasedPromise<T>((resolve) => {\n this.once(\"add\", resolve);\n });\n }\n } while (!(await this.acquire(callback)));\n }\n\n protected snapshotCore(serializer: IFluidSerializer): ITree {\n // If we are transitioning from unattached to attached mode,\n // then we are losing all checked out work!\n this.removeClient(idForLocalUnattachedClient);\n\n const tree: ITree = {\n entries: [\n {\n mode: FileMode.File,\n path: snapshotFileNameData,\n type: TreeEntry.Blob,\n value: {\n contents: this.serializeValue(this.data.asArray(), serializer),\n encoding: \"utf-8\",\n },\n },\n ],\n };\n\n tree.entries.push({\n mode: FileMode.File,\n path: snapshotFileNameTracking,\n type: TreeEntry.Blob,\n value: {\n contents: this.serializeValue(Array.from(this.jobTracking.entries()), serializer),\n encoding: \"utf-8\",\n },\n });\n\n return tree;\n }\n\n protected isActive() {\n return this.runtime.connected && this.runtime.deltaManager.active;\n }\n\n protected async complete(acquireId: string) {\n if (!this.isAttached()) {\n this.completeCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n await this.submit<IConsensusOrderedCollectionCompleteOperation>({\n opName: \"complete\",\n acquireId,\n });\n }\n }\n\n protected completeCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.emit(\"complete\", rec.value);\n }\n }\n\n protected release(acquireId: string) {\n if (!this.isAttached()) {\n this.releaseCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n this.submit<IConsensusOrderedCollectionReleaseOperation>({\n opName: \"release\",\n acquireId,\n }).catch((error) => {\n this.runtime.logger.sendErrorEvent({ eventName: \"ConsensusQueue_release\" }, error);\n });\n }\n }\n\n protected releaseCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.data.add(rec.value);\n this.emit(\"add\", rec.value, false /* newlyAdded */);\n }\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n */\n protected async loadCore(storage: IChannelStorageService): Promise<void> {\n assert(this.jobTracking.size === 0, 0x068 /* \"On consensusOrderedCollection load, job tracking size > 0\" */);\n const blob = await storage.readBlob(snapshotFileNameTracking);\n const rawContentTracking = bufferToString(blob, \"utf8\");\n const content = this.deserializeValue(rawContentTracking, this.serializer);\n this.jobTracking = new Map(content) as JobTrackingInfo<T>;\n\n assert(this.data.size() === 0, 0x069 /* \"On consensusOrderedCollection load, data size > 0\" */);\n const blob2 = await storage.readBlob(snapshotFileNameData);\n const rawContentData = bufferToString(blob2, \"utf8\");\n const content2 = this.deserializeValue(rawContentData, this.serializer) as T[];\n this.data.loadFrom(content2);\n }\n\n protected registerCore() {\n return;\n }\n\n protected onDisconnect() {\n for (const [, { value, clientId }] of this.jobTracking) {\n if (clientId === this.runtime.clientId) {\n this.emit(\"localRelease\", value, false /* intentional */);\n }\n }\n }\n\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {\n if (message.type === MessageType.Operation) {\n const op: IConsensusOrderedCollectionOperation = message.contents;\n let value: IConsensusOrderedCollectionValue<T> | undefined;\n switch (op.opName) {\n case \"add\":\n this.addCore(this.deserializeValue(op.value, this.serializer) as T);\n break;\n\n case \"acquire\":\n value = this.acquireCore(op.acquireId, message.clientId);\n break;\n\n case \"complete\":\n this.completeCore(op.acquireId);\n break;\n\n case \"release\":\n this.releaseCore(op.acquireId);\n break;\n\n default: unreachableCase(op);\n }\n if (local) {\n // Resolve the pending promise for this operation now that we have received an ack for it.\n const resolve = localOpMetadata as PendingResolve<T>;\n resolve(value);\n }\n }\n }\n\n private async submit<TMessage extends IConsensusOrderedCollectionOperation>(\n message: TMessage,\n ): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n assert(this.isAttached(), 0x06a /* \"Trying to submit message while detached!\" */);\n\n return this.newAckBasedPromise<IConsensusOrderedCollectionValue<T> | undefined>((resolve) => {\n // Send the resolve function as the localOpMetadata. This will be provided back to us when the\n // op is ack'd.\n this.submitLocalMessage(message, resolve);\n // If we fail due to runtime being disposed, it's better to return undefined then unhandled exception.\n }).catch((error) => undefined);\n }\n\n private addCore(value: T) {\n this.data.add(value);\n this.emit(\"add\", value, true /* newlyAdded */);\n }\n\n private acquireCore(acquireId: string, clientId?: string): IConsensusOrderedCollectionValue<T> | undefined {\n if (this.data.size() === 0) {\n return undefined;\n }\n const value = this.data.remove();\n\n const value2: IConsensusOrderedCollectionValue<T> = {\n acquireId,\n value,\n };\n this.jobTracking.set(value2.acquireId, { value, clientId });\n\n this.emit(\"acquire\", value, clientId);\n return value2;\n }\n\n private async acquireInternal(): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n if (!this.isAttached()) {\n // can be undefined if queue is empty\n return this.acquireCore(uuid(), idForLocalUnattachedClient);\n }\n\n return this.submit<IConsensusOrderedCollectionAcquireOperation>({\n opName: \"acquire\",\n acquireId: uuid(),\n });\n }\n\n private removeClient(clientIdToRemove?: string) {\n const added: T[] = [];\n for (const [acquireId, { value, clientId }] of this.jobTracking) {\n if (clientId === clientIdToRemove) {\n this.jobTracking.delete(acquireId);\n this.data.add(value);\n added.push(value);\n }\n }\n\n // Raise all events only after all state changes are completed,\n // to guarantee same ordering of operations if collection is manipulated from events.\n added.map((value) => this.emit(\"add\", value, false /* newlyAdded */));\n }\n\n private serializeValue(value, serializer: IFluidSerializer) {\n return serializer.stringify(value, this.handle);\n }\n\n private deserializeValue(content: string, serializer: IFluidSerializer) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return serializer.parse(content);\n }\n\n protected applyStashedOp() {\n throw new Error(\"not implemented\");\n }\n}\n"]}
1
+ {"version":3,"file":"consensusOrderedCollection.js","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert , bufferToString, unreachableCase } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n ConsensusCallback,\n ConsensusResult,\n IConsensusOrderedCollection,\n IOrderedCollection,\n IConsensusOrderedCollectionEvents,\n} from \"./interfaces\";\n\nconst snapshotFileNameData = \"header\";\nconst snapshotFileNameTracking = \"jobTracking\";\n\ninterface IConsensusOrderedCollectionValue<T> {\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n readonly acquireId: string;\n\n // The actual value\n readonly value: T;\n}\n\n/**\n * An operation for consensus ordered collection\n */\ninterface IConsensusOrderedCollectionAddOperation {\n opName: \"add\";\n // serialized value\n value: string;\n}\n\ninterface IConsensusOrderedCollectionAcquireOperation {\n opName: \"acquire\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionCompleteOperation {\n opName: \"complete\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionReleaseOperation {\n opName: \"release\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ntype IConsensusOrderedCollectionOperation =\n IConsensusOrderedCollectionAddOperation |\n IConsensusOrderedCollectionAcquireOperation |\n IConsensusOrderedCollectionCompleteOperation |\n IConsensusOrderedCollectionReleaseOperation;\n\n/** The type of the resolve function to call after the local operation is ack'd */\ntype PendingResolve<T> = (value: IConsensusOrderedCollectionValue<T> | undefined) => void;\n\n/**\n * For job tracking, we need to keep track of which client \"owns\" a given value.\n * Key is the acquireId from when it was acquired\n * Value is the acquired value, and the id of the client who acquired it, or undefined for unattached client\n */\ntype JobTrackingInfo<T> = Map<string, { value: T, clientId: string | undefined }>;\nconst idForLocalUnattachedClient = undefined;\n\n/**\n * Implementation of a consensus collection shared object\n *\n * Implements the shared object's communication, and the semantics around the\n * release/complete mechanism following acquire.\n *\n * Generally not used directly. A derived type will pass in a backing data type\n * IOrderedCollection that will define the deterministic add/acquire order and snapshot ability.\n */\nexport class ConsensusOrderedCollection<T = any>\n extends SharedObject<IConsensusOrderedCollectionEvents<T>> implements IConsensusOrderedCollection<T> {\n /**\n * The set of values that have been acquired but not yet completed or released\n */\n private jobTracking: JobTrackingInfo<T> = new Map();\n\n /**\n * Constructs a new consensus collection. If the object is non-local an id and service interfaces will\n * be provided\n */\n protected constructor(\n id: string,\n runtime: IFluidDataStoreRuntime,\n attributes: IChannelAttributes,\n private readonly data: IOrderedCollection<T>,\n ) {\n super(id, runtime, attributes);\n\n // We can't simply call this.removeClient(this.runtime.clientId) in on runtime disconnected,\n // because other clients may disconnect concurrently.\n // Disconnect order matters because it defines the order items go back to the queue.\n // So we put items back to queue only when we process our own removeMember event.\n runtime.getQuorum().on(\"removeMember\", (clientId: string) => {\n assert(!!clientId, 0x067 /* \"Missing clientId for removal!\" */);\n this.removeClient(clientId);\n });\n }\n\n /**\n * Add a value to the consensus collection.\n */\n public async add(value: T): Promise<void> {\n const valueSer = this.serializeValue(value, this.serializer);\n\n if (!this.isAttached()) {\n // For the case where this is not attached yet, explicitly JSON\n // clone the value to match the behavior of going thru the wire.\n const addValue = this.deserializeValue(valueSer, this.serializer) as T;\n this.addCore(addValue);\n return;\n }\n\n await this.submit<IConsensusOrderedCollectionAddOperation>({\n opName: \"add\",\n value: valueSer,\n });\n }\n\n /**\n * Remove a value from the consensus collection. If the collection is empty, returns false.\n * Otherwise calls callback with the value\n */\n public async acquire(callback: ConsensusCallback<T>): Promise<boolean> {\n const result = await this.acquireInternal();\n if (result === undefined) {\n return false;\n }\n\n const res = await callback(result.value);\n\n switch (res) {\n case ConsensusResult.Complete:\n await this.complete(result.acquireId);\n break;\n case ConsensusResult.Release:\n this.release(result.acquireId);\n this.emit(\"localRelease\", result.value, true /* intentional */);\n break;\n default: unreachableCase(res);\n }\n\n return true;\n }\n\n /**\n * Wait for a value to be available and acquire it from the consensus collection\n */\n public async waitAndAcquire(callback: ConsensusCallback<T>): Promise<void> {\n do {\n if (this.data.size() === 0) {\n // Wait for new entry before trying to acquire again\n await this.newAckBasedPromise<T>((resolve) => {\n this.once(\"add\", resolve);\n });\n }\n } while (!(await this.acquire(callback)));\n }\n\n protected summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats {\n // If we are transitioning from unattached to attached mode,\n // then we are losing all checked out work!\n this.removeClient(idForLocalUnattachedClient);\n\n const builder = new SummaryTreeBuilder();\n let blobContent = this.serializeValue(this.data.asArray(), serializer);\n builder.addBlob(snapshotFileNameData, blobContent);\n blobContent = this.serializeValue(Array.from(this.jobTracking.entries()), serializer);\n builder.addBlob(snapshotFileNameTracking, blobContent);\n return builder.getSummaryTree();\n }\n\n protected isActive() {\n return this.runtime.connected && this.runtime.deltaManager.active;\n }\n\n protected async complete(acquireId: string) {\n if (!this.isAttached()) {\n this.completeCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n await this.submit<IConsensusOrderedCollectionCompleteOperation>({\n opName: \"complete\",\n acquireId,\n });\n }\n }\n\n protected completeCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.emit(\"complete\", rec.value);\n }\n }\n\n protected release(acquireId: string) {\n if (!this.isAttached()) {\n this.releaseCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n this.submit<IConsensusOrderedCollectionReleaseOperation>({\n opName: \"release\",\n acquireId,\n }).catch((error) => {\n this.runtime.logger.sendErrorEvent({ eventName: \"ConsensusQueue_release\" }, error);\n });\n }\n }\n\n protected releaseCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.data.add(rec.value);\n this.emit(\"add\", rec.value, false /* newlyAdded */);\n }\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n */\n protected async loadCore(storage: IChannelStorageService): Promise<void> {\n assert(this.jobTracking.size === 0, 0x068 /* \"On consensusOrderedCollection load, job tracking size > 0\" */);\n const blob = await storage.readBlob(snapshotFileNameTracking);\n const rawContentTracking = bufferToString(blob, \"utf8\");\n const content = this.deserializeValue(rawContentTracking, this.serializer);\n this.jobTracking = new Map(content) as JobTrackingInfo<T>;\n\n assert(this.data.size() === 0, 0x069 /* \"On consensusOrderedCollection load, data size > 0\" */);\n const blob2 = await storage.readBlob(snapshotFileNameData);\n const rawContentData = bufferToString(blob2, \"utf8\");\n const content2 = this.deserializeValue(rawContentData, this.serializer) as T[];\n this.data.loadFrom(content2);\n }\n\n protected registerCore() {\n return;\n }\n\n protected onDisconnect() {\n for (const [, { value, clientId }] of this.jobTracking) {\n if (clientId === this.runtime.clientId) {\n this.emit(\"localRelease\", value, false /* intentional */);\n }\n }\n }\n\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {\n if (message.type === MessageType.Operation) {\n const op: IConsensusOrderedCollectionOperation = message.contents;\n let value: IConsensusOrderedCollectionValue<T> | undefined;\n switch (op.opName) {\n case \"add\":\n this.addCore(this.deserializeValue(op.value, this.serializer) as T);\n break;\n\n case \"acquire\":\n value = this.acquireCore(op.acquireId, message.clientId);\n break;\n\n case \"complete\":\n this.completeCore(op.acquireId);\n break;\n\n case \"release\":\n this.releaseCore(op.acquireId);\n break;\n\n default: unreachableCase(op);\n }\n if (local) {\n // Resolve the pending promise for this operation now that we have received an ack for it.\n const resolve = localOpMetadata as PendingResolve<T>;\n resolve(value);\n }\n }\n }\n\n private async submit<TMessage extends IConsensusOrderedCollectionOperation>(\n message: TMessage,\n ): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n assert(this.isAttached(), 0x06a /* \"Trying to submit message while detached!\" */);\n\n return this.newAckBasedPromise<IConsensusOrderedCollectionValue<T> | undefined>((resolve) => {\n // Send the resolve function as the localOpMetadata. This will be provided back to us when the\n // op is ack'd.\n this.submitLocalMessage(message, resolve);\n // If we fail due to runtime being disposed, it's better to return undefined then unhandled exception.\n }).catch((error) => undefined);\n }\n\n private addCore(value: T) {\n this.data.add(value);\n this.emit(\"add\", value, true /* newlyAdded */);\n }\n\n private acquireCore(acquireId: string, clientId?: string): IConsensusOrderedCollectionValue<T> | undefined {\n if (this.data.size() === 0) {\n return undefined;\n }\n const value = this.data.remove();\n\n const value2: IConsensusOrderedCollectionValue<T> = {\n acquireId,\n value,\n };\n this.jobTracking.set(value2.acquireId, { value, clientId });\n\n this.emit(\"acquire\", value, clientId);\n return value2;\n }\n\n private async acquireInternal(): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n if (!this.isAttached()) {\n // can be undefined if queue is empty\n return this.acquireCore(uuid(), idForLocalUnattachedClient);\n }\n\n return this.submit<IConsensusOrderedCollectionAcquireOperation>({\n opName: \"acquire\",\n acquireId: uuid(),\n });\n }\n\n private removeClient(clientIdToRemove?: string) {\n const added: T[] = [];\n for (const [acquireId, { value, clientId }] of this.jobTracking) {\n if (clientId === clientIdToRemove) {\n this.jobTracking.delete(acquireId);\n this.data.add(value);\n added.push(value);\n }\n }\n\n // Raise all events only after all state changes are completed,\n // to guarantee same ordering of operations if collection is manipulated from events.\n added.map((value) => this.emit(\"add\", value, false /* newlyAdded */));\n }\n\n private serializeValue(value, serializer: IFluidSerializer) {\n return serializer.stringify(value, this.handle);\n }\n\n private deserializeValue(content: string, serializer: IFluidSerializer) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return serializer.parse(content);\n }\n\n protected applyStashedOp() {\n throw new Error(\"not implemented\");\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/ordered-collection";
8
- export declare const pkgVersion = "0.54.0";
8
+ export declare const pkgVersion = "0.55.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -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/ordered-collection";
11
- exports.pkgVersion = "0.54.0";
11
+ exports.pkgVersion = "0.55.0";
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,oCAAoC,CAAC;AAC/C,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/ordered-collection\";\nexport const pkgVersion = \"0.54.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,oCAAoC,CAAC;AAC/C,QAAA,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/ordered-collection\";\nexport const pkgVersion = \"0.55.0\";\n"]}
@@ -2,10 +2,10 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { IFluidSerializer } from "@fluidframework/core-interfaces";
6
- import { ISequencedDocumentMessage, ITree } from "@fluidframework/protocol-definitions";
5
+ import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
7
6
  import { IChannelAttributes, IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
8
- import { SharedObject } from "@fluidframework/shared-object-base";
7
+ import { IFluidSerializer, SharedObject } from "@fluidframework/shared-object-base";
8
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
9
9
  import { ConsensusCallback, IConsensusOrderedCollection, IOrderedCollection, IConsensusOrderedCollectionEvents } from "./interfaces";
10
10
  /**
11
11
  * Implementation of a consensus collection shared object
@@ -40,7 +40,7 @@ export declare class ConsensusOrderedCollection<T = any> extends SharedObject<IC
40
40
  * Wait for a value to be available and acquire it from the consensus collection
41
41
  */
42
42
  waitAndAcquire(callback: ConsensusCallback<T>): Promise<void>;
43
- protected snapshotCore(serializer: IFluidSerializer): ITree;
43
+ protected summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats;
44
44
  protected isActive(): boolean;
45
45
  protected complete(acquireId: string): Promise<void>;
46
46
  protected completeCore(acquireId: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"consensusOrderedCollection.d.ts","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAEH,yBAAyB,EACzB,KAAK,EAGR,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EACH,iBAAiB,EAEjB,2BAA2B,EAC3B,kBAAkB,EAClB,iCAAiC,EACpC,MAAM,cAAc,CAAC;AA6DtB;;;;;;;;GAQG;AACH,qBAAa,0BAA0B,CAAC,CAAC,GAAG,GAAG,CAC3C,SAAQ,YAAY,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAE,YAAW,2BAA2B,CAAC,CAAC,CAAC;IAchG,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbzB;;OAEG;IACH,OAAO,CAAC,WAAW,CAAiC;IAEpD;;;OAGG;IACH,SAAS,aACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB,EACb,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAchD;;OAEG;IACU,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzC;;;OAGG;IACU,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBtE;;OAEG;IACU,cAAc,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,gBAAgB,GAAG,KAAK;IAgC3D,SAAS,CAAC,QAAQ;cAIF,QAAQ,CAAC,SAAS,EAAE,MAAM;IAe1C,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM;IASxC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM;IAiBnC,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM;IAUvC;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxE,SAAS,CAAC,YAAY;IAItB,SAAS,CAAC,YAAY;IAQtB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO;YA+BpF,MAAM;IAapB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,WAAW;YAgBL,eAAe;IAY7B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAKxB,SAAS,CAAC,cAAc;CAG3B"}
1
+ {"version":3,"file":"consensusOrderedCollection.d.ts","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EACH,kBAAkB,EAClB,sBAAsB,EACtB,sBAAsB,EACzB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,OAAO,EACH,iBAAiB,EAEjB,2BAA2B,EAC3B,kBAAkB,EAClB,iCAAiC,EACpC,MAAM,cAAc,CAAC;AA6DtB;;;;;;;;GAQG;AACH,qBAAa,0BAA0B,CAAC,CAAC,GAAG,GAAG,CAC3C,SAAQ,YAAY,CAAC,iCAAiC,CAAC,CAAC,CAAC,CAAE,YAAW,2BAA2B,CAAC,CAAC,CAAC;IAchG,OAAO,CAAC,QAAQ,CAAC,IAAI;IAbzB;;OAEG;IACH,OAAO,CAAC,WAAW,CAAiC;IAEpD;;;OAGG;IACH,SAAS,aACL,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,sBAAsB,EAC/B,UAAU,EAAE,kBAAkB,EACb,IAAI,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAchD;;OAEG;IACU,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzC;;;OAGG;IACU,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBtE;;OAEG;IACU,cAAc,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1E,SAAS,CAAC,aAAa,CAAC,UAAU,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,GAAG,qBAAqB;IAa/F,SAAS,CAAC,QAAQ;cAIF,QAAQ,CAAC,SAAS,EAAE,MAAM;IAe1C,SAAS,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM;IASxC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM;IAiBnC,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM;IAUvC;;OAEG;cACa,QAAQ,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxE,SAAS,CAAC,YAAY;IAItB,SAAS,CAAC,YAAY;IAQtB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO;YA+BpF,MAAM;IAapB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,WAAW;YAgBL,eAAe;IAY7B,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;IAKxB,SAAS,CAAC,cAAc;CAG3B"}
@@ -3,8 +3,9 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { assert, bufferToString, unreachableCase } from "@fluidframework/common-utils";
6
- import { FileMode, MessageType, TreeEntry, } from "@fluidframework/protocol-definitions";
6
+ import { MessageType } from "@fluidframework/protocol-definitions";
7
7
  import { SharedObject } from "@fluidframework/shared-object-base";
8
+ import { SummaryTreeBuilder } from "@fluidframework/runtime-utils";
8
9
  import { v4 as uuid } from "uuid";
9
10
  import { ConsensusResult, } from "./interfaces";
10
11
  const snapshotFileNameData = "header";
@@ -92,33 +93,16 @@ export class ConsensusOrderedCollection extends SharedObject {
92
93
  }
93
94
  } while (!(await this.acquire(callback)));
94
95
  }
95
- snapshotCore(serializer) {
96
+ summarizeCore(serializer, fullTree) {
96
97
  // If we are transitioning from unattached to attached mode,
97
98
  // then we are losing all checked out work!
98
99
  this.removeClient(idForLocalUnattachedClient);
99
- const tree = {
100
- entries: [
101
- {
102
- mode: FileMode.File,
103
- path: snapshotFileNameData,
104
- type: TreeEntry.Blob,
105
- value: {
106
- contents: this.serializeValue(this.data.asArray(), serializer),
107
- encoding: "utf-8",
108
- },
109
- },
110
- ],
111
- };
112
- tree.entries.push({
113
- mode: FileMode.File,
114
- path: snapshotFileNameTracking,
115
- type: TreeEntry.Blob,
116
- value: {
117
- contents: this.serializeValue(Array.from(this.jobTracking.entries()), serializer),
118
- encoding: "utf-8",
119
- },
120
- });
121
- return tree;
100
+ const builder = new SummaryTreeBuilder();
101
+ let blobContent = this.serializeValue(this.data.asArray(), serializer);
102
+ builder.addBlob(snapshotFileNameData, blobContent);
103
+ blobContent = this.serializeValue(Array.from(this.jobTracking.entries()), serializer);
104
+ builder.addBlob(snapshotFileNameTracking, blobContent);
105
+ return builder.getSummaryTree();
122
106
  }
123
107
  isActive() {
124
108
  return this.runtime.connected && this.runtime.deltaManager.active;
@@ -1 +1 @@
1
- {"version":3,"file":"consensusOrderedCollection.js","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert , bufferToString, unreachableCase } from \"@fluidframework/common-utils\";\nimport { IFluidSerializer } from \"@fluidframework/core-interfaces\";\nimport {\n FileMode,\n ISequencedDocumentMessage,\n ITree,\n MessageType,\n TreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { SharedObject } from \"@fluidframework/shared-object-base\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n ConsensusCallback,\n ConsensusResult,\n IConsensusOrderedCollection,\n IOrderedCollection,\n IConsensusOrderedCollectionEvents,\n} from \"./interfaces\";\n\nconst snapshotFileNameData = \"header\";\nconst snapshotFileNameTracking = \"jobTracking\";\n\ninterface IConsensusOrderedCollectionValue<T> {\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n readonly acquireId: string;\n\n // The actual value\n readonly value: T;\n}\n\n/**\n * An operation for consensus ordered collection\n */\ninterface IConsensusOrderedCollectionAddOperation {\n opName: \"add\";\n // serialized value\n value: string;\n}\n\ninterface IConsensusOrderedCollectionAcquireOperation {\n opName: \"acquire\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionCompleteOperation {\n opName: \"complete\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionReleaseOperation {\n opName: \"release\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ntype IConsensusOrderedCollectionOperation =\n IConsensusOrderedCollectionAddOperation |\n IConsensusOrderedCollectionAcquireOperation |\n IConsensusOrderedCollectionCompleteOperation |\n IConsensusOrderedCollectionReleaseOperation;\n\n/** The type of the resolve function to call after the local operation is ack'd */\ntype PendingResolve<T> = (value: IConsensusOrderedCollectionValue<T> | undefined) => void;\n\n/**\n * For job tracking, we need to keep track of which client \"owns\" a given value.\n * Key is the acquireId from when it was acquired\n * Value is the acquired value, and the id of the client who acquired it, or undefined for unattached client\n */\ntype JobTrackingInfo<T> = Map<string, { value: T, clientId: string | undefined }>;\nconst idForLocalUnattachedClient = undefined;\n\n/**\n * Implementation of a consensus collection shared object\n *\n * Implements the shared object's communication, and the semantics around the\n * release/complete mechanism following acquire.\n *\n * Generally not used directly. A derived type will pass in a backing data type\n * IOrderedCollection that will define the deterministic add/acquire order and snapshot ability.\n */\nexport class ConsensusOrderedCollection<T = any>\n extends SharedObject<IConsensusOrderedCollectionEvents<T>> implements IConsensusOrderedCollection<T> {\n /**\n * The set of values that have been acquired but not yet completed or released\n */\n private jobTracking: JobTrackingInfo<T> = new Map();\n\n /**\n * Constructs a new consensus collection. If the object is non-local an id and service interfaces will\n * be provided\n */\n protected constructor(\n id: string,\n runtime: IFluidDataStoreRuntime,\n attributes: IChannelAttributes,\n private readonly data: IOrderedCollection<T>,\n ) {\n super(id, runtime, attributes);\n\n // We can't simply call this.removeClient(this.runtime.clientId) in on runtime disconnected,\n // because other clients may disconnect concurrently.\n // Disconnect order matters because it defines the order items go back to the queue.\n // So we put items back to queue only when we process our own removeMember event.\n runtime.getQuorum().on(\"removeMember\", (clientId: string) => {\n assert(!!clientId, 0x067 /* \"Missing clientId for removal!\" */);\n this.removeClient(clientId);\n });\n }\n\n /**\n * Add a value to the consensus collection.\n */\n public async add(value: T): Promise<void> {\n const valueSer = this.serializeValue(value, this.serializer);\n\n if (!this.isAttached()) {\n // For the case where this is not attached yet, explicitly JSON\n // clone the value to match the behavior of going thru the wire.\n const addValue = this.deserializeValue(valueSer, this.serializer) as T;\n this.addCore(addValue);\n return;\n }\n\n await this.submit<IConsensusOrderedCollectionAddOperation>({\n opName: \"add\",\n value: valueSer,\n });\n }\n\n /**\n * Remove a value from the consensus collection. If the collection is empty, returns false.\n * Otherwise calls callback with the value\n */\n public async acquire(callback: ConsensusCallback<T>): Promise<boolean> {\n const result = await this.acquireInternal();\n if (result === undefined) {\n return false;\n }\n\n const res = await callback(result.value);\n\n switch (res) {\n case ConsensusResult.Complete:\n await this.complete(result.acquireId);\n break;\n case ConsensusResult.Release:\n this.release(result.acquireId);\n this.emit(\"localRelease\", result.value, true /* intentional */);\n break;\n default: unreachableCase(res);\n }\n\n return true;\n }\n\n /**\n * Wait for a value to be available and acquire it from the consensus collection\n */\n public async waitAndAcquire(callback: ConsensusCallback<T>): Promise<void> {\n do {\n if (this.data.size() === 0) {\n // Wait for new entry before trying to acquire again\n await this.newAckBasedPromise<T>((resolve) => {\n this.once(\"add\", resolve);\n });\n }\n } while (!(await this.acquire(callback)));\n }\n\n protected snapshotCore(serializer: IFluidSerializer): ITree {\n // If we are transitioning from unattached to attached mode,\n // then we are losing all checked out work!\n this.removeClient(idForLocalUnattachedClient);\n\n const tree: ITree = {\n entries: [\n {\n mode: FileMode.File,\n path: snapshotFileNameData,\n type: TreeEntry.Blob,\n value: {\n contents: this.serializeValue(this.data.asArray(), serializer),\n encoding: \"utf-8\",\n },\n },\n ],\n };\n\n tree.entries.push({\n mode: FileMode.File,\n path: snapshotFileNameTracking,\n type: TreeEntry.Blob,\n value: {\n contents: this.serializeValue(Array.from(this.jobTracking.entries()), serializer),\n encoding: \"utf-8\",\n },\n });\n\n return tree;\n }\n\n protected isActive() {\n return this.runtime.connected && this.runtime.deltaManager.active;\n }\n\n protected async complete(acquireId: string) {\n if (!this.isAttached()) {\n this.completeCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n await this.submit<IConsensusOrderedCollectionCompleteOperation>({\n opName: \"complete\",\n acquireId,\n });\n }\n }\n\n protected completeCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.emit(\"complete\", rec.value);\n }\n }\n\n protected release(acquireId: string) {\n if (!this.isAttached()) {\n this.releaseCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n this.submit<IConsensusOrderedCollectionReleaseOperation>({\n opName: \"release\",\n acquireId,\n }).catch((error) => {\n this.runtime.logger.sendErrorEvent({ eventName: \"ConsensusQueue_release\" }, error);\n });\n }\n }\n\n protected releaseCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.data.add(rec.value);\n this.emit(\"add\", rec.value, false /* newlyAdded */);\n }\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n */\n protected async loadCore(storage: IChannelStorageService): Promise<void> {\n assert(this.jobTracking.size === 0, 0x068 /* \"On consensusOrderedCollection load, job tracking size > 0\" */);\n const blob = await storage.readBlob(snapshotFileNameTracking);\n const rawContentTracking = bufferToString(blob, \"utf8\");\n const content = this.deserializeValue(rawContentTracking, this.serializer);\n this.jobTracking = new Map(content) as JobTrackingInfo<T>;\n\n assert(this.data.size() === 0, 0x069 /* \"On consensusOrderedCollection load, data size > 0\" */);\n const blob2 = await storage.readBlob(snapshotFileNameData);\n const rawContentData = bufferToString(blob2, \"utf8\");\n const content2 = this.deserializeValue(rawContentData, this.serializer) as T[];\n this.data.loadFrom(content2);\n }\n\n protected registerCore() {\n return;\n }\n\n protected onDisconnect() {\n for (const [, { value, clientId }] of this.jobTracking) {\n if (clientId === this.runtime.clientId) {\n this.emit(\"localRelease\", value, false /* intentional */);\n }\n }\n }\n\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {\n if (message.type === MessageType.Operation) {\n const op: IConsensusOrderedCollectionOperation = message.contents;\n let value: IConsensusOrderedCollectionValue<T> | undefined;\n switch (op.opName) {\n case \"add\":\n this.addCore(this.deserializeValue(op.value, this.serializer) as T);\n break;\n\n case \"acquire\":\n value = this.acquireCore(op.acquireId, message.clientId);\n break;\n\n case \"complete\":\n this.completeCore(op.acquireId);\n break;\n\n case \"release\":\n this.releaseCore(op.acquireId);\n break;\n\n default: unreachableCase(op);\n }\n if (local) {\n // Resolve the pending promise for this operation now that we have received an ack for it.\n const resolve = localOpMetadata as PendingResolve<T>;\n resolve(value);\n }\n }\n }\n\n private async submit<TMessage extends IConsensusOrderedCollectionOperation>(\n message: TMessage,\n ): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n assert(this.isAttached(), 0x06a /* \"Trying to submit message while detached!\" */);\n\n return this.newAckBasedPromise<IConsensusOrderedCollectionValue<T> | undefined>((resolve) => {\n // Send the resolve function as the localOpMetadata. This will be provided back to us when the\n // op is ack'd.\n this.submitLocalMessage(message, resolve);\n // If we fail due to runtime being disposed, it's better to return undefined then unhandled exception.\n }).catch((error) => undefined);\n }\n\n private addCore(value: T) {\n this.data.add(value);\n this.emit(\"add\", value, true /* newlyAdded */);\n }\n\n private acquireCore(acquireId: string, clientId?: string): IConsensusOrderedCollectionValue<T> | undefined {\n if (this.data.size() === 0) {\n return undefined;\n }\n const value = this.data.remove();\n\n const value2: IConsensusOrderedCollectionValue<T> = {\n acquireId,\n value,\n };\n this.jobTracking.set(value2.acquireId, { value, clientId });\n\n this.emit(\"acquire\", value, clientId);\n return value2;\n }\n\n private async acquireInternal(): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n if (!this.isAttached()) {\n // can be undefined if queue is empty\n return this.acquireCore(uuid(), idForLocalUnattachedClient);\n }\n\n return this.submit<IConsensusOrderedCollectionAcquireOperation>({\n opName: \"acquire\",\n acquireId: uuid(),\n });\n }\n\n private removeClient(clientIdToRemove?: string) {\n const added: T[] = [];\n for (const [acquireId, { value, clientId }] of this.jobTracking) {\n if (clientId === clientIdToRemove) {\n this.jobTracking.delete(acquireId);\n this.data.add(value);\n added.push(value);\n }\n }\n\n // Raise all events only after all state changes are completed,\n // to guarantee same ordering of operations if collection is manipulated from events.\n added.map((value) => this.emit(\"add\", value, false /* newlyAdded */));\n }\n\n private serializeValue(value, serializer: IFluidSerializer) {\n return serializer.stringify(value, this.handle);\n }\n\n private deserializeValue(content: string, serializer: IFluidSerializer) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return serializer.parse(content);\n }\n\n protected applyStashedOp() {\n throw new Error(\"not implemented\");\n }\n}\n"]}
1
+ {"version":3,"file":"consensusOrderedCollection.js","sourceRoot":"","sources":["../src/consensusOrderedCollection.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert , bufferToString, unreachableCase } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelStorageService,\n} from \"@fluidframework/datastore-definitions\";\nimport { IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n ConsensusCallback,\n ConsensusResult,\n IConsensusOrderedCollection,\n IOrderedCollection,\n IConsensusOrderedCollectionEvents,\n} from \"./interfaces\";\n\nconst snapshotFileNameData = \"header\";\nconst snapshotFileNameTracking = \"jobTracking\";\n\ninterface IConsensusOrderedCollectionValue<T> {\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n readonly acquireId: string;\n\n // The actual value\n readonly value: T;\n}\n\n/**\n * An operation for consensus ordered collection\n */\ninterface IConsensusOrderedCollectionAddOperation {\n opName: \"add\";\n // serialized value\n value: string;\n}\n\ninterface IConsensusOrderedCollectionAcquireOperation {\n opName: \"acquire\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionCompleteOperation {\n opName: \"complete\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ninterface IConsensusOrderedCollectionReleaseOperation {\n opName: \"release\";\n // an ID used to indicate acquired item.\n // Used in acquire/release/complete ops.\n acquireId: string;\n}\n\ntype IConsensusOrderedCollectionOperation =\n IConsensusOrderedCollectionAddOperation |\n IConsensusOrderedCollectionAcquireOperation |\n IConsensusOrderedCollectionCompleteOperation |\n IConsensusOrderedCollectionReleaseOperation;\n\n/** The type of the resolve function to call after the local operation is ack'd */\ntype PendingResolve<T> = (value: IConsensusOrderedCollectionValue<T> | undefined) => void;\n\n/**\n * For job tracking, we need to keep track of which client \"owns\" a given value.\n * Key is the acquireId from when it was acquired\n * Value is the acquired value, and the id of the client who acquired it, or undefined for unattached client\n */\ntype JobTrackingInfo<T> = Map<string, { value: T, clientId: string | undefined }>;\nconst idForLocalUnattachedClient = undefined;\n\n/**\n * Implementation of a consensus collection shared object\n *\n * Implements the shared object's communication, and the semantics around the\n * release/complete mechanism following acquire.\n *\n * Generally not used directly. A derived type will pass in a backing data type\n * IOrderedCollection that will define the deterministic add/acquire order and snapshot ability.\n */\nexport class ConsensusOrderedCollection<T = any>\n extends SharedObject<IConsensusOrderedCollectionEvents<T>> implements IConsensusOrderedCollection<T> {\n /**\n * The set of values that have been acquired but not yet completed or released\n */\n private jobTracking: JobTrackingInfo<T> = new Map();\n\n /**\n * Constructs a new consensus collection. If the object is non-local an id and service interfaces will\n * be provided\n */\n protected constructor(\n id: string,\n runtime: IFluidDataStoreRuntime,\n attributes: IChannelAttributes,\n private readonly data: IOrderedCollection<T>,\n ) {\n super(id, runtime, attributes);\n\n // We can't simply call this.removeClient(this.runtime.clientId) in on runtime disconnected,\n // because other clients may disconnect concurrently.\n // Disconnect order matters because it defines the order items go back to the queue.\n // So we put items back to queue only when we process our own removeMember event.\n runtime.getQuorum().on(\"removeMember\", (clientId: string) => {\n assert(!!clientId, 0x067 /* \"Missing clientId for removal!\" */);\n this.removeClient(clientId);\n });\n }\n\n /**\n * Add a value to the consensus collection.\n */\n public async add(value: T): Promise<void> {\n const valueSer = this.serializeValue(value, this.serializer);\n\n if (!this.isAttached()) {\n // For the case where this is not attached yet, explicitly JSON\n // clone the value to match the behavior of going thru the wire.\n const addValue = this.deserializeValue(valueSer, this.serializer) as T;\n this.addCore(addValue);\n return;\n }\n\n await this.submit<IConsensusOrderedCollectionAddOperation>({\n opName: \"add\",\n value: valueSer,\n });\n }\n\n /**\n * Remove a value from the consensus collection. If the collection is empty, returns false.\n * Otherwise calls callback with the value\n */\n public async acquire(callback: ConsensusCallback<T>): Promise<boolean> {\n const result = await this.acquireInternal();\n if (result === undefined) {\n return false;\n }\n\n const res = await callback(result.value);\n\n switch (res) {\n case ConsensusResult.Complete:\n await this.complete(result.acquireId);\n break;\n case ConsensusResult.Release:\n this.release(result.acquireId);\n this.emit(\"localRelease\", result.value, true /* intentional */);\n break;\n default: unreachableCase(res);\n }\n\n return true;\n }\n\n /**\n * Wait for a value to be available and acquire it from the consensus collection\n */\n public async waitAndAcquire(callback: ConsensusCallback<T>): Promise<void> {\n do {\n if (this.data.size() === 0) {\n // Wait for new entry before trying to acquire again\n await this.newAckBasedPromise<T>((resolve) => {\n this.once(\"add\", resolve);\n });\n }\n } while (!(await this.acquire(callback)));\n }\n\n protected summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats {\n // If we are transitioning from unattached to attached mode,\n // then we are losing all checked out work!\n this.removeClient(idForLocalUnattachedClient);\n\n const builder = new SummaryTreeBuilder();\n let blobContent = this.serializeValue(this.data.asArray(), serializer);\n builder.addBlob(snapshotFileNameData, blobContent);\n blobContent = this.serializeValue(Array.from(this.jobTracking.entries()), serializer);\n builder.addBlob(snapshotFileNameTracking, blobContent);\n return builder.getSummaryTree();\n }\n\n protected isActive() {\n return this.runtime.connected && this.runtime.deltaManager.active;\n }\n\n protected async complete(acquireId: string) {\n if (!this.isAttached()) {\n this.completeCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n await this.submit<IConsensusOrderedCollectionCompleteOperation>({\n opName: \"complete\",\n acquireId,\n });\n }\n }\n\n protected completeCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.emit(\"complete\", rec.value);\n }\n }\n\n protected release(acquireId: string) {\n if (!this.isAttached()) {\n this.releaseCore(acquireId);\n return;\n }\n\n // if not active, this item already was released to queue (as observed by other clients)\n if (this.isActive()) {\n this.submit<IConsensusOrderedCollectionReleaseOperation>({\n opName: \"release\",\n acquireId,\n }).catch((error) => {\n this.runtime.logger.sendErrorEvent({ eventName: \"ConsensusQueue_release\" }, error);\n });\n }\n }\n\n protected releaseCore(acquireId: string) {\n // Note: item may be no longer in jobTracking and returned back to queue!\n const rec = this.jobTracking.get(acquireId);\n if (rec !== undefined) {\n this.jobTracking.delete(acquireId);\n this.data.add(rec.value);\n this.emit(\"add\", rec.value, false /* newlyAdded */);\n }\n }\n\n /**\n * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n */\n protected async loadCore(storage: IChannelStorageService): Promise<void> {\n assert(this.jobTracking.size === 0, 0x068 /* \"On consensusOrderedCollection load, job tracking size > 0\" */);\n const blob = await storage.readBlob(snapshotFileNameTracking);\n const rawContentTracking = bufferToString(blob, \"utf8\");\n const content = this.deserializeValue(rawContentTracking, this.serializer);\n this.jobTracking = new Map(content) as JobTrackingInfo<T>;\n\n assert(this.data.size() === 0, 0x069 /* \"On consensusOrderedCollection load, data size > 0\" */);\n const blob2 = await storage.readBlob(snapshotFileNameData);\n const rawContentData = bufferToString(blob2, \"utf8\");\n const content2 = this.deserializeValue(rawContentData, this.serializer) as T[];\n this.data.loadFrom(content2);\n }\n\n protected registerCore() {\n return;\n }\n\n protected onDisconnect() {\n for (const [, { value, clientId }] of this.jobTracking) {\n if (clientId === this.runtime.clientId) {\n this.emit(\"localRelease\", value, false /* intentional */);\n }\n }\n }\n\n protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown) {\n if (message.type === MessageType.Operation) {\n const op: IConsensusOrderedCollectionOperation = message.contents;\n let value: IConsensusOrderedCollectionValue<T> | undefined;\n switch (op.opName) {\n case \"add\":\n this.addCore(this.deserializeValue(op.value, this.serializer) as T);\n break;\n\n case \"acquire\":\n value = this.acquireCore(op.acquireId, message.clientId);\n break;\n\n case \"complete\":\n this.completeCore(op.acquireId);\n break;\n\n case \"release\":\n this.releaseCore(op.acquireId);\n break;\n\n default: unreachableCase(op);\n }\n if (local) {\n // Resolve the pending promise for this operation now that we have received an ack for it.\n const resolve = localOpMetadata as PendingResolve<T>;\n resolve(value);\n }\n }\n }\n\n private async submit<TMessage extends IConsensusOrderedCollectionOperation>(\n message: TMessage,\n ): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n assert(this.isAttached(), 0x06a /* \"Trying to submit message while detached!\" */);\n\n return this.newAckBasedPromise<IConsensusOrderedCollectionValue<T> | undefined>((resolve) => {\n // Send the resolve function as the localOpMetadata. This will be provided back to us when the\n // op is ack'd.\n this.submitLocalMessage(message, resolve);\n // If we fail due to runtime being disposed, it's better to return undefined then unhandled exception.\n }).catch((error) => undefined);\n }\n\n private addCore(value: T) {\n this.data.add(value);\n this.emit(\"add\", value, true /* newlyAdded */);\n }\n\n private acquireCore(acquireId: string, clientId?: string): IConsensusOrderedCollectionValue<T> | undefined {\n if (this.data.size() === 0) {\n return undefined;\n }\n const value = this.data.remove();\n\n const value2: IConsensusOrderedCollectionValue<T> = {\n acquireId,\n value,\n };\n this.jobTracking.set(value2.acquireId, { value, clientId });\n\n this.emit(\"acquire\", value, clientId);\n return value2;\n }\n\n private async acquireInternal(): Promise<IConsensusOrderedCollectionValue<T> | undefined> {\n if (!this.isAttached()) {\n // can be undefined if queue is empty\n return this.acquireCore(uuid(), idForLocalUnattachedClient);\n }\n\n return this.submit<IConsensusOrderedCollectionAcquireOperation>({\n opName: \"acquire\",\n acquireId: uuid(),\n });\n }\n\n private removeClient(clientIdToRemove?: string) {\n const added: T[] = [];\n for (const [acquireId, { value, clientId }] of this.jobTracking) {\n if (clientId === clientIdToRemove) {\n this.jobTracking.delete(acquireId);\n this.data.add(value);\n added.push(value);\n }\n }\n\n // Raise all events only after all state changes are completed,\n // to guarantee same ordering of operations if collection is manipulated from events.\n added.map((value) => this.emit(\"add\", value, false /* newlyAdded */));\n }\n\n private serializeValue(value, serializer: IFluidSerializer) {\n return serializer.stringify(value, this.handle);\n }\n\n private deserializeValue(content: string, serializer: IFluidSerializer) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return serializer.parse(content);\n }\n\n protected applyStashedOp() {\n throw new Error(\"not implemented\");\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/ordered-collection";
8
- export declare const pkgVersion = "0.54.0";
8
+ export declare const pkgVersion = "0.55.0";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/ordered-collection";
8
- export const pkgVersion = "0.54.0";
8
+ export const pkgVersion = "0.55.0";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,oCAAoC,CAAC;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/ordered-collection\";\nexport const pkgVersion = \"0.54.0\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,oCAAoC,CAAC;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/ordered-collection\";\nexport const pkgVersion = \"0.55.0\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/ordered-collection",
3
- "version": "0.54.0",
3
+ "version": "0.55.0",
4
4
  "description": "Consensus Collection",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -23,7 +23,7 @@
23
23
  "ci:build:docs": "api-extractor run --typescript-compiler-folder ../../../node_modules/typescript && copyfiles -u 1 ./_api-extractor-temp/* ../../../_api-extractor-temp/",
24
24
  "clean": "rimraf dist lib *.tsbuildinfo *.build.log",
25
25
  "eslint": "eslint --format stylish src",
26
- "eslint:fix": "eslint --format stylish src --fix",
26
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
27
27
  "lint": "npm run eslint",
28
28
  "lint:fix": "npm run eslint:fix",
29
29
  "test": "npm run test:mocha",
@@ -57,32 +57,35 @@
57
57
  "dependencies": {
58
58
  "@fluidframework/common-utils": "^0.32.1",
59
59
  "@fluidframework/core-interfaces": "^0.41.0",
60
- "@fluidframework/datastore-definitions": "^0.54.0",
60
+ "@fluidframework/datastore-definitions": "^0.55.0",
61
61
  "@fluidframework/protocol-definitions": "^0.1026.0",
62
- "@fluidframework/shared-object-base": "^0.54.0",
62
+ "@fluidframework/runtime-definitions": "^0.55.0",
63
+ "@fluidframework/runtime-utils": "^0.55.0",
64
+ "@fluidframework/shared-object-base": "^0.55.0",
63
65
  "uuid": "^8.3.1"
64
66
  },
65
67
  "devDependencies": {
66
- "@fluid-internal/test-dds-utils": "^0.54.0",
68
+ "@fluid-internal/test-dds-utils": "^0.55.0",
67
69
  "@fluidframework/build-common": "^0.23.0",
68
- "@fluidframework/eslint-config-fluid": "^0.24.0",
69
- "@fluidframework/mocha-test-setup": "^0.54.0",
70
- "@fluidframework/test-runtime-utils": "^0.54.0",
70
+ "@fluidframework/eslint-config-fluid": "^0.25.0",
71
+ "@fluidframework/mocha-test-setup": "^0.55.0",
72
+ "@fluidframework/test-runtime-utils": "^0.55.0",
71
73
  "@microsoft/api-extractor": "^7.16.1",
74
+ "@rushstack/eslint-config": "^2.5.1",
72
75
  "@types/mocha": "^8.2.2",
73
76
  "@types/node": "^14.18.0",
74
- "@typescript-eslint/eslint-plugin": "~4.14.0",
75
- "@typescript-eslint/parser": "~4.14.0",
77
+ "@typescript-eslint/eslint-plugin": "~5.9.0",
78
+ "@typescript-eslint/parser": "~5.9.0",
76
79
  "concurrently": "^6.2.0",
77
80
  "copyfiles": "^2.1.0",
78
81
  "cross-env": "^7.0.2",
79
- "eslint": "~7.18.0",
82
+ "eslint": "~8.6.0",
83
+ "eslint-plugin-editorconfig": "~3.2.0",
80
84
  "eslint-plugin-eslint-comments": "~3.2.0",
81
- "eslint-plugin-import": "~2.22.1",
85
+ "eslint-plugin-import": "~2.25.4",
82
86
  "eslint-plugin-no-null": "~1.0.2",
83
- "eslint-plugin-prefer-arrow": "~1.2.2",
84
- "eslint-plugin-react": "~7.22.0",
85
- "eslint-plugin-unicorn": "~26.0.1",
87
+ "eslint-plugin-react": "~7.28.0",
88
+ "eslint-plugin-unicorn": "~40.0.0",
86
89
  "mocha": "^8.4.0",
87
90
  "nyc": "^15.0.0",
88
91
  "rimraf": "^2.6.2",
@@ -4,20 +4,15 @@
4
4
  */
5
5
 
6
6
  import { assert , bufferToString, unreachableCase } from "@fluidframework/common-utils";
7
- import { IFluidSerializer } from "@fluidframework/core-interfaces";
8
- import {
9
- FileMode,
10
- ISequencedDocumentMessage,
11
- ITree,
12
- MessageType,
13
- TreeEntry,
14
- } from "@fluidframework/protocol-definitions";
7
+ import { ISequencedDocumentMessage, MessageType } from "@fluidframework/protocol-definitions";
15
8
  import {
16
9
  IChannelAttributes,
17
10
  IFluidDataStoreRuntime,
18
11
  IChannelStorageService,
19
12
  } from "@fluidframework/datastore-definitions";
20
- import { SharedObject } from "@fluidframework/shared-object-base";
13
+ import { IFluidSerializer, SharedObject } from "@fluidframework/shared-object-base";
14
+ import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
15
+ import { SummaryTreeBuilder } from "@fluidframework/runtime-utils";
21
16
  import { v4 as uuid } from "uuid";
22
17
  import {
23
18
  ConsensusCallback,
@@ -184,36 +179,17 @@ export class ConsensusOrderedCollection<T = any>
184
179
  } while (!(await this.acquire(callback)));
185
180
  }
186
181
 
187
- protected snapshotCore(serializer: IFluidSerializer): ITree {
182
+ protected summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats {
188
183
  // If we are transitioning from unattached to attached mode,
189
184
  // then we are losing all checked out work!
190
185
  this.removeClient(idForLocalUnattachedClient);
191
186
 
192
- const tree: ITree = {
193
- entries: [
194
- {
195
- mode: FileMode.File,
196
- path: snapshotFileNameData,
197
- type: TreeEntry.Blob,
198
- value: {
199
- contents: this.serializeValue(this.data.asArray(), serializer),
200
- encoding: "utf-8",
201
- },
202
- },
203
- ],
204
- };
205
-
206
- tree.entries.push({
207
- mode: FileMode.File,
208
- path: snapshotFileNameTracking,
209
- type: TreeEntry.Blob,
210
- value: {
211
- contents: this.serializeValue(Array.from(this.jobTracking.entries()), serializer),
212
- encoding: "utf-8",
213
- },
214
- });
215
-
216
- return tree;
187
+ const builder = new SummaryTreeBuilder();
188
+ let blobContent = this.serializeValue(this.data.asArray(), serializer);
189
+ builder.addBlob(snapshotFileNameData, blobContent);
190
+ blobContent = this.serializeValue(Array.from(this.jobTracking.entries()), serializer);
191
+ builder.addBlob(snapshotFileNameTracking, blobContent);
192
+ return builder.getSummaryTree();
217
193
  }
218
194
 
219
195
  protected isActive() {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/ordered-collection";
9
- export const pkgVersion = "0.54.0";
9
+ export const pkgVersion = "0.55.0";