@fluid-experimental/tree 0.54.3 → 0.55.2
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 +1 -1
- package/api/tree.api.md +3 -3
- package/dist/RevisionValueCache.d.ts.map +1 -1
- package/dist/RevisionValueCache.js +2 -0
- package/dist/RevisionValueCache.js.map +1 -1
- package/dist/SummaryBackCompatibility.d.ts +1 -1
- package/dist/SummaryBackCompatibility.d.ts.map +1 -1
- package/dist/SummaryBackCompatibility.js.map +1 -1
- package/dist/default-edits/UndoRedoHandler.d.ts +1 -1
- package/dist/default-edits/UndoRedoHandler.d.ts.map +1 -1
- package/dist/default-edits/UndoRedoHandler.js +4 -0
- package/dist/default-edits/UndoRedoHandler.js.map +1 -1
- package/dist/generic/GenericSharedTree.d.ts +5 -5
- package/dist/generic/GenericSharedTree.d.ts.map +1 -1
- package/dist/generic/GenericSharedTree.js +5 -19
- package/dist/generic/GenericSharedTree.js.map +1 -1
- package/dist/generic/Summary.d.ts +2 -1
- package/dist/generic/Summary.d.ts.map +1 -1
- package/dist/generic/Summary.js.map +1 -1
- package/lib/RevisionValueCache.d.ts.map +1 -1
- package/lib/RevisionValueCache.js +2 -0
- package/lib/RevisionValueCache.js.map +1 -1
- package/lib/SummaryBackCompatibility.d.ts +1 -1
- package/lib/SummaryBackCompatibility.d.ts.map +1 -1
- package/lib/SummaryBackCompatibility.js.map +1 -1
- package/lib/default-edits/UndoRedoHandler.d.ts +1 -1
- package/lib/default-edits/UndoRedoHandler.d.ts.map +1 -1
- package/lib/default-edits/UndoRedoHandler.js +4 -0
- package/lib/default-edits/UndoRedoHandler.js.map +1 -1
- package/lib/generic/GenericSharedTree.d.ts +5 -5
- package/lib/generic/GenericSharedTree.d.ts.map +1 -1
- package/lib/generic/GenericSharedTree.js +6 -20
- package/lib/generic/GenericSharedTree.js.map +1 -1
- package/lib/generic/Summary.d.ts +2 -1
- package/lib/generic/Summary.d.ts.map +1 -1
- package/lib/generic/Summary.js.map +1 -1
- package/lib/test/SnapshotUtilities.tests.js +2 -1
- package/lib/test/SnapshotUtilities.tests.js.map +1 -1
- package/lib/test/utilities/TestSerializer.d.ts +4 -2
- package/lib/test/utilities/TestSerializer.d.ts.map +1 -1
- package/lib/test/utilities/TestSerializer.js +4 -1
- package/lib/test/utilities/TestSerializer.js.map +1 -1
- package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
- package/lib/test/utilities/TestUtilities.js +2 -1
- package/lib/test/utilities/TestUtilities.js.map +1 -1
- package/package.json +21 -19
- package/src/RevisionValueCache.ts +2 -0
- package/src/SummaryBackCompatibility.ts +1 -1
- package/src/default-edits/UndoRedoHandler.ts +5 -1
- package/src/generic/GenericSharedTree.ts +15 -22
- package/src/generic/Summary.ts +2 -2
package/.eslintrc.js
CHANGED
|
@@ -30,7 +30,7 @@ module.exports = {
|
|
|
30
30
|
// Rules which could be re-enabled (by dropping these overrides, as they are enabled in base config) with some minor fixes:
|
|
31
31
|
'@typescript-eslint/no-shadow': 'off',
|
|
32
32
|
'no-shadow': 'off',
|
|
33
|
-
'
|
|
33
|
+
'@typescript-eslint/no-unsafe-return': 'off',
|
|
34
34
|
},
|
|
35
35
|
overrides: [
|
|
36
36
|
{
|
package/api/tree.api.md
CHANGED
|
@@ -12,13 +12,13 @@ import { IChannelStorageService } from '@fluidframework/datastore-definitions';
|
|
|
12
12
|
import { IDisposable } from '@fluidframework/common-definitions';
|
|
13
13
|
import { IErrorEvent } from '@fluidframework/common-definitions';
|
|
14
14
|
import { IFluidDataStoreRuntime } from '@fluidframework/datastore-definitions';
|
|
15
|
-
import { IFluidSerializer } from '@fluidframework/
|
|
15
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
16
16
|
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
17
17
|
import { ISharedObject } from '@fluidframework/shared-object-base';
|
|
18
18
|
import { ISharedObjectEvents } from '@fluidframework/shared-object-base';
|
|
19
|
+
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
19
20
|
import { ITelemetryBaseEvent } from '@fluidframework/common-definitions';
|
|
20
21
|
import { ITelemetryLogger } from '@fluidframework/common-definitions';
|
|
21
|
-
import { ITree } from '@fluidframework/protocol-definitions';
|
|
22
22
|
import { Serializable } from '@fluidframework/datastore-definitions';
|
|
23
23
|
import { SharedObject } from '@fluidframework/shared-object-base';
|
|
24
24
|
|
|
@@ -279,7 +279,7 @@ export abstract class GenericSharedTree<TChange> extends SharedObject<ISharedTre
|
|
|
279
279
|
// @internal
|
|
280
280
|
saveSummary(): SharedTreeSummaryBase;
|
|
281
281
|
// (undocumented)
|
|
282
|
-
|
|
282
|
+
summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats;
|
|
283
283
|
// (undocumented)
|
|
284
284
|
protected readonly summarizeHistory: boolean;
|
|
285
285
|
// (undocumented)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevisionValueCache.d.ts","sourceRoot":"","sources":["../src/RevisionValueCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;GAQG;AACH,qBAAa,kBAAkB,CAAC,MAAM;IAyBpC;;;OAGG;
|
|
1
|
+
{"version":3,"file":"RevisionValueCache.d.ts","sourceRoot":"","sources":["../src/RevisionValueCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;GAQG;AACH,qBAAa,kBAAkB,CAAC,MAAM;IAyBpC;;;OAGG;IAGH,OAAO,CAAC,oBAAoB;IA9B7B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgE;IAE9F;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAwB;IAE3D;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuB;;IAGxD;;OAEG;IACH,aAAa,EAAE,MAAM;IACrB;;;OAGG;IAGK,oBAAoB,EAAE,QAAQ;IACtC;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;IAqBvC;;OAEG;IACI,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO;IAI3D;;;OAGG;IACI,qBAAqB,CAAC,uBAAuB,EAAE,QAAQ,GAAG,IAAI;IAwBrE;;OAEG;IACI,eAAe,CAAC,iBAAiB,EAAE,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS;IAQpG;;OAEG;IACI,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlE;;;;;;OAMG;IACI,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAS1D"}
|
|
@@ -31,6 +31,8 @@ class RevisionValueCache {
|
|
|
31
31
|
* The first revision within the retention window. All entries with revisions >= retentionWindowStart will be retained.
|
|
32
32
|
* Must be >= 0.
|
|
33
33
|
*/
|
|
34
|
+
// False positive
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
34
36
|
retentionWindowStart,
|
|
35
37
|
/**
|
|
36
38
|
* Optional list of entries to permanently retain.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevisionValueCache.js","sourceRoot":"","sources":["../src/RevisionValueCache.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;AAEH,gEAAiC;AACjC,0DAA4B;AAC5B,qCAAwC;AAExC,2DAA2D;AAE3D;;;;;;;;GAQG;AACH,MAAa,kBAAkB;IAoB9B;IACC;;OAEG;IACH,aAAqB;IACrB;;;OAGG;
|
|
1
|
+
{"version":3,"file":"RevisionValueCache.js","sourceRoot":"","sources":["../src/RevisionValueCache.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 BTree from 'sorted-btree';\nimport LRU from 'lru-cache';\nimport { assert, fail } from './Common';\nimport { Revision } from './LogViewer';\nimport { compareFiniteNumbers } from './SnapshotUtilities';\n\n/**\n * A cache of `TValue`s corresponding to `Revision`s.\n *\n * A value is kept in cache if it meets any of the following criteria:\n * - The revision is >= `retentionWindowStart`\n * - The value has been used recently, meaning getClosestEntry or cacheValue was called with its revision. Note that being returned\n * \t\twhen a large revision was passed to getClosestEntry does not count.\n * - The value is `retained` meaning it was provided to to constructor in retainedEntries or passed to `cacheRetainedValue`\n */\nexport class RevisionValueCache<TValue> {\n\t/**\n\t * A cache of entries for revisions.\n\t * This is sorted to allow efficient access to the nearest preceding entry (see getClosestEntry).\n\t * Contains all cached values, regardless of why they are cached (retained, LRU or window).\n\t */\n\tprivate readonly sortedEntries = new BTree<Revision, TValue>(undefined, compareFiniteNumbers);\n\n\t/**\n\t * Least recently used cache of evictable entries.\n\t * Subset of 'sortedValues` eligible for eviction:\n\t * All entries are also in `sortedValues`, and are removed from `sortedValues` when evicted from this cache.\n\t */\n\tprivate readonly evictableRevisions: LRU<Revision, TValue>;\n\n\t/**\n\t * Set of all revisions that should never be evicted.\n\t */\n\tprivate readonly retainedRevisions = new Set<Revision>();\n\n\tpublic constructor(\n\t\t/**\n\t\t * Maximum capacity for evictable cache entries (those neither marked as retained nor within the retention window).\n\t\t */\n\t\tevictableSize: number,\n\t\t/**\n\t\t * The first revision within the retention window. All entries with revisions >= retentionWindowStart will be retained.\n\t\t * Must be >= 0.\n\t\t */\n\t\t// False positive\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-readonly\n\t\tprivate retentionWindowStart: Revision,\n\t\t/**\n\t\t * Optional list of entries to permanently retain.\n\t\t */\n\t\tretainedEntries?: [Revision, TValue][]\n\t) {\n\t\tassert(retentionWindowStart >= 0, 'retentionWindowStart must be initialized >= 0');\n\t\tthis.evictableRevisions = new LRU({\n\t\t\tmax: evictableSize,\n\t\t\tnoDisposeOnSet: true,\n\t\t\tdispose: (revision) => {\n\t\t\t\tif (revision >= this.retentionWindowStart) {\n\t\t\t\t\tfail('Entries in retention window should never be evicted.');\n\t\t\t\t}\n\t\t\t\tif (this.retainedRevisions.has(revision)) {\n\t\t\t\t\tfail('Retained entries should not be evicted');\n\t\t\t\t}\n\t\t\t\tthis.sortedEntries.delete(revision);\n\t\t\t},\n\t\t});\n\t\tif (retainedEntries !== undefined) {\n\t\t\tretainedEntries.forEach(([revision, entry]) => this.cacheRetainedValue(revision, entry));\n\t\t}\n\t}\n\n\t/**\n\t * @returns if the supplied revision is within the retention window.\n\t */\n\tpublic isWithinRetentionWindow(revision: Revision): boolean {\n\t\treturn revision >= this.retentionWindowStart;\n\t}\n\n\t/**\n\t * Sets the new retention window.\n\t * @param newRetentionWindowStart - defines the trailing edge (inclusive) of the new retention window.\n\t */\n\tpublic updateRetentionWindow(newRetentionWindowStart: Revision): void {\n\t\tif (newRetentionWindowStart < this.retentionWindowStart) {\n\t\t\tfail('retention window boundary must not move backwards');\n\t\t}\n\t\tconst prevRetentionWindowStart = this.retentionWindowStart;\n\t\tthis.retentionWindowStart = newRetentionWindowStart;\n\t\tconst oldWindowEntries: [Revision, TValue][] = [];\n\t\tthis.sortedEntries.forRange(\n\t\t\tprevRetentionWindowStart,\n\t\t\tthis.retentionWindowStart,\n\t\t\tfalse,\n\t\t\t(windowRevision, windowEntry) => {\n\t\t\t\tif (!this.retainedRevisions.has(windowRevision)) {\n\t\t\t\t\t// Adding to the LRU can cause eviction which in turn mutates the b-tree we are enumerating. Thus, store list of\n\t\t\t\t\t// old window entries separately.\n\t\t\t\t\toldWindowEntries.push([windowRevision, windowEntry]);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t\toldWindowEntries.forEach(([revision, value]) => {\n\t\t\tthis.evictableRevisions.set(revision, value);\n\t\t});\n\t}\n\n\t/**\n\t * @returns a [cachedRevision, value] where cachedRevision <= requestedRevision, or undefined if no such revision is cached.\n\t */\n\tpublic getClosestEntry(requestedRevision: Revision): [revision: Revision, value: TValue] | undefined {\n\t\tconst fromLRU = this.evictableRevisions.get(requestedRevision);\n\t\tif (fromLRU !== undefined) {\n\t\t\treturn [requestedRevision, fromLRU];\n\t\t}\n\t\treturn this.sortedEntries.nextLowerPair(requestedRevision + 1) ?? undefined;\n\t}\n\n\t/**\n\t * Caches the supplied value and guarantees it will never be evicted.\n\t */\n\tpublic cacheRetainedValue(revision: Revision, value: TValue): void {\n\t\tthis.retainedRevisions.add(revision);\n\t\tthis.sortedEntries.set(revision, value);\n\t}\n\n\t/**\n\t * Caches the supplied value.\n\t * The cached value is subject to eviction unless it is within the retention window or was previously added\n\t * via `cacheRetainedValue`.\n\t * Note that if a non-retained entry starts out within the retention window and passes outside of it due to a call to\n\t * updateRetentionWindow it is then subject to eviction.\n\t */\n\tpublic cacheValue(revision: Revision, value: TValue): void {\n\t\tif (this.retainedRevisions.has(revision)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.sortedEntries.set(revision, value);\n\t\tif (revision < this.retentionWindowStart) {\n\t\t\tthis.evictableRevisions.set(revision, value);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
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/
|
|
5
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
6
6
|
import { ErrorString } from './Common';
|
|
7
7
|
import { ChangeNode, Edit, SharedTreeSummaryBase, SharedTreeSummary } from './generic';
|
|
8
8
|
/** The summary format version that is read by SharedTree. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SummaryBackCompatibility.d.ts","sourceRoot":"","sources":["../src/SummaryBackCompatibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"SummaryBackCompatibility.d.ts","sourceRoot":"","sources":["../src/SummaryBackCompatibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEvF,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,UAAU,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,uBAAuB,CAAC,OAAO,CAAE,SAAQ,qBAAqB;IAC9E,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,gBAAgB,GAAG,qBAAqB,GAAG,WAAW,CAmBlH;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EACjD,OAAO,EAAE,qBAAqB,GAC5B,iBAAiB,CAAC,OAAO,CAAC,GAAG,WAAW,CA4C1C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SummaryBackCompatibility.js","sourceRoot":"","sources":["../src/SummaryBackCompatibility.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,uCAAoC;AAGpC,6DAA6D;AAChD,QAAA,iBAAiB,GAAG,OAAO,CAAC;AAgBzC;;;;;;;;GAQG;AACH,SAAgB,WAAW,CAAC,WAAmB,EAAE,UAA4B;IAC5E,IAAI,OAAuC,CAAC;IAC5C,IAAI;QACH,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;KACxC;IAAC,WAAM;QACP,OAAO,8BAA8B,CAAC;KACtC;IAED,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAChC,OAAO,0BAA0B,CAAC;KAClC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,IAAI,OAAO,KAAK,SAAS,EAAE;QAC1B,uBAAS,OAAO,IAAK,OAAO,EAAG;KAC/B;IAED,OAAO,2BAA2B,CAAC;AACpC,CAAC;AAnBD,kCAmBC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACzC,OAA8B;IAE9B,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,IAAI,OAAO,KAAK,yBAAiB,EAAE;QAClC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAqC,CAAC;QAE3E,IAAI,WAAW,KAAK,SAAS,EAAE;YAC9B,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACpC,OAAO,+BAA+B,CAAC;aACvC;YAED,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC;YAE5C,oHAAoH;YACpH,IAAI,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE;gBACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;aAC7C;SACD;KACD;SAAM,IAAI,OAAO,KAAK,OAAO,EAAE;QAC/B,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAA2C,CAAC;QAEpF,IAAI,cAAc,KAAK,SAAS,EAAE;YACjC;;eAEG;YACH,MAAM,YAAY,GAAG,IAAI,CAAC;YAE1B,yEAAyE;YACzE,MAAM,YAAY,GAAG,IAAI,iBAAO,CAAU,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;YAC9E,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/B,YAAY,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,uBAAuB,EAAE,CAAC,EAAE,CAAC,CACtF,CAAC;YAEF,OAAO;gBACN,WAAW;gBACX,WAAW,EAAE,YAAY,CAAC,iBAAiB,EAAE;gBAC7C,OAAO,EAAE,yBAAiB;aAC1B,CAAC;SACF;KACD;SAAM;QACN,OAAO,iCAAiC,CAAC;KACzC;IAED,OAAO,2BAA2B,CAAC;AACpC,CAAC;AA9CD,gEA8CC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidSerializer } from '@fluidframework/
|
|
1
|
+
{"version":3,"file":"SummaryBackCompatibility.js","sourceRoot":"","sources":["../src/SummaryBackCompatibility.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,uCAAoC;AAGpC,6DAA6D;AAChD,QAAA,iBAAiB,GAAG,OAAO,CAAC;AAgBzC;;;;;;;;GAQG;AACH,SAAgB,WAAW,CAAC,WAAmB,EAAE,UAA4B;IAC5E,IAAI,OAAuC,CAAC;IAC5C,IAAI;QACH,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;KACxC;IAAC,WAAM;QACP,OAAO,8BAA8B,CAAC;KACtC;IAED,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAChC,OAAO,0BAA0B,CAAC;KAClC;IAED,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,IAAI,OAAO,KAAK,SAAS,EAAE;QAC1B,uBAAS,OAAO,IAAK,OAAO,EAAG;KAC/B;IAED,OAAO,2BAA2B,CAAC;AACpC,CAAC;AAnBD,kCAmBC;AAED;;;GAGG;AACH,SAAgB,0BAA0B,CACzC,OAA8B;IAE9B,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,IAAI,OAAO,KAAK,yBAAiB,EAAE;QAClC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAqC,CAAC;QAE3E,IAAI,WAAW,KAAK,SAAS,EAAE;YAC9B,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;gBACpC,OAAO,+BAA+B,CAAC;aACvC;YAED,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC;YAE5C,oHAAoH;YACpH,IAAI,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE;gBACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;aAC7C;SACD;KACD;SAAM,IAAI,OAAO,KAAK,OAAO,EAAE;QAC/B,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,GAAG,OAA2C,CAAC;QAEpF,IAAI,cAAc,KAAK,SAAS,EAAE;YACjC;;eAEG;YACH,MAAM,YAAY,GAAG,IAAI,CAAC;YAE1B,yEAAyE;YACzE,MAAM,YAAY,GAAG,IAAI,iBAAO,CAAU,SAAS,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;YAC9E,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/B,YAAY,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,uBAAuB,EAAE,CAAC,EAAE,CAAC,CACtF,CAAC;YAEF,OAAO;gBACN,WAAW;gBACX,WAAW,EAAE,YAAY,CAAC,iBAAiB,EAAE;gBAC7C,OAAO,EAAE,yBAAiB;aAC1B,CAAC;SACF;KACD;SAAM;QACN,OAAO,iCAAiC,CAAC;KACzC;IAED,OAAO,2BAA2B,CAAC;AACpC,CAAC;AA9CD,gEA8CC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidSerializer } from '@fluidframework/shared-object-base';\nimport { ErrorString } from './Common';\nimport { EditLog } from './EditLog';\nimport { ChangeNode, Edit, SharedTreeSummaryBase, SharedTreeSummary } from './generic';\n\n/** The summary format version that is read by SharedTree. */\nexport const readFormatVersion = '0.1.0';\n\n/**\n * Legacy summary format currently still used for writing.\n * TODO:#49901: Remove export when this format is no longer written.\n * @internal\n */\nexport interface SharedTreeSummary_0_0_2<TChange> extends SharedTreeSummaryBase {\n\treadonly currentTree: ChangeNode;\n\n\t/**\n\t * A list of edits.\n\t */\n\treadonly sequencedEdits: readonly Edit<TChange>[];\n}\n\n/**\n * Deserializes a JSON object produced by `serialize()` and uses it to initialize the tree with the encoded state.\n * Also constructs handle objects from their serialized form.\n *\n * @param jsonSummary - The string to deserialize.\n * @param serializer - The serializer required to deserialize handles in the string.\n * @returns A SharedTree summary or an ErrorString if the summary could not be interpreted.\n *\n */\nexport function deserialize(jsonSummary: string, serializer: IFluidSerializer): SharedTreeSummaryBase | ErrorString {\n\tlet summary: Partial<SharedTreeSummaryBase>;\n\ttry {\n\t\tsummary = serializer.parse(jsonSummary);\n\t} catch {\n\t\treturn 'Json syntax error in Summary';\n\t}\n\n\tif (typeof summary !== 'object') {\n\t\treturn 'Summary is not an object';\n\t}\n\n\tconst { version } = summary;\n\n\tif (version !== undefined) {\n\t\treturn { version, ...summary };\n\t}\n\n\treturn 'Missing fields on summary';\n}\n\n/**\n * @returns SharedTreeSummary that can be used to initialize a SharedTree, or an ErrorString if the summary could not be converted.\n *\n */\nexport function convertSummaryToReadFormat<TChange>(\n\tsummary: SharedTreeSummaryBase\n): SharedTreeSummary<TChange> | ErrorString {\n\tconst { version } = summary;\n\n\tif (version === readFormatVersion) {\n\t\tconst { currentTree, editHistory } = summary as SharedTreeSummary<TChange>;\n\n\t\tif (editHistory !== undefined) {\n\t\t\tif (typeof editHistory !== 'object') {\n\t\t\t\treturn 'Edit history is not an object';\n\t\t\t}\n\n\t\t\tconst { editChunks, editIds } = editHistory;\n\n\t\t\t// TODO:#45414: Add more robust validation of the summary's fields. Even if they are present, they may be malformed.\n\t\t\tif (editChunks !== undefined && editIds !== undefined) {\n\t\t\t\treturn { currentTree, editHistory, version };\n\t\t\t}\n\t\t}\n\t} else if (version === '0.0.2') {\n\t\tconst { currentTree, sequencedEdits } = summary as SharedTreeSummary_0_0_2<TChange>;\n\n\t\tif (sequencedEdits !== undefined) {\n\t\t\t/**\n\t\t\t * The number of edits that can safely fit in a blob upload.\n\t\t\t */\n\t\t\tconst maxChunkSize = 1000;\n\n\t\t\t// This saves all of the edits in the summary as part of the first chunk.\n\t\t\tconst temporaryLog = new EditLog<TChange>(undefined, undefined, maxChunkSize);\n\t\t\tsequencedEdits.forEach((edit) =>\n\t\t\t\ttemporaryLog.addSequencedEdit(edit, { sequenceNumber: 1, referenceSequenceNumber: 0 })\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tcurrentTree,\n\t\t\t\teditHistory: temporaryLog.getEditLogSummary(),\n\t\t\t\tversion: readFormatVersion,\n\t\t\t};\n\t\t}\n\t} else {\n\t\treturn 'Format version is not supported';\n\t}\n\n\treturn 'Missing fields on summary';\n}\n"]}
|
|
@@ -16,7 +16,7 @@ export interface IUndoConsumer {
|
|
|
16
16
|
* undo redo stack manager
|
|
17
17
|
*/
|
|
18
18
|
export declare class SharedTreeUndoRedoHandler {
|
|
19
|
-
private
|
|
19
|
+
private stackManager;
|
|
20
20
|
constructor(stackManager: IUndoConsumer);
|
|
21
21
|
attachTree(tree: SharedTree): void;
|
|
22
22
|
detachTree(tree: SharedTree): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UndoRedoHandler.d.ts","sourceRoot":"","sources":["../../src/default-edits/UndoRedoHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C,MAAM,WAAW,WAAW;IAC3B,MAAM,QAAG;IACT,OAAO,QAAG;CACV;AAED,MAAM,WAAW,aAAa;IAC7B,sBAAsB,CAAC,UAAU,EAAE,WAAW,OAAE;CAChD;AAED;;;GAGG;AACH,qBAAa,yBAAyB;
|
|
1
|
+
{"version":3,"file":"UndoRedoHandler.d.ts","sourceRoot":"","sources":["../../src/default-edits/UndoRedoHandler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAK1C,MAAM,WAAW,WAAW;IAC3B,MAAM,QAAG;IACT,OAAO,QAAG;CACV;AAED,MAAM,WAAW,aAAa;IAC7B,sBAAsB,CAAC,UAAU,EAAE,WAAW,OAAE;CAChD;AAED;;;GAGG;AACH,qBAAa,yBAAyB;IAGzB,OAAO,CAAC,YAAY;gBAAZ,YAAY,EAAE,aAAa;IAExC,UAAU,CAAC,IAAI,EAAE,UAAU;IAG3B,UAAU,CAAC,IAAI,EAAE,UAAU;IAIlC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAc/B;CACF;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,WAAW;IAG3C,OAAO,CAAC,MAAM;IAAU,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAArC,MAAM,EAAE,MAAM,EAAmB,IAAI,EAAE,UAAU;IAE9D,MAAM;IASN,OAAO;CAGd"}
|
|
@@ -12,6 +12,8 @@ const generic_1 = require("../generic");
|
|
|
12
12
|
* undo redo stack manager
|
|
13
13
|
*/
|
|
14
14
|
class SharedTreeUndoRedoHandler {
|
|
15
|
+
// False positive
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
15
17
|
constructor(stackManager) {
|
|
16
18
|
this.stackManager = stackManager;
|
|
17
19
|
this.treeDeltaHandler = (eventArguments) => {
|
|
@@ -33,6 +35,8 @@ exports.SharedTreeUndoRedoHandler = SharedTreeUndoRedoHandler;
|
|
|
33
35
|
* Tracks a change on a shared tree and allows reverting it
|
|
34
36
|
*/
|
|
35
37
|
class SharedTreeRevertible {
|
|
38
|
+
// False positive
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
36
40
|
constructor(editId, tree) {
|
|
37
41
|
this.editId = editId;
|
|
38
42
|
this.tree = tree;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UndoRedoHandler.js","sourceRoot":"","sources":["../../src/default-edits/UndoRedoHandler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,sCAA+C;AAE/C,wCAA0E;AAe1E;;;GAGG;AACH,MAAa,yBAAyB;IACrC,
|
|
1
|
+
{"version":3,"file":"UndoRedoHandler.js","sourceRoot":"","sources":["../../src/default-edits/UndoRedoHandler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,sCAA+C;AAE/C,wCAA0E;AAe1E;;;GAGG;AACH,MAAa,yBAAyB;IACrC,iBAAiB;IACjB,8DAA8D;IAC9D,YAAoB,YAA2B;QAA3B,iBAAY,GAAZ,YAAY,CAAe;QAS9B,qBAAgB,GAAG,CAAC,cAAuD,EAAE,EAAE;YAC/F,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,cAAc,CAAC;YAE/C,IAAI,KAAK,EAAE;gBACV,IAAI,CAAC,YAAY,CAAC,sBAAsB,CACvC,IAAI,oBAAoB,CACvB,MAAM,EACN,2BAAkB,CACjB,IAAI,EACJ,sGAAsG,CACtG,CACD,CACD,CAAC;aACF;QACF,CAAC,CAAC;IAvBgD,CAAC;IAE5C,UAAU,CAAC,IAAgB;QACjC,IAAI,CAAC,EAAE,CAAC,yBAAe,CAAC,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/D,CAAC;IACM,UAAU,CAAC,IAAgB;QACjC,IAAI,CAAC,GAAG,CAAC,yBAAe,CAAC,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAChE,CAAC;CAiBD;AA3BD,8DA2BC;AAED;;GAEG;AACH,MAAa,oBAAoB;IAChC,iBAAiB;IACjB,8DAA8D;IAC9D,YAAoB,MAAc,EAAmB,IAAgB;QAAjD,WAAM,GAAN,MAAM,CAAQ;QAAmB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAElE,MAAM;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;QAChE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAE3E,+DAA+D;QAC/D,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAC7D,CAAC;IAEM,OAAO;QACb,OAAO;IACR,CAAC;CACD;AAjBD,oDAiBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assertNotUndefined } from '../Common';\nimport { EditId } from '../Identifiers';\nimport { EditCommittedEventArguments, SharedTreeEvent } from '../generic';\nimport { SharedTree } from './SharedTree';\n\n// TODO: We temporarily duplicate these contracts from 'framework/undo-redo' to unblock development\n// while we decide on the correct layering for undo.\n\nexport interface IRevertible {\n\trevert();\n\tdiscard();\n}\n\nexport interface IUndoConsumer {\n\tpushToCurrentOperation(revertible: IRevertible);\n}\n\n/**\n * A shared tree undo redo handler that will add revertible local tree changes to the provided\n * undo redo stack manager\n */\nexport class SharedTreeUndoRedoHandler {\n\t// False positive\n\t// eslint-disable-next-line @typescript-eslint/prefer-readonly\n\tconstructor(private stackManager: IUndoConsumer) {}\n\n\tpublic attachTree(tree: SharedTree) {\n\t\ttree.on(SharedTreeEvent.EditCommitted, this.treeDeltaHandler);\n\t}\n\tpublic detachTree(tree: SharedTree) {\n\t\ttree.off(SharedTreeEvent.EditCommitted, this.treeDeltaHandler);\n\t}\n\n\tprivate readonly treeDeltaHandler = (eventArguments: EditCommittedEventArguments<SharedTree>) => {\n\t\tconst { editId, local, tree } = eventArguments;\n\n\t\tif (local) {\n\t\t\tthis.stackManager.pushToCurrentOperation(\n\t\t\t\tnew SharedTreeRevertible(\n\t\t\t\t\teditId,\n\t\t\t\t\tassertNotUndefined(\n\t\t\t\t\t\ttree,\n\t\t\t\t\t\t'An edit committed event for a revertible edit should include the target SharedTree in its arguments.'\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t};\n}\n\n/**\n * Tracks a change on a shared tree and allows reverting it\n */\nexport class SharedTreeRevertible implements IRevertible {\n\t// False positive\n\t// eslint-disable-next-line @typescript-eslint/prefer-readonly\n\tconstructor(private editId: EditId, private readonly tree: SharedTree) {}\n\n\tpublic revert() {\n\t\tconst editIndex = this.tree.edits.getIndexOfId(this.editId);\n\t\tconst edit = this.tree.edits.getEditInSessionAtIndex(editIndex);\n\t\tconst snapshotBefore = this.tree.logViewer.getSnapshotInSession(editIndex);\n\n\t\t// Apply the revert edit and set it as the new revertible edit.\n\t\tthis.editId = this.tree.editor.revert(edit, snapshotBefore);\n\t}\n\n\tpublic discard() {\n\t\treturn;\n\t}\n}\n"]}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { ISequencedDocumentMessage, ITree } from '@fluidframework/protocol-definitions';
|
|
5
|
+
import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';
|
|
7
6
|
import { IFluidDataStoreRuntime, IChannelStorageService, IChannelAttributes } from '@fluidframework/datastore-definitions';
|
|
8
|
-
import { ISharedObjectEvents, SharedObject } from '@fluidframework/shared-object-base';
|
|
7
|
+
import { IFluidSerializer, ISharedObjectEvents, SharedObject } from '@fluidframework/shared-object-base';
|
|
9
8
|
import { ITelemetryLogger } from '@fluidframework/common-definitions';
|
|
9
|
+
import { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';
|
|
10
10
|
import { OrderedEditSet } from '../EditLog';
|
|
11
11
|
import { EditId } from '../Identifiers';
|
|
12
12
|
import { Snapshot } from '../Snapshot';
|
|
@@ -148,9 +148,9 @@ export declare abstract class GenericSharedTree<TChange> extends SharedObject<IS
|
|
|
148
148
|
*/
|
|
149
149
|
private uploadEditChunk;
|
|
150
150
|
/**
|
|
151
|
-
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.
|
|
151
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}
|
|
152
152
|
*/
|
|
153
|
-
|
|
153
|
+
summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats;
|
|
154
154
|
/**
|
|
155
155
|
* Saves this SharedTree into a serialized summary.
|
|
156
156
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenericSharedTree.d.ts","sourceRoot":"","sources":["../../src/generic/GenericSharedTree.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"GenericSharedTree.d.ts","sourceRoot":"","sources":["../../src/generic/GenericSharedTree.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.GenericSharedTree = exports.SharedTreeDiagnosticEvent = exports.SharedTreeEvent = void 0;
|
|
8
8
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
9
|
-
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
|
|
10
9
|
const container_definitions_1 = require("@fluidframework/container-definitions");
|
|
11
10
|
const shared_object_base_1 = require("@fluidframework/shared-object-base");
|
|
12
11
|
const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
|
|
@@ -216,23 +215,10 @@ class GenericSharedTree extends shared_object_base_1.SharedObject {
|
|
|
216
215
|
}
|
|
217
216
|
}
|
|
218
217
|
/**
|
|
219
|
-
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.
|
|
218
|
+
* {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}
|
|
220
219
|
*/
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
entries: [
|
|
224
|
-
{
|
|
225
|
-
mode: protocol_definitions_1.FileMode.File,
|
|
226
|
-
path: snapshotFileName,
|
|
227
|
-
type: protocol_definitions_1.TreeEntry[protocol_definitions_1.TreeEntry.Blob],
|
|
228
|
-
value: {
|
|
229
|
-
contents: this.saveSerializedSummary({ serializer }),
|
|
230
|
-
encoding: 'utf-8',
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
],
|
|
234
|
-
};
|
|
235
|
-
return tree;
|
|
220
|
+
summarizeCore(serializer, fullTree) {
|
|
221
|
+
return shared_object_base_1.createSingleBlobSummary(snapshotFileName, this.saveSerializedSummary({ serializer }));
|
|
236
222
|
}
|
|
237
223
|
/**
|
|
238
224
|
* Saves this SharedTree into a serialized summary.
|
|
@@ -376,7 +362,7 @@ class GenericSharedTree extends shared_object_base_1.SharedObject {
|
|
|
376
362
|
}
|
|
377
363
|
else if (type === PersistedTypes_1.SharedTreeOpType.Edit) {
|
|
378
364
|
const semiSerializedEdit = message.contents.edit;
|
|
379
|
-
// semiSerializedEdit may have handles which have been replaced by `serializer.
|
|
365
|
+
// semiSerializedEdit may have handles which have been replaced by `serializer.encode`.
|
|
380
366
|
// Since there is no API to un-replace them except via parse, re-stringify the edit, then parse it.
|
|
381
367
|
// Stringify using JSON, not IFluidSerializer since OPs use JSON directly.
|
|
382
368
|
// TODO:Performance:#48025: Avoid this serialization round trip.
|
|
@@ -445,7 +431,7 @@ class GenericSharedTree extends shared_object_base_1.SharedObject {
|
|
|
445
431
|
// IFluidHandles are not allowed in Ops.
|
|
446
432
|
// Ops can contain Fluid's Serializable (for payloads) which allows IFluidHandles.
|
|
447
433
|
// So replace the handles before sending:
|
|
448
|
-
const semiSerialized = this.serializer.
|
|
434
|
+
const semiSerialized = this.serializer.encode(editOp, this.handle);
|
|
449
435
|
// TODO:44711: what should be passed in when unattached?
|
|
450
436
|
this.submitLocalMessage(semiSerialized);
|
|
451
437
|
this.editLog.addLocalEdit(edit);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenericSharedTree.js","sourceRoot":"","sources":["../../src/generic/GenericSharedTree.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 { bufferToString, IsoBuffer } from '@fluidframework/common-utils';\nimport { IFluidHandle, IFluidSerializer } from '@fluidframework/core-interfaces';\nimport { FileMode, ISequencedDocumentMessage, ITree, TreeEntry } from '@fluidframework/protocol-definitions';\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n\tIChannelAttributes,\n} from '@fluidframework/datastore-definitions';\nimport { AttachState } from '@fluidframework/container-definitions';\nimport { ISharedObjectEvents, serializeHandles, SharedObject } from '@fluidframework/shared-object-base';\nimport { ITelemetryLogger } from '@fluidframework/common-definitions';\nimport { ChildLogger, ITelemetryLoggerPropertyBags, PerformanceEvent } from '@fluidframework/telemetry-utils';\nimport { assert, assertNotUndefined, fail } from '../Common';\nimport { EditLog, OrderedEditSet } from '../EditLog';\nimport { EditId } from '../Identifiers';\nimport { Snapshot } from '../Snapshot';\nimport { initialTree } from '../InitialTree';\nimport { CachingLogViewer, EditStatusCallback, LogViewer } from '../LogViewer';\nimport { convertSummaryToReadFormat, deserialize, readFormatVersion } from '../SummaryBackCompatibility';\nimport {\n\tEdit,\n\tSharedTreeOpType,\n\tSharedTreeEditOp,\n\tSharedTreeHandleOp,\n\tEditWithoutId,\n\tSharedTreeOp,\n\tEditStatus,\n} from './PersistedTypes';\nimport { serialize, SharedTreeSummarizer, SharedTreeSummary, SharedTreeSummaryBase } from './Summary';\nimport { GenericTransaction } from './GenericTransaction';\nimport { newEdit } from './GenericEditUtilities';\n\n/**\n * Filename where the snapshot is stored.\n */\nconst snapshotFileName = 'header';\n\nconst initialSummary: SharedTreeSummary<unknown> = {\n\tversion: readFormatVersion,\n\tcurrentTree: initialTree,\n\teditHistory: {\n\t\teditChunks: [],\n\t\teditIds: [],\n\t},\n};\n\n/**\n * An event emitted by a `SharedTree` to indicate a state change. See {@link ISharedTreeEvents} for event argument information.\n * @public\n */\nexport enum SharedTreeEvent {\n\t/**\n\t * An edit has been committed to the log.\n\t * This happens when either:\n\t * \t1. A locally generated edit is added to the log.\n\t * \t2. A remotely generated edit is added to the log.\n\t * Note that, for locally generated edits, this event will not be emitted again when that edit is sequenced.\n\t * Passed the EditId of the committed edit, i.e. supports callbacks of type {@link EditCommittedHandler}.\n\t */\n\tEditCommitted = 'committedEdit',\n}\n\n/**\n * An event emitted by a `SharedTree` for diagnostic purposes.\n * See {@link ISharedTreeEvents} for event argument information.\n */\nexport enum SharedTreeDiagnosticEvent {\n\t/**\n\t * A single catch up blob has been uploaded.\n\t */\n\tCatchUpBlobUploaded = 'uploadedCatchUpBlob',\n\t/**\n\t * A valid edit (local or remote) has been applied.\n\t * Passed the EditId of the applied edit.\n\t * Note that this may be called multiple times, due to concurrent edits causing reordering,\n\t * and/or due to not caching the output of every edit.\n\t */\n\tAppliedEdit = 'appliedEdit',\n\t/**\n\t * An invalid edit (local or remote) has been dropped.\n\t * Passed the EditId of the dropped edit.\n\t * Note that this may be called multiple times, due to concurrent edits causing reordering,\n\t * and/or due to not caching the output of every edit.\n\t */\n\tDroppedInvalidEdit = 'droppedInvalidEdit',\n\t/**\n\t * A malformed edit (local or remote) has been dropped.\n\t * Passed the EditId of the dropped edit.\n\t * Note that this may be called multiple times, due to concurrent edits causing reordering,\n\t * and/or due to not caching the output of every edit.\n\t */\n\tDroppedMalformedEdit = 'droppedMalformedEdit',\n}\n\n/**\n * The arguments included when the EditCommitted SharedTreeEvent is emitted.\n * @public\n */\nexport interface EditCommittedEventArguments<TSharedTree> {\n\t/** The ID of the edit committed. */\n\teditId: EditId;\n\t/** Whether or not this is a local edit. */\n\tlocal: boolean;\n\t/** The tree the edit was committed on. Required for local edit events handled by SharedTreeUndoRedoHandler. */\n\ttree: TSharedTree;\n}\n\n/**\n * Events which may be emitted by `SharedTree`. See {@link SharedTreeEvent} for documentation of event semantics.\n */\nexport interface ISharedTreeEvents<TSharedTree> extends ISharedObjectEvents {\n\t(event: 'committedEdit', listener: EditCommittedHandler<TSharedTree>);\n}\n\n/**\n * Expected type for a handler of the `EditCommitted` event.\n */\nexport type EditCommittedHandler<TSharedTree> = (args: EditCommittedEventArguments<TSharedTree>) => void;\n\nconst sharedTreeTelemetryProperties: ITelemetryLoggerPropertyBags = { all: { isSharedTreeEvent: true } };\n\n/**\n * A distributed tree.\n * @public\n */\nexport abstract class GenericSharedTree<TChange> extends SharedObject<ISharedTreeEvents<TChange>> {\n\t/**\n\t * The log of completed edits for this SharedTree.\n\t */\n\tprivate editLog: EditLog<TChange>;\n\n\t/**\n\t * As an implementation detail, SharedTree uses a log viewer that caches snapshots at different revisions.\n\t * It is not exposed to avoid accidental correctness issues, but `logViewer` is exposed in order to give clients a way\n\t * to access the revision history.\n\t */\n\tprivate cachingLogViewer: CachingLogViewer<TChange>;\n\n\t/**\n\t * Viewer for trees defined by editLog. This allows access to views of the tree at different revisions (various points in time).\n\t */\n\tpublic get logViewer(): LogViewer {\n\t\treturn this.cachingLogViewer;\n\t}\n\n\tprotected readonly logger: ITelemetryLogger;\n\n\tpublic readonly transactionFactory: (snapshot: Snapshot) => GenericTransaction<TChange>;\n\n\t/** Indicates if the client is the oldest member of the quorum. */\n\tprivate currentIsOldest: boolean;\n\n\tprivate readonly processEditResult = (editResult: EditStatus, editId: EditId): void => {\n\t\t// TODO:#44859: Invalid results should be handled by the app\n\t\tthis.emit(GenericSharedTree.eventFromEditResult(editResult), editId);\n\t};\n\n\t/**\n\t * Create a new SharedTreeFactory.\n\t * @param runtime - The runtime the SharedTree will be associated with\n\t * @param id - Unique ID for the SharedTree\n\t * @param expensiveValidation - Enable expensive asserts.\n\t * @param summarizeHistory - Determines if the history is included in summaries.\n\t */\n\tpublic constructor(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\ttransactionFactory: (snapshot: Snapshot) => GenericTransaction<TChange>,\n\t\tattributes: IChannelAttributes,\n\t\tprivate readonly expensiveValidation = false,\n\t\tprotected readonly summarizeHistory = true\n\t) {\n\t\tsuper(id, runtime, attributes);\n\t\tthis.expensiveValidation = expensiveValidation;\n\t\tthis.transactionFactory = transactionFactory;\n\n\t\t// This code is somewhat duplicated from OldestClientObserver because it currently depends on the container runtime\n\t\t// which SharedTree does not have access to.\n\t\t// TODO:#55900: Get rid of copy-pasted OldestClientObserver code\n\t\tconst quorum = this.runtime.getQuorum();\n\t\tthis.currentIsOldest = this.computeIsOldest();\n\t\tquorum.on('addMember', this.updateOldest);\n\t\tquorum.on('removeMember', this.updateOldest);\n\t\truntime.on('connected', this.updateOldest);\n\t\truntime.on('disconnected', this.updateOldest);\n\n\t\tthis.logger = ChildLogger.create(runtime.logger, 'SharedTree', sharedTreeTelemetryProperties);\n\t\tconst { editLog, cachingLogViewer } = this.createEditLogFromSummary(initialSummary, this.processEditResult);\n\n\t\tthis.editLog = editLog;\n\t\tthis.cachingLogViewer = cachingLogViewer;\n\t}\n\n\t/**\n\t * Re-computes currentIsOldest and emits an event if it has changed.\n\t * TODO:#55900: Get rid of copy-pasted OldestClientObserver code\n\t */\n\tprivate readonly updateOldest = () => {\n\t\tconst oldest = this.computeIsOldest();\n\t\tif (this.currentIsOldest !== oldest) {\n\t\t\tthis.currentIsOldest = oldest;\n\t\t\tif (oldest) {\n\t\t\t\tthis.emit('becameOldest');\n\t\t\t} else {\n\t\t\t\tthis.emit('lostOldest');\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Computes the oldest client in the quorum, true by default if the container is detached and false by default if the client isn't connected.\n\t * TODO:#55900: Get rid of copy-pasted OldestClientObserver code\n\t */\n\tprivate computeIsOldest(): boolean {\n\t\t// If the container is detached, we are the only ones that know about it and are the oldest by default.\n\t\tif (this.runtime.attachState === AttachState.Detached) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If we're not connected we can't be the oldest connected client.\n\t\tif (!this.runtime.connected) {\n\t\t\treturn false;\n\t\t}\n\n\t\tassert(this.runtime.clientId !== undefined, 'Client id should be set if connected.');\n\n\t\tconst quorum = this.runtime.getQuorum();\n\t\tconst selfSequencedClient = quorum.getMember(this.runtime.clientId);\n\t\t// When in readonly mode our clientId will not be present in the quorum.\n\t\tif (selfSequencedClient === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst members = quorum.getMembers();\n\t\tfor (const sequencedClient of members.values()) {\n\t\t\tif (sequencedClient.sequenceNumber < selfSequencedClient.sequenceNumber) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// No member of the quorum was older\n\t\treturn true;\n\t}\n\n\t/**\n\t * @returns the current view of the tree.\n\t */\n\tpublic get currentView(): Snapshot {\n\t\treturn this.logViewer.getSnapshotInSession(Number.POSITIVE_INFINITY);\n\t}\n\n\t/**\n\t * @returns the edit history of the tree.\n\t */\n\tpublic get edits(): OrderedEditSet<TChange> {\n\t\treturn this.editLog;\n\t}\n\n\t/**\n\t * Convenience helper for applying an edit containing the given changes.\n\t * Opens an edit, applies the given changes, and closes the edit. See (`openEdit()`/`applyChanges()`/`closeEdit()`).\n\t *\n\t * For convenient imperative variants of edits, see `editor`.\n\t * @internal\n\t */\n\tpublic applyEdit(...changes: TChange[]): EditId {\n\t\tconst edit = newEdit(changes);\n\t\tthis.processLocalEdit(edit);\n\t\treturn edit.id;\n\t}\n\n\tprivate deserializeHandle(serializedHandle: string): IFluidHandle<ArrayBufferLike> {\n\t\tconst deserializeHandle = this.serializer.parse(serializedHandle);\n\t\tassert(typeof deserializeHandle === 'object');\n\t\treturn deserializeHandle as IFluidHandle<ArrayBufferLike>;\n\t}\n\n\t/**\n\t * Uploads the edit chunk and sends the chunk starting revision along with the resulting handle as an op.\n\t */\n\tprivate async uploadEditChunk(edits: readonly EditWithoutId<TChange>[], startRevision: number): Promise<void> {\n\t\ttry {\n\t\t\tconst editHandle = await this.runtime.uploadBlob(IsoBuffer.from(JSON.stringify({ edits })));\n\t\t\tthis.submitLocalMessage({\n\t\t\t\teditHandle: serializeHandles(editHandle, this.serializer, this.handle),\n\t\t\t\tstartRevision,\n\t\t\t\ttype: SharedTreeOpType.Handle,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t// If chunk load fails, we will try again later in loadCore on the oldest client so we log the error instead of throwing.\n\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: 'EditChunkUploadFailure',\n\t\t\t\t},\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.snapshotCore}\n\t */\n\tpublic snapshotCore(serializer: IFluidSerializer): ITree {\n\t\tconst tree: ITree = {\n\t\t\tentries: [\n\t\t\t\t{\n\t\t\t\t\tmode: FileMode.File,\n\t\t\t\t\tpath: snapshotFileName,\n\t\t\t\t\ttype: TreeEntry[TreeEntry.Blob],\n\t\t\t\t\tvalue: {\n\t\t\t\t\t\tcontents: this.saveSerializedSummary({ serializer }),\n\t\t\t\t\t\tencoding: 'utf-8',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t};\n\n\t\treturn tree;\n\t}\n\n\t/**\n\t * Saves this SharedTree into a serialized summary.\n\t *\n\t * @param options - Optional serializer and summarizer to use. If not passed in, SharedTree's serializer and summarizer are used.\n\t * @internal\n\t */\n\tpublic saveSerializedSummary(options?: {\n\t\tserializer?: IFluidSerializer;\n\t\tsummarizer?: SharedTreeSummarizer<TChange>;\n\t}): string {\n\t\tconst { serializer, summarizer } = options || {};\n\n\t\treturn serialize(\n\t\t\tsummarizer ? summarizer(this.editLog, this.currentView) : this.saveSummary(),\n\t\t\tserializer || this.serializer,\n\t\t\tthis.handle\n\t\t);\n\t}\n\n\t/**\n\t * Saves this SharedTree into a summary.\n\t * @internal\n\t */\n\tpublic saveSummary(): SharedTreeSummaryBase {\n\t\t// If local changes exist, emulate the sequencing of those changes.\n\t\t// Doing so is necessary so edits created during DataObject.initializingFirstTime are included.\n\t\t// Doing so is safe because it is guaranteed that the DDS has not yet been attached. This is because summary creation is only\n\t\t// ever invoked on a DataObject containing local changes when it is attached for the first time. In post-attach flows, an extra\n\t\t// instance of the DataObject is created for generating summaries and will never have local edits.\n\t\tif (this.editLog.numberOfLocalEdits > 0) {\n\t\t\tassert(\n\t\t\t\tthis.runtime.attachState !== AttachState.Attached,\n\t\t\t\t'Summarizing should not occur with local edits except on first attach.'\n\t\t\t);\n\t\t\tthis.editLog.sequenceLocalEdits();\n\t\t}\n\n\t\tassert(this.editLog.numberOfLocalEdits === 0, 'generateSummary must not be called with local edits');\n\t\treturn this.generateSummary(this.editLog);\n\t}\n\n\t/**\n\t * Generates a SharedTree summary for the current state of the tree.\n\t * Will never be called when local edits are present.\n\t */\n\tprotected abstract generateSummary(editLog: OrderedEditSet<TChange>): SharedTreeSummaryBase;\n\n\t/**\n\t * Initialize shared tree with a summary.\n\t * @internal\n\t */\n\tpublic loadSummary(summary: SharedTreeSummaryBase): void {\n\t\tconst { editLog, cachingLogViewer } = this.createEditLogFromSummary(summary, this.processEditResult);\n\t\tthis.editLog = editLog;\n\t\tthis.cachingLogViewer = cachingLogViewer;\n\n\t\tif (this.runtime.connected) {\n\t\t\tconst noChunksReadyForUpload = this.editLog.getEditChunksReadyForUpload()[Symbol.iterator]().next().done;\n\t\t\tif (noChunksReadyForUpload === undefined || !noChunksReadyForUpload) {\n\t\t\t\t// A client does not become a member of the quorum until it is within the collaboration window.\n\t\t\t\t//\n\t\t\t\t// The collaboration window is the range from the minimum sequence number enforced by the server and head.\n\t\t\t\t// When a client sends an op, they include the last sequence number the client has processed. We call this the reference\n\t\t\t\t// sequence number.\n\t\t\t\t//\n\t\t\t\t// If there are no members in the quorum, we send a no op op in order to have this client added as a member to the quorum.\n\t\t\t\t// This is required so we can ensure only the oldest client will upload blobs during summary load.\n\t\t\t\tif (this.runtime.getQuorum().getMembers().size === 0) {\n\t\t\t\t\tconst noop: SharedTreeOp = {\n\t\t\t\t\t\ttype: SharedTreeOpType.NoOp,\n\t\t\t\t\t};\n\n\t\t\t\t\tthis.submitLocalMessage(noop);\n\t\t\t\t} else if (this.currentIsOldest) {\n\t\t\t\t\tvoid this.uploadCatchUpBlobs();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If this client becomes the oldest, it should take care of uploading catch up blobs.\n\t\t\tthis.on('becameOldest', () => void this.uploadCatchUpBlobs());\n\t\t}\n\t}\n\n\tprivate static eventFromEditResult(editStatus: EditStatus): SharedTreeDiagnosticEvent {\n\t\tswitch (editStatus) {\n\t\t\tcase EditStatus.Applied:\n\t\t\t\treturn SharedTreeDiagnosticEvent.AppliedEdit;\n\t\t\tcase EditStatus.Invalid:\n\t\t\t\treturn SharedTreeDiagnosticEvent.DroppedInvalidEdit;\n\t\t\tdefault:\n\t\t\t\treturn SharedTreeDiagnosticEvent.DroppedMalformedEdit;\n\t\t}\n\t}\n\n\tprivate createEditLogFromSummary(\n\t\tsummary: SharedTreeSummaryBase,\n\t\tcallback: EditStatusCallback\n\t): { editLog: EditLog<TChange>; cachingLogViewer: CachingLogViewer<TChange> } {\n\t\tconst convertedSummary = convertSummaryToReadFormat<TChange>(summary);\n\t\tif (typeof convertedSummary === 'string') {\n\t\t\tfail(convertedSummary);\n\t\t}\n\t\tconst { editHistory, currentTree } = convertedSummary;\n\t\tconst currentView = Snapshot.fromTree(currentTree);\n\n\t\tconst editLog = new EditLog(editHistory, this.logger);\n\t\tconst logViewer = new CachingLogViewer(\n\t\t\teditLog,\n\t\t\tSnapshot.fromTree(initialTree),\n\t\t\t// TODO:#47830: Store multiple checkpoints in summary.\n\t\t\t[[editLog.length, { snapshot: currentView }]],\n\t\t\tthis.expensiveValidation,\n\t\t\tcallback,\n\t\t\tthis.logger,\n\t\t\tthis.transactionFactory,\n\t\t\t0\n\t\t);\n\n\t\treturn { editLog, cachingLogViewer: logViewer };\n\t}\n\n\t/**\n\t * Upload any full chunks that have yet to be uploaded.\n\t */\n\tprivate async uploadCatchUpBlobs(): Promise<void> {\n\t\tfor (const [startRevision, chunk] of this.editLog.getEditChunksReadyForUpload()) {\n\t\t\tawait this.uploadEditChunk(chunk, startRevision);\n\t\t\tthis.emit(SharedTreeDiagnosticEvent.CatchUpBlobUploaded);\n\t\t}\n\t}\n\n\t/**\n\t * Compares this shared tree to another for equality.\n\t *\n\t * Equality means that the histories as captured by the EditLogs are equal.\n\t *\n\t * Equality does not include:\n\t * - if an edit is open\n\t * - the shared tree's id\n\t * - local vs sequenced status of edits\n\t * - registered event listeners\n\t * - state of caches\n\t * */\n\tpublic equals<TOtherChangeTypes>(sharedTree: GenericSharedTree<TOtherChangeTypes>): boolean {\n\t\tif (!this.currentView.equals(sharedTree.currentView)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.editLog.equals(sharedTree.editLog);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst summaryLoadPerformanceEvent = PerformanceEvent.start(this.logger, { eventName: 'SummaryLoad' });\n\n\t\ttry {\n\t\t\tconst newBlob = await storage.readBlob(snapshotFileName);\n\t\t\tconst blobData = bufferToString(newBlob, 'utf8');\n\n\t\t\tconst summary = deserialize(blobData, this.serializer);\n\t\t\tif (typeof summary === 'string') {\n\t\t\t\tfail(summary);\n\t\t\t}\n\t\t\tthis.loadSummary(summary);\n\n\t\t\tsummaryLoadPerformanceEvent.end({ historySize: this.edits.length });\n\t\t} catch (error) {\n\t\t\tsummaryLoadPerformanceEvent.cancel(undefined, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(message: ISequencedDocumentMessage, local: boolean): void {\n\t\tthis.cachingLogViewer.setMinimumSequenceNumber(message.minimumSequenceNumber);\n\t\tconst { type } = message.contents;\n\t\tif (type === SharedTreeOpType.Handle) {\n\t\t\tconst { editHandle, startRevision } = message.contents as SharedTreeHandleOp;\n\t\t\tthis.editLog.processEditChunkHandle(this.deserializeHandle(editHandle), startRevision);\n\t\t} else if (type === SharedTreeOpType.Edit) {\n\t\t\tconst semiSerializedEdit = message.contents.edit;\n\t\t\t// semiSerializedEdit may have handles which have been replaced by `serializer.replaceHandles`.\n\t\t\t// Since there is no API to un-replace them except via parse, re-stringify the edit, then parse it.\n\t\t\t// Stringify using JSON, not IFluidSerializer since OPs use JSON directly.\n\t\t\t// TODO:Performance:#48025: Avoid this serialization round trip.\n\t\t\tconst stringEdit = JSON.stringify(semiSerializedEdit);\n\t\t\tconst parsedEdit = this.serializer.parse(stringEdit);\n\t\t\tconst edit = parsedEdit as Edit<TChange>;\n\t\t\tthis.processSequencedEdit(edit, message);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}\n\t */\n\tprotected registerCore(): void {\n\t\t// Do nothing\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {\n\t\t// Do nothing\n\t}\n\n\tprivate processSequencedEdit(edit: Edit<TChange>, message: ISequencedDocumentMessage): void {\n\t\tconst { id: editId } = edit;\n\t\tconst wasLocalEdit = this.editLog.isLocalEdit(editId);\n\n\t\t// If the id of the supplied edit matches a non-local edit already present in the log, this would normally be indicative of an error.\n\t\t// However, the @fluidframework packages prior to 0.37.x have a bug which can cause data corruption by sequencing duplicate edits--\n\t\t// see discussion on the following github issue: https://github.com/microsoft/FluidFramework/issues/4399\n\t\t// To work around this issue, we currently tolerate duplicate ops in loaded documents.\n\t\t// This could be strengthened in the future to only apply to documents which may have been impacted.\n\t\tconst shouldIgnoreEdit = this.editLog.tryGetIndexOfId(editId) !== undefined && !wasLocalEdit;\n\t\tif (shouldIgnoreEdit) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.editLog.addSequencedEdit(edit, message);\n\t\tif (!wasLocalEdit) {\n\t\t\tconst eventArguments: EditCommittedEventArguments<GenericSharedTree<TChange>> = {\n\t\t\t\teditId,\n\t\t\t\tlocal: false,\n\t\t\t\ttree: this,\n\t\t\t};\n\t\t\tthis.emit(SharedTreeEvent.EditCommitted, eventArguments);\n\t\t} else {\n\t\t\t// If this client created the edit that filled up a chunk, it is responsible for uploading that chunk.\n\t\t\tconst lastPair = this.editLog.getLastEditChunk();\n\t\t\tif (lastPair !== undefined) {\n\t\t\t\tconst [startRevision, chunk] = lastPair;\n\t\t\t\tconst edits = assertNotUndefined(chunk.edits);\n\t\t\t\tif (edits.length === this.editLog.editsPerChunk) {\n\t\t\t\t\tvoid this.uploadEditChunk(edits, startRevision);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Add an `Edit` directly.\n\t * External users should use one of the more specialized functions, like applyEdit which handles constructing the actual `Edit` object.\n\t * This is exposed as it is useful for testing, particularly with invalid and malformed Edits.\n\t * @internal\n\t */\n\tpublic processLocalEdit(edit: Edit<TChange>): void {\n\t\tconst editOp: SharedTreeEditOp<TChange> = {\n\t\t\ttype: SharedTreeOpType.Edit,\n\t\t\tedit,\n\t\t};\n\n\t\t// IFluidHandles are not allowed in Ops.\n\t\t// Ops can contain Fluid's Serializable (for payloads) which allows IFluidHandles.\n\t\t// So replace the handles before sending:\n\t\tconst semiSerialized = this.serializer.replaceHandles(editOp, this.handle);\n\n\t\t// TODO:44711: what should be passed in when unattached?\n\t\tthis.submitLocalMessage(semiSerialized);\n\t\tthis.editLog.addLocalEdit(edit);\n\n\t\tconst eventArguments: EditCommittedEventArguments<GenericSharedTree<TChange>> = {\n\t\t\teditId: edit.id,\n\t\t\tlocal: true,\n\t\t\ttree: this,\n\t\t};\n\t\tthis.emit(SharedTreeEvent.EditCommitted, eventArguments);\n\t}\n\n\tpublic getRuntime(): IFluidDataStoreRuntime {\n\t\treturn this.runtime;\n\t}\n\n\tprotected applyStashedOp() {\n\t\tthrow new Error('not implemented');\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GenericSharedTree.js","sourceRoot":"","sources":["../../src/generic/GenericSharedTree.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 { bufferToString, IsoBuffer } from '@fluidframework/common-utils';\nimport { IFluidHandle } from '@fluidframework/core-interfaces';\nimport { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions';\nimport {\n\tIFluidDataStoreRuntime,\n\tIChannelStorageService,\n\tIChannelAttributes,\n} from '@fluidframework/datastore-definitions';\nimport { AttachState } from '@fluidframework/container-definitions';\nimport {\n\tcreateSingleBlobSummary,\n\tIFluidSerializer,\n\tISharedObjectEvents,\n\tserializeHandles,\n\tSharedObject,\n} from '@fluidframework/shared-object-base';\nimport { ITelemetryLogger } from '@fluidframework/common-definitions';\nimport { ChildLogger, ITelemetryLoggerPropertyBags, PerformanceEvent } from '@fluidframework/telemetry-utils';\nimport { ISummaryTreeWithStats } from '@fluidframework/runtime-definitions';\nimport { assert, assertNotUndefined, fail } from '../Common';\nimport { EditLog, OrderedEditSet } from '../EditLog';\nimport { EditId } from '../Identifiers';\nimport { Snapshot } from '../Snapshot';\nimport { initialTree } from '../InitialTree';\nimport { CachingLogViewer, EditStatusCallback, LogViewer } from '../LogViewer';\nimport { convertSummaryToReadFormat, deserialize, readFormatVersion } from '../SummaryBackCompatibility';\nimport {\n\tEdit,\n\tSharedTreeOpType,\n\tSharedTreeEditOp,\n\tSharedTreeHandleOp,\n\tEditWithoutId,\n\tSharedTreeOp,\n\tEditStatus,\n} from './PersistedTypes';\nimport { serialize, SharedTreeSummarizer, SharedTreeSummary, SharedTreeSummaryBase } from './Summary';\nimport { GenericTransaction } from './GenericTransaction';\nimport { newEdit } from './GenericEditUtilities';\n\n/**\n * Filename where the snapshot is stored.\n */\nconst snapshotFileName = 'header';\n\nconst initialSummary: SharedTreeSummary<unknown> = {\n\tversion: readFormatVersion,\n\tcurrentTree: initialTree,\n\teditHistory: {\n\t\teditChunks: [],\n\t\teditIds: [],\n\t},\n};\n\n/**\n * An event emitted by a `SharedTree` to indicate a state change. See {@link ISharedTreeEvents} for event argument information.\n * @public\n */\nexport enum SharedTreeEvent {\n\t/**\n\t * An edit has been committed to the log.\n\t * This happens when either:\n\t * \t1. A locally generated edit is added to the log.\n\t * \t2. A remotely generated edit is added to the log.\n\t * Note that, for locally generated edits, this event will not be emitted again when that edit is sequenced.\n\t * Passed the EditId of the committed edit, i.e. supports callbacks of type {@link EditCommittedHandler}.\n\t */\n\tEditCommitted = 'committedEdit',\n}\n\n/**\n * An event emitted by a `SharedTree` for diagnostic purposes.\n * See {@link ISharedTreeEvents} for event argument information.\n */\nexport enum SharedTreeDiagnosticEvent {\n\t/**\n\t * A single catch up blob has been uploaded.\n\t */\n\tCatchUpBlobUploaded = 'uploadedCatchUpBlob',\n\t/**\n\t * A valid edit (local or remote) has been applied.\n\t * Passed the EditId of the applied edit.\n\t * Note that this may be called multiple times, due to concurrent edits causing reordering,\n\t * and/or due to not caching the output of every edit.\n\t */\n\tAppliedEdit = 'appliedEdit',\n\t/**\n\t * An invalid edit (local or remote) has been dropped.\n\t * Passed the EditId of the dropped edit.\n\t * Note that this may be called multiple times, due to concurrent edits causing reordering,\n\t * and/or due to not caching the output of every edit.\n\t */\n\tDroppedInvalidEdit = 'droppedInvalidEdit',\n\t/**\n\t * A malformed edit (local or remote) has been dropped.\n\t * Passed the EditId of the dropped edit.\n\t * Note that this may be called multiple times, due to concurrent edits causing reordering,\n\t * and/or due to not caching the output of every edit.\n\t */\n\tDroppedMalformedEdit = 'droppedMalformedEdit',\n}\n\n/**\n * The arguments included when the EditCommitted SharedTreeEvent is emitted.\n * @public\n */\nexport interface EditCommittedEventArguments<TSharedTree> {\n\t/** The ID of the edit committed. */\n\teditId: EditId;\n\t/** Whether or not this is a local edit. */\n\tlocal: boolean;\n\t/** The tree the edit was committed on. Required for local edit events handled by SharedTreeUndoRedoHandler. */\n\ttree: TSharedTree;\n}\n\n/**\n * Events which may be emitted by `SharedTree`. See {@link SharedTreeEvent} for documentation of event semantics.\n */\nexport interface ISharedTreeEvents<TSharedTree> extends ISharedObjectEvents {\n\t(event: 'committedEdit', listener: EditCommittedHandler<TSharedTree>);\n}\n\n/**\n * Expected type for a handler of the `EditCommitted` event.\n */\nexport type EditCommittedHandler<TSharedTree> = (args: EditCommittedEventArguments<TSharedTree>) => void;\n\nconst sharedTreeTelemetryProperties: ITelemetryLoggerPropertyBags = { all: { isSharedTreeEvent: true } };\n\n/**\n * A distributed tree.\n * @public\n */\nexport abstract class GenericSharedTree<TChange> extends SharedObject<ISharedTreeEvents<TChange>> {\n\t/**\n\t * The log of completed edits for this SharedTree.\n\t */\n\tprivate editLog: EditLog<TChange>;\n\n\t/**\n\t * As an implementation detail, SharedTree uses a log viewer that caches snapshots at different revisions.\n\t * It is not exposed to avoid accidental correctness issues, but `logViewer` is exposed in order to give clients a way\n\t * to access the revision history.\n\t */\n\tprivate cachingLogViewer: CachingLogViewer<TChange>;\n\n\t/**\n\t * Viewer for trees defined by editLog. This allows access to views of the tree at different revisions (various points in time).\n\t */\n\tpublic get logViewer(): LogViewer {\n\t\treturn this.cachingLogViewer;\n\t}\n\n\tprotected readonly logger: ITelemetryLogger;\n\n\tpublic readonly transactionFactory: (snapshot: Snapshot) => GenericTransaction<TChange>;\n\n\t/** Indicates if the client is the oldest member of the quorum. */\n\tprivate currentIsOldest: boolean;\n\n\tprivate readonly processEditResult = (editResult: EditStatus, editId: EditId): void => {\n\t\t// TODO:#44859: Invalid results should be handled by the app\n\t\tthis.emit(GenericSharedTree.eventFromEditResult(editResult), editId);\n\t};\n\n\t/**\n\t * Create a new SharedTreeFactory.\n\t * @param runtime - The runtime the SharedTree will be associated with\n\t * @param id - Unique ID for the SharedTree\n\t * @param expensiveValidation - Enable expensive asserts.\n\t * @param summarizeHistory - Determines if the history is included in summaries.\n\t */\n\tpublic constructor(\n\t\truntime: IFluidDataStoreRuntime,\n\t\tid: string,\n\t\ttransactionFactory: (snapshot: Snapshot) => GenericTransaction<TChange>,\n\t\tattributes: IChannelAttributes,\n\t\tprivate readonly expensiveValidation = false,\n\t\tprotected readonly summarizeHistory = true\n\t) {\n\t\tsuper(id, runtime, attributes);\n\t\tthis.expensiveValidation = expensiveValidation;\n\t\tthis.transactionFactory = transactionFactory;\n\n\t\t// This code is somewhat duplicated from OldestClientObserver because it currently depends on the container runtime\n\t\t// which SharedTree does not have access to.\n\t\t// TODO:#55900: Get rid of copy-pasted OldestClientObserver code\n\t\tconst quorum = this.runtime.getQuorum();\n\t\tthis.currentIsOldest = this.computeIsOldest();\n\t\tquorum.on('addMember', this.updateOldest);\n\t\tquorum.on('removeMember', this.updateOldest);\n\t\truntime.on('connected', this.updateOldest);\n\t\truntime.on('disconnected', this.updateOldest);\n\n\t\tthis.logger = ChildLogger.create(runtime.logger, 'SharedTree', sharedTreeTelemetryProperties);\n\t\tconst { editLog, cachingLogViewer } = this.createEditLogFromSummary(initialSummary, this.processEditResult);\n\n\t\tthis.editLog = editLog;\n\t\tthis.cachingLogViewer = cachingLogViewer;\n\t}\n\n\t/**\n\t * Re-computes currentIsOldest and emits an event if it has changed.\n\t * TODO:#55900: Get rid of copy-pasted OldestClientObserver code\n\t */\n\tprivate readonly updateOldest = () => {\n\t\tconst oldest = this.computeIsOldest();\n\t\tif (this.currentIsOldest !== oldest) {\n\t\t\tthis.currentIsOldest = oldest;\n\t\t\tif (oldest) {\n\t\t\t\tthis.emit('becameOldest');\n\t\t\t} else {\n\t\t\t\tthis.emit('lostOldest');\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * Computes the oldest client in the quorum, true by default if the container is detached and false by default if the client isn't connected.\n\t * TODO:#55900: Get rid of copy-pasted OldestClientObserver code\n\t */\n\tprivate computeIsOldest(): boolean {\n\t\t// If the container is detached, we are the only ones that know about it and are the oldest by default.\n\t\tif (this.runtime.attachState === AttachState.Detached) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If we're not connected we can't be the oldest connected client.\n\t\tif (!this.runtime.connected) {\n\t\t\treturn false;\n\t\t}\n\n\t\tassert(this.runtime.clientId !== undefined, 'Client id should be set if connected.');\n\n\t\tconst quorum = this.runtime.getQuorum();\n\t\tconst selfSequencedClient = quorum.getMember(this.runtime.clientId);\n\t\t// When in readonly mode our clientId will not be present in the quorum.\n\t\tif (selfSequencedClient === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst members = quorum.getMembers();\n\t\tfor (const sequencedClient of members.values()) {\n\t\t\tif (sequencedClient.sequenceNumber < selfSequencedClient.sequenceNumber) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\t// No member of the quorum was older\n\t\treturn true;\n\t}\n\n\t/**\n\t * @returns the current view of the tree.\n\t */\n\tpublic get currentView(): Snapshot {\n\t\treturn this.logViewer.getSnapshotInSession(Number.POSITIVE_INFINITY);\n\t}\n\n\t/**\n\t * @returns the edit history of the tree.\n\t */\n\tpublic get edits(): OrderedEditSet<TChange> {\n\t\treturn this.editLog;\n\t}\n\n\t/**\n\t * Convenience helper for applying an edit containing the given changes.\n\t * Opens an edit, applies the given changes, and closes the edit. See (`openEdit()`/`applyChanges()`/`closeEdit()`).\n\t *\n\t * For convenient imperative variants of edits, see `editor`.\n\t * @internal\n\t */\n\tpublic applyEdit(...changes: TChange[]): EditId {\n\t\tconst edit = newEdit(changes);\n\t\tthis.processLocalEdit(edit);\n\t\treturn edit.id;\n\t}\n\n\tprivate deserializeHandle(serializedHandle: string): IFluidHandle<ArrayBufferLike> {\n\t\tconst deserializeHandle = this.serializer.parse(serializedHandle);\n\t\tassert(typeof deserializeHandle === 'object');\n\t\treturn deserializeHandle as IFluidHandle<ArrayBufferLike>;\n\t}\n\n\t/**\n\t * Uploads the edit chunk and sends the chunk starting revision along with the resulting handle as an op.\n\t */\n\tprivate async uploadEditChunk(edits: readonly EditWithoutId<TChange>[], startRevision: number): Promise<void> {\n\t\ttry {\n\t\t\tconst editHandle = await this.runtime.uploadBlob(IsoBuffer.from(JSON.stringify({ edits })));\n\t\t\tthis.submitLocalMessage({\n\t\t\t\teditHandle: serializeHandles(editHandle, this.serializer, this.handle),\n\t\t\t\tstartRevision,\n\t\t\t\ttype: SharedTreeOpType.Handle,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t// If chunk load fails, we will try again later in loadCore on the oldest client so we log the error instead of throwing.\n\t\t\tthis.logger.sendErrorEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: 'EditChunkUploadFailure',\n\t\t\t\t},\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.summarizeCore}\n\t */\n\tpublic summarizeCore(serializer: IFluidSerializer, fullTree: boolean): ISummaryTreeWithStats {\n\t\treturn createSingleBlobSummary(snapshotFileName, this.saveSerializedSummary({ serializer }));\n\t}\n\n\t/**\n\t * Saves this SharedTree into a serialized summary.\n\t *\n\t * @param options - Optional serializer and summarizer to use. If not passed in, SharedTree's serializer and summarizer are used.\n\t * @internal\n\t */\n\tpublic saveSerializedSummary(options?: {\n\t\tserializer?: IFluidSerializer;\n\t\tsummarizer?: SharedTreeSummarizer<TChange>;\n\t}): string {\n\t\tconst { serializer, summarizer } = options || {};\n\n\t\treturn serialize(\n\t\t\tsummarizer ? summarizer(this.editLog, this.currentView) : this.saveSummary(),\n\t\t\tserializer || this.serializer,\n\t\t\tthis.handle\n\t\t);\n\t}\n\n\t/**\n\t * Saves this SharedTree into a summary.\n\t * @internal\n\t */\n\tpublic saveSummary(): SharedTreeSummaryBase {\n\t\t// If local changes exist, emulate the sequencing of those changes.\n\t\t// Doing so is necessary so edits created during DataObject.initializingFirstTime are included.\n\t\t// Doing so is safe because it is guaranteed that the DDS has not yet been attached. This is because summary creation is only\n\t\t// ever invoked on a DataObject containing local changes when it is attached for the first time. In post-attach flows, an extra\n\t\t// instance of the DataObject is created for generating summaries and will never have local edits.\n\t\tif (this.editLog.numberOfLocalEdits > 0) {\n\t\t\tassert(\n\t\t\t\tthis.runtime.attachState !== AttachState.Attached,\n\t\t\t\t'Summarizing should not occur with local edits except on first attach.'\n\t\t\t);\n\t\t\tthis.editLog.sequenceLocalEdits();\n\t\t}\n\n\t\tassert(this.editLog.numberOfLocalEdits === 0, 'generateSummary must not be called with local edits');\n\t\treturn this.generateSummary(this.editLog);\n\t}\n\n\t/**\n\t * Generates a SharedTree summary for the current state of the tree.\n\t * Will never be called when local edits are present.\n\t */\n\tprotected abstract generateSummary(editLog: OrderedEditSet<TChange>): SharedTreeSummaryBase;\n\n\t/**\n\t * Initialize shared tree with a summary.\n\t * @internal\n\t */\n\tpublic loadSummary(summary: SharedTreeSummaryBase): void {\n\t\tconst { editLog, cachingLogViewer } = this.createEditLogFromSummary(summary, this.processEditResult);\n\t\tthis.editLog = editLog;\n\t\tthis.cachingLogViewer = cachingLogViewer;\n\n\t\tif (this.runtime.connected) {\n\t\t\tconst noChunksReadyForUpload = this.editLog.getEditChunksReadyForUpload()[Symbol.iterator]().next().done;\n\t\t\tif (noChunksReadyForUpload === undefined || !noChunksReadyForUpload) {\n\t\t\t\t// A client does not become a member of the quorum until it is within the collaboration window.\n\t\t\t\t//\n\t\t\t\t// The collaboration window is the range from the minimum sequence number enforced by the server and head.\n\t\t\t\t// When a client sends an op, they include the last sequence number the client has processed. We call this the reference\n\t\t\t\t// sequence number.\n\t\t\t\t//\n\t\t\t\t// If there are no members in the quorum, we send a no op op in order to have this client added as a member to the quorum.\n\t\t\t\t// This is required so we can ensure only the oldest client will upload blobs during summary load.\n\t\t\t\tif (this.runtime.getQuorum().getMembers().size === 0) {\n\t\t\t\t\tconst noop: SharedTreeOp = {\n\t\t\t\t\t\ttype: SharedTreeOpType.NoOp,\n\t\t\t\t\t};\n\n\t\t\t\t\tthis.submitLocalMessage(noop);\n\t\t\t\t} else if (this.currentIsOldest) {\n\t\t\t\t\tvoid this.uploadCatchUpBlobs();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If this client becomes the oldest, it should take care of uploading catch up blobs.\n\t\t\tthis.on('becameOldest', () => void this.uploadCatchUpBlobs());\n\t\t}\n\t}\n\n\tprivate static eventFromEditResult(editStatus: EditStatus): SharedTreeDiagnosticEvent {\n\t\tswitch (editStatus) {\n\t\t\tcase EditStatus.Applied:\n\t\t\t\treturn SharedTreeDiagnosticEvent.AppliedEdit;\n\t\t\tcase EditStatus.Invalid:\n\t\t\t\treturn SharedTreeDiagnosticEvent.DroppedInvalidEdit;\n\t\t\tdefault:\n\t\t\t\treturn SharedTreeDiagnosticEvent.DroppedMalformedEdit;\n\t\t}\n\t}\n\n\tprivate createEditLogFromSummary(\n\t\tsummary: SharedTreeSummaryBase,\n\t\tcallback: EditStatusCallback\n\t): { editLog: EditLog<TChange>; cachingLogViewer: CachingLogViewer<TChange> } {\n\t\tconst convertedSummary = convertSummaryToReadFormat<TChange>(summary);\n\t\tif (typeof convertedSummary === 'string') {\n\t\t\tfail(convertedSummary);\n\t\t}\n\t\tconst { editHistory, currentTree } = convertedSummary;\n\t\tconst currentView = Snapshot.fromTree(currentTree);\n\n\t\tconst editLog = new EditLog(editHistory, this.logger);\n\t\tconst logViewer = new CachingLogViewer(\n\t\t\teditLog,\n\t\t\tSnapshot.fromTree(initialTree),\n\t\t\t// TODO:#47830: Store multiple checkpoints in summary.\n\t\t\t[[editLog.length, { snapshot: currentView }]],\n\t\t\tthis.expensiveValidation,\n\t\t\tcallback,\n\t\t\tthis.logger,\n\t\t\tthis.transactionFactory,\n\t\t\t0\n\t\t);\n\n\t\treturn { editLog, cachingLogViewer: logViewer };\n\t}\n\n\t/**\n\t * Upload any full chunks that have yet to be uploaded.\n\t */\n\tprivate async uploadCatchUpBlobs(): Promise<void> {\n\t\tfor (const [startRevision, chunk] of this.editLog.getEditChunksReadyForUpload()) {\n\t\t\tawait this.uploadEditChunk(chunk, startRevision);\n\t\t\tthis.emit(SharedTreeDiagnosticEvent.CatchUpBlobUploaded);\n\t\t}\n\t}\n\n\t/**\n\t * Compares this shared tree to another for equality.\n\t *\n\t * Equality means that the histories as captured by the EditLogs are equal.\n\t *\n\t * Equality does not include:\n\t * - if an edit is open\n\t * - the shared tree's id\n\t * - local vs sequenced status of edits\n\t * - registered event listeners\n\t * - state of caches\n\t * */\n\tpublic equals<TOtherChangeTypes>(sharedTree: GenericSharedTree<TOtherChangeTypes>): boolean {\n\t\tif (!this.currentView.equals(sharedTree.currentView)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.editLog.equals(sharedTree.editLog);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.loadCore}\n\t */\n\tprotected async loadCore(storage: IChannelStorageService): Promise<void> {\n\t\tconst summaryLoadPerformanceEvent = PerformanceEvent.start(this.logger, { eventName: 'SummaryLoad' });\n\n\t\ttry {\n\t\t\tconst newBlob = await storage.readBlob(snapshotFileName);\n\t\t\tconst blobData = bufferToString(newBlob, 'utf8');\n\n\t\t\tconst summary = deserialize(blobData, this.serializer);\n\t\t\tif (typeof summary === 'string') {\n\t\t\t\tfail(summary);\n\t\t\t}\n\t\t\tthis.loadSummary(summary);\n\n\t\t\tsummaryLoadPerformanceEvent.end({ historySize: this.edits.length });\n\t\t} catch (error) {\n\t\t\tsummaryLoadPerformanceEvent.cancel(undefined, error);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.processCore}\n\t */\n\tprotected processCore(message: ISequencedDocumentMessage, local: boolean): void {\n\t\tthis.cachingLogViewer.setMinimumSequenceNumber(message.minimumSequenceNumber);\n\t\tconst { type } = message.contents;\n\t\tif (type === SharedTreeOpType.Handle) {\n\t\t\tconst { editHandle, startRevision } = message.contents as SharedTreeHandleOp;\n\t\t\tthis.editLog.processEditChunkHandle(this.deserializeHandle(editHandle), startRevision);\n\t\t} else if (type === SharedTreeOpType.Edit) {\n\t\t\tconst semiSerializedEdit = message.contents.edit;\n\t\t\t// semiSerializedEdit may have handles which have been replaced by `serializer.encode`.\n\t\t\t// Since there is no API to un-replace them except via parse, re-stringify the edit, then parse it.\n\t\t\t// Stringify using JSON, not IFluidSerializer since OPs use JSON directly.\n\t\t\t// TODO:Performance:#48025: Avoid this serialization round trip.\n\t\t\tconst stringEdit = JSON.stringify(semiSerializedEdit);\n\t\t\tconst parsedEdit = this.serializer.parse(stringEdit);\n\t\t\tconst edit = parsedEdit as Edit<TChange>;\n\t\t\tthis.processSequencedEdit(edit, message);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.registerCore}\n\t */\n\tprotected registerCore(): void {\n\t\t// Do nothing\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/shared-object-base#SharedObject.onDisconnect}\n\t */\n\tprotected onDisconnect(): void {\n\t\t// Do nothing\n\t}\n\n\tprivate processSequencedEdit(edit: Edit<TChange>, message: ISequencedDocumentMessage): void {\n\t\tconst { id: editId } = edit;\n\t\tconst wasLocalEdit = this.editLog.isLocalEdit(editId);\n\n\t\t// If the id of the supplied edit matches a non-local edit already present in the log, this would normally be indicative of an error.\n\t\t// However, the @fluidframework packages prior to 0.37.x have a bug which can cause data corruption by sequencing duplicate edits--\n\t\t// see discussion on the following github issue: https://github.com/microsoft/FluidFramework/issues/4399\n\t\t// To work around this issue, we currently tolerate duplicate ops in loaded documents.\n\t\t// This could be strengthened in the future to only apply to documents which may have been impacted.\n\t\tconst shouldIgnoreEdit = this.editLog.tryGetIndexOfId(editId) !== undefined && !wasLocalEdit;\n\t\tif (shouldIgnoreEdit) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.editLog.addSequencedEdit(edit, message);\n\t\tif (!wasLocalEdit) {\n\t\t\tconst eventArguments: EditCommittedEventArguments<GenericSharedTree<TChange>> = {\n\t\t\t\teditId,\n\t\t\t\tlocal: false,\n\t\t\t\ttree: this,\n\t\t\t};\n\t\t\tthis.emit(SharedTreeEvent.EditCommitted, eventArguments);\n\t\t} else {\n\t\t\t// If this client created the edit that filled up a chunk, it is responsible for uploading that chunk.\n\t\t\tconst lastPair = this.editLog.getLastEditChunk();\n\t\t\tif (lastPair !== undefined) {\n\t\t\t\tconst [startRevision, chunk] = lastPair;\n\t\t\t\tconst edits = assertNotUndefined(chunk.edits);\n\t\t\t\tif (edits.length === this.editLog.editsPerChunk) {\n\t\t\t\t\tvoid this.uploadEditChunk(edits, startRevision);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Add an `Edit` directly.\n\t * External users should use one of the more specialized functions, like applyEdit which handles constructing the actual `Edit` object.\n\t * This is exposed as it is useful for testing, particularly with invalid and malformed Edits.\n\t * @internal\n\t */\n\tpublic processLocalEdit(edit: Edit<TChange>): void {\n\t\tconst editOp: SharedTreeEditOp<TChange> = {\n\t\t\ttype: SharedTreeOpType.Edit,\n\t\t\tedit,\n\t\t};\n\n\t\t// IFluidHandles are not allowed in Ops.\n\t\t// Ops can contain Fluid's Serializable (for payloads) which allows IFluidHandles.\n\t\t// So replace the handles before sending:\n\t\tconst semiSerialized = this.serializer.encode(editOp, this.handle);\n\n\t\t// TODO:44711: what should be passed in when unattached?\n\t\tthis.submitLocalMessage(semiSerialized);\n\t\tthis.editLog.addLocalEdit(edit);\n\n\t\tconst eventArguments: EditCommittedEventArguments<GenericSharedTree<TChange>> = {\n\t\t\teditId: edit.id,\n\t\t\tlocal: true,\n\t\t\ttree: this,\n\t\t};\n\t\tthis.emit(SharedTreeEvent.EditCommitted, eventArguments);\n\t}\n\n\tpublic getRuntime(): IFluidDataStoreRuntime {\n\t\treturn this.runtime;\n\t}\n\n\tprotected applyStashedOp() {\n\t\tthrow new Error('not implemented');\n\t}\n}\n"]}
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { IFluidHandle
|
|
5
|
+
import { IFluidHandle } from '@fluidframework/core-interfaces';
|
|
6
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
6
7
|
import { EditLogSummary, OrderedEditSet } from '../EditLog';
|
|
7
8
|
import { Snapshot } from '../Snapshot';
|
|
8
9
|
import { SharedTreeSummary_0_0_2 } from '../SummaryBackCompatibility';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Summary.d.ts","sourceRoot":"","sources":["../../src/generic/Summary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"Summary.d.ts","sourceRoot":"","sources":["../../src/generic/Summary.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAoB,MAAM,oCAAoC,CAAC;AAExF,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAqB,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,EAAE,UAAU,EAAQ,MAAM,kBAAkB,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,aAAa,UAAU,CAAC;AAErC;;;;;;GAMG;AACH,oBAAY,oBAAoB,CAAC,OAAO,IAAI,CAC3C,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,EAChC,WAAW,EAAE,QAAQ,KACjB,qBAAqB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB,CAAC,OAAO,CAAE,SAAQ,qBAAqB;IACxE,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC;IAEjC;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;CAC/C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CAElH;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAC5C,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,EAChC,WAAW,EAAE,QAAQ,GACnB,uBAAuB,CAAC,OAAO,CAAC,CAwBlC;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAClD,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,EAChC,WAAW,EAAE,QAAQ,GACnB,iBAAiB,CAAC,OAAO,CAAC,CAM5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Summary.js","sourceRoot":"","sources":["../../src/generic/Summary.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,
|
|
1
|
+
{"version":3,"file":"Summary.js","sourceRoot":"","sources":["../../src/generic/Summary.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,2EAAwF;AACxF,sCAAuD;AAGvD,0EAAyF;AAGzF;;;;GAIG;AACU,QAAA,aAAa,GAAG,OAAO,CAAC;AAqCrC;;;;;;;GAOG;AACH,SAAgB,SAAS,CAAC,OAA8B,EAAE,UAA4B,EAAE,IAAkB;IACzG,OAAO,2BAAkB,CAAC,qCAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;AACxE,CAAC;AAFD,8BAEC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CACpC,OAAgC,EAChC,WAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAE5D,MAAM,cAAc,GAAoB,EAAE,CAAC;IAC3C,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;QAChC,eAAM,CACL,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,4FAA4F,CAC5F,CAAC;QAEF,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;YAC7B,cAAc,CAAC,IAAI,CAAC;gBACnB,OAAO;gBACP,EAAE,EAAE,2BAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,kDAAkD,CAAC;aAC9F,CAAC,CAAC;QACJ,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACN,WAAW,EAAE,WAAW,CAAC,iBAAiB,EAAE;QAC5C,cAAc;QACd,OAAO,EAAE,qBAAa;KACtB,CAAC;AACH,CAAC;AA3BD,sDA2BC;AAED;;GAEG;AACH,SAAgB,2BAA2B,CAC1C,OAAgC,EAChC,WAAqB;IAErB,OAAO;QACN,WAAW,EAAE,WAAW,CAAC,iBAAiB,EAAE;QAC5C,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC5C,OAAO,EAAE,4CAAiB;KAC1B,CAAC;AACH,CAAC;AATD,kEASC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IFluidHandle } from '@fluidframework/core-interfaces';\nimport { IFluidSerializer, serializeHandles } from '@fluidframework/shared-object-base';\nimport { assert, assertNotUndefined } from '../Common';\nimport { EditLogSummary, OrderedEditSet } from '../EditLog';\nimport { Snapshot } from '../Snapshot';\nimport { readFormatVersion, SharedTreeSummary_0_0_2 } from '../SummaryBackCompatibility';\nimport { ChangeNode, Edit } from './PersistedTypes';\n\n/**\n * Format version for summaries that are written.\n * When next changing the format, we should add a new format version variable for the edit-specific summaries and assign it an independent\n * version number.\n */\nexport const formatVersion = '0.0.2';\n\n/**\n * Handler for summarizing the tree state.\n * The handler is invoked when saving a summary. It accepts a view of the current state of the tree, the sequenced edits known\n * to the SharedTree, and optional helpers for serializing the edit information.\n * @returns a summary of the supplied state.\n * @internal\n */\nexport type SharedTreeSummarizer<TChange> = (\n\teditLog: OrderedEditSet<TChange>,\n\tcurrentView: Snapshot\n) => SharedTreeSummaryBase;\n\n/**\n * The minimal information on a SharedTree summary. Contains the summary format version.\n */\nexport interface SharedTreeSummaryBase {\n\t/**\n\t * Field on summary under which version is stored.\n\t */\n\treadonly version: string;\n}\n\n/**\n * The contents of a SharedTree summary: the current tree, and the edits needed to get from `initialTree` to the current tree.\n * @public\n */\nexport interface SharedTreeSummary<TChange> extends SharedTreeSummaryBase {\n\treadonly currentTree: ChangeNode;\n\n\t/**\n\t * Information that can populate an edit log.\n\t */\n\treadonly editHistory?: EditLogSummary<TChange>;\n}\n\n/**\n * Serializes a SharedTree summary into a JSON string. This may later be used to initialize a SharedTree's state via `deserialize()`\n * Also replaces handle objects with their serialized form.\n *\n * @param summary - The SharedTree summary to serialize.\n * @param serializer - The serializer required to serialize handles in the summary.\n * @param bind - The object handle required to serialize handles in the summary\n */\nexport function serialize(summary: SharedTreeSummaryBase, serializer: IFluidSerializer, bind: IFluidHandle): string {\n\treturn assertNotUndefined(serializeHandles(summary, serializer, bind));\n}\n\n/**\n * Preserves the full history in the generated summary.\n * @public\n */\nexport function fullHistorySummarizer<TChange>(\n\teditLog: OrderedEditSet<TChange>,\n\tcurrentView: Snapshot\n): SharedTreeSummary_0_0_2<TChange> {\n\tconst { editChunks, editIds } = editLog.getEditLogSummary();\n\n\tconst sequencedEdits: Edit<TChange>[] = [];\n\tlet idIndex = 0;\n\teditChunks.forEach(({ chunk }) => {\n\t\tassert(\n\t\t\tArray.isArray(chunk),\n\t\t\t'Handles should not be included in the summary until format version 0.1.0 is being written.'\n\t\t);\n\n\t\tchunk.forEach(({ changes }) => {\n\t\t\tsequencedEdits.push({\n\t\t\t\tchanges,\n\t\t\t\tid: assertNotUndefined(editIds[idIndex++], 'Number of edits should match number of edit IDs.'),\n\t\t\t});\n\t\t});\n\t});\n\n\treturn {\n\t\tcurrentTree: currentView.getChangeNodeTree(),\n\t\tsequencedEdits,\n\t\tversion: formatVersion,\n\t};\n}\n\n/**\n * Generates a summary with format version 0.1.0. This will prefer handles over edits in edit chunks where possible.\n */\nexport function fullHistorySummarizer_0_1_0<TChange>(\n\teditLog: OrderedEditSet<TChange>,\n\tcurrentView: Snapshot\n): SharedTreeSummary<TChange> {\n\treturn {\n\t\tcurrentTree: currentView.getChangeNodeTree(),\n\t\teditHistory: editLog.getEditLogSummary(true),\n\t\tversion: readFormatVersion,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevisionValueCache.d.ts","sourceRoot":"","sources":["../src/RevisionValueCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;GAQG;AACH,qBAAa,kBAAkB,CAAC,MAAM;IAyBpC;;;OAGG;
|
|
1
|
+
{"version":3,"file":"RevisionValueCache.d.ts","sourceRoot":"","sources":["../src/RevisionValueCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;GAQG;AACH,qBAAa,kBAAkB,CAAC,MAAM;IAyBpC;;;OAGG;IAGH,OAAO,CAAC,oBAAoB;IA9B7B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgE;IAE9F;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAwB;IAE3D;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAuB;;IAGxD;;OAEG;IACH,aAAa,EAAE,MAAM;IACrB;;;OAGG;IAGK,oBAAoB,EAAE,QAAQ;IACtC;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;IAqBvC;;OAEG;IACI,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO;IAI3D;;;OAGG;IACI,qBAAqB,CAAC,uBAAuB,EAAE,QAAQ,GAAG,IAAI;IAwBrE;;OAEG;IACI,eAAe,CAAC,iBAAiB,EAAE,QAAQ,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS;IAQpG;;OAEG;IACI,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKlE;;;;;;OAMG;IACI,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;CAS1D"}
|
|
@@ -25,6 +25,8 @@ export class RevisionValueCache {
|
|
|
25
25
|
* The first revision within the retention window. All entries with revisions >= retentionWindowStart will be retained.
|
|
26
26
|
* Must be >= 0.
|
|
27
27
|
*/
|
|
28
|
+
// False positive
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/prefer-readonly
|
|
28
30
|
retentionWindowStart,
|
|
29
31
|
/**
|
|
30
32
|
* Optional list of entries to permanently retain.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RevisionValueCache.js","sourceRoot":"","sources":["../src/RevisionValueCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,GAAG,MAAM,WAAW,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,OAAO,kBAAkB;IAoB9B;IACC;;OAEG;IACH,aAAqB;IACrB;;;OAGG;
|
|
1
|
+
{"version":3,"file":"RevisionValueCache.js","sourceRoot":"","sources":["../src/RevisionValueCache.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 BTree from 'sorted-btree';\nimport LRU from 'lru-cache';\nimport { assert, fail } from './Common';\nimport { Revision } from './LogViewer';\nimport { compareFiniteNumbers } from './SnapshotUtilities';\n\n/**\n * A cache of `TValue`s corresponding to `Revision`s.\n *\n * A value is kept in cache if it meets any of the following criteria:\n * - The revision is >= `retentionWindowStart`\n * - The value has been used recently, meaning getClosestEntry or cacheValue was called with its revision. Note that being returned\n * \t\twhen a large revision was passed to getClosestEntry does not count.\n * - The value is `retained` meaning it was provided to to constructor in retainedEntries or passed to `cacheRetainedValue`\n */\nexport class RevisionValueCache<TValue> {\n\t/**\n\t * A cache of entries for revisions.\n\t * This is sorted to allow efficient access to the nearest preceding entry (see getClosestEntry).\n\t * Contains all cached values, regardless of why they are cached (retained, LRU or window).\n\t */\n\tprivate readonly sortedEntries = new BTree<Revision, TValue>(undefined, compareFiniteNumbers);\n\n\t/**\n\t * Least recently used cache of evictable entries.\n\t * Subset of 'sortedValues` eligible for eviction:\n\t * All entries are also in `sortedValues`, and are removed from `sortedValues` when evicted from this cache.\n\t */\n\tprivate readonly evictableRevisions: LRU<Revision, TValue>;\n\n\t/**\n\t * Set of all revisions that should never be evicted.\n\t */\n\tprivate readonly retainedRevisions = new Set<Revision>();\n\n\tpublic constructor(\n\t\t/**\n\t\t * Maximum capacity for evictable cache entries (those neither marked as retained nor within the retention window).\n\t\t */\n\t\tevictableSize: number,\n\t\t/**\n\t\t * The first revision within the retention window. All entries with revisions >= retentionWindowStart will be retained.\n\t\t * Must be >= 0.\n\t\t */\n\t\t// False positive\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-readonly\n\t\tprivate retentionWindowStart: Revision,\n\t\t/**\n\t\t * Optional list of entries to permanently retain.\n\t\t */\n\t\tretainedEntries?: [Revision, TValue][]\n\t) {\n\t\tassert(retentionWindowStart >= 0, 'retentionWindowStart must be initialized >= 0');\n\t\tthis.evictableRevisions = new LRU({\n\t\t\tmax: evictableSize,\n\t\t\tnoDisposeOnSet: true,\n\t\t\tdispose: (revision) => {\n\t\t\t\tif (revision >= this.retentionWindowStart) {\n\t\t\t\t\tfail('Entries in retention window should never be evicted.');\n\t\t\t\t}\n\t\t\t\tif (this.retainedRevisions.has(revision)) {\n\t\t\t\t\tfail('Retained entries should not be evicted');\n\t\t\t\t}\n\t\t\t\tthis.sortedEntries.delete(revision);\n\t\t\t},\n\t\t});\n\t\tif (retainedEntries !== undefined) {\n\t\t\tretainedEntries.forEach(([revision, entry]) => this.cacheRetainedValue(revision, entry));\n\t\t}\n\t}\n\n\t/**\n\t * @returns if the supplied revision is within the retention window.\n\t */\n\tpublic isWithinRetentionWindow(revision: Revision): boolean {\n\t\treturn revision >= this.retentionWindowStart;\n\t}\n\n\t/**\n\t * Sets the new retention window.\n\t * @param newRetentionWindowStart - defines the trailing edge (inclusive) of the new retention window.\n\t */\n\tpublic updateRetentionWindow(newRetentionWindowStart: Revision): void {\n\t\tif (newRetentionWindowStart < this.retentionWindowStart) {\n\t\t\tfail('retention window boundary must not move backwards');\n\t\t}\n\t\tconst prevRetentionWindowStart = this.retentionWindowStart;\n\t\tthis.retentionWindowStart = newRetentionWindowStart;\n\t\tconst oldWindowEntries: [Revision, TValue][] = [];\n\t\tthis.sortedEntries.forRange(\n\t\t\tprevRetentionWindowStart,\n\t\t\tthis.retentionWindowStart,\n\t\t\tfalse,\n\t\t\t(windowRevision, windowEntry) => {\n\t\t\t\tif (!this.retainedRevisions.has(windowRevision)) {\n\t\t\t\t\t// Adding to the LRU can cause eviction which in turn mutates the b-tree we are enumerating. Thus, store list of\n\t\t\t\t\t// old window entries separately.\n\t\t\t\t\toldWindowEntries.push([windowRevision, windowEntry]);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t\toldWindowEntries.forEach(([revision, value]) => {\n\t\t\tthis.evictableRevisions.set(revision, value);\n\t\t});\n\t}\n\n\t/**\n\t * @returns a [cachedRevision, value] where cachedRevision <= requestedRevision, or undefined if no such revision is cached.\n\t */\n\tpublic getClosestEntry(requestedRevision: Revision): [revision: Revision, value: TValue] | undefined {\n\t\tconst fromLRU = this.evictableRevisions.get(requestedRevision);\n\t\tif (fromLRU !== undefined) {\n\t\t\treturn [requestedRevision, fromLRU];\n\t\t}\n\t\treturn this.sortedEntries.nextLowerPair(requestedRevision + 1) ?? undefined;\n\t}\n\n\t/**\n\t * Caches the supplied value and guarantees it will never be evicted.\n\t */\n\tpublic cacheRetainedValue(revision: Revision, value: TValue): void {\n\t\tthis.retainedRevisions.add(revision);\n\t\tthis.sortedEntries.set(revision, value);\n\t}\n\n\t/**\n\t * Caches the supplied value.\n\t * The cached value is subject to eviction unless it is within the retention window or was previously added\n\t * via `cacheRetainedValue`.\n\t * Note that if a non-retained entry starts out within the retention window and passes outside of it due to a call to\n\t * updateRetentionWindow it is then subject to eviction.\n\t */\n\tpublic cacheValue(revision: Revision, value: TValue): void {\n\t\tif (this.retainedRevisions.has(revision)) {\n\t\t\treturn;\n\t\t}\n\t\tthis.sortedEntries.set(revision, value);\n\t\tif (revision < this.retentionWindowStart) {\n\t\t\tthis.evictableRevisions.set(revision, value);\n\t\t}\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
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/
|
|
5
|
+
import { IFluidSerializer } from '@fluidframework/shared-object-base';
|
|
6
6
|
import { ErrorString } from './Common';
|
|
7
7
|
import { ChangeNode, Edit, SharedTreeSummaryBase, SharedTreeSummary } from './generic';
|
|
8
8
|
/** The summary format version that is read by SharedTree. */
|