@fluidframework/tree 2.103.0 → 2.110.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/api-report/tree.alpha.api.md +12 -3
- package/api-report/tree.beta.api.md +11 -3
- package/api-report/tree.legacy.beta.api.md +11 -3
- package/dist/codec/versioned/format.js +2 -24
- package/dist/codec/versioned/format.js.map +1 -1
- package/dist/core/rebase/types.js +2 -24
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/schema-stored/formatV1.js +2 -24
- package/dist/core/schema-stored/formatV1.js.map +1 -1
- package/dist/core/schema-stored/formatV2.js +2 -24
- package/dist/core/schema-stored/formatV2.js.map +1 -1
- package/dist/core/schema-stored/index.js +3 -25
- package/dist/core/schema-stored/index.js.map +1 -1
- package/dist/core/tree/anchorSet.js +4 -8
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatCommon.js +2 -24
- package/dist/core/tree/detachedFieldIndexFormatCommon.js.map +1 -1
- package/dist/core/tree/detachedFieldIndexFormatV2.js +2 -24
- package/dist/core/tree/detachedFieldIndexFormatV2.js.map +1 -1
- package/dist/core/tree/persistedTreeTextFormat.js +2 -24
- package/dist/core/tree/persistedTreeTextFormat.js.map +1 -1
- package/dist/entrypoints/internal.js +2 -15
- package/dist/entrypoints/internal.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +7 -11
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatGeneric.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatV1.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatV2.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js +2 -24
- package/dist/feature-libraries/chunked-forest/codec/format/formatVText.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyEntity.js +9 -19
- package/dist/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +3 -13
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/forest-summary/formatCommon.js +2 -24
- package/dist/feature-libraries/forest-summary/formatCommon.js.map +1 -1
- package/dist/feature-libraries/index.js +2 -24
- package/dist/feature-libraries/index.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js +2 -24
- package/dist/feature-libraries/modular-schema/genericFieldKindFormat.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +10 -30
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js +2 -24
- package/dist/feature-libraries/modular-schema/modularChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js +2 -24
- package/dist/feature-libraries/modular-schema/modularChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +0 -5
- package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +11 -55
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js +2 -24
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV1.js.map +1 -1
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js +2 -24
- package/dist/feature-libraries/optional-field/optionalFieldChangeFormatV2.js.map +1 -1
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.js +2 -24
- package/dist/feature-libraries/schema-edits/schemaChangeFormat.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV1.js +2 -24
- package/dist/feature-libraries/schema-index/formatV1.js.map +1 -1
- package/dist/feature-libraries/schema-index/formatV2.js +2 -24
- package/dist/feature-libraries/schema-index/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV1.js +2 -24
- package/dist/feature-libraries/sequence-field/formatV1.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV2.js +2 -24
- package/dist/feature-libraries/sequence-field/formatV2.js.map +1 -1
- package/dist/feature-libraries/sequence-field/formatV3.js +2 -24
- package/dist/feature-libraries/sequence-field/formatV3.js.map +1 -1
- package/dist/index.js +2 -24
- package/dist/index.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/shared-tree/schematizingTreeView.d.ts +1 -0
- package/dist/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/dist/shared-tree/schematizingTreeView.js +7 -41
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/sharedTree.d.ts +0 -1
- package/dist/shared-tree/sharedTree.d.ts.map +1 -1
- package/dist/shared-tree/sharedTree.js +6 -45
- package/dist/shared-tree/sharedTree.js.map +1 -1
- package/dist/shared-tree/sharedTreeChangeFormat.js +2 -24
- package/dist/shared-tree/sharedTreeChangeFormat.js.map +1 -1
- package/dist/shared-tree/treeCheckout.d.ts +12 -3
- package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
- package/dist/shared-tree/treeCheckout.js +106 -136
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.js +13 -17
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatCommons.js +2 -24
- package/dist/shared-tree-core/editManagerFormatCommons.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatV1toV4.js +2 -24
- package/dist/shared-tree-core/editManagerFormatV1toV4.js.map +1 -1
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js +2 -24
- package/dist/shared-tree-core/editManagerFormatVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageCodecVSharedBranches.js +2 -24
- package/dist/shared-tree-core/messageCodecVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/messageFormatV1ToV4.js +2 -24
- package/dist/shared-tree-core/messageFormatV1ToV4.js.map +1 -1
- package/dist/shared-tree-core/messageFormatVSharedBranches.js +2 -24
- package/dist/shared-tree-core/messageFormatVSharedBranches.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +6 -43
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/shared-tree-core/transaction.js +20 -30
- package/dist/shared-tree-core/transaction.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaCodec.js +2 -24
- package/dist/simple-tree/api/simpleSchemaCodec.js.map +1 -1
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js +2 -24
- package/dist/simple-tree/api/snapshotCompatibilityChecker.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +10 -0
- package/dist/simple-tree/api/tree.d.ts.map +1 -1
- package/dist/simple-tree/api/tree.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +83 -93
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/core/unhydratedFlexTree.js +6 -10
- package/dist/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/dist/simple-tree/leafNodeSchema.js +2 -12
- package/dist/simple-tree/leafNodeSchema.js.map +1 -1
- package/dist/simple-tree/node-kinds/array/arrayNode.js +2 -6
- package/dist/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/dist/simple-tree/simpleSchemaFormatV1.js +2 -24
- package/dist/simple-tree/simpleSchemaFormatV1.js.map +1 -1
- package/dist/tableSchema.d.ts +50 -4
- package/dist/tableSchema.d.ts.map +1 -1
- package/dist/tableSchema.js +202 -106
- package/dist/tableSchema.js.map +1 -1
- package/dist/util/arrayUtilities.d.ts +20 -0
- package/dist/util/arrayUtilities.d.ts.map +1 -1
- package/dist/util/arrayUtilities.js +24 -1
- package/dist/util/arrayUtilities.js.map +1 -1
- package/dist/util/index.d.ts +1 -1
- package/dist/util/index.d.ts.map +1 -1
- package/dist/util/index.js +3 -2
- package/dist/util/index.js.map +1 -1
- package/dist/util/rangeMap.d.ts +13 -0
- package/dist/util/rangeMap.d.ts.map +1 -1
- package/dist/util/rangeMap.js +69 -8
- package/dist/util/rangeMap.js.map +1 -1
- package/dist/util/typeboxBrand.js +2 -24
- package/dist/util/typeboxBrand.js.map +1 -1
- package/dist/util/utils.js +2 -24
- package/dist/util/utils.js.map +1 -1
- package/eslint.config.mts +0 -30
- package/lib/core/tree/anchorSet.js +1 -5
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +1 -5
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyEntity.js +1 -11
- package/lib/feature-libraries/flex-tree/lazyEntity.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +1 -11
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +10 -30
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +0 -5
- package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +1 -45
- package/lib/feature-libraries/object-forest/objectForest.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/schematizingTreeView.d.ts +1 -0
- package/lib/shared-tree/schematizingTreeView.d.ts.map +1 -1
- package/lib/shared-tree/schematizingTreeView.js +4 -38
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/sharedTree.d.ts +0 -1
- package/lib/shared-tree/sharedTree.d.ts.map +1 -1
- package/lib/shared-tree/sharedTree.js +1 -40
- package/lib/shared-tree/sharedTree.js.map +1 -1
- package/lib/shared-tree/treeCheckout.d.ts +12 -3
- package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
- package/lib/shared-tree/treeCheckout.js +62 -92
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.js +1 -5
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +1 -38
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/shared-tree-core/transaction.js +1 -11
- package/lib/shared-tree-core/transaction.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +10 -0
- package/lib/simple-tree/api/tree.d.ts.map +1 -1
- package/lib/simple-tree/api/tree.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +1 -11
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/core/unhydratedFlexTree.js +1 -5
- package/lib/simple-tree/core/unhydratedFlexTree.js.map +1 -1
- package/lib/simple-tree/leafNodeSchema.js +1 -11
- package/lib/simple-tree/leafNodeSchema.js.map +1 -1
- package/lib/simple-tree/node-kinds/array/arrayNode.js +1 -5
- package/lib/simple-tree/node-kinds/array/arrayNode.js.map +1 -1
- package/lib/tableSchema.d.ts +50 -4
- package/lib/tableSchema.d.ts.map +1 -1
- package/lib/tableSchema.js +171 -75
- package/lib/tableSchema.js.map +1 -1
- package/lib/util/arrayUtilities.d.ts +20 -0
- package/lib/util/arrayUtilities.d.ts.map +1 -1
- package/lib/util/arrayUtilities.js +22 -0
- package/lib/util/arrayUtilities.js.map +1 -1
- package/lib/util/index.d.ts +1 -1
- package/lib/util/index.d.ts.map +1 -1
- package/lib/util/index.js +1 -1
- package/lib/util/index.js.map +1 -1
- package/lib/util/rangeMap.d.ts +13 -0
- package/lib/util/rangeMap.d.ts.map +1 -1
- package/lib/util/rangeMap.js +69 -8
- package/lib/util/rangeMap.js.map +1 -1
- package/package.json +24 -23
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +14 -47
- package/src/feature-libraries/modular-schema/modularChangeTypes.ts +0 -5
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +4 -0
- package/src/shared-tree/sharedTree.ts +2 -6
- package/src/shared-tree/treeCheckout.ts +59 -51
- package/src/simple-tree/api/tree.ts +11 -0
- package/src/tableSchema.ts +306 -80
- package/src/util/arrayUtilities.ts +35 -0
- package/src/util/index.ts +2 -0
- package/src/util/rangeMap.ts +108 -9
- package/tsconfig.json +5 -0
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
IFluidSerializer,
|
|
14
14
|
SharedKernel,
|
|
15
15
|
} from "@fluidframework/shared-object-base/internal";
|
|
16
|
-
import {
|
|
16
|
+
import { type TelemetryLoggerExt, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
19
|
type CodecTree,
|
|
@@ -317,7 +317,6 @@ export class SharedTreeKernel
|
|
|
317
317
|
chunkCompressionStrategy: options.treeEncodeType,
|
|
318
318
|
logger,
|
|
319
319
|
breaker: this.breaker,
|
|
320
|
-
disposeForksAfterTransaction: options.disposeForksAfterTransaction,
|
|
321
320
|
});
|
|
322
321
|
|
|
323
322
|
this.registerSharedBranchForEditing("main", this.checkout);
|
|
@@ -632,9 +631,7 @@ export interface SharedTreeOptions
|
|
|
632
631
|
|
|
633
632
|
export interface SharedTreeOptionsInternal
|
|
634
633
|
extends SharedTreeOptions,
|
|
635
|
-
Partial<SharedTreeCoreOptionsInternal> {
|
|
636
|
-
disposeForksAfterTransaction?: boolean;
|
|
637
|
-
}
|
|
634
|
+
Partial<SharedTreeCoreOptionsInternal> {}
|
|
638
635
|
|
|
639
636
|
/**
|
|
640
637
|
* Configuration options for SharedTree's internal tree storage.
|
|
@@ -757,7 +754,6 @@ export const defaultSharedTreeOptions: Required<SharedTreeOptionsInternal> = {
|
|
|
757
754
|
minVersionForCollab: FluidClientVersion.v2_0,
|
|
758
755
|
forest: ForestTypeReference,
|
|
759
756
|
treeEncodeType: TreeCompressionStrategy.Compressed,
|
|
760
|
-
disposeForksAfterTransaction: true,
|
|
761
757
|
shouldEncodeIncrementally: defaultIncrementalEncodingPolicy,
|
|
762
758
|
enableSharedBranches: false,
|
|
763
759
|
healUnresolvableIdentifiersOnDecode: false,
|
|
@@ -8,7 +8,7 @@ import type { IFluidHandle, Listenable } from "@fluidframework/core-interfaces/i
|
|
|
8
8
|
import { assert, unreachableCase, fail } from "@fluidframework/core-utils/internal";
|
|
9
9
|
import type { IIdCompressor, SessionId } from "@fluidframework/id-compressor";
|
|
10
10
|
import { isStableId } from "@fluidframework/id-compressor/internal";
|
|
11
|
-
import {
|
|
11
|
+
import { type TelemetryLoggerExt, UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
14
|
FluidClientVersion,
|
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
makeAnonChange,
|
|
58
58
|
type TaggedChange,
|
|
59
59
|
deltaFieldMapHasVisibleChanges,
|
|
60
|
+
findCommonAncestor,
|
|
60
61
|
} from "../core/index.js";
|
|
61
62
|
import {
|
|
62
63
|
type FieldBatchCodec,
|
|
@@ -74,7 +75,6 @@ import {
|
|
|
74
75
|
SquashingTransactionStack,
|
|
75
76
|
SharedTreeBranch,
|
|
76
77
|
TransactionResult as InternalTransactionResult,
|
|
77
|
-
onForkTransitive,
|
|
78
78
|
type SharedTreeBranchChange,
|
|
79
79
|
type Transactor,
|
|
80
80
|
} from "../shared-tree-core/index.js";
|
|
@@ -87,7 +87,6 @@ import {
|
|
|
87
87
|
type ViewableTree,
|
|
88
88
|
type TreeBranch,
|
|
89
89
|
type TreeBranchAlpha,
|
|
90
|
-
type TreeChangeEvents,
|
|
91
90
|
type VerboseTree,
|
|
92
91
|
type VoidTransactionCallbackStatus,
|
|
93
92
|
type TransactionCallbackStatus,
|
|
@@ -308,7 +307,6 @@ export function createTreeCheckout(
|
|
|
308
307
|
chunkCompressionStrategy?: TreeCompressionStrategy;
|
|
309
308
|
logger?: TelemetryLoggerExt;
|
|
310
309
|
breaker?: Breakable;
|
|
311
|
-
disposeForksAfterTransaction?: boolean;
|
|
312
310
|
codecOptions?: Partial<CodecWriteOptions>;
|
|
313
311
|
},
|
|
314
312
|
): TreeCheckout {
|
|
@@ -355,7 +353,6 @@ export function createTreeCheckout(
|
|
|
355
353
|
args?.removedRoots,
|
|
356
354
|
args?.logger,
|
|
357
355
|
breaker,
|
|
358
|
-
args?.disposeForksAfterTransaction,
|
|
359
356
|
);
|
|
360
357
|
}
|
|
361
358
|
|
|
@@ -527,7 +524,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
527
524
|
/** Optional logger for telemetry. */
|
|
528
525
|
private readonly logger?: TelemetryLoggerExt,
|
|
529
526
|
public readonly breaker: Breakable = new Breakable("TreeCheckout"),
|
|
530
|
-
public readonly disposeForksAfterTransaction = true,
|
|
531
527
|
) {
|
|
532
528
|
this.#transaction = this.createTransactionStack(branch);
|
|
533
529
|
this.editLock = new EditLock(this.#transaction.activeBranchEditor);
|
|
@@ -659,9 +655,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
659
655
|
branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>,
|
|
660
656
|
): SquashingTransactionStack<SharedTreeEditBuilder, SharedTreeChange> {
|
|
661
657
|
return new SquashingTransactionStack(branch, this.mintRevisionTag, () => {
|
|
662
|
-
const disposeForks = this.disposeForksAfterTransaction
|
|
663
|
-
? trackForksForDisposal(this)
|
|
664
|
-
: undefined;
|
|
665
658
|
// When each transaction is started, make a restorable checkpoint of the current state of removed roots
|
|
666
659
|
const restoreRemovedRoots = this._removedRoots.createCheckpoint();
|
|
667
660
|
return (result, viewUpdate: SharedTreeChange | undefined) => {
|
|
@@ -688,7 +681,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
688
681
|
unreachableCase(result);
|
|
689
682
|
}
|
|
690
683
|
}
|
|
691
|
-
disposeForks?.();
|
|
692
684
|
};
|
|
693
685
|
});
|
|
694
686
|
}
|
|
@@ -788,19 +780,48 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
788
780
|
labels: buildLabelsSet(this.labelTreeNode),
|
|
789
781
|
};
|
|
790
782
|
|
|
791
|
-
this
|
|
783
|
+
this.emitChangedLocked(() => {
|
|
784
|
+
this.#events.emit("changed", metadata, getRevertible);
|
|
785
|
+
});
|
|
792
786
|
withinEventContext = false;
|
|
793
787
|
}
|
|
794
788
|
} else if (this.isRemoteChangeEvent(event)) {
|
|
795
789
|
// TODO: figure out how to plumb through commit kind info for remote changes
|
|
796
|
-
this
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
790
|
+
this.emitChangedLocked(() => {
|
|
791
|
+
this.#events.emit("changed", {
|
|
792
|
+
isLocal: false,
|
|
793
|
+
kind: CommitKind.Default,
|
|
794
|
+
labels: new Set<unknown>(),
|
|
795
|
+
});
|
|
800
796
|
});
|
|
801
797
|
}
|
|
802
798
|
};
|
|
803
799
|
|
|
800
|
+
/**
|
|
801
|
+
* Hold the `editLock` for the duration of `emit`, so that re-entrant edits, transactions,
|
|
802
|
+
* branch operations, etc. attempted from inside a `changed` listener throw the canonical
|
|
803
|
+
* "forbidden during a change event" {@link UsageError} via {@link EditLock.checkUnlocked}.
|
|
804
|
+
*
|
|
805
|
+
* @remarks
|
|
806
|
+
* Shared by both the local and remote `changed` emission paths in {@link TreeCheckout.onAfterBranchChange}.
|
|
807
|
+
* The `try`/`finally` ensures the lock is released even if a listener throws.
|
|
808
|
+
*/
|
|
809
|
+
private emitChangedLocked(emit: () => void): void {
|
|
810
|
+
this.editLock.lock();
|
|
811
|
+
try {
|
|
812
|
+
emit();
|
|
813
|
+
} finally {
|
|
814
|
+
// TODO: any event that throws potentially leaves the code which triggered that event,
|
|
815
|
+
// and thus this checkout (and likely more) in a broken state.
|
|
816
|
+
// Unlocking this editLock prevents future use of this broken state from giving a confusing error in this case,
|
|
817
|
+
// however, a better approach would probably be to put something (this checkout and/or the editLock)
|
|
818
|
+
// into a broken state (using a properly scoped `Breakable`),
|
|
819
|
+
// likely by moving emitChangedLocked into EditLock, and having EditLock get a Breakable,
|
|
820
|
+
// and having the new emitChangedLocked use `Breakable.use`.
|
|
821
|
+
this.editLock.unlock();
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
|
|
804
825
|
private readonly onAfterChange = (event: SharedTreeBranchChange<SharedTreeChange>): void => {
|
|
805
826
|
this.editLock.lock();
|
|
806
827
|
this.#events.emit("beforeBatch", event);
|
|
@@ -908,6 +929,15 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
908
929
|
|
|
909
930
|
private mountTransaction(params: RunTransactionParams | undefined, isAsync: boolean): void {
|
|
910
931
|
this.checkNotDisposed();
|
|
932
|
+
// Starting a transaction is an edit, so it is forbidden from within a change-event
|
|
933
|
+
// callback (where the edit lock is held), the same as direct edits. For the async
|
|
934
|
+
// entry point this throw is captured as a rejected promise by the `async` wrapper.
|
|
935
|
+
//
|
|
936
|
+
// Note: because runTransaction/runTransactionAsync are `@breakingMethod`, this throw also
|
|
937
|
+
// puts the checkout into a broken state (unlike a direct edit, which throws recoverably).
|
|
938
|
+
// That is the same pre-existing broken-state limitation tracked by the TODO in
|
|
939
|
+
// `emitChangedLocked`, not something specific to transactions.
|
|
940
|
+
this.editLock.checkUnlocked("Running a transaction");
|
|
911
941
|
if (isAsync && this.transaction.size > 0) {
|
|
912
942
|
throw new UsageError(
|
|
913
943
|
"An asynchronous transaction cannot be started while another transaction is already in progress.",
|
|
@@ -1170,7 +1200,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1170
1200
|
throw new UsageError("A view cannot be forked while it has a pending transaction.");
|
|
1171
1201
|
}
|
|
1172
1202
|
|
|
1173
|
-
this.editLock.checkUnlocked("Branching");
|
|
1174
1203
|
const branch = this.#transaction.activeBranch.fork();
|
|
1175
1204
|
const storedSchema = this.storedSchema.clone();
|
|
1176
1205
|
const forkBreaker = new Breakable("TreeCheckout");
|
|
@@ -1187,7 +1216,6 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1187
1216
|
this._removedRoots.clone(),
|
|
1188
1217
|
this.logger,
|
|
1189
1218
|
forkBreaker,
|
|
1190
|
-
this.disposeForksAfterTransaction,
|
|
1191
1219
|
);
|
|
1192
1220
|
this.#events.emit("fork", checkout);
|
|
1193
1221
|
return checkout;
|
|
@@ -1250,6 +1278,19 @@ export class TreeCheckout implements ITreeCheckout {
|
|
|
1250
1278
|
getCheckout(branch).rebase(this);
|
|
1251
1279
|
}
|
|
1252
1280
|
|
|
1281
|
+
public isMissingEditsFrom(branch: TreeBranch): boolean {
|
|
1282
|
+
const branchCheckout = getCheckout(branch);
|
|
1283
|
+
const targetPath: GraphCommit<unknown>[] = [];
|
|
1284
|
+
const ancestor = findCommonAncestor(this.mainBranch.getHead(), [
|
|
1285
|
+
branchCheckout.mainBranch.getHead(),
|
|
1286
|
+
targetPath,
|
|
1287
|
+
]);
|
|
1288
|
+
if (ancestor === undefined) {
|
|
1289
|
+
throw new UsageError("Branches do not share a common ancestor.");
|
|
1290
|
+
}
|
|
1291
|
+
return targetPath.length > 0;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1253
1294
|
public merge(branch: TreeBranch): void;
|
|
1254
1295
|
public merge(branch: TreeBranch, disposeMerged: boolean): void;
|
|
1255
1296
|
public merge(branch: TreeBranch, disposeMerged = true): void {
|
|
@@ -1681,12 +1722,7 @@ class EditLock {
|
|
|
1681
1722
|
*/
|
|
1682
1723
|
public checkUnlocked<T extends string>(action: T extends Capitalize<T> ? T : never): void {
|
|
1683
1724
|
if (this.locked) {
|
|
1684
|
-
|
|
1685
|
-
const nodeChanged: keyof TreeChangeEvents = "nodeChanged";
|
|
1686
|
-
const treeChanged: keyof TreeChangeEvents = "treeChanged";
|
|
1687
|
-
throw new UsageError(
|
|
1688
|
-
`${action} is forbidden during a ${nodeChanged} or ${treeChanged} event`,
|
|
1689
|
-
);
|
|
1725
|
+
throw new UsageError(`${action} is forbidden during a change event callback`);
|
|
1690
1726
|
}
|
|
1691
1727
|
}
|
|
1692
1728
|
|
|
@@ -1700,34 +1736,6 @@ class EditLock {
|
|
|
1700
1736
|
}
|
|
1701
1737
|
}
|
|
1702
1738
|
|
|
1703
|
-
/**
|
|
1704
|
-
* Keeps track of all new forks created until the returned function is invoked, which will dispose all of those for.
|
|
1705
|
-
* The returned function may only be called once.
|
|
1706
|
-
*
|
|
1707
|
-
* @param checkout - The tree checkout for which you want to monitor forks for disposal.
|
|
1708
|
-
* @returns a function which can be called to dispose all of the tracked forks.
|
|
1709
|
-
*/
|
|
1710
|
-
function trackForksForDisposal(checkout: TreeCheckout): () => void {
|
|
1711
|
-
const forks = new Set<TreeCheckout>();
|
|
1712
|
-
const onDisposeUnSubscribes: (() => void)[] = [];
|
|
1713
|
-
const onForkUnSubscribe = onForkTransitive(checkout, (fork) => {
|
|
1714
|
-
forks.add(fork);
|
|
1715
|
-
onDisposeUnSubscribes.push(fork.events.on("dispose", () => forks.delete(fork)));
|
|
1716
|
-
});
|
|
1717
|
-
let disposed = false;
|
|
1718
|
-
return () => {
|
|
1719
|
-
assert(!disposed, 0xaa9 /* Forks may only be disposed once */);
|
|
1720
|
-
for (const fork of forks) {
|
|
1721
|
-
fork.dispose();
|
|
1722
|
-
}
|
|
1723
|
-
for (const unsubscribe of onDisposeUnSubscribes) {
|
|
1724
|
-
unsubscribe();
|
|
1725
|
-
}
|
|
1726
|
-
onForkUnSubscribe();
|
|
1727
|
-
disposed = true;
|
|
1728
|
-
};
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
1739
|
function verboseFromCursor(
|
|
1732
1740
|
reader: ITreeCursor,
|
|
1733
1741
|
schema: ReadonlyMap<TreeNodeSchemaIdentifier, TreeNodeStoredSchema>,
|
|
@@ -342,6 +342,17 @@ export interface TreeBranchAlpha extends TreeBranch, TreeContextAlpha {
|
|
|
342
342
|
* Update the tests and docs to match when that is done.
|
|
343
343
|
*/
|
|
344
344
|
applyChange(change: JsonCompatibleReadOnly): void;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Determines if there are changes on the given branch that are not present on this branch.
|
|
348
|
+
* @param branch - The branch to compare to.
|
|
349
|
+
*
|
|
350
|
+
* The new edits, if any, can be applied to this branch by {@link TreeBranch.rebaseOnto | rebasing this branch onto the given branch}
|
|
351
|
+
* or by {@link TreeBranch.merge | merging the given branch into this branch}.
|
|
352
|
+
*
|
|
353
|
+
* @throws UsageError if the branches are unrelated.
|
|
354
|
+
*/
|
|
355
|
+
isMissingEditsFrom(branch: TreeBranch): boolean;
|
|
345
356
|
}
|
|
346
357
|
|
|
347
358
|
/**
|