@fluidframework/ordered-collection 1.4.0-115997 → 2.0.0-dev-rc.1.0.0.224419

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 (116) hide show
  1. package/.eslintrc.js +5 -7
  2. package/.mocharc.js +12 -0
  3. package/CHANGELOG.md +117 -0
  4. package/README.md +22 -1
  5. package/api-extractor-lint.json +4 -0
  6. package/api-extractor.json +2 -2
  7. package/api-report/ordered-collection.api.md +111 -0
  8. package/dist/{consensusOrderedCollection.js → consensusOrderedCollection.cjs} +16 -12
  9. package/dist/consensusOrderedCollection.cjs.map +1 -0
  10. package/dist/consensusOrderedCollection.d.ts +1 -0
  11. package/dist/consensusOrderedCollection.d.ts.map +1 -1
  12. package/dist/{consensusOrderedCollectionFactory.js → consensusOrderedCollectionFactory.cjs} +3 -3
  13. package/dist/consensusOrderedCollectionFactory.cjs.map +1 -0
  14. package/dist/consensusOrderedCollectionFactory.d.ts.map +1 -1
  15. package/dist/{consensusQueue.js → consensusQueue.cjs} +5 -5
  16. package/dist/consensusQueue.cjs.map +1 -0
  17. package/dist/consensusQueue.d.ts +1 -0
  18. package/dist/consensusQueue.d.ts.map +1 -1
  19. package/dist/index.cjs +17 -0
  20. package/dist/index.cjs.map +1 -0
  21. package/dist/index.d.ts +4 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/{interfaces.js → interfaces.cjs} +5 -2
  24. package/dist/interfaces.cjs.map +1 -0
  25. package/dist/interfaces.d.ts +11 -2
  26. package/dist/interfaces.d.ts.map +1 -1
  27. package/dist/ordered-collection-alpha.d.ts +226 -0
  28. package/dist/ordered-collection-beta.d.ts +35 -0
  29. package/dist/ordered-collection-public.d.ts +35 -0
  30. package/dist/ordered-collection-untrimmed.d.ts +246 -0
  31. package/dist/{packageVersion.js → packageVersion.cjs} +2 -2
  32. package/dist/packageVersion.cjs.map +1 -0
  33. package/dist/packageVersion.d.ts +1 -1
  34. package/dist/packageVersion.d.ts.map +1 -1
  35. package/dist/{snapshotableArray.js → snapshotableArray.cjs} +3 -3
  36. package/dist/snapshotableArray.cjs.map +1 -0
  37. package/dist/snapshotableArray.d.ts.map +1 -1
  38. package/dist/{testUtils.js → testUtils.cjs} +4 -2
  39. package/dist/testUtils.cjs.map +1 -0
  40. package/dist/testUtils.d.ts +2 -0
  41. package/dist/testUtils.d.ts.map +1 -1
  42. package/dist/tsdoc-metadata.json +11 -0
  43. package/lib/{consensusOrderedCollection.d.ts → consensusOrderedCollection.d.mts} +2 -1
  44. package/lib/consensusOrderedCollection.d.mts.map +1 -0
  45. package/lib/{consensusOrderedCollection.js → consensusOrderedCollection.mjs} +10 -6
  46. package/lib/consensusOrderedCollection.mjs.map +1 -0
  47. package/lib/{consensusOrderedCollectionFactory.d.ts → consensusOrderedCollectionFactory.d.mts} +1 -1
  48. package/lib/consensusOrderedCollectionFactory.d.mts.map +1 -0
  49. package/lib/{consensusOrderedCollectionFactory.js → consensusOrderedCollectionFactory.mjs} +3 -3
  50. package/lib/consensusOrderedCollectionFactory.mjs.map +1 -0
  51. package/lib/{consensusQueue.d.ts → consensusQueue.d.mts} +2 -1
  52. package/lib/consensusQueue.d.mts.map +1 -0
  53. package/lib/{consensusQueue.js → consensusQueue.mjs} +5 -5
  54. package/lib/consensusQueue.mjs.map +1 -0
  55. package/lib/index.d.mts +9 -0
  56. package/lib/index.d.mts.map +1 -0
  57. package/lib/index.mjs +9 -0
  58. package/lib/index.mjs.map +1 -0
  59. package/lib/{interfaces.d.ts → interfaces.d.mts} +11 -2
  60. package/lib/interfaces.d.mts.map +1 -0
  61. package/lib/{interfaces.js → interfaces.mjs} +4 -1
  62. package/lib/interfaces.mjs.map +1 -0
  63. package/lib/ordered-collection-alpha.d.mts +226 -0
  64. package/lib/ordered-collection-beta.d.mts +35 -0
  65. package/lib/ordered-collection-public.d.mts +35 -0
  66. package/lib/ordered-collection-untrimmed.d.mts +246 -0
  67. package/lib/{packageVersion.d.ts → packageVersion.d.mts} +1 -1
  68. package/lib/{packageVersion.d.ts.map → packageVersion.d.mts.map} +1 -1
  69. package/lib/{packageVersion.js → packageVersion.mjs} +2 -2
  70. package/lib/packageVersion.mjs.map +1 -0
  71. package/lib/{snapshotableArray.d.ts.map → snapshotableArray.d.mts.map} +1 -1
  72. package/lib/{snapshotableArray.js → snapshotableArray.mjs} +2 -2
  73. package/lib/snapshotableArray.mjs.map +1 -0
  74. package/lib/{testUtils.d.ts → testUtils.d.mts} +3 -1
  75. package/lib/testUtils.d.mts.map +1 -0
  76. package/lib/{testUtils.js → testUtils.mjs} +4 -2
  77. package/lib/testUtils.mjs.map +1 -0
  78. package/package.json +98 -63
  79. package/prettier.config.cjs +8 -0
  80. package/src/consensusOrderedCollection.ts +340 -319
  81. package/src/consensusOrderedCollectionFactory.ts +33 -32
  82. package/src/consensusQueue.ts +42 -38
  83. package/src/index.ts +12 -4
  84. package/src/interfaces.ts +83 -74
  85. package/src/packageVersion.ts +1 -1
  86. package/src/snapshotableArray.ts +12 -12
  87. package/src/testUtils.ts +21 -18
  88. package/tsc-multi.test.json +4 -0
  89. package/tsconfig.json +11 -13
  90. package/dist/consensusOrderedCollection.js.map +0 -1
  91. package/dist/consensusOrderedCollectionFactory.js.map +0 -1
  92. package/dist/consensusQueue.js.map +0 -1
  93. package/dist/index.js +0 -21
  94. package/dist/index.js.map +0 -1
  95. package/dist/interfaces.js.map +0 -1
  96. package/dist/packageVersion.js.map +0 -1
  97. package/dist/snapshotableArray.js.map +0 -1
  98. package/dist/testUtils.js.map +0 -1
  99. package/lib/consensusOrderedCollection.d.ts.map +0 -1
  100. package/lib/consensusOrderedCollection.js.map +0 -1
  101. package/lib/consensusOrderedCollectionFactory.d.ts.map +0 -1
  102. package/lib/consensusOrderedCollectionFactory.js.map +0 -1
  103. package/lib/consensusQueue.d.ts.map +0 -1
  104. package/lib/consensusQueue.js.map +0 -1
  105. package/lib/index.d.ts +0 -9
  106. package/lib/index.d.ts.map +0 -1
  107. package/lib/index.js +0 -9
  108. package/lib/index.js.map +0 -1
  109. package/lib/interfaces.d.ts.map +0 -1
  110. package/lib/interfaces.js.map +0 -1
  111. package/lib/packageVersion.js.map +0 -1
  112. package/lib/snapshotableArray.js.map +0 -1
  113. package/lib/testUtils.d.ts.map +0 -1
  114. package/lib/testUtils.js.map +0 -1
  115. package/tsconfig.esnext.json +0 -7
  116. /package/lib/{snapshotableArray.d.ts → snapshotableArray.d.mts} +0 -0
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import {
7
- IChannelAttributes,
8
- IFluidDataStoreRuntime,
9
- IChannelServices,
7
+ IChannelAttributes,
8
+ IFluidDataStoreRuntime,
9
+ IChannelServices,
10
10
  } from "@fluidframework/datastore-definitions";
11
11
  import { ConsensusQueue } from "./consensusQueue";
12
12
  import { IConsensusOrderedCollection, IConsensusOrderedCollectionFactory } from "./interfaces";
@@ -16,38 +16,39 @@ import { pkgVersion } from "./packageVersion";
16
16
  * The factory that defines the consensus queue
17
17
  */
18
18
  export class ConsensusQueueFactory implements IConsensusOrderedCollectionFactory {
19
- public static Type = "https://graph.microsoft.com/types/consensus-queue";
19
+ public static Type = "https://graph.microsoft.com/types/consensus-queue";
20
20
 
21
- public static readonly Attributes: IChannelAttributes = {
22
- type: ConsensusQueueFactory.Type,
23
- snapshotFormatVersion: "0.1",
24
- packageVersion: pkgVersion,
25
- };
21
+ public static readonly Attributes: IChannelAttributes = {
22
+ type: ConsensusQueueFactory.Type,
23
+ snapshotFormatVersion: "0.1",
24
+ packageVersion: pkgVersion,
25
+ };
26
26
 
27
- public get type() {
28
- return ConsensusQueueFactory.Type;
29
- }
27
+ public get type() {
28
+ return ConsensusQueueFactory.Type;
29
+ }
30
30
 
31
- public get attributes() {
32
- return ConsensusQueueFactory.Attributes;
33
- }
31
+ public get attributes() {
32
+ return ConsensusQueueFactory.Attributes;
33
+ }
34
34
 
35
- /**
36
- * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
37
- */
38
- public async load(
39
- runtime: IFluidDataStoreRuntime,
40
- id: string,
41
- services: IChannelServices,
42
- attributes: IChannelAttributes): Promise<IConsensusOrderedCollection> {
43
- const collection = new ConsensusQueue(id, runtime, attributes);
44
- await collection.load(services);
45
- return collection;
46
- }
35
+ /**
36
+ * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}
37
+ */
38
+ public async load(
39
+ runtime: IFluidDataStoreRuntime,
40
+ id: string,
41
+ services: IChannelServices,
42
+ attributes: IChannelAttributes,
43
+ ): Promise<IConsensusOrderedCollection> {
44
+ const collection = new ConsensusQueue(id, runtime, attributes);
45
+ await collection.load(services);
46
+ return collection;
47
+ }
47
48
 
48
- public create(document: IFluidDataStoreRuntime, id: string): IConsensusOrderedCollection {
49
- const collection = new ConsensusQueue(id, document, this.attributes);
50
- collection.initializeLocal();
51
- return collection;
52
- }
49
+ public create(document: IFluidDataStoreRuntime, id: string): IConsensusOrderedCollection {
50
+ const collection = new ConsensusQueue(id, document, this.attributes);
51
+ collection.initializeLocal();
52
+ return collection;
53
+ }
53
54
  }
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import {
7
- IFluidDataStoreRuntime,
8
- IChannelAttributes,
9
- IChannelFactory,
7
+ IFluidDataStoreRuntime,
8
+ IChannelAttributes,
9
+ IChannelFactory,
10
10
  } from "@fluidframework/datastore-definitions";
11
11
  import { ConsensusOrderedCollection } from "./consensusOrderedCollection";
12
12
  import { ConsensusQueueFactory } from "./consensusOrderedCollectionFactory";
@@ -17,50 +17,54 @@ import { SnapshotableArray } from "./snapshotableArray";
17
17
  * An JS array based queue implementation that is the backing data structure for ConsensusQueue
18
18
  */
19
19
  class SnapshotableQueue<T> extends SnapshotableArray<T> implements IOrderedCollection<T> {
20
- public add(value: T) {
21
- this.data.push(value);
22
- }
20
+ public add(value: T) {
21
+ this.data.push(value);
22
+ }
23
23
 
24
- public remove(): T {
25
- if (this.size() === 0) {
26
- throw new Error("SnapshotableQueue is empty");
27
- }
28
- return this.data.shift() as T;
29
- }
24
+ public remove(): T {
25
+ if (this.size() === 0) {
26
+ throw new Error("SnapshotableQueue is empty");
27
+ }
28
+ return this.data.shift() as T;
29
+ }
30
30
  }
31
31
 
32
32
  /**
33
33
  * Implementation of a consensus stack
34
34
  *
35
35
  * An derived type of ConsensusOrderedCollection with a queue as the backing data and order.
36
+ * @alpha
36
37
  */
37
38
  export class ConsensusQueue<T = any> extends ConsensusOrderedCollection<T> {
38
- /**
39
- * Create a new consensus queue
40
- *
41
- * @param runtime - data store runtime the new consensus queue belongs to
42
- * @param id - optional name of theconsensus queue
43
- * @returns newly create consensus queue (but not attached yet)
44
- */
45
- // eslint-disable-next-line @typescript-eslint/no-shadow
46
- public static create<T = any>(runtime: IFluidDataStoreRuntime, id?: string) {
47
- return runtime.createChannel(id, ConsensusQueueFactory.Type) as ConsensusQueue<T>;
48
- }
39
+ /**
40
+ * Create a new consensus queue
41
+ *
42
+ * @param runtime - data store runtime the new consensus queue belongs to
43
+ * @param id - optional name of theconsensus queue
44
+ * @returns newly create consensus queue (but not attached yet)
45
+ */
46
+ public static create<T = any>(runtime: IFluidDataStoreRuntime, id?: string) {
47
+ return runtime.createChannel(id, ConsensusQueueFactory.Type) as ConsensusQueue<T>;
48
+ }
49
49
 
50
- /**
51
- * Get a factory for ConsensusQueue to register with the data store.
52
- *
53
- * @returns a factory that creates and load ConsensusQueue
54
- */
55
- public static getFactory(): IChannelFactory {
56
- return new ConsensusQueueFactory();
57
- }
50
+ /**
51
+ * Get a factory for ConsensusQueue to register with the data store.
52
+ *
53
+ * @returns a factory that creates and load ConsensusQueue
54
+ */
55
+ public static getFactory(): IChannelFactory {
56
+ return new ConsensusQueueFactory();
57
+ }
58
58
 
59
- /**
60
- * Constructs a new consensus queue. If the object is non-local an id and service interfaces will
61
- * be provided
62
- */
63
- public constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes) {
64
- super(id, runtime, attributes, new SnapshotableQueue<T>());
65
- }
59
+ /**
60
+ * Constructs a new consensus queue. If the object is non-local an id and service interfaces will
61
+ * be provided
62
+ */
63
+ public constructor(
64
+ id: string,
65
+ runtime: IFluidDataStoreRuntime,
66
+ attributes: IChannelAttributes,
67
+ ) {
68
+ super(id, runtime, attributes, new SnapshotableQueue<T>());
69
+ }
66
70
  }
package/src/index.ts CHANGED
@@ -3,7 +3,15 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- export * from "./consensusOrderedCollection";
7
- export * from "./consensusQueue";
8
- export * from "./interfaces";
9
- export * from "./testUtils";
6
+ export {
7
+ ConsensusCallback,
8
+ ConsensusResult,
9
+ IConsensusOrderedCollection,
10
+ IConsensusOrderedCollectionEvents,
11
+ IConsensusOrderedCollectionFactory,
12
+ IOrderedCollection,
13
+ ISnapshotable,
14
+ } from "./interfaces";
15
+ export { ConsensusOrderedCollection } from "./consensusOrderedCollection";
16
+ export { ConsensusQueue } from "./consensusQueue";
17
+ export { acquireAndComplete, waitAcquireAndComplete } from "./testUtils";
package/src/interfaces.ts CHANGED
@@ -4,21 +4,25 @@
4
4
  */
5
5
 
6
6
  import {
7
- IFluidDataStoreRuntime,
8
- IChannelServices,
9
- IChannelAttributes,
10
- IChannelFactory,
7
+ IFluidDataStoreRuntime,
8
+ IChannelServices,
9
+ IChannelAttributes,
10
+ IChannelFactory,
11
11
  } from "@fluidframework/datastore-definitions";
12
12
  import { ISharedObject, ISharedObjectEvents } from "@fluidframework/shared-object-base";
13
13
 
14
+ /**
15
+ * @alpha
16
+ */
14
17
  export enum ConsensusResult {
15
- Release,
16
- Complete,
18
+ Release,
19
+ Complete,
17
20
  }
18
21
 
19
22
  /**
20
23
  * Callback provided to acquire() and waitAndAcquire() methods.
21
24
  * @returns ConsensusResult indicating whether item was completed, or releases back to the queue.
25
+ * @alpha
22
26
  */
23
27
  export type ConsensusCallback<T> = (value: T) => Promise<ConsensusResult>;
24
28
 
@@ -27,47 +31,49 @@ export type ConsensusCallback<T> = (value: T) => Promise<ConsensusResult>;
27
31
  *
28
32
  * Extends the base IChannelFactory to return a more definite type of IConsensusOrderedCollection
29
33
  * Use for the runtime to create and load distributed data structure by type name of each channel
34
+ * @internal
30
35
  */
31
36
  export interface IConsensusOrderedCollectionFactory extends IChannelFactory {
32
- load(
33
- document: IFluidDataStoreRuntime,
34
- id: string,
35
- services: IChannelServices,
36
- attributes: IChannelAttributes): Promise<IConsensusOrderedCollection>;
37
-
38
- create(document: IFluidDataStoreRuntime, id: string): IConsensusOrderedCollection;
37
+ load(
38
+ document: IFluidDataStoreRuntime,
39
+ id: string,
40
+ services: IChannelServices,
41
+ attributes: IChannelAttributes,
42
+ ): Promise<IConsensusOrderedCollection>;
43
+
44
+ create(document: IFluidDataStoreRuntime, id: string): IConsensusOrderedCollection;
39
45
  }
40
46
 
41
47
  /**
42
48
  * Events notifying about addition, acquisition, release and completion of items
49
+ * @alpha
43
50
  */
44
51
  export interface IConsensusOrderedCollectionEvents<T> extends ISharedObjectEvents {
45
-
46
- /**
47
- * Event fires when new item is added to the queue or
48
- * an item previously acquired is returned back to a queue (including client loosing connection)
49
- * @param newlyAdded - indicates if it's newly added item of previously acquired item
50
- */
51
- (event: "add", listener: (value: T, newlyAdded: boolean) => void): this;
52
- /**
53
- * Event fires when a client acquired an item
54
- * Fires both for locally acquired items, as well as items acquired by remote clients
55
- */
56
- (event: "acquire", listener: (value: T, clientId?: string) => void): this;
57
-
58
- /**
59
- * "Complete event fires when a client completes an item.
60
- */
61
- (event: "complete", listener: (value: T) => void): this;
62
-
63
- /**
64
- * Event fires when locally acquired item is being released back to the queue.
65
- * Please note that release process is asynchronous, so it takes a while for it to happen
66
- * ("add" event will be fired as result of it)
67
- * @param intentional - indicates whether release was intentional (result of returning
68
- * ConsensusResult.Release from callback) or it happened as result of lost connection.
69
- */
70
- (event: "localRelease", listener: (value: T, intentional: boolean) => void): this;
52
+ /**
53
+ * Event fires when new item is added to the queue or
54
+ * an item previously acquired is returned back to a queue (including client loosing connection)
55
+ * @param newlyAdded - indicates if it's newly added item of previously acquired item
56
+ */
57
+ (event: "add", listener: (value: T, newlyAdded: boolean) => void): this;
58
+ /**
59
+ * Event fires when a client acquired an item
60
+ * Fires both for locally acquired items, as well as items acquired by remote clients
61
+ */
62
+ (event: "acquire", listener: (value: T, clientId?: string) => void): this;
63
+
64
+ /**
65
+ * "Complete event fires when a client completes an item.
66
+ */
67
+ (event: "complete", listener: (value: T) => void): this;
68
+
69
+ /**
70
+ * Event fires when locally acquired item is being released back to the queue.
71
+ * Please note that release process is asynchronous, so it takes a while for it to happen
72
+ * ("add" event will be fired as result of it)
73
+ * @param intentional - indicates whether release was intentional (result of returning
74
+ * ConsensusResult.Release from callback) or it happened as result of lost connection.
75
+ */
76
+ (event: "localRelease", listener: (value: T, intentional: boolean) => void): this;
71
77
  }
72
78
 
73
79
  /**
@@ -93,26 +99,27 @@ export interface IConsensusOrderedCollectionEvents<T> extends ISharedObjectEvent
93
99
  * All objects added to the collection will be cloned (via JSON).
94
100
  * They will not be references to the original input object. Thus changed to
95
101
  * the input object will not reflect the object in the collection.
102
+ * @alpha
96
103
  */
97
- export interface IConsensusOrderedCollection<T = any> extends ISharedObject<IConsensusOrderedCollectionEvents<T>> {
98
-
99
- /**
100
- * Adds a value to the collection
101
- */
102
- add(value: T): Promise<void>;
103
-
104
- /**
105
- * Retrieves a value from the collection.
106
- * @returns Returns true (and calls callback with acquired value) if collection was not empty.
107
- * Otherwise returns false.
108
- */
109
- acquire(callback: ConsensusCallback<T>): Promise<boolean>;
110
-
111
- /**
112
- * Wait for a value to be available and remove it from the consensus collection
113
- * Calls callback with retrieved value.
114
- */
115
- waitAndAcquire(callback: ConsensusCallback<T>): Promise<void>;
104
+ export interface IConsensusOrderedCollection<T = any>
105
+ extends ISharedObject<IConsensusOrderedCollectionEvents<T>> {
106
+ /**
107
+ * Adds a value to the collection
108
+ */
109
+ add(value: T): Promise<void>;
110
+
111
+ /**
112
+ * Retrieves a value from the collection.
113
+ * @returns Returns true (and calls callback with acquired value) if collection was not empty.
114
+ * Otherwise returns false.
115
+ */
116
+ acquire(callback: ConsensusCallback<T>): Promise<boolean>;
117
+
118
+ /**
119
+ * Wait for a value to be available and remove it from the consensus collection
120
+ * Calls callback with retrieved value.
121
+ */
122
+ waitAndAcquire(callback: ConsensusCallback<T>): Promise<void>;
116
123
  }
117
124
 
118
125
  /**
@@ -120,11 +127,12 @@ export interface IConsensusOrderedCollection<T = any> extends ISharedObject<ICon
120
127
  *
121
128
  * TODO: move this to be use in other place
122
129
  * TODO: currently input and output is not symmetrical, can they become symmetrical?
130
+ * @alpha
123
131
  */
124
132
  export interface ISnapshotable<T> {
125
- asArray(): T[];
133
+ asArray(): T[];
126
134
 
127
- loadFrom(values: T[]): void;
135
+ loadFrom(values: T[]): void;
128
136
  }
129
137
 
130
138
  /**
@@ -133,20 +141,21 @@ export interface ISnapshotable<T> {
133
141
  * Collection of objects that has deterministic add and remove ordering.
134
142
  * Object implementing this interface can be used as the data backing
135
143
  * for the ConsensusOrderedCollection
144
+ * @alpha
136
145
  */
137
146
  export interface IOrderedCollection<T = any> extends ISnapshotable<T> {
138
- /**
139
- * Adds a value to the collection
140
- */
141
- add(value: T);
142
-
143
- /**
144
- * Retrieves a value from the collection.
145
- */
146
- remove(): T;
147
-
148
- /**
149
- * Return the size of the collection
150
- */
151
- size(): number;
147
+ /**
148
+ * Adds a value to the collection
149
+ */
150
+ add(value: T);
151
+
152
+ /**
153
+ * Retrieves a value from the collection.
154
+ */
155
+ remove(): T;
156
+
157
+ /**
158
+ * Return the size of the collection
159
+ */
160
+ size(): number;
152
161
  }
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/ordered-collection";
9
- export const pkgVersion = "1.4.0-115997";
9
+ export const pkgVersion = "2.0.0-dev-rc.1.0.0.224419";
@@ -3,21 +3,21 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { assert } from "@fluidframework/common-utils";
6
+ import { assert } from "@fluidframework/core-utils";
7
7
 
8
8
  export class SnapshotableArray<T> extends Array {
9
- protected data: T[] = [];
9
+ protected data: T[] = [];
10
10
 
11
- public asArray() {
12
- return this.data;
13
- }
11
+ public asArray() {
12
+ return this.data;
13
+ }
14
14
 
15
- public async loadFrom(from: T[]): Promise<void> {
16
- assert(this.data.length === 0, 0x06b /* "Loading snapshot into a non-empty collection" */);
17
- this.data = from;
18
- }
15
+ public async loadFrom(from: T[]): Promise<void> {
16
+ assert(this.data.length === 0, 0x06b /* "Loading snapshot into a non-empty collection" */);
17
+ this.data = from;
18
+ }
19
19
 
20
- public size(): number {
21
- return this.data.length;
22
- }
20
+ public size(): number {
21
+ return this.data.length;
22
+ }
23
23
  }
package/src/testUtils.ts CHANGED
@@ -3,33 +3,36 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import {
7
- ConsensusResult,
8
- IConsensusOrderedCollection,
9
- } from "./interfaces";
6
+ import { ConsensusResult, IConsensusOrderedCollection } from "./interfaces";
10
7
 
11
8
  /**
12
9
  * Helper method to acquire and complete an item
13
10
  * Should be used in test code only
11
+ * @internal
14
12
  */
15
- export async function acquireAndComplete<T>(collection: IConsensusOrderedCollection<T>): Promise<T | undefined> {
16
- let res: T | undefined;
17
- await collection.acquire(async (value: T) => {
18
- res = value;
19
- return ConsensusResult.Complete;
20
- });
21
- return res;
13
+ export async function acquireAndComplete<T>(
14
+ collection: IConsensusOrderedCollection<T>,
15
+ ): Promise<T | undefined> {
16
+ let res: T | undefined;
17
+ await collection.acquire(async (value: T) => {
18
+ res = value;
19
+ return ConsensusResult.Complete;
20
+ });
21
+ return res;
22
22
  }
23
23
 
24
24
  /**
25
25
  * Helper method to acquire and complete an item
26
26
  * Should be used in test code only
27
+ * @internal
27
28
  */
28
- export async function waitAcquireAndComplete<T>(collection: IConsensusOrderedCollection<T>): Promise<T> {
29
- let res: T | undefined;
30
- await collection.waitAndAcquire(async (value: T) => {
31
- res = value;
32
- return ConsensusResult.Complete;
33
- });
34
- return res as T;
29
+ export async function waitAcquireAndComplete<T>(
30
+ collection: IConsensusOrderedCollection<T>,
31
+ ): Promise<T> {
32
+ let res: T | undefined;
33
+ await collection.waitAndAcquire(async (value: T) => {
34
+ res = value;
35
+ return ConsensusResult.Complete;
36
+ });
37
+ return res as T;
35
38
  }
@@ -0,0 +1,4 @@
1
+ {
2
+ "targets": [{ "extname": ".cjs", "module": "CommonJS", "moduleResolution": "Node10" }],
3
+ "projects": ["./tsconfig.json", "./src/test/tsconfig.json"]
4
+ }
package/tsconfig.json CHANGED
@@ -1,14 +1,12 @@
1
1
  {
2
- "extends": "@fluidframework/build-common/ts-common-config.json",
3
- "exclude": [
4
- "src/test/**/*"
5
- ],
6
- "compilerOptions": {
7
- "rootDir": "./src",
8
- "outDir": "./dist",
9
- "composite": true
10
- },
11
- "include": [
12
- "src/**/*"
13
- ]
14
- }
2
+ "extends": [
3
+ "../../../common/build/build-common/tsconfig.base.json",
4
+ "../../../common/build/build-common/tsconfig.cjs.json",
5
+ ],
6
+ "include": ["src/**/*"],
7
+ "exclude": ["src/test/**/*"],
8
+ "compilerOptions": {
9
+ "rootDir": "./src",
10
+ "outDir": "./dist",
11
+ },
12
+ }
@@ -1 +0,0 @@
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, \"fluid_consensusOrderedCollection_\");\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): 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 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 +0,0 @@
1
- {"version":3,"file":"consensusOrderedCollectionFactory.js","sourceRoot":"","sources":["../src/consensusOrderedCollectionFactory.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOH,qDAAkD;AAElD,qDAA8C;AAE9C;;GAEG;AACH,MAAa,qBAAqB;IAS9B,IAAW,IAAI;QACX,OAAO,qBAAqB,CAAC,IAAI,CAAC;IACtC,CAAC;IAED,IAAW,UAAU;QACjB,OAAO,qBAAqB,CAAC,UAAU,CAAC;IAC5C,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CACb,OAA+B,EAC/B,EAAU,EACV,QAA0B,EAC1B,UAA8B;QAC9B,MAAM,UAAU,GAAG,IAAI,+BAAc,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC/D,MAAM,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC;IACtB,CAAC;IAEM,MAAM,CAAC,QAAgC,EAAE,EAAU;QACtD,MAAM,UAAU,GAAG,IAAI,+BAAc,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACrE,UAAU,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAC;IACtB,CAAC;;AAlCL,sDAmCC;AAlCiB,0BAAI,GAAG,mDAAmD,CAAC;AAElD,gCAAU,GAAuB;IACpD,IAAI,EAAE,qBAAqB,CAAC,IAAI;IAChC,qBAAqB,EAAE,KAAK;IAC5B,cAAc,EAAE,2BAAU;CAC7B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n IChannelAttributes,\n IFluidDataStoreRuntime,\n IChannelServices,\n} from \"@fluidframework/datastore-definitions\";\nimport { ConsensusQueue } from \"./consensusQueue\";\nimport { IConsensusOrderedCollection, IConsensusOrderedCollectionFactory } from \"./interfaces\";\nimport { pkgVersion } from \"./packageVersion\";\n\n/**\n * The factory that defines the consensus queue\n */\nexport class ConsensusQueueFactory implements IConsensusOrderedCollectionFactory {\n public static Type = \"https://graph.microsoft.com/types/consensus-queue\";\n\n public static readonly Attributes: IChannelAttributes = {\n type: ConsensusQueueFactory.Type,\n snapshotFormatVersion: \"0.1\",\n packageVersion: pkgVersion,\n };\n\n public get type() {\n return ConsensusQueueFactory.Type;\n }\n\n public get attributes() {\n return ConsensusQueueFactory.Attributes;\n }\n\n /**\n * {@inheritDoc @fluidframework/datastore-definitions#IChannelFactory.load}\n */\n public async load(\n runtime: IFluidDataStoreRuntime,\n id: string,\n services: IChannelServices,\n attributes: IChannelAttributes): Promise<IConsensusOrderedCollection> {\n const collection = new ConsensusQueue(id, runtime, attributes);\n await collection.load(services);\n return collection;\n }\n\n public create(document: IFluidDataStoreRuntime, id: string): IConsensusOrderedCollection {\n const collection = new ConsensusQueue(id, document, this.attributes);\n collection.initializeLocal();\n return collection;\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"consensusQueue.js","sourceRoot":"","sources":["../src/consensusQueue.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAOH,6EAA0E;AAC1E,2FAA4E;AAE5E,2DAAwD;AAExD;;GAEG;AACH,MAAM,iBAAqB,SAAQ,qCAAoB;IAC5C,GAAG,CAAC,KAAQ;QACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEM,MAAM;QACT,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;YACnB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;SACjD;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAO,CAAC;IAClC,CAAC;CACJ;AAED;;;;GAIG;AACH,MAAa,cAAwB,SAAQ,uDAA6B;IACtE;;;;;;OAMG;IACH,wDAAwD;IACjD,MAAM,CAAC,MAAM,CAAU,OAA+B,EAAE,EAAW;QACtE,OAAO,OAAO,CAAC,aAAa,CAAC,EAAE,EAAE,yDAAqB,CAAC,IAAI,CAAsB,CAAC;IACtF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,UAAU;QACpB,OAAO,IAAI,yDAAqB,EAAE,CAAC;IACvC,CAAC;IAED;;;OAGG;IACH,YAAmB,EAAU,EAAE,OAA+B,EAAE,UAA8B;QAC1F,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,iBAAiB,EAAK,CAAC,CAAC;IAC/D,CAAC;CACJ;AA7BD,wCA6BC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n IFluidDataStoreRuntime,\n IChannelAttributes,\n IChannelFactory,\n} from \"@fluidframework/datastore-definitions\";\nimport { ConsensusOrderedCollection } from \"./consensusOrderedCollection\";\nimport { ConsensusQueueFactory } from \"./consensusOrderedCollectionFactory\";\nimport { IOrderedCollection } from \"./interfaces\";\nimport { SnapshotableArray } from \"./snapshotableArray\";\n\n/**\n * An JS array based queue implementation that is the backing data structure for ConsensusQueue\n */\nclass SnapshotableQueue<T> extends SnapshotableArray<T> implements IOrderedCollection<T> {\n public add(value: T) {\n this.data.push(value);\n }\n\n public remove(): T {\n if (this.size() === 0) {\n throw new Error(\"SnapshotableQueue is empty\");\n }\n return this.data.shift() as T;\n }\n}\n\n/**\n * Implementation of a consensus stack\n *\n * An derived type of ConsensusOrderedCollection with a queue as the backing data and order.\n */\nexport class ConsensusQueue<T = any> extends ConsensusOrderedCollection<T> {\n /**\n * Create a new consensus queue\n *\n * @param runtime - data store runtime the new consensus queue belongs to\n * @param id - optional name of theconsensus queue\n * @returns newly create consensus queue (but not attached yet)\n */\n // eslint-disable-next-line @typescript-eslint/no-shadow\n public static create<T = any>(runtime: IFluidDataStoreRuntime, id?: string) {\n return runtime.createChannel(id, ConsensusQueueFactory.Type) as ConsensusQueue<T>;\n }\n\n /**\n * Get a factory for ConsensusQueue to register with the data store.\n *\n * @returns a factory that creates and load ConsensusQueue\n */\n public static getFactory(): IChannelFactory {\n return new ConsensusQueueFactory();\n }\n\n /**\n * Constructs a new consensus queue. If the object is non-local an id and service interfaces will\n * be provided\n */\n public constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes) {\n super(id, runtime, attributes, new SnapshotableQueue<T>());\n }\n}\n"]}
package/dist/index.js DELETED
@@ -1,21 +0,0 @@
1
- "use strict";
2
- /*!
3
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
- * Licensed under the MIT License.
5
- */
6
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
- if (k2 === undefined) k2 = k;
8
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./consensusOrderedCollection"), exports);
18
- __exportStar(require("./consensusQueue"), exports);
19
- __exportStar(require("./interfaces"), exports);
20
- __exportStar(require("./testUtils"), exports);
21
- //# sourceMappingURL=index.js.map