@fluidframework/tree 2.0.0-rc.2.0.6 → 2.0.0-rc.2.0.7
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/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +3 -2
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +3 -2
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/package.json +19 -19
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree-core/sharedTreeCore.ts +3 -3
package/dist/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/tree";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-rc.2.0.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-rc.2.0.7";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/dist/packageVersion.js
CHANGED
|
@@ -8,5 +8,5 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.pkgVersion = exports.pkgName = void 0;
|
|
10
10
|
exports.pkgName = "@fluidframework/tree";
|
|
11
|
-
exports.pkgVersion = "2.0.0-rc.2.0.
|
|
11
|
+
exports.pkgVersion = "2.0.0-rc.2.0.7";
|
|
12
12
|
//# sourceMappingURL=packageVersion.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,sBAAsB,CAAC;AACjC,QAAA,UAAU,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/tree\";\nexport const pkgVersion = \"2.0.0-rc.2.0.
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,sBAAsB,CAAC;AACjC,QAAA,UAAU,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/tree\";\nexport const pkgVersion = \"2.0.0-rc.2.0.7\";\n"]}
|
|
@@ -132,11 +132,12 @@ class SharedTreeCore extends shared_object_base_1.SharedObject {
|
|
|
132
132
|
}, {
|
|
133
133
|
schema: this.schemaAndPolicy ?? undefined,
|
|
134
134
|
});
|
|
135
|
-
this.submitLocalMessage(message);
|
|
135
|
+
this.submitLocalMessage(this.serializer.encode(message, this.handle));
|
|
136
136
|
}
|
|
137
137
|
processCore(message, local, localOpMetadata) {
|
|
138
|
+
const contents = this.serializer.decode(message.contents);
|
|
138
139
|
// Empty context object is passed in, as our decode function is schema-agnostic.
|
|
139
|
-
const { commit, sessionId } = this.messageCodec.decode(
|
|
140
|
+
const { commit, sessionId } = this.messageCodec.decode(contents, {});
|
|
140
141
|
this.editManager.addSequencedChange({ ...commit, sessionId }, (0, index_js_2.brand)(message.sequenceNumber), (0, index_js_2.brand)(message.referenceSequenceNumber));
|
|
141
142
|
this.editManager.advanceMinimumSequenceNumber((0, index_js_2.brand)(message.minimumSequenceNumber));
|
|
142
143
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeCore.js","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tIChannelAttributes,\n\tIChannelStorageService,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions\";\nimport { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tITelemetryContext,\n\tISummaryTreeWithStats,\n\tIGarbageCollectionData,\n\tIExperimentalIncrementalSummaryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { ICodecOptions, IJsonCodec } from \"../codec/index.js\";\nimport { ChangeFamily, ChangeFamilyEditor, GraphCommit, RevisionTagCodec } from \"../core/index.js\";\nimport { brand, JsonCompatibleReadOnly } from \"../util/index.js\";\nimport { SchemaAndPolicy } from \"../feature-libraries/index.js\";\nimport { SharedTreeBranch, getChangeReplaceType } from \"./branch.js\";\nimport { EditManagerSummarizer } from \"./editManagerSummarizer.js\";\nimport { EditManager, minimumPossibleSequenceNumber } from \"./editManager.js\";\nimport { SeqNumber } from \"./editManagerFormat.js\";\nimport { DecodedMessage } from \"./messageTypes.js\";\nimport { MessageEncodingContext, makeMessageCodec } from \"./messageCodecs.js\";\n\n// TODO: How should the format version be determined?\nconst formatVersion = 0;\n// TODO: Organize this to be adjacent to persisted types.\nconst summarizablesTreeKey = \"indexes\";\n\n/**\n * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.\n *\n * TODO: actually implement\n * TODO: is history policy a detail of what indexes are used, or is there something else to it?\n */\nexport class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {\n\tprivate readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;\n\tprivate readonly summarizables: readonly Summarizable[];\n\n\t/**\n\t * The sequence number that this instance is at.\n\t * This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.\n\t * Is `undefined` after (and only after) this instance is attached.\n\t */\n\tprivate detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;\n\n\t/**\n\t * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.\n\t * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.\n\t */\n\tpublic get editor(): TEditor {\n\t\treturn this.getLocalBranch().editor;\n\t}\n\n\t/**\n\t * Used to encode/decode messages sent to/received from the Fluid runtime.\n\t *\n\t * @remarks Since there is currently only one format, this can just be cached on the class.\n\t * With more write formats active, it may make sense to keep around the \"usual\" format codec\n\t * (the one for the current persisted configuration) and resolve codecs for different versions\n\t * as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window\n\t * and an op needs to be interpreted which isn't written with the current configuration).\n\t */\n\tprivate readonly messageCodec: IJsonCodec<\n\t\tDecodedMessage<TChange>,\n\t\tunknown,\n\t\tunknown,\n\t\tMessageEncodingContext\n\t>;\n\n\tprivate readonly idCompressor: IIdCompressor;\n\n\tprivate readonly schemaAndPolicy: SchemaAndPolicy;\n\n\t/**\n\t * @param summarizables - Summarizers for all indexes used by this tree\n\t * @param changeFamily - The change family\n\t * @param editManager - The edit manager\n\t * @param id - The id of the shared object\n\t * @param runtime - The IFluidDataStoreRuntime which contains the shared object\n\t * @param attributes - Attributes of the shared object\n\t * @param telemetryContextPrefix - the context for any telemetry logs/errors emitted\n\t */\n\tpublic constructor(\n\t\tsummarizables: readonly Summarizable[],\n\t\tchangeFamily: ChangeFamily<TEditor, TChange>,\n\t\toptions: ICodecOptions,\n\t\t// Base class arguments\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t\ttelemetryContextPrefix: string,\n\t\tschemaAndPolicy: SchemaAndPolicy,\n\t) {\n\t\tsuper(id, runtime, attributes, telemetryContextPrefix);\n\n\t\tthis.schemaAndPolicy = schemaAndPolicy;\n\n\t\tassert(\n\t\t\truntime.idCompressor !== undefined,\n\t\t\t0x886 /* IdCompressor must be enabled to use SharedTree */,\n\t\t);\n\t\tthis.idCompressor = runtime.idCompressor;\n\t\tconst mintRevisionTag = () => this.idCompressor.generateCompressedId();\n\t\t/**\n\t\t * A random ID that uniquely identifies this client in the collab session.\n\t\t * This is sent alongside every op to identify which client the op originated from.\n\t\t * This is used rather than the Fluid client ID because the Fluid client ID is not stable across reconnections.\n\t\t */\n\t\tconst localSessionId = runtime.idCompressor.localSessionId;\n\t\tthis.editManager = new EditManager(changeFamily, localSessionId, mintRevisionTag);\n\t\tthis.editManager.localBranch.on(\"afterChange\", (args) => {\n\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t// Avoid submitting ops for changes that are part of a transaction.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (args.type) {\n\t\t\t\tcase \"append\":\n\t\t\t\t\tfor (const c of args.newCommits) {\n\t\t\t\t\t\tthis.submitCommit(c);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"replace\":\n\t\t\t\t\tif (getChangeReplaceType(args) === \"transactionCommit\") {\n\t\t\t\t\t\tthis.submitCommit(args.newCommits[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\tconst revisionTagCodec = new RevisionTagCodec(runtime.idCompressor);\n\t\tthis.summarizables = [\n\t\t\tnew EditManagerSummarizer(\n\t\t\t\tthis.editManager,\n\t\t\t\trevisionTagCodec,\n\t\t\t\toptions,\n\t\t\t\tthis.schemaAndPolicy,\n\t\t\t),\n\t\t\t...summarizables,\n\t\t];\n\t\tassert(\n\t\t\tnew Set(this.summarizables.map((e) => e.key)).size === this.summarizables.length,\n\t\t\t0x350 /* Index summary element keys must be unique */,\n\t\t);\n\n\t\tthis.messageCodec = makeMessageCodec(\n\t\t\tchangeFamily.codecs.resolve(formatVersion).json,\n\t\t\tnew RevisionTagCodec(runtime.idCompressor),\n\t\t\toptions,\n\t\t);\n\t}\n\n\t// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:\n\t// We might want to not subclass it, or override/reimplement most of its functionality.\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tconst summarizableBuilder = new SummaryTreeBuilder();\n\t\t// Merge the summaries of all summarizables together under a single ISummaryTree\n\t\tfor (const s of this.summarizables) {\n\t\t\tsummarizableBuilder.addWithStats(\n\t\t\t\ts.key,\n\t\t\t\ts.getAttachSummary(\n\t\t\t\t\t(contents) => serializer.stringify(contents, this.handle),\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttelemetryContext,\n\t\t\t\t\tincrementalSummaryContext,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tbuilder.addWithStats(summarizablesTreeKey, summarizableBuilder.getSummaryTree());\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tprotected async loadCore(services: IChannelStorageService): Promise<void> {\n\t\tconst loadSummaries = this.summarizables.map(async (summaryElement) =>\n\t\t\tsummaryElement.load(\n\t\t\t\tscopeStorageService(services, summarizablesTreeKey, summaryElement.key),\n\t\t\t\t(contents) => this.serializer.parse(contents),\n\t\t\t),\n\t\t);\n\n\t\tawait Promise.all(loadSummaries);\n\t}\n\n\t/**\n\t * Submits an op to the Fluid runtime containing the given commit\n\t * @param commit - the commit to submit\n\t */\n\tprivate submitCommit(commit: GraphCommit<TChange>, isResubmit = false): void {\n\t\t// Edits should not be submitted until all transactions finish\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting() || isResubmit,\n\t\t\t0x68b /* Unexpected edit submitted during transaction */,\n\t\t);\n\n\t\t// Edits submitted before the first attach are treated as sequenced because they will be included\n\t\t// in the attach summary that is uploaded to the service.\n\t\t// Until this attach workflow happens, this instance essentially behaves as a centralized data structure.\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tconst newRevision: SeqNumber = brand((this.detachedRevision as number) + 1);\n\t\t\tthis.detachedRevision = newRevision;\n\t\t\tthis.editManager.addSequencedChange(\n\t\t\t\t{ ...commit, sessionId: this.editManager.localSessionId },\n\t\t\t\tnewRevision,\n\t\t\t\tthis.detachedRevision,\n\t\t\t);\n\t\t\tthis.editManager.advanceMinimumSequenceNumber(newRevision);\n\t\t}\n\n\t\t// Don't submit the op if it is not attached\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst message = this.messageCodec.encode(\n\t\t\t{\n\t\t\t\tcommit,\n\t\t\t\tsessionId: this.editManager.localSessionId,\n\t\t\t},\n\t\t\t{\n\t\t\t\tschema: this.schemaAndPolicy ?? undefined,\n\t\t\t},\n\t\t);\n\t\tthis.submitLocalMessage(message);\n\t}\n\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t) {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst { commit, sessionId } = this.messageCodec.decode(message.contents, {});\n\n\t\tthis.editManager.addSequencedChange(\n\t\t\t{ ...commit, sessionId },\n\t\t\tbrand(message.sequenceNumber),\n\t\t\tbrand(message.referenceSequenceNumber),\n\t\t);\n\n\t\tthis.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));\n\t}\n\n\t/**\n\t * @returns the head commit of the root local branch\n\t */\n\tprotected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {\n\t\treturn this.editManager.localBranch;\n\t}\n\n\tprotected onDisconnect() {}\n\n\tprotected override didAttach(): void {\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tthis.detachedRevision = undefined;\n\t\t}\n\t}\n\n\tprotected override reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown) {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tconst [commit] = this.editManager.findLocalCommit(revision);\n\t\tthis.submitCommit(commit, true);\n\t}\n\n\tprotected applyStashedOp(content: JsonCompatibleReadOnly): void {\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting(),\n\t\t\t0x674 /* Unexpected transaction is open while applying stashed ops */,\n\t\t);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision, change },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tthis.editManager.localBranch.apply(change, revision);\n\t}\n\n\tpublic override getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\tconst gcNodes: IGarbageCollectionData[\"gcNodes\"] = super.getGCData(fullGC).gcNodes;\n\t\tfor (const s of this.summarizables) {\n\t\t\tfor (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {\n\t\t\t\tgcNodes[id] ??= [];\n\t\t\t\tfor (const route of routes) {\n\t\t\t\t\tgcNodes[id].push(route);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tgcNodes,\n\t\t};\n\t}\n}\n\n/**\n * Specifies the behavior of a component that puts data in a summary.\n */\nexport interface Summarizable {\n\t/**\n\t * Field name in summary json under which this element stores its data.\n\t */\n\treadonly key: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tgetAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).summarize}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tsummarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats>;\n\n\t/**\n\t * {@inheritDoc (ISharedObject:interface).getGCData}\n\t */\n\t// TODO: Change this interface (and the one in ISharedObject, if necessary) to support \"handles within handles\".\n\t// Consider the case of a document with history; the return value here currently grows unboundedly.\n\tgetGCData(fullGC?: boolean): IGarbageCollectionData;\n\n\t/**\n\t * Allows the component to perform custom loading. The storage service is scoped to this component and therefore\n\t * paths in this component will not collide with those in other components, even if they are the same string.\n\t * @param service - Storage used by the component\n\t * @param parse - Parses serialized data from storage into runtime objects for the component\n\t */\n\tload(service: IChannelStorageService, parse: SummaryElementParser): Promise<void>;\n}\n\n/**\n * Serializes the given contents into a string acceptable for storing in summaries, i.e. all\n * Fluid handles have been replaced appropriately by an IFluidSerializer\n */\nexport type SummaryElementStringifier = (contents: unknown) => string;\n\n/**\n * Parses a serialized/summarized string into an object, rehydrating any Fluid handles as necessary\n */\nexport type SummaryElementParser = (contents: string) => unknown;\n\n/**\n * Compose an {@link IChannelStorageService} which prefixes all paths before forwarding them to the original service\n */\nfunction scopeStorageService(\n\tservice: IChannelStorageService,\n\t...pathElements: string[]\n): IChannelStorageService {\n\tconst scope = `${pathElements.join(\"/\")}/`;\n\n\treturn {\n\t\tasync readBlob(path: string): Promise<ArrayBufferLike> {\n\t\t\treturn service.readBlob(`${scope}${path}`);\n\t\t},\n\t\tasync contains(path) {\n\t\t\treturn service.contains(`${scope}${path}`);\n\t\t},\n\t\tasync list(path) {\n\t\t\treturn service.list(`${scope}${path}`);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sharedTreeCore.js","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tIChannelAttributes,\n\tIChannelStorageService,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions\";\nimport { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tITelemetryContext,\n\tISummaryTreeWithStats,\n\tIGarbageCollectionData,\n\tIExperimentalIncrementalSummaryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { ICodecOptions, IJsonCodec } from \"../codec/index.js\";\nimport { ChangeFamily, ChangeFamilyEditor, GraphCommit, RevisionTagCodec } from \"../core/index.js\";\nimport { brand, JsonCompatibleReadOnly } from \"../util/index.js\";\nimport { SchemaAndPolicy } from \"../feature-libraries/index.js\";\nimport { SharedTreeBranch, getChangeReplaceType } from \"./branch.js\";\nimport { EditManagerSummarizer } from \"./editManagerSummarizer.js\";\nimport { EditManager, minimumPossibleSequenceNumber } from \"./editManager.js\";\nimport { SeqNumber } from \"./editManagerFormat.js\";\nimport { DecodedMessage } from \"./messageTypes.js\";\nimport { MessageEncodingContext, makeMessageCodec } from \"./messageCodecs.js\";\n\n// TODO: How should the format version be determined?\nconst formatVersion = 0;\n// TODO: Organize this to be adjacent to persisted types.\nconst summarizablesTreeKey = \"indexes\";\n\n/**\n * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.\n *\n * TODO: actually implement\n * TODO: is history policy a detail of what indexes are used, or is there something else to it?\n */\nexport class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {\n\tprivate readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;\n\tprivate readonly summarizables: readonly Summarizable[];\n\n\t/**\n\t * The sequence number that this instance is at.\n\t * This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.\n\t * Is `undefined` after (and only after) this instance is attached.\n\t */\n\tprivate detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;\n\n\t/**\n\t * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.\n\t * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.\n\t */\n\tpublic get editor(): TEditor {\n\t\treturn this.getLocalBranch().editor;\n\t}\n\n\t/**\n\t * Used to encode/decode messages sent to/received from the Fluid runtime.\n\t *\n\t * @remarks Since there is currently only one format, this can just be cached on the class.\n\t * With more write formats active, it may make sense to keep around the \"usual\" format codec\n\t * (the one for the current persisted configuration) and resolve codecs for different versions\n\t * as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window\n\t * and an op needs to be interpreted which isn't written with the current configuration).\n\t */\n\tprivate readonly messageCodec: IJsonCodec<\n\t\tDecodedMessage<TChange>,\n\t\tunknown,\n\t\tunknown,\n\t\tMessageEncodingContext\n\t>;\n\n\tprivate readonly idCompressor: IIdCompressor;\n\n\tprivate readonly schemaAndPolicy: SchemaAndPolicy;\n\n\t/**\n\t * @param summarizables - Summarizers for all indexes used by this tree\n\t * @param changeFamily - The change family\n\t * @param editManager - The edit manager\n\t * @param id - The id of the shared object\n\t * @param runtime - The IFluidDataStoreRuntime which contains the shared object\n\t * @param attributes - Attributes of the shared object\n\t * @param telemetryContextPrefix - the context for any telemetry logs/errors emitted\n\t */\n\tpublic constructor(\n\t\tsummarizables: readonly Summarizable[],\n\t\tchangeFamily: ChangeFamily<TEditor, TChange>,\n\t\toptions: ICodecOptions,\n\t\t// Base class arguments\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t\ttelemetryContextPrefix: string,\n\t\tschemaAndPolicy: SchemaAndPolicy,\n\t) {\n\t\tsuper(id, runtime, attributes, telemetryContextPrefix);\n\n\t\tthis.schemaAndPolicy = schemaAndPolicy;\n\n\t\tassert(\n\t\t\truntime.idCompressor !== undefined,\n\t\t\t0x886 /* IdCompressor must be enabled to use SharedTree */,\n\t\t);\n\t\tthis.idCompressor = runtime.idCompressor;\n\t\tconst mintRevisionTag = () => this.idCompressor.generateCompressedId();\n\t\t/**\n\t\t * A random ID that uniquely identifies this client in the collab session.\n\t\t * This is sent alongside every op to identify which client the op originated from.\n\t\t * This is used rather than the Fluid client ID because the Fluid client ID is not stable across reconnections.\n\t\t */\n\t\tconst localSessionId = runtime.idCompressor.localSessionId;\n\t\tthis.editManager = new EditManager(changeFamily, localSessionId, mintRevisionTag);\n\t\tthis.editManager.localBranch.on(\"afterChange\", (args) => {\n\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t// Avoid submitting ops for changes that are part of a transaction.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (args.type) {\n\t\t\t\tcase \"append\":\n\t\t\t\t\tfor (const c of args.newCommits) {\n\t\t\t\t\t\tthis.submitCommit(c);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"replace\":\n\t\t\t\t\tif (getChangeReplaceType(args) === \"transactionCommit\") {\n\t\t\t\t\t\tthis.submitCommit(args.newCommits[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\tconst revisionTagCodec = new RevisionTagCodec(runtime.idCompressor);\n\t\tthis.summarizables = [\n\t\t\tnew EditManagerSummarizer(\n\t\t\t\tthis.editManager,\n\t\t\t\trevisionTagCodec,\n\t\t\t\toptions,\n\t\t\t\tthis.schemaAndPolicy,\n\t\t\t),\n\t\t\t...summarizables,\n\t\t];\n\t\tassert(\n\t\t\tnew Set(this.summarizables.map((e) => e.key)).size === this.summarizables.length,\n\t\t\t0x350 /* Index summary element keys must be unique */,\n\t\t);\n\n\t\tthis.messageCodec = makeMessageCodec(\n\t\t\tchangeFamily.codecs.resolve(formatVersion).json,\n\t\t\tnew RevisionTagCodec(runtime.idCompressor),\n\t\t\toptions,\n\t\t);\n\t}\n\n\t// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:\n\t// We might want to not subclass it, or override/reimplement most of its functionality.\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tconst summarizableBuilder = new SummaryTreeBuilder();\n\t\t// Merge the summaries of all summarizables together under a single ISummaryTree\n\t\tfor (const s of this.summarizables) {\n\t\t\tsummarizableBuilder.addWithStats(\n\t\t\t\ts.key,\n\t\t\t\ts.getAttachSummary(\n\t\t\t\t\t(contents) => serializer.stringify(contents, this.handle),\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttelemetryContext,\n\t\t\t\t\tincrementalSummaryContext,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tbuilder.addWithStats(summarizablesTreeKey, summarizableBuilder.getSummaryTree());\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tprotected async loadCore(services: IChannelStorageService): Promise<void> {\n\t\tconst loadSummaries = this.summarizables.map(async (summaryElement) =>\n\t\t\tsummaryElement.load(\n\t\t\t\tscopeStorageService(services, summarizablesTreeKey, summaryElement.key),\n\t\t\t\t(contents) => this.serializer.parse(contents),\n\t\t\t),\n\t\t);\n\n\t\tawait Promise.all(loadSummaries);\n\t}\n\n\t/**\n\t * Submits an op to the Fluid runtime containing the given commit\n\t * @param commit - the commit to submit\n\t */\n\tprivate submitCommit(commit: GraphCommit<TChange>, isResubmit = false): void {\n\t\t// Edits should not be submitted until all transactions finish\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting() || isResubmit,\n\t\t\t0x68b /* Unexpected edit submitted during transaction */,\n\t\t);\n\n\t\t// Edits submitted before the first attach are treated as sequenced because they will be included\n\t\t// in the attach summary that is uploaded to the service.\n\t\t// Until this attach workflow happens, this instance essentially behaves as a centralized data structure.\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tconst newRevision: SeqNumber = brand((this.detachedRevision as number) + 1);\n\t\t\tthis.detachedRevision = newRevision;\n\t\t\tthis.editManager.addSequencedChange(\n\t\t\t\t{ ...commit, sessionId: this.editManager.localSessionId },\n\t\t\t\tnewRevision,\n\t\t\t\tthis.detachedRevision,\n\t\t\t);\n\t\t\tthis.editManager.advanceMinimumSequenceNumber(newRevision);\n\t\t}\n\n\t\t// Don't submit the op if it is not attached\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst message = this.messageCodec.encode(\n\t\t\t{\n\t\t\t\tcommit,\n\t\t\t\tsessionId: this.editManager.localSessionId,\n\t\t\t},\n\t\t\t{\n\t\t\t\tschema: this.schemaAndPolicy ?? undefined,\n\t\t\t},\n\t\t);\n\t\tthis.submitLocalMessage(this.serializer.encode(message, this.handle));\n\t}\n\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t) {\n\t\tconst contents: unknown = this.serializer.decode(message.contents);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst { commit, sessionId } = this.messageCodec.decode(contents, {});\n\t\tthis.editManager.addSequencedChange(\n\t\t\t{ ...commit, sessionId },\n\t\t\tbrand(message.sequenceNumber),\n\t\t\tbrand(message.referenceSequenceNumber),\n\t\t);\n\n\t\tthis.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));\n\t}\n\n\t/**\n\t * @returns the head commit of the root local branch\n\t */\n\tprotected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {\n\t\treturn this.editManager.localBranch;\n\t}\n\n\tprotected onDisconnect() {}\n\n\tprotected override didAttach(): void {\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tthis.detachedRevision = undefined;\n\t\t}\n\t}\n\n\tprotected override reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown) {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tconst [commit] = this.editManager.findLocalCommit(revision);\n\t\tthis.submitCommit(commit, true);\n\t}\n\n\tprotected applyStashedOp(content: JsonCompatibleReadOnly): void {\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting(),\n\t\t\t0x674 /* Unexpected transaction is open while applying stashed ops */,\n\t\t);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision, change },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tthis.editManager.localBranch.apply(change, revision);\n\t}\n\n\tpublic override getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\tconst gcNodes: IGarbageCollectionData[\"gcNodes\"] = super.getGCData(fullGC).gcNodes;\n\t\tfor (const s of this.summarizables) {\n\t\t\tfor (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {\n\t\t\t\tgcNodes[id] ??= [];\n\t\t\t\tfor (const route of routes) {\n\t\t\t\t\tgcNodes[id].push(route);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tgcNodes,\n\t\t};\n\t}\n}\n\n/**\n * Specifies the behavior of a component that puts data in a summary.\n */\nexport interface Summarizable {\n\t/**\n\t * Field name in summary json under which this element stores its data.\n\t */\n\treadonly key: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tgetAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).summarize}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tsummarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats>;\n\n\t/**\n\t * {@inheritDoc (ISharedObject:interface).getGCData}\n\t */\n\t// TODO: Change this interface (and the one in ISharedObject, if necessary) to support \"handles within handles\".\n\t// Consider the case of a document with history; the return value here currently grows unboundedly.\n\tgetGCData(fullGC?: boolean): IGarbageCollectionData;\n\n\t/**\n\t * Allows the component to perform custom loading. The storage service is scoped to this component and therefore\n\t * paths in this component will not collide with those in other components, even if they are the same string.\n\t * @param service - Storage used by the component\n\t * @param parse - Parses serialized data from storage into runtime objects for the component\n\t */\n\tload(service: IChannelStorageService, parse: SummaryElementParser): Promise<void>;\n}\n\n/**\n * Serializes the given contents into a string acceptable for storing in summaries, i.e. all\n * Fluid handles have been replaced appropriately by an IFluidSerializer\n */\nexport type SummaryElementStringifier = (contents: unknown) => string;\n\n/**\n * Parses a serialized/summarized string into an object, rehydrating any Fluid handles as necessary\n */\nexport type SummaryElementParser = (contents: string) => unknown;\n\n/**\n * Compose an {@link IChannelStorageService} which prefixes all paths before forwarding them to the original service\n */\nfunction scopeStorageService(\n\tservice: IChannelStorageService,\n\t...pathElements: string[]\n): IChannelStorageService {\n\tconst scope = `${pathElements.join(\"/\")}/`;\n\n\treturn {\n\t\tasync readBlob(path: string): Promise<ArrayBufferLike> {\n\t\t\treturn service.readBlob(`${scope}${path}`);\n\t\t},\n\t\tasync contains(path) {\n\t\t\treturn service.contains(`${scope}${path}`);\n\t\t},\n\t\tasync list(path) {\n\t\t\treturn service.list(`${scope}${path}`);\n\t\t},\n\t};\n}\n"]}
|
package/lib/packageVersion.d.ts
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
|
|
6
6
|
*/
|
|
7
7
|
export declare const pkgName = "@fluidframework/tree";
|
|
8
|
-
export declare const pkgVersion = "2.0.0-rc.2.0.
|
|
8
|
+
export declare const pkgVersion = "2.0.0-rc.2.0.7";
|
|
9
9
|
//# sourceMappingURL=packageVersion.d.ts.map
|
package/lib/packageVersion.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,sBAAsB,CAAC;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/tree\";\nexport const pkgVersion = \"2.0.0-rc.2.0.
|
|
1
|
+
{"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,sBAAsB,CAAC;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/tree\";\nexport const pkgVersion = \"2.0.0-rc.2.0.7\";\n"]}
|
|
@@ -129,11 +129,12 @@ export class SharedTreeCore extends SharedObject {
|
|
|
129
129
|
}, {
|
|
130
130
|
schema: this.schemaAndPolicy ?? undefined,
|
|
131
131
|
});
|
|
132
|
-
this.submitLocalMessage(message);
|
|
132
|
+
this.submitLocalMessage(this.serializer.encode(message, this.handle));
|
|
133
133
|
}
|
|
134
134
|
processCore(message, local, localOpMetadata) {
|
|
135
|
+
const contents = this.serializer.decode(message.contents);
|
|
135
136
|
// Empty context object is passed in, as our decode function is schema-agnostic.
|
|
136
|
-
const { commit, sessionId } = this.messageCodec.decode(
|
|
137
|
+
const { commit, sessionId } = this.messageCodec.decode(contents, {});
|
|
137
138
|
this.editManager.addSequencedChange({ ...commit, sessionId }, brand(message.sequenceNumber), brand(message.referenceSequenceNumber));
|
|
138
139
|
this.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));
|
|
139
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharedTreeCore.js","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAcpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAoB,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAEpF,OAAO,EAAiD,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,KAAK,EAA0B,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAoB,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EAA0B,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,qDAAqD;AACrD,MAAM,aAAa,GAAG,CAAC,CAAC;AACxB,yDAAyD;AACzD,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,OAAO,cAA4D,SAAQ,YAAY;IAW5F;;;OAGG;IACH,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,MAAM,CAAC;IACrC,CAAC;IAsBD;;;;;;;;OAQG;IACH,YACC,aAAsC,EACtC,YAA4C,EAC5C,OAAsB;IACtB,uBAAuB;IACvB,EAAU,EACV,OAA+B,EAC/B,UAA8B,EAC9B,sBAA8B,EAC9B,eAAgC;QAEhC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,sBAAsB,CAAC,CAAC;QAvDxD;;;;WAIG;QACK,qBAAgB,GAA0B,6BAA6B,CAAC;QAoD/E,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QAEvC,MAAM,CACL,OAAO,CAAC,YAAY,KAAK,SAAS,EAClC,KAAK,CAAC,oDAAoD,CAC1D,CAAC;QACF,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,oBAAoB,EAAE,CAAC;QACvE;;;;WAIG;QACH,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC;QAC3D,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,YAAY,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;QAClF,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACvD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,aAAa,EAAE,EAAE;gBAC1C,mEAAmE;gBACnE,OAAO;aACP;YACD,QAAQ,IAAI,CAAC,IAAI,EAAE;gBAClB,KAAK,QAAQ;oBACZ,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,EAAE;wBAChC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;qBACrB;oBACD,MAAM;gBACP,KAAK,SAAS;oBACb,IAAI,oBAAoB,CAAC,IAAI,CAAC,KAAK,mBAAmB,EAAE;wBACvD,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;qBACtC;oBACD,MAAM;gBACP;oBACC,MAAM;aACP;QACF,CAAC,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACpE,IAAI,CAAC,aAAa,GAAG;YACpB,IAAI,qBAAqB,CACxB,IAAI,CAAC,WAAW,EAChB,gBAAgB,EAChB,OAAO,EACP,IAAI,CAAC,eAAe,CACpB;YACD,GAAG,aAAa;SAChB,CAAC;QACF,MAAM,CACL,IAAI,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,EAChF,KAAK,CAAC,+CAA+C,CACrD,CAAC;QAEF,IAAI,CAAC,YAAY,GAAG,gBAAgB,CACnC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,IAAI,EAC/C,IAAI,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,EAC1C,OAAO,CACP,CAAC;IACH,CAAC;IAED,uGAAuG;IACvG,uFAAuF;IAC7E,aAAa,CACtB,UAA4B,EAC5B,gBAAoC,EACpC,yBAAkE;QAElE,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACzC,MAAM,mBAAmB,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrD,gFAAgF;QAChF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE;YACnC,mBAAmB,CAAC,YAAY,CAC/B,CAAC,CAAC,GAAG,EACL,CAAC,CAAC,gBAAgB,CACjB,CAAC,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EACzD,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,yBAAyB,CACzB,CACD,CAAC;SACF;QAED,OAAO,CAAC,YAAY,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,cAAc,EAAE,CAAC,CAAC;QACjF,OAAO,OAAO,CAAC,cAAc,EAAE,CAAC;IACjC,CAAC;IAES,KAAK,CAAC,QAAQ,CAAC,QAAgC;QACxD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CACrE,cAAc,CAAC,IAAI,CAClB,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,cAAc,CAAC,GAAG,CAAC,EACvE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAC7C,CACD,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACK,YAAY,CAAC,MAA4B,EAAE,UAAU,GAAG,KAAK;QACpE,8DAA8D;QAC9D,MAAM,CACL,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,aAAa,EAAE,IAAI,UAAU,EACpD,KAAK,CAAC,kDAAkD,CACxD,CAAC;QAEF,iGAAiG;QACjG,yDAAyD;QACzD,yGAAyG;QACzG,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE;YACxC,MAAM,WAAW,GAAc,KAAK,CAAE,IAAI,CAAC,gBAA2B,GAAG,CAAC,CAAC,CAAC;YAC5E,IAAI,CAAC,gBAAgB,GAAG,WAAW,CAAC;YACpC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAClC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,EACzD,WAAW,EACX,IAAI,CAAC,gBAAgB,CACrB,CAAC;YACF,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,WAAW,CAAC,CAAC;SAC3D;QAED,4CAA4C;QAC5C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;YACvB,OAAO;SACP;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CACvC;YACC,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,cAAc;SAC1C,EACD;YACC,MAAM,EAAE,IAAI,CAAC,eAAe,IAAI,SAAS;SACzC,CACD,CAAC;QACF,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;IAES,WAAW,CACpB,OAAkC,EAClC,KAAc,EACd,eAAwB;QAExB,gFAAgF;QAChF,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAE7E,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAClC,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,EACxB,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAC7B,KAAK,CAAC,OAAO,CAAC,uBAAuB,CAAC,CACtC,CAAC;QAEF,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC;IACrF,CAAC;IAED;;OAEG;IACO,cAAc;QACvB,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC;IACrC,CAAC;IAES,YAAY,KAAI,CAAC;IAER,SAAS;QAC3B,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS,EAAE;YACxC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;SAClC;IACF,CAAC;IAEkB,YAAY,CAAC,OAA+B,EAAE,eAAwB;QACxF,gFAAgF;QAChF,MAAM,EACL,MAAM,EAAE,EAAE,QAAQ,EAAE,GACpB,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAES,cAAc,CAAC,OAA+B;QACvD,MAAM,CACL,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,aAAa,EAAE,EACtC,KAAK,CAAC,+DAA+D,CACrE,CAAC;QACF,gFAAgF;QAChF,MAAM,EACL,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAC5B,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;IAEe,SAAS,CAAC,MAAgB;QACzC,MAAM,OAAO,GAAsC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;QACnF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE;YACnC,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE;gBACvE,OAAO,CAAC,EAAE,MAAV,OAAO,CAAC,EAAE,IAAM,EAAE,EAAC;gBACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;oBAC3B,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBACxB;aACD;SACD;QAED,OAAO;YACN,OAAO;SACP,CAAC;IACH,CAAC;CACD;AA6DD;;GAEG;AACH,SAAS,mBAAmB,CAC3B,OAA+B,EAC/B,GAAG,YAAsB;IAEzB,MAAM,KAAK,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAE3C,OAAO;QACN,KAAK,CAAC,QAAQ,CAAC,IAAY;YAC1B,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,IAAI;YAClB,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI;YACd,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;QACxC,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tIChannelAttributes,\n\tIChannelStorageService,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions\";\nimport { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tITelemetryContext,\n\tISummaryTreeWithStats,\n\tIGarbageCollectionData,\n\tIExperimentalIncrementalSummaryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { ICodecOptions, IJsonCodec } from \"../codec/index.js\";\nimport { ChangeFamily, ChangeFamilyEditor, GraphCommit, RevisionTagCodec } from \"../core/index.js\";\nimport { brand, JsonCompatibleReadOnly } from \"../util/index.js\";\nimport { SchemaAndPolicy } from \"../feature-libraries/index.js\";\nimport { SharedTreeBranch, getChangeReplaceType } from \"./branch.js\";\nimport { EditManagerSummarizer } from \"./editManagerSummarizer.js\";\nimport { EditManager, minimumPossibleSequenceNumber } from \"./editManager.js\";\nimport { SeqNumber } from \"./editManagerFormat.js\";\nimport { DecodedMessage } from \"./messageTypes.js\";\nimport { MessageEncodingContext, makeMessageCodec } from \"./messageCodecs.js\";\n\n// TODO: How should the format version be determined?\nconst formatVersion = 0;\n// TODO: Organize this to be adjacent to persisted types.\nconst summarizablesTreeKey = \"indexes\";\n\n/**\n * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.\n *\n * TODO: actually implement\n * TODO: is history policy a detail of what indexes are used, or is there something else to it?\n */\nexport class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {\n\tprivate readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;\n\tprivate readonly summarizables: readonly Summarizable[];\n\n\t/**\n\t * The sequence number that this instance is at.\n\t * This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.\n\t * Is `undefined` after (and only after) this instance is attached.\n\t */\n\tprivate detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;\n\n\t/**\n\t * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.\n\t * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.\n\t */\n\tpublic get editor(): TEditor {\n\t\treturn this.getLocalBranch().editor;\n\t}\n\n\t/**\n\t * Used to encode/decode messages sent to/received from the Fluid runtime.\n\t *\n\t * @remarks Since there is currently only one format, this can just be cached on the class.\n\t * With more write formats active, it may make sense to keep around the \"usual\" format codec\n\t * (the one for the current persisted configuration) and resolve codecs for different versions\n\t * as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window\n\t * and an op needs to be interpreted which isn't written with the current configuration).\n\t */\n\tprivate readonly messageCodec: IJsonCodec<\n\t\tDecodedMessage<TChange>,\n\t\tunknown,\n\t\tunknown,\n\t\tMessageEncodingContext\n\t>;\n\n\tprivate readonly idCompressor: IIdCompressor;\n\n\tprivate readonly schemaAndPolicy: SchemaAndPolicy;\n\n\t/**\n\t * @param summarizables - Summarizers for all indexes used by this tree\n\t * @param changeFamily - The change family\n\t * @param editManager - The edit manager\n\t * @param id - The id of the shared object\n\t * @param runtime - The IFluidDataStoreRuntime which contains the shared object\n\t * @param attributes - Attributes of the shared object\n\t * @param telemetryContextPrefix - the context for any telemetry logs/errors emitted\n\t */\n\tpublic constructor(\n\t\tsummarizables: readonly Summarizable[],\n\t\tchangeFamily: ChangeFamily<TEditor, TChange>,\n\t\toptions: ICodecOptions,\n\t\t// Base class arguments\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t\ttelemetryContextPrefix: string,\n\t\tschemaAndPolicy: SchemaAndPolicy,\n\t) {\n\t\tsuper(id, runtime, attributes, telemetryContextPrefix);\n\n\t\tthis.schemaAndPolicy = schemaAndPolicy;\n\n\t\tassert(\n\t\t\truntime.idCompressor !== undefined,\n\t\t\t0x886 /* IdCompressor must be enabled to use SharedTree */,\n\t\t);\n\t\tthis.idCompressor = runtime.idCompressor;\n\t\tconst mintRevisionTag = () => this.idCompressor.generateCompressedId();\n\t\t/**\n\t\t * A random ID that uniquely identifies this client in the collab session.\n\t\t * This is sent alongside every op to identify which client the op originated from.\n\t\t * This is used rather than the Fluid client ID because the Fluid client ID is not stable across reconnections.\n\t\t */\n\t\tconst localSessionId = runtime.idCompressor.localSessionId;\n\t\tthis.editManager = new EditManager(changeFamily, localSessionId, mintRevisionTag);\n\t\tthis.editManager.localBranch.on(\"afterChange\", (args) => {\n\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t// Avoid submitting ops for changes that are part of a transaction.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (args.type) {\n\t\t\t\tcase \"append\":\n\t\t\t\t\tfor (const c of args.newCommits) {\n\t\t\t\t\t\tthis.submitCommit(c);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"replace\":\n\t\t\t\t\tif (getChangeReplaceType(args) === \"transactionCommit\") {\n\t\t\t\t\t\tthis.submitCommit(args.newCommits[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\tconst revisionTagCodec = new RevisionTagCodec(runtime.idCompressor);\n\t\tthis.summarizables = [\n\t\t\tnew EditManagerSummarizer(\n\t\t\t\tthis.editManager,\n\t\t\t\trevisionTagCodec,\n\t\t\t\toptions,\n\t\t\t\tthis.schemaAndPolicy,\n\t\t\t),\n\t\t\t...summarizables,\n\t\t];\n\t\tassert(\n\t\t\tnew Set(this.summarizables.map((e) => e.key)).size === this.summarizables.length,\n\t\t\t0x350 /* Index summary element keys must be unique */,\n\t\t);\n\n\t\tthis.messageCodec = makeMessageCodec(\n\t\t\tchangeFamily.codecs.resolve(formatVersion).json,\n\t\t\tnew RevisionTagCodec(runtime.idCompressor),\n\t\t\toptions,\n\t\t);\n\t}\n\n\t// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:\n\t// We might want to not subclass it, or override/reimplement most of its functionality.\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tconst summarizableBuilder = new SummaryTreeBuilder();\n\t\t// Merge the summaries of all summarizables together under a single ISummaryTree\n\t\tfor (const s of this.summarizables) {\n\t\t\tsummarizableBuilder.addWithStats(\n\t\t\t\ts.key,\n\t\t\t\ts.getAttachSummary(\n\t\t\t\t\t(contents) => serializer.stringify(contents, this.handle),\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttelemetryContext,\n\t\t\t\t\tincrementalSummaryContext,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tbuilder.addWithStats(summarizablesTreeKey, summarizableBuilder.getSummaryTree());\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tprotected async loadCore(services: IChannelStorageService): Promise<void> {\n\t\tconst loadSummaries = this.summarizables.map(async (summaryElement) =>\n\t\t\tsummaryElement.load(\n\t\t\t\tscopeStorageService(services, summarizablesTreeKey, summaryElement.key),\n\t\t\t\t(contents) => this.serializer.parse(contents),\n\t\t\t),\n\t\t);\n\n\t\tawait Promise.all(loadSummaries);\n\t}\n\n\t/**\n\t * Submits an op to the Fluid runtime containing the given commit\n\t * @param commit - the commit to submit\n\t */\n\tprivate submitCommit(commit: GraphCommit<TChange>, isResubmit = false): void {\n\t\t// Edits should not be submitted until all transactions finish\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting() || isResubmit,\n\t\t\t0x68b /* Unexpected edit submitted during transaction */,\n\t\t);\n\n\t\t// Edits submitted before the first attach are treated as sequenced because they will be included\n\t\t// in the attach summary that is uploaded to the service.\n\t\t// Until this attach workflow happens, this instance essentially behaves as a centralized data structure.\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tconst newRevision: SeqNumber = brand((this.detachedRevision as number) + 1);\n\t\t\tthis.detachedRevision = newRevision;\n\t\t\tthis.editManager.addSequencedChange(\n\t\t\t\t{ ...commit, sessionId: this.editManager.localSessionId },\n\t\t\t\tnewRevision,\n\t\t\t\tthis.detachedRevision,\n\t\t\t);\n\t\t\tthis.editManager.advanceMinimumSequenceNumber(newRevision);\n\t\t}\n\n\t\t// Don't submit the op if it is not attached\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst message = this.messageCodec.encode(\n\t\t\t{\n\t\t\t\tcommit,\n\t\t\t\tsessionId: this.editManager.localSessionId,\n\t\t\t},\n\t\t\t{\n\t\t\t\tschema: this.schemaAndPolicy ?? undefined,\n\t\t\t},\n\t\t);\n\t\tthis.submitLocalMessage(message);\n\t}\n\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t) {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst { commit, sessionId } = this.messageCodec.decode(message.contents, {});\n\n\t\tthis.editManager.addSequencedChange(\n\t\t\t{ ...commit, sessionId },\n\t\t\tbrand(message.sequenceNumber),\n\t\t\tbrand(message.referenceSequenceNumber),\n\t\t);\n\n\t\tthis.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));\n\t}\n\n\t/**\n\t * @returns the head commit of the root local branch\n\t */\n\tprotected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {\n\t\treturn this.editManager.localBranch;\n\t}\n\n\tprotected onDisconnect() {}\n\n\tprotected override didAttach(): void {\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tthis.detachedRevision = undefined;\n\t\t}\n\t}\n\n\tprotected override reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown) {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tconst [commit] = this.editManager.findLocalCommit(revision);\n\t\tthis.submitCommit(commit, true);\n\t}\n\n\tprotected applyStashedOp(content: JsonCompatibleReadOnly): void {\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting(),\n\t\t\t0x674 /* Unexpected transaction is open while applying stashed ops */,\n\t\t);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision, change },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tthis.editManager.localBranch.apply(change, revision);\n\t}\n\n\tpublic override getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\tconst gcNodes: IGarbageCollectionData[\"gcNodes\"] = super.getGCData(fullGC).gcNodes;\n\t\tfor (const s of this.summarizables) {\n\t\t\tfor (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {\n\t\t\t\tgcNodes[id] ??= [];\n\t\t\t\tfor (const route of routes) {\n\t\t\t\t\tgcNodes[id].push(route);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tgcNodes,\n\t\t};\n\t}\n}\n\n/**\n * Specifies the behavior of a component that puts data in a summary.\n */\nexport interface Summarizable {\n\t/**\n\t * Field name in summary json under which this element stores its data.\n\t */\n\treadonly key: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tgetAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).summarize}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tsummarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats>;\n\n\t/**\n\t * {@inheritDoc (ISharedObject:interface).getGCData}\n\t */\n\t// TODO: Change this interface (and the one in ISharedObject, if necessary) to support \"handles within handles\".\n\t// Consider the case of a document with history; the return value here currently grows unboundedly.\n\tgetGCData(fullGC?: boolean): IGarbageCollectionData;\n\n\t/**\n\t * Allows the component to perform custom loading. The storage service is scoped to this component and therefore\n\t * paths in this component will not collide with those in other components, even if they are the same string.\n\t * @param service - Storage used by the component\n\t * @param parse - Parses serialized data from storage into runtime objects for the component\n\t */\n\tload(service: IChannelStorageService, parse: SummaryElementParser): Promise<void>;\n}\n\n/**\n * Serializes the given contents into a string acceptable for storing in summaries, i.e. all\n * Fluid handles have been replaced appropriately by an IFluidSerializer\n */\nexport type SummaryElementStringifier = (contents: unknown) => string;\n\n/**\n * Parses a serialized/summarized string into an object, rehydrating any Fluid handles as necessary\n */\nexport type SummaryElementParser = (contents: string) => unknown;\n\n/**\n * Compose an {@link IChannelStorageService} which prefixes all paths before forwarding them to the original service\n */\nfunction scopeStorageService(\n\tservice: IChannelStorageService,\n\t...pathElements: string[]\n): IChannelStorageService {\n\tconst scope = `${pathElements.join(\"/\")}/`;\n\n\treturn {\n\t\tasync readBlob(path: string): Promise<ArrayBufferLike> {\n\t\t\treturn service.readBlob(`${scope}${path}`);\n\t\t},\n\t\tasync contains(path) {\n\t\t\treturn service.contains(`${scope}${path}`);\n\t\t},\n\t\tasync list(path) {\n\t\t\treturn service.list(`${scope}${path}`);\n\t\t},\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sharedTreeCore.js","sourceRoot":"","sources":["../../src/shared-tree-core/sharedTreeCore.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils\";\nimport {\n\tIChannelAttributes,\n\tIChannelStorageService,\n\tIFluidDataStoreRuntime,\n} from \"@fluidframework/datastore-definitions\";\nimport { IIdCompressor } from \"@fluidframework/id-compressor\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport {\n\tITelemetryContext,\n\tISummaryTreeWithStats,\n\tIGarbageCollectionData,\n\tIExperimentalIncrementalSummaryContext,\n} from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { IFluidSerializer, SharedObject } from \"@fluidframework/shared-object-base\";\nimport { ICodecOptions, IJsonCodec } from \"../codec/index.js\";\nimport { ChangeFamily, ChangeFamilyEditor, GraphCommit, RevisionTagCodec } from \"../core/index.js\";\nimport { brand, JsonCompatibleReadOnly } from \"../util/index.js\";\nimport { SchemaAndPolicy } from \"../feature-libraries/index.js\";\nimport { SharedTreeBranch, getChangeReplaceType } from \"./branch.js\";\nimport { EditManagerSummarizer } from \"./editManagerSummarizer.js\";\nimport { EditManager, minimumPossibleSequenceNumber } from \"./editManager.js\";\nimport { SeqNumber } from \"./editManagerFormat.js\";\nimport { DecodedMessage } from \"./messageTypes.js\";\nimport { MessageEncodingContext, makeMessageCodec } from \"./messageCodecs.js\";\n\n// TODO: How should the format version be determined?\nconst formatVersion = 0;\n// TODO: Organize this to be adjacent to persisted types.\nconst summarizablesTreeKey = \"indexes\";\n\n/**\n * Generic shared tree, which needs to be configured with indexes, field kinds and a history policy to be used.\n *\n * TODO: actually implement\n * TODO: is history policy a detail of what indexes are used, or is there something else to it?\n */\nexport class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends SharedObject {\n\tprivate readonly editManager: EditManager<TEditor, TChange, ChangeFamily<TEditor, TChange>>;\n\tprivate readonly summarizables: readonly Summarizable[];\n\n\t/**\n\t * The sequence number that this instance is at.\n\t * This number is artificial in that it is made up by this instance as opposed to being provided by the runtime.\n\t * Is `undefined` after (and only after) this instance is attached.\n\t */\n\tprivate detachedRevision: SeqNumber | undefined = minimumPossibleSequenceNumber;\n\n\t/**\n\t * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.\n\t * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.\n\t */\n\tpublic get editor(): TEditor {\n\t\treturn this.getLocalBranch().editor;\n\t}\n\n\t/**\n\t * Used to encode/decode messages sent to/received from the Fluid runtime.\n\t *\n\t * @remarks Since there is currently only one format, this can just be cached on the class.\n\t * With more write formats active, it may make sense to keep around the \"usual\" format codec\n\t * (the one for the current persisted configuration) and resolve codecs for different versions\n\t * as necessary (e.g. an upgrade op came in, or the configuration changed within the collab window\n\t * and an op needs to be interpreted which isn't written with the current configuration).\n\t */\n\tprivate readonly messageCodec: IJsonCodec<\n\t\tDecodedMessage<TChange>,\n\t\tunknown,\n\t\tunknown,\n\t\tMessageEncodingContext\n\t>;\n\n\tprivate readonly idCompressor: IIdCompressor;\n\n\tprivate readonly schemaAndPolicy: SchemaAndPolicy;\n\n\t/**\n\t * @param summarizables - Summarizers for all indexes used by this tree\n\t * @param changeFamily - The change family\n\t * @param editManager - The edit manager\n\t * @param id - The id of the shared object\n\t * @param runtime - The IFluidDataStoreRuntime which contains the shared object\n\t * @param attributes - Attributes of the shared object\n\t * @param telemetryContextPrefix - the context for any telemetry logs/errors emitted\n\t */\n\tpublic constructor(\n\t\tsummarizables: readonly Summarizable[],\n\t\tchangeFamily: ChangeFamily<TEditor, TChange>,\n\t\toptions: ICodecOptions,\n\t\t// Base class arguments\n\t\tid: string,\n\t\truntime: IFluidDataStoreRuntime,\n\t\tattributes: IChannelAttributes,\n\t\ttelemetryContextPrefix: string,\n\t\tschemaAndPolicy: SchemaAndPolicy,\n\t) {\n\t\tsuper(id, runtime, attributes, telemetryContextPrefix);\n\n\t\tthis.schemaAndPolicy = schemaAndPolicy;\n\n\t\tassert(\n\t\t\truntime.idCompressor !== undefined,\n\t\t\t0x886 /* IdCompressor must be enabled to use SharedTree */,\n\t\t);\n\t\tthis.idCompressor = runtime.idCompressor;\n\t\tconst mintRevisionTag = () => this.idCompressor.generateCompressedId();\n\t\t/**\n\t\t * A random ID that uniquely identifies this client in the collab session.\n\t\t * This is sent alongside every op to identify which client the op originated from.\n\t\t * This is used rather than the Fluid client ID because the Fluid client ID is not stable across reconnections.\n\t\t */\n\t\tconst localSessionId = runtime.idCompressor.localSessionId;\n\t\tthis.editManager = new EditManager(changeFamily, localSessionId, mintRevisionTag);\n\t\tthis.editManager.localBranch.on(\"afterChange\", (args) => {\n\t\t\tif (this.getLocalBranch().isTransacting()) {\n\t\t\t\t// Avoid submitting ops for changes that are part of a transaction.\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tswitch (args.type) {\n\t\t\t\tcase \"append\":\n\t\t\t\t\tfor (const c of args.newCommits) {\n\t\t\t\t\t\tthis.submitCommit(c);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"replace\":\n\t\t\t\t\tif (getChangeReplaceType(args) === \"transactionCommit\") {\n\t\t\t\t\t\tthis.submitCommit(args.newCommits[0]);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t});\n\n\t\tconst revisionTagCodec = new RevisionTagCodec(runtime.idCompressor);\n\t\tthis.summarizables = [\n\t\t\tnew EditManagerSummarizer(\n\t\t\t\tthis.editManager,\n\t\t\t\trevisionTagCodec,\n\t\t\t\toptions,\n\t\t\t\tthis.schemaAndPolicy,\n\t\t\t),\n\t\t\t...summarizables,\n\t\t];\n\t\tassert(\n\t\t\tnew Set(this.summarizables.map((e) => e.key)).size === this.summarizables.length,\n\t\t\t0x350 /* Index summary element keys must be unique */,\n\t\t);\n\n\t\tthis.messageCodec = makeMessageCodec(\n\t\t\tchangeFamily.codecs.resolve(formatVersion).json,\n\t\t\tnew RevisionTagCodec(runtime.idCompressor),\n\t\t\toptions,\n\t\t);\n\t}\n\n\t// TODO: SharedObject's merging of the two summary methods into summarizeCore is not what we want here:\n\t// We might want to not subclass it, or override/reimplement most of its functionality.\n\tprotected summarizeCore(\n\t\tserializer: IFluidSerializer,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats {\n\t\tconst builder = new SummaryTreeBuilder();\n\t\tconst summarizableBuilder = new SummaryTreeBuilder();\n\t\t// Merge the summaries of all summarizables together under a single ISummaryTree\n\t\tfor (const s of this.summarizables) {\n\t\t\tsummarizableBuilder.addWithStats(\n\t\t\t\ts.key,\n\t\t\t\ts.getAttachSummary(\n\t\t\t\t\t(contents) => serializer.stringify(contents, this.handle),\n\t\t\t\t\tundefined,\n\t\t\t\t\tundefined,\n\t\t\t\t\ttelemetryContext,\n\t\t\t\t\tincrementalSummaryContext,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tbuilder.addWithStats(summarizablesTreeKey, summarizableBuilder.getSummaryTree());\n\t\treturn builder.getSummaryTree();\n\t}\n\n\tprotected async loadCore(services: IChannelStorageService): Promise<void> {\n\t\tconst loadSummaries = this.summarizables.map(async (summaryElement) =>\n\t\t\tsummaryElement.load(\n\t\t\t\tscopeStorageService(services, summarizablesTreeKey, summaryElement.key),\n\t\t\t\t(contents) => this.serializer.parse(contents),\n\t\t\t),\n\t\t);\n\n\t\tawait Promise.all(loadSummaries);\n\t}\n\n\t/**\n\t * Submits an op to the Fluid runtime containing the given commit\n\t * @param commit - the commit to submit\n\t */\n\tprivate submitCommit(commit: GraphCommit<TChange>, isResubmit = false): void {\n\t\t// Edits should not be submitted until all transactions finish\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting() || isResubmit,\n\t\t\t0x68b /* Unexpected edit submitted during transaction */,\n\t\t);\n\n\t\t// Edits submitted before the first attach are treated as sequenced because they will be included\n\t\t// in the attach summary that is uploaded to the service.\n\t\t// Until this attach workflow happens, this instance essentially behaves as a centralized data structure.\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tconst newRevision: SeqNumber = brand((this.detachedRevision as number) + 1);\n\t\t\tthis.detachedRevision = newRevision;\n\t\t\tthis.editManager.addSequencedChange(\n\t\t\t\t{ ...commit, sessionId: this.editManager.localSessionId },\n\t\t\t\tnewRevision,\n\t\t\t\tthis.detachedRevision,\n\t\t\t);\n\t\t\tthis.editManager.advanceMinimumSequenceNumber(newRevision);\n\t\t}\n\n\t\t// Don't submit the op if it is not attached\n\t\tif (!this.isAttached()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst message = this.messageCodec.encode(\n\t\t\t{\n\t\t\t\tcommit,\n\t\t\t\tsessionId: this.editManager.localSessionId,\n\t\t\t},\n\t\t\t{\n\t\t\t\tschema: this.schemaAndPolicy ?? undefined,\n\t\t\t},\n\t\t);\n\t\tthis.submitLocalMessage(this.serializer.encode(message, this.handle));\n\t}\n\n\tprotected processCore(\n\t\tmessage: ISequencedDocumentMessage,\n\t\tlocal: boolean,\n\t\tlocalOpMetadata: unknown,\n\t) {\n\t\tconst contents: unknown = this.serializer.decode(message.contents);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst { commit, sessionId } = this.messageCodec.decode(contents, {});\n\t\tthis.editManager.addSequencedChange(\n\t\t\t{ ...commit, sessionId },\n\t\t\tbrand(message.sequenceNumber),\n\t\t\tbrand(message.referenceSequenceNumber),\n\t\t);\n\n\t\tthis.editManager.advanceMinimumSequenceNumber(brand(message.minimumSequenceNumber));\n\t}\n\n\t/**\n\t * @returns the head commit of the root local branch\n\t */\n\tprotected getLocalBranch(): SharedTreeBranch<TEditor, TChange> {\n\t\treturn this.editManager.localBranch;\n\t}\n\n\tprotected onDisconnect() {}\n\n\tprotected override didAttach(): void {\n\t\tif (this.detachedRevision !== undefined) {\n\t\t\tthis.detachedRevision = undefined;\n\t\t}\n\t}\n\n\tprotected override reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown) {\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tconst [commit] = this.editManager.findLocalCommit(revision);\n\t\tthis.submitCommit(commit, true);\n\t}\n\n\tprotected applyStashedOp(content: JsonCompatibleReadOnly): void {\n\t\tassert(\n\t\t\t!this.getLocalBranch().isTransacting(),\n\t\t\t0x674 /* Unexpected transaction is open while applying stashed ops */,\n\t\t);\n\t\t// Empty context object is passed in, as our decode function is schema-agnostic.\n\t\tconst {\n\t\t\tcommit: { revision, change },\n\t\t} = this.messageCodec.decode(content, {});\n\t\tthis.editManager.localBranch.apply(change, revision);\n\t}\n\n\tpublic override getGCData(fullGC?: boolean): IGarbageCollectionData {\n\t\tconst gcNodes: IGarbageCollectionData[\"gcNodes\"] = super.getGCData(fullGC).gcNodes;\n\t\tfor (const s of this.summarizables) {\n\t\t\tfor (const [id, routes] of Object.entries(s.getGCData(fullGC).gcNodes)) {\n\t\t\t\tgcNodes[id] ??= [];\n\t\t\t\tfor (const route of routes) {\n\t\t\t\t\tgcNodes[id].push(route);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tgcNodes,\n\t\t};\n\t}\n}\n\n/**\n * Specifies the behavior of a component that puts data in a summary.\n */\nexport interface Summarizable {\n\t/**\n\t * Field name in summary json under which this element stores its data.\n\t */\n\treadonly key: string;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).getAttachSummary}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tgetAttachSummary(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t\tincrementalSummaryContext?: IExperimentalIncrementalSummaryContext,\n\t): ISummaryTreeWithStats;\n\n\t/**\n\t * {@inheritDoc @fluidframework/datastore-definitions#(IChannel:interface).summarize}\n\t * @param stringify - Serializes the contents of the component (including {@link (IFluidHandle:interface)}s) for storage.\n\t */\n\tsummarize(\n\t\tstringify: SummaryElementStringifier,\n\t\tfullTree?: boolean,\n\t\ttrackState?: boolean,\n\t\ttelemetryContext?: ITelemetryContext,\n\t): Promise<ISummaryTreeWithStats>;\n\n\t/**\n\t * {@inheritDoc (ISharedObject:interface).getGCData}\n\t */\n\t// TODO: Change this interface (and the one in ISharedObject, if necessary) to support \"handles within handles\".\n\t// Consider the case of a document with history; the return value here currently grows unboundedly.\n\tgetGCData(fullGC?: boolean): IGarbageCollectionData;\n\n\t/**\n\t * Allows the component to perform custom loading. The storage service is scoped to this component and therefore\n\t * paths in this component will not collide with those in other components, even if they are the same string.\n\t * @param service - Storage used by the component\n\t * @param parse - Parses serialized data from storage into runtime objects for the component\n\t */\n\tload(service: IChannelStorageService, parse: SummaryElementParser): Promise<void>;\n}\n\n/**\n * Serializes the given contents into a string acceptable for storing in summaries, i.e. all\n * Fluid handles have been replaced appropriately by an IFluidSerializer\n */\nexport type SummaryElementStringifier = (contents: unknown) => string;\n\n/**\n * Parses a serialized/summarized string into an object, rehydrating any Fluid handles as necessary\n */\nexport type SummaryElementParser = (contents: string) => unknown;\n\n/**\n * Compose an {@link IChannelStorageService} which prefixes all paths before forwarding them to the original service\n */\nfunction scopeStorageService(\n\tservice: IChannelStorageService,\n\t...pathElements: string[]\n): IChannelStorageService {\n\tconst scope = `${pathElements.join(\"/\")}/`;\n\n\treturn {\n\t\tasync readBlob(path: string): Promise<ArrayBufferLike> {\n\t\t\treturn service.readBlob(`${scope}${path}`);\n\t\t},\n\t\tasync contains(path) {\n\t\t\treturn service.contains(`${scope}${path}`);\n\t\t},\n\t\tasync list(path) {\n\t\t\treturn service.list(`${scope}${path}`);\n\t\t},\n\t};\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/tree",
|
|
3
|
-
"version": "2.0.0-rc.2.0.
|
|
3
|
+
"version": "2.0.0-rc.2.0.7",
|
|
4
4
|
"description": "Distributed tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -57,17 +57,17 @@
|
|
|
57
57
|
"temp-directory": "nyc/.nyc_output"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.
|
|
61
|
-
"@fluidframework/container-runtime": ">=2.0.0-rc.2.0.
|
|
62
|
-
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.
|
|
63
|
-
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.
|
|
64
|
-
"@fluidframework/datastore-definitions": ">=2.0.0-rc.2.0.
|
|
65
|
-
"@fluidframework/id-compressor": ">=2.0.0-rc.2.0.
|
|
60
|
+
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
61
|
+
"@fluidframework/container-runtime": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
62
|
+
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
63
|
+
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
64
|
+
"@fluidframework/datastore-definitions": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
65
|
+
"@fluidframework/id-compressor": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
66
66
|
"@fluidframework/protocol-definitions": "^3.2.0",
|
|
67
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.
|
|
68
|
-
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.
|
|
69
|
-
"@fluidframework/shared-object-base": ">=2.0.0-rc.2.0.
|
|
70
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.
|
|
67
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
68
|
+
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
69
|
+
"@fluidframework/shared-object-base": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
70
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
71
71
|
"@sinclair/typebox": "^0.29.4",
|
|
72
72
|
"@tylerbu/sorted-btree-es6": "^1.8.0",
|
|
73
73
|
"@ungap/structured-clone": "^1.2.0",
|
|
@@ -75,19 +75,19 @@
|
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@arethetypeswrong/cli": "^0.13.3",
|
|
78
|
-
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.
|
|
79
|
-
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.
|
|
80
|
-
"@fluid-private/test-dds-utils": ">=2.0.0-rc.2.0.
|
|
81
|
-
"@fluid-private/test-drivers": ">=2.0.0-rc.2.0.
|
|
78
|
+
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
79
|
+
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
80
|
+
"@fluid-private/test-dds-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
81
|
+
"@fluid-private/test-drivers": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
82
82
|
"@fluid-tools/benchmark": "^0.48.0",
|
|
83
83
|
"@fluid-tools/build-cli": "^0.34.0",
|
|
84
84
|
"@fluidframework/build-common": "^2.0.3",
|
|
85
85
|
"@fluidframework/build-tools": "^0.34.0",
|
|
86
|
-
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.
|
|
87
|
-
"@fluidframework/container-loader": ">=2.0.0-rc.2.0.
|
|
86
|
+
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
87
|
+
"@fluidframework/container-loader": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
88
88
|
"@fluidframework/eslint-config-fluid": "^4.0.0",
|
|
89
|
-
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.
|
|
90
|
-
"@fluidframework/test-utils": ">=2.0.0-rc.2.0.
|
|
89
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
90
|
+
"@fluidframework/test-utils": ">=2.0.0-rc.2.0.7 <2.0.0-rc.2.1.0",
|
|
91
91
|
"@microsoft/api-extractor": "^7.42.3",
|
|
92
92
|
"@types/diff": "^3.5.1",
|
|
93
93
|
"@types/easy-table": "^0.0.32",
|
package/src/packageVersion.ts
CHANGED
|
@@ -237,7 +237,7 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends
|
|
|
237
237
|
schema: this.schemaAndPolicy ?? undefined,
|
|
238
238
|
},
|
|
239
239
|
);
|
|
240
|
-
this.submitLocalMessage(message);
|
|
240
|
+
this.submitLocalMessage(this.serializer.encode(message, this.handle));
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
protected processCore(
|
|
@@ -245,9 +245,9 @@ export class SharedTreeCore<TEditor extends ChangeFamilyEditor, TChange> extends
|
|
|
245
245
|
local: boolean,
|
|
246
246
|
localOpMetadata: unknown,
|
|
247
247
|
) {
|
|
248
|
+
const contents: unknown = this.serializer.decode(message.contents);
|
|
248
249
|
// Empty context object is passed in, as our decode function is schema-agnostic.
|
|
249
|
-
const { commit, sessionId } = this.messageCodec.decode(
|
|
250
|
-
|
|
250
|
+
const { commit, sessionId } = this.messageCodec.decode(contents, {});
|
|
251
251
|
this.editManager.addSequencedChange(
|
|
252
252
|
{ ...commit, sessionId },
|
|
253
253
|
brand(message.sequenceNumber),
|