@fluidframework/tree 2.10.0-305357 → 2.10.0-306579
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +56 -25
- package/api-report/tree.alpha.api.md +3 -2
- package/api-report/tree.beta.api.md +3 -2
- package/api-report/tree.legacy.alpha.api.md +3 -2
- package/api-report/tree.legacy.public.api.md +3 -2
- package/api-report/tree.public.api.md +3 -2
- package/dist/core/forest/forest.d.ts +5 -1
- package/dist/core/forest/forest.d.ts.map +1 -1
- package/dist/core/forest/forest.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/schema-stored/storedSchemaRepository.d.ts +7 -3
- package/dist/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
- package/dist/core/schema-stored/storedSchemaRepository.js +4 -6
- package/dist/core/schema-stored/storedSchemaRepository.js.map +1 -1
- package/dist/core/tree/anchorSet.d.ts +8 -5
- package/dist/core/tree/anchorSet.d.ts.map +1 -1
- package/dist/core/tree/anchorSet.js +12 -11
- package/dist/core/tree/anchorSet.js.map +1 -1
- package/dist/events/emitter.d.ts +21 -9
- package/dist/events/emitter.d.ts.map +1 -1
- package/dist/events/emitter.js +36 -21
- package/dist/events/emitter.js.map +1 -1
- package/dist/events/listeners.d.ts +16 -5
- package/dist/events/listeners.d.ts.map +1 -1
- package/dist/events/listeners.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js +1 -1
- package/dist/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts +3 -2
- package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/dist/feature-libraries/chunked-forest/chunkedForest.js +14 -9
- package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/dist/feature-libraries/flex-tree/context.d.ts +3 -2
- package/dist/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/dist/feature-libraries/flex-tree/context.js +3 -3
- package/dist/feature-libraries/flex-tree/context.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js +1 -1
- package/dist/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js +1 -1
- package/dist/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/dist/feature-libraries/flex-tree/utilities.js +1 -1
- package/dist/feature-libraries/flex-tree/utilities.js.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/comparison.js +3 -0
- package/dist/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/dist/feature-libraries/modular-schema/discrepancies.d.ts +2 -2
- package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/discrepancies.js +90 -44
- package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -1
- package/dist/feature-libraries/modular-schema/genericFieldKind.js +2 -2
- package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.d.ts +2 -2
- package/dist/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/dist/feature-libraries/object-forest/objectForest.js +6 -8
- package/dist/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js +1 -1
- package/dist/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +2 -2
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/markListFactory.js +1 -1
- package/dist/feature-libraries/sequence-field/markListFactory.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.js +2 -2
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/shared-tree/treeApi.js +2 -2
- package/dist/shared-tree/treeApi.js.map +1 -1
- package/dist/shared-tree/treeCheckout.js +7 -7
- package/dist/shared-tree/treeCheckout.js.map +1 -1
- package/dist/shared-tree-core/branch.d.ts +7 -7
- package/dist/shared-tree-core/branch.d.ts.map +1 -1
- package/dist/shared-tree-core/branch.js +35 -25
- package/dist/shared-tree-core/branch.js.map +1 -1
- package/dist/shared-tree-core/editManager.js +4 -4
- package/dist/shared-tree-core/editManager.js.map +1 -1
- package/dist/shared-tree-core/sharedTreeCore.js +5 -5
- package/dist/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +66 -10
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +34 -9
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/treeNodeApi.js +4 -4
- package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
- package/dist/simple-tree/arrayNode.js +1 -1
- package/dist/simple-tree/arrayNode.js.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.d.ts +3 -3
- package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/dist/simple-tree/core/treeNodeKernel.js +7 -8
- package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/dist/simple-tree/proxies.js +1 -1
- package/dist/simple-tree/proxies.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +26 -1
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/dist/simple-tree/treeNodeValid.js +2 -2
- package/dist/simple-tree/treeNodeValid.js.map +1 -1
- package/dist/util/nestedMap.d.ts.map +1 -1
- package/dist/util/nestedMap.js.map +1 -1
- package/lib/core/forest/forest.d.ts +5 -1
- package/lib/core/forest/forest.d.ts.map +1 -1
- package/lib/core/forest/forest.js.map +1 -1
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/schema-stored/storedSchemaRepository.d.ts +7 -3
- package/lib/core/schema-stored/storedSchemaRepository.d.ts.map +1 -1
- package/lib/core/schema-stored/storedSchemaRepository.js +4 -6
- package/lib/core/schema-stored/storedSchemaRepository.js.map +1 -1
- package/lib/core/tree/anchorSet.d.ts +8 -5
- package/lib/core/tree/anchorSet.d.ts.map +1 -1
- package/lib/core/tree/anchorSet.js +12 -11
- package/lib/core/tree/anchorSet.js.map +1 -1
- package/lib/events/emitter.d.ts +21 -9
- package/lib/events/emitter.d.ts.map +1 -1
- package/lib/events/emitter.js +37 -22
- package/lib/events/emitter.js.map +1 -1
- package/lib/events/listeners.d.ts +16 -5
- package/lib/events/listeners.d.ts.map +1 -1
- package/lib/events/listeners.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js +1 -1
- package/lib/feature-libraries/chunked-forest/chunkTree.js.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts +3 -2
- package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
- package/lib/feature-libraries/chunked-forest/chunkedForest.js +14 -9
- package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
- package/lib/feature-libraries/flex-tree/context.d.ts +3 -2
- package/lib/feature-libraries/flex-tree/context.d.ts.map +1 -1
- package/lib/feature-libraries/flex-tree/context.js +3 -3
- package/lib/feature-libraries/flex-tree/context.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js +1 -1
- package/lib/feature-libraries/flex-tree/lazyField.js.map +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js +1 -1
- package/lib/feature-libraries/flex-tree/lazyNode.js.map +1 -1
- package/lib/feature-libraries/flex-tree/utilities.js +1 -1
- package/lib/feature-libraries/flex-tree/utilities.js.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/comparison.js +3 -0
- package/lib/feature-libraries/modular-schema/comparison.js.map +1 -1
- package/lib/feature-libraries/modular-schema/discrepancies.d.ts +2 -2
- package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/discrepancies.js +91 -45
- package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -1
- package/lib/feature-libraries/modular-schema/genericFieldKind.js +2 -2
- package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.d.ts +2 -2
- package/lib/feature-libraries/object-forest/objectForest.d.ts.map +1 -1
- package/lib/feature-libraries/object-forest/objectForest.js +6 -8
- package/lib/feature-libraries/object-forest/objectForest.js.map +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js +1 -1
- package/lib/feature-libraries/schema-index/schemaSummarizer.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +2 -2
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/markListFactory.js +1 -1
- package/lib/feature-libraries/sequence-field/markListFactory.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.js +2 -2
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/shared-tree/treeApi.js +2 -2
- package/lib/shared-tree/treeApi.js.map +1 -1
- package/lib/shared-tree/treeCheckout.js +7 -7
- package/lib/shared-tree/treeCheckout.js.map +1 -1
- package/lib/shared-tree-core/branch.d.ts +7 -7
- package/lib/shared-tree-core/branch.d.ts.map +1 -1
- package/lib/shared-tree-core/branch.js +36 -26
- package/lib/shared-tree-core/branch.js.map +1 -1
- package/lib/shared-tree-core/editManager.js +4 -4
- package/lib/shared-tree-core/editManager.js.map +1 -1
- package/lib/shared-tree-core/sharedTreeCore.js +5 -5
- package/lib/shared-tree-core/sharedTreeCore.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +66 -10
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +34 -9
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/treeNodeApi.js +4 -4
- package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
- package/lib/simple-tree/arrayNode.js +1 -1
- package/lib/simple-tree/arrayNode.js.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.d.ts +3 -3
- package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
- package/lib/simple-tree/core/treeNodeKernel.js +7 -8
- package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
- package/lib/simple-tree/proxies.js +1 -1
- package/lib/simple-tree/proxies.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +26 -1
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/lib/simple-tree/treeNodeValid.js +2 -2
- package/lib/simple-tree/treeNodeValid.js.map +1 -1
- package/lib/util/nestedMap.d.ts.map +1 -1
- package/lib/util/nestedMap.js.map +1 -1
- package/package.json +20 -20
- package/src/core/forest/forest.ts +6 -1
- package/src/core/index.ts +1 -1
- package/src/core/schema-stored/storedSchemaRepository.ts +10 -13
- package/src/core/tree/anchorSet.ts +13 -20
- package/src/events/emitter.ts +45 -24
- package/src/events/listeners.ts +17 -5
- package/src/feature-libraries/chunked-forest/chunkTree.ts +1 -1
- package/src/feature-libraries/chunked-forest/chunkedForest.ts +8 -14
- package/src/feature-libraries/flex-tree/context.ts +5 -7
- package/src/feature-libraries/flex-tree/lazyField.ts +1 -1
- package/src/feature-libraries/flex-tree/lazyNode.ts +1 -1
- package/src/feature-libraries/flex-tree/utilities.ts +1 -1
- package/src/feature-libraries/modular-schema/comparison.ts +4 -0
- package/src/feature-libraries/modular-schema/discrepancies.ts +116 -50
- package/src/feature-libraries/modular-schema/genericFieldKind.ts +2 -2
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +1 -1
- package/src/feature-libraries/object-forest/objectForest.ts +5 -11
- package/src/feature-libraries/schema-index/schemaSummarizer.ts +1 -1
- package/src/feature-libraries/sequence-field/compose.ts +2 -2
- package/src/feature-libraries/sequence-field/markListFactory.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +2 -2
- package/src/shared-tree/treeApi.ts +2 -2
- package/src/shared-tree/treeCheckout.ts +7 -7
- package/src/shared-tree-core/branch.ts +30 -30
- package/src/shared-tree-core/editManager.ts +4 -4
- package/src/shared-tree-core/sharedTreeCore.ts +5 -5
- package/src/simple-tree/api/schemaFactory.ts +37 -11
- package/src/simple-tree/api/treeNodeApi.ts +4 -4
- package/src/simple-tree/arrayNode.ts +1 -1
- package/src/simple-tree/core/treeNodeKernel.ts +8 -10
- package/src/simple-tree/proxies.ts +1 -1
- package/src/simple-tree/schemaTypes.ts +26 -1
- package/src/simple-tree/treeNodeValid.ts +2 -2
- package/src/util/nestedMap.ts +1 -0
|
@@ -11,12 +11,14 @@ import {
|
|
|
11
11
|
LeafNodeStoredSchema,
|
|
12
12
|
MapNodeStoredSchema,
|
|
13
13
|
ObjectNodeStoredSchema,
|
|
14
|
+
storedEmptyFieldSchema,
|
|
14
15
|
type TreeFieldStoredSchema,
|
|
15
16
|
type TreeNodeSchemaIdentifier,
|
|
16
17
|
type TreeStoredSchema,
|
|
17
18
|
type TreeTypeSet,
|
|
18
19
|
type ValueSchema,
|
|
19
20
|
} from "../../core/index.js";
|
|
21
|
+
import { brand } from "../../util/index.js";
|
|
20
22
|
|
|
21
23
|
// TODO:
|
|
22
24
|
// The comparisons in this file seem redundant with those in comparison.ts.
|
|
@@ -79,8 +81,8 @@ export interface AllowedTypeIncompatibility {
|
|
|
79
81
|
export interface FieldKindIncompatibility {
|
|
80
82
|
identifier: string | undefined; // undefined indicates root field schema
|
|
81
83
|
mismatch: "fieldKind";
|
|
82
|
-
view: FieldKindIdentifier
|
|
83
|
-
stored: FieldKindIdentifier
|
|
84
|
+
view: FieldKindIdentifier;
|
|
85
|
+
stored: FieldKindIdentifier;
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
export interface ValueSchemaIncompatibility {
|
|
@@ -348,12 +350,15 @@ function trackObjectNodeDiscrepancies(
|
|
|
348
350
|
|
|
349
351
|
for (const [fieldKey, fieldStoredSchema] of view.objectNodeFields) {
|
|
350
352
|
viewFieldKeys.add(fieldKey);
|
|
351
|
-
if (
|
|
353
|
+
if (
|
|
354
|
+
!stored.objectNodeFields.has(fieldKey) &&
|
|
355
|
+
fieldStoredSchema.kind !== storedEmptyFieldSchema.kind
|
|
356
|
+
) {
|
|
352
357
|
differences.push({
|
|
353
358
|
identifier: fieldKey,
|
|
354
359
|
mismatch: "fieldKind",
|
|
355
360
|
view: fieldStoredSchema.kind,
|
|
356
|
-
stored:
|
|
361
|
+
stored: storedEmptyFieldSchema.kind,
|
|
357
362
|
} satisfies FieldKindIncompatibility);
|
|
358
363
|
} else {
|
|
359
364
|
differences.push(
|
|
@@ -370,12 +375,15 @@ function trackObjectNodeDiscrepancies(
|
|
|
370
375
|
if (viewFieldKeys.has(fieldKey)) {
|
|
371
376
|
continue;
|
|
372
377
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
378
|
+
|
|
379
|
+
if (fieldStoredSchema.kind !== storedEmptyFieldSchema.kind) {
|
|
380
|
+
differences.push({
|
|
381
|
+
identifier: fieldKey,
|
|
382
|
+
mismatch: "fieldKind",
|
|
383
|
+
view: storedEmptyFieldSchema.kind,
|
|
384
|
+
stored: fieldStoredSchema.kind,
|
|
385
|
+
} satisfies FieldKindIncompatibility);
|
|
386
|
+
}
|
|
379
387
|
}
|
|
380
388
|
|
|
381
389
|
return differences;
|
|
@@ -404,7 +412,11 @@ export function isRepoSuperset(view: TreeStoredSchema, stored: TreeStoredSchema)
|
|
|
404
412
|
for (const incompatibility of incompatibilities) {
|
|
405
413
|
switch (incompatibility.mismatch) {
|
|
406
414
|
case "nodeKind": {
|
|
407
|
-
|
|
415
|
+
if (incompatibility.stored !== undefined) {
|
|
416
|
+
// It's fine for the view schema to know of a node type that the stored schema doesn't know about.
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
break;
|
|
408
420
|
}
|
|
409
421
|
case "valueSchema":
|
|
410
422
|
case "allowedTypes":
|
|
@@ -439,17 +451,7 @@ function validateFieldIncompatibility(incompatibility: FieldIncompatibility): bo
|
|
|
439
451
|
return incompatibility.stored.length === 0;
|
|
440
452
|
}
|
|
441
453
|
case "fieldKind": {
|
|
442
|
-
|
|
443
|
-
// Add an optional field
|
|
444
|
-
if (incompatibility.view === "Optional") {
|
|
445
|
-
return true;
|
|
446
|
-
}
|
|
447
|
-
} else {
|
|
448
|
-
// Relax the field to make it more general
|
|
449
|
-
return compareFieldKind(incompatibility.stored, incompatibility.view);
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
break;
|
|
454
|
+
return posetLte(incompatibility.stored, incompatibility.view, fieldRealizer);
|
|
453
455
|
}
|
|
454
456
|
case "valueSchema": {
|
|
455
457
|
return false;
|
|
@@ -460,41 +462,105 @@ function validateFieldIncompatibility(incompatibility: FieldIncompatibility): bo
|
|
|
460
462
|
}
|
|
461
463
|
|
|
462
464
|
/**
|
|
463
|
-
* A
|
|
464
|
-
*
|
|
465
|
-
* This is used to determine if one field kind can be considered a superset of another.
|
|
465
|
+
* A linear extension of a partially-ordered set of `T`s. See:
|
|
466
|
+
* https://en.wikipedia.org/wiki/Linear_extension
|
|
466
467
|
*
|
|
467
|
-
*
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
|
|
475
|
-
|
|
468
|
+
* The linear extension is represented as a lookup from each poset element to its index in the linear extension.
|
|
469
|
+
*/
|
|
470
|
+
type LinearExtension<T> = Map<T, number>;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* A realizer for a partially-ordered set. See:
|
|
474
|
+
* https://en.wikipedia.org/wiki/Order_dimension
|
|
475
|
+
*/
|
|
476
|
+
type Realizer<T> = LinearExtension<T>[];
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* @privateRemarks
|
|
480
|
+
* TODO: Knowledge of specific field kinds is not appropriate for modular schema.
|
|
481
|
+
* This bit of field comparison should be dependency injected by default-schema if this comparison logic remains in modular-schema
|
|
482
|
+
* (this is analogous to what is done in comparison.ts).
|
|
476
483
|
*/
|
|
477
|
-
const
|
|
478
|
-
"Forbidden"
|
|
479
|
-
"Value"
|
|
480
|
-
"
|
|
481
|
-
|
|
484
|
+
const FieldKindIdentifiers = {
|
|
485
|
+
forbidden: brand<FieldKindIdentifier>("Forbidden"),
|
|
486
|
+
required: brand<FieldKindIdentifier>("Value"),
|
|
487
|
+
identifier: brand<FieldKindIdentifier>("Identifier"),
|
|
488
|
+
optional: brand<FieldKindIdentifier>("Optional"),
|
|
489
|
+
sequence: brand<FieldKindIdentifier>("Sequence"),
|
|
482
490
|
};
|
|
483
491
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
492
|
+
/**
|
|
493
|
+
* A realizer for the partial order of field kind relaxability.
|
|
494
|
+
*
|
|
495
|
+
* It seems extremely likely that this partial order will remain dimension 2 over time (i.e. the set of allowed relaxations can be visualized
|
|
496
|
+
* with a [dominance drawing](https://en.wikipedia.org/wiki/Dominance_drawing)), so this strategy allows efficient comarison between field kinds
|
|
497
|
+
* without excessive casework.
|
|
498
|
+
*
|
|
499
|
+
* Hasse diagram for the partial order is shown below (lower fields can be relaxed to higher fields):
|
|
500
|
+
* ```
|
|
501
|
+
* sequence
|
|
502
|
+
* |
|
|
503
|
+
* optional
|
|
504
|
+
* | \
|
|
505
|
+
* required forbidden
|
|
506
|
+
* |
|
|
507
|
+
* identifier
|
|
508
|
+
* ```
|
|
509
|
+
*/
|
|
510
|
+
const fieldRealizer: Realizer<FieldKindIdentifier> = [
|
|
511
|
+
[
|
|
512
|
+
FieldKindIdentifiers.forbidden,
|
|
513
|
+
FieldKindIdentifiers.identifier,
|
|
514
|
+
FieldKindIdentifiers.required,
|
|
515
|
+
FieldKindIdentifiers.optional,
|
|
516
|
+
FieldKindIdentifiers.sequence,
|
|
517
|
+
],
|
|
518
|
+
[
|
|
519
|
+
FieldKindIdentifiers.identifier,
|
|
520
|
+
FieldKindIdentifiers.required,
|
|
521
|
+
FieldKindIdentifiers.forbidden,
|
|
522
|
+
FieldKindIdentifiers.optional,
|
|
523
|
+
FieldKindIdentifiers.sequence,
|
|
524
|
+
],
|
|
525
|
+
].map((extension) => new Map(extension.map((identifier, index) => [identifier, index])));
|
|
526
|
+
|
|
527
|
+
const PosetComparisonResult = {
|
|
528
|
+
Less: "<",
|
|
529
|
+
Greater: ">",
|
|
530
|
+
Equal: "=",
|
|
531
|
+
Incomparable: "||",
|
|
532
|
+
} as const;
|
|
533
|
+
type PosetComparisonResult =
|
|
534
|
+
(typeof PosetComparisonResult)[keyof typeof PosetComparisonResult];
|
|
535
|
+
|
|
536
|
+
function comparePosetElements<T>(a: T, b: T, realizer: Realizer<T>): PosetComparisonResult {
|
|
537
|
+
let hasLessThanResult = false;
|
|
538
|
+
let hasGreaterThanResult = false;
|
|
539
|
+
for (const extension of realizer) {
|
|
540
|
+
const aIndex = extension.get(a);
|
|
541
|
+
const bIndex = extension.get(b);
|
|
542
|
+
assert(aIndex !== undefined && bIndex !== undefined, "Invalid realizer");
|
|
543
|
+
if (aIndex < bIndex) {
|
|
544
|
+
hasLessThanResult = true;
|
|
545
|
+
} else if (aIndex > bIndex) {
|
|
546
|
+
hasGreaterThanResult = true;
|
|
547
|
+
}
|
|
490
548
|
}
|
|
491
549
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
550
|
+
return hasLessThanResult
|
|
551
|
+
? hasGreaterThanResult
|
|
552
|
+
? PosetComparisonResult.Incomparable
|
|
553
|
+
: PosetComparisonResult.Less
|
|
554
|
+
: hasGreaterThanResult
|
|
555
|
+
? PosetComparisonResult.Greater
|
|
556
|
+
: PosetComparisonResult.Equal;
|
|
557
|
+
}
|
|
495
558
|
|
|
496
|
-
|
|
497
|
-
|
|
559
|
+
function posetLte<T>(a: T, b: T, realizer: Realizer<T>): boolean {
|
|
560
|
+
const comparison = comparePosetElements(a, b, realizer);
|
|
561
|
+
return (
|
|
562
|
+
comparison === PosetComparisonResult.Less || comparison === PosetComparisonResult.Equal
|
|
563
|
+
);
|
|
498
564
|
}
|
|
499
565
|
|
|
500
566
|
function throwUnsupportedNodeType(type: string): never {
|
|
@@ -103,8 +103,8 @@ function rebaseGenericChange(
|
|
|
103
103
|
break;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
const newIndex = newEntry?.[0] ??
|
|
107
|
-
const baseIndex = baseEntry?.[0] ??
|
|
106
|
+
const newIndex = newEntry?.[0] ?? Number.POSITIVE_INFINITY;
|
|
107
|
+
const baseIndex = baseEntry?.[0] ?? Number.POSITIVE_INFINITY;
|
|
108
108
|
let newNodeChange: NodeId | undefined;
|
|
109
109
|
let baseNodeChange: NodeId | undefined;
|
|
110
110
|
let index: number;
|
|
@@ -3016,7 +3016,7 @@ function getFirstIntersectingCrossFieldEntry(
|
|
|
3016
3016
|
table: CrossFieldKeyTable,
|
|
3017
3017
|
[target, revision, id, count]: CrossFieldKeyRange,
|
|
3018
3018
|
): [CrossFieldKeyRange, FieldId] | undefined {
|
|
3019
|
-
const entry = table.nextLowerPair([target, revision, id,
|
|
3019
|
+
const entry = table.nextLowerPair([target, revision, id, Number.POSITIVE_INFINITY]);
|
|
3020
3020
|
if (entry === undefined) {
|
|
3021
3021
|
return undefined;
|
|
3022
3022
|
}
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
aboveRootPlaceholder,
|
|
34
34
|
deepCopyMapTree,
|
|
35
35
|
} from "../../core/index.js";
|
|
36
|
-
import { createEmitter } from "../../events/index.js";
|
|
36
|
+
import { createEmitter, type Listenable } from "../../events/index.js";
|
|
37
37
|
import {
|
|
38
38
|
assertNonNegativeSafeInteger,
|
|
39
39
|
assertValidIndex,
|
|
@@ -73,7 +73,8 @@ export class ObjectForest implements IEditableForest {
|
|
|
73
73
|
// All cursors that are in the "Current" state. Must be empty when editing.
|
|
74
74
|
public readonly currentCursors: Set<Cursor> = new Set();
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
readonly #events = createEmitter<ForestEvents>();
|
|
77
|
+
public readonly events: Listenable<ForestEvents> = this.#events;
|
|
77
78
|
|
|
78
79
|
readonly #roots: MutableMapTree;
|
|
79
80
|
public get roots(): MapTree {
|
|
@@ -98,13 +99,6 @@ export class ObjectForest implements IEditableForest {
|
|
|
98
99
|
return this.roots.fields.size === 0;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
public on<K extends keyof ForestEvents>(
|
|
102
|
-
eventName: K,
|
|
103
|
-
listener: ForestEvents[K],
|
|
104
|
-
): () => void {
|
|
105
|
-
return this.events.on(eventName, listener);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
102
|
public clone(_: TreeStoredSchemaSubscription, anchors: AnchorSet): ObjectForest {
|
|
109
103
|
return new ObjectForest(anchors, this.additionalAsserts, this.roots);
|
|
110
104
|
}
|
|
@@ -133,7 +127,7 @@ export class ObjectForest implements IEditableForest {
|
|
|
133
127
|
* This is required for each change since there may be app facing change event handlers which create cursors.
|
|
134
128
|
*/
|
|
135
129
|
const preEdit = (): void => {
|
|
136
|
-
this
|
|
130
|
+
this.#events.emit("beforeChange");
|
|
137
131
|
assert(
|
|
138
132
|
this.currentCursors.has(cursor),
|
|
139
133
|
0x995 /* missing visitor cursor while editing */,
|
|
@@ -168,7 +162,7 @@ export class ObjectForest implements IEditableForest {
|
|
|
168
162
|
public create(content: ProtoNodes, destination: FieldKey): void {
|
|
169
163
|
preEdit();
|
|
170
164
|
this.forest.add(content, destination);
|
|
171
|
-
this.forest
|
|
165
|
+
this.forest.#events.emit("afterRootFieldCreated", destination);
|
|
172
166
|
}
|
|
173
167
|
public attach(source: FieldKey, count: number, destination: PlaceIndex): void {
|
|
174
168
|
preEdit();
|
|
@@ -52,7 +52,7 @@ export class SchemaSummarizer implements Summarizable {
|
|
|
52
52
|
collabWindow: CollabWindow,
|
|
53
53
|
) {
|
|
54
54
|
this.codec = makeSchemaCodec(options);
|
|
55
|
-
this.schema.on("afterSchemaChange", () => {
|
|
55
|
+
this.schema.events.on("afterSchemaChange", () => {
|
|
56
56
|
// Invalidate the cache, as we need to regenerate the blob if the schema changes
|
|
57
57
|
// We are assuming that schema changes from remote ops are valid, as we are in a summarization context.
|
|
58
58
|
this.schemaIndexLastChangedSeq = collabWindow.getCurrentSeq();
|
|
@@ -582,7 +582,7 @@ export class ComposeQueue {
|
|
|
582
582
|
}
|
|
583
583
|
}
|
|
584
584
|
|
|
585
|
-
private dequeueBase(length: number =
|
|
585
|
+
private dequeueBase(length: number = Number.POSITIVE_INFINITY): ComposeMarks {
|
|
586
586
|
const baseMark = this.baseMarks.dequeueUpTo(length);
|
|
587
587
|
const movedChanges = getMovedChangesFromMark(this.moveEffects, baseMark);
|
|
588
588
|
if (movedChanges !== undefined) {
|
|
@@ -593,7 +593,7 @@ export class ComposeQueue {
|
|
|
593
593
|
return { baseMark, newMark };
|
|
594
594
|
}
|
|
595
595
|
|
|
596
|
-
private dequeueNew(length: number =
|
|
596
|
+
private dequeueNew(length: number = Number.POSITIVE_INFINITY): ComposeMarks {
|
|
597
597
|
const newMark = this.newMarks.dequeueUpTo(length);
|
|
598
598
|
const baseMark = createNoopMark(newMark.count, undefined, getInputCellId(newMark));
|
|
599
599
|
|
|
@@ -42,7 +42,7 @@ export class MarkListFactory {
|
|
|
42
42
|
if (prev !== undefined && prev.type === mark.type) {
|
|
43
43
|
const merged = tryMergeMarks(prev, mark);
|
|
44
44
|
if (merged !== undefined) {
|
|
45
|
-
this.list.splice(
|
|
45
|
+
this.list.splice(-1, 1, merged);
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
}
|
package/src/packageVersion.ts
CHANGED
|
@@ -297,7 +297,7 @@ export class SchematizingSimpleTreeView<
|
|
|
297
297
|
new HydratedContext(this.rootFieldSchema.allowedTypeSet, view.context),
|
|
298
298
|
);
|
|
299
299
|
|
|
300
|
-
const unregister = this.checkout.storedSchema.on("afterSchemaChange", () => {
|
|
300
|
+
const unregister = this.checkout.storedSchema.events.on("afterSchemaChange", () => {
|
|
301
301
|
unregister();
|
|
302
302
|
this.unregisterCallbacks.delete(unregister);
|
|
303
303
|
view[disposeSymbol]();
|
|
@@ -307,7 +307,7 @@ export class SchematizingSimpleTreeView<
|
|
|
307
307
|
this.view = undefined;
|
|
308
308
|
this.checkout.forest.anchors.slots.delete(SimpleContextSlot);
|
|
309
309
|
|
|
310
|
-
const unregister = this.checkout.storedSchema.on("afterSchemaChange", () => {
|
|
310
|
+
const unregister = this.checkout.storedSchema.events.on("afterSchemaChange", () => {
|
|
311
311
|
unregister();
|
|
312
312
|
this.unregisterCallbacks.delete(unregister);
|
|
313
313
|
this.update();
|
|
@@ -478,10 +478,10 @@ function runTransactionInCheckout<TResult>(
|
|
|
478
478
|
let result: ReturnType<typeof transaction>;
|
|
479
479
|
try {
|
|
480
480
|
result = transaction();
|
|
481
|
-
} catch (
|
|
481
|
+
} catch (error) {
|
|
482
482
|
// If the transaction has an unhandled error, abort and rollback the transaction but continue to propagate the error.
|
|
483
483
|
checkout.transaction.abort();
|
|
484
|
-
throw
|
|
484
|
+
throw error;
|
|
485
485
|
}
|
|
486
486
|
|
|
487
487
|
if (result === rollback) {
|
|
@@ -444,15 +444,15 @@ export class TreeCheckout implements ITreeCheckoutFork {
|
|
|
444
444
|
private readonly breaker: Breakable = new Breakable("TreeCheckout"),
|
|
445
445
|
) {
|
|
446
446
|
// when a transaction is started, take a snapshot of the current state of removed roots
|
|
447
|
-
_branch.on("transactionStarted", () => {
|
|
447
|
+
_branch.events.on("transactionStarted", () => {
|
|
448
448
|
this.removedRootsSnapshots.push(this.removedRoots.clone());
|
|
449
449
|
});
|
|
450
450
|
// when a transaction is committed, the latest snapshot of removed roots can be discarded
|
|
451
|
-
_branch.on("transactionCommitted", () => {
|
|
451
|
+
_branch.events.on("transactionCommitted", () => {
|
|
452
452
|
this.removedRootsSnapshots.pop();
|
|
453
453
|
});
|
|
454
454
|
// after a transaction is rolled back, revert removed roots back to the latest snapshot
|
|
455
|
-
_branch.on("transactionRolledBack", () => {
|
|
455
|
+
_branch.events.on("transactionRolledBack", () => {
|
|
456
456
|
const snapshot = this.removedRootsSnapshots.pop();
|
|
457
457
|
assert(snapshot !== undefined, 0x9ae /* a snapshot for removed roots does not exist */);
|
|
458
458
|
this.removedRoots = snapshot;
|
|
@@ -462,7 +462,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
|
|
|
462
462
|
// For example, a bug in the editor might produce a malformed change object and thus applying the change to the forest will throw an error.
|
|
463
463
|
// In such a case we will crash here, preventing the change from being added to the commit graph, and preventing `afterChange` from firing.
|
|
464
464
|
// One important consequence of this is that we will not submit the op containing the invalid change, since op submissions happens in response to `afterChange`.
|
|
465
|
-
_branch.on("beforeChange", (event) => {
|
|
465
|
+
_branch.events.on("beforeChange", (event) => {
|
|
466
466
|
if (event.change !== undefined) {
|
|
467
467
|
const revision =
|
|
468
468
|
event.type === "replace"
|
|
@@ -509,7 +509,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
|
|
|
509
509
|
}
|
|
510
510
|
}
|
|
511
511
|
});
|
|
512
|
-
_branch.on("afterChange", (event) => {
|
|
512
|
+
_branch.events.on("afterChange", (event) => {
|
|
513
513
|
// The following logic allows revertibles to be generated for the change.
|
|
514
514
|
// Currently only appends (including merges) and transaction commits are supported.
|
|
515
515
|
if (!_branch.isTransacting()) {
|
|
@@ -590,7 +590,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
|
|
|
590
590
|
|
|
591
591
|
// When the branch is trimmed, we can garbage collect any repair data whose latest relevant revision is one of the
|
|
592
592
|
// trimmed revisions.
|
|
593
|
-
_branch.on("ancestryTrimmed", (revisions) => {
|
|
593
|
+
_branch.events.on("ancestryTrimmed", (revisions) => {
|
|
594
594
|
this.withCombinedVisitor((visitor) => {
|
|
595
595
|
revisions.forEach((revision) => {
|
|
596
596
|
// get all the roots last created or used by the revision
|
|
@@ -653,7 +653,7 @@ export class TreeCheckout implements ITreeCheckoutFork {
|
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
public get rootEvents(): Listenable<AnchorSetRootEvents> {
|
|
656
|
-
return this.forest.anchors;
|
|
656
|
+
return this.forest.anchors.events;
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
public get editor(): ISharedTreeEditor {
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
tagRollbackInverse,
|
|
22
22
|
type RebaseStatsWithDuration,
|
|
23
23
|
} from "../core/index.js";
|
|
24
|
-
import {
|
|
24
|
+
import { createEmitter, type Listenable } from "../events/index.js";
|
|
25
25
|
|
|
26
26
|
import { TransactionStack } from "./transactionStack.js";
|
|
27
27
|
import { fail } from "../util/index.js";
|
|
@@ -175,10 +175,9 @@ export interface BranchTrimmingEvents {
|
|
|
175
175
|
/**
|
|
176
176
|
* A branch of changes that can be applied to a SharedTree.
|
|
177
177
|
*/
|
|
178
|
-
export class SharedTreeBranch<
|
|
179
|
-
|
|
180
|
-
TChange
|
|
181
|
-
> extends EventEmitter<SharedTreeBranchEvents<TEditor, TChange>> {
|
|
178
|
+
export class SharedTreeBranch<TEditor extends ChangeFamilyEditor, TChange> {
|
|
179
|
+
readonly #events = createEmitter<SharedTreeBranchEvents<TEditor, TChange>>();
|
|
180
|
+
public readonly events: Listenable<SharedTreeBranchEvents<TEditor, TChange>> = this.#events;
|
|
182
181
|
public readonly editor: TEditor;
|
|
183
182
|
private readonly transactions = new TransactionStack();
|
|
184
183
|
/**
|
|
@@ -222,12 +221,11 @@ export class SharedTreeBranch<
|
|
|
222
221
|
keyof RebaseStatsWithDuration
|
|
223
222
|
>,
|
|
224
223
|
) {
|
|
225
|
-
super();
|
|
226
224
|
this.editor = this.changeFamily.buildEditor(mintRevisionTag, (change) =>
|
|
227
225
|
this.apply(change),
|
|
228
226
|
);
|
|
229
227
|
this.unsubscribeBranchTrimmer = branchTrimmer?.on("ancestryTrimmed", (commit) => {
|
|
230
|
-
this.emit("ancestryTrimmed", commit);
|
|
228
|
+
this.#events.emit("ancestryTrimmed", commit);
|
|
231
229
|
});
|
|
232
230
|
}
|
|
233
231
|
|
|
@@ -267,9 +265,9 @@ export class SharedTreeBranch<
|
|
|
267
265
|
newCommits: [newHead],
|
|
268
266
|
} as const;
|
|
269
267
|
|
|
270
|
-
this.emit("beforeChange", changeEvent);
|
|
268
|
+
this.#events.emit("beforeChange", changeEvent);
|
|
271
269
|
this.head = newHead;
|
|
272
|
-
this.emit("afterChange", changeEvent);
|
|
270
|
+
this.#events.emit("afterChange", changeEvent);
|
|
273
271
|
return [taggedChange.change, newHead];
|
|
274
272
|
}
|
|
275
273
|
|
|
@@ -290,7 +288,7 @@ export class SharedTreeBranch<
|
|
|
290
288
|
const onDisposeUnSubscribes: (() => void)[] = [];
|
|
291
289
|
const onForkUnSubscribe = onForkTransitive(this, (fork) => {
|
|
292
290
|
forks.add(fork);
|
|
293
|
-
onDisposeUnSubscribes.push(fork.on("dispose", () => forks.delete(fork)));
|
|
291
|
+
onDisposeUnSubscribes.push(fork.events.on("dispose", () => forks.delete(fork)));
|
|
294
292
|
});
|
|
295
293
|
this.transactions.push(this.head.revision, () => {
|
|
296
294
|
forks.forEach((fork) => fork.dispose());
|
|
@@ -298,7 +296,7 @@ export class SharedTreeBranch<
|
|
|
298
296
|
onForkUnSubscribe();
|
|
299
297
|
});
|
|
300
298
|
this.editor.enterTransaction();
|
|
301
|
-
this.emit("transactionStarted", this.transactions.size === 1);
|
|
299
|
+
this.#events.emit("transactionStarted", this.transactions.size === 1);
|
|
302
300
|
}
|
|
303
301
|
|
|
304
302
|
/**
|
|
@@ -315,7 +313,7 @@ export class SharedTreeBranch<
|
|
|
315
313
|
const [startCommit, commits] = this.popTransaction();
|
|
316
314
|
this.editor.exitTransaction();
|
|
317
315
|
|
|
318
|
-
this.emit("transactionCommitted", this.transactions.size === 0);
|
|
316
|
+
this.#events.emit("transactionCommitted", this.transactions.size === 0);
|
|
319
317
|
if (commits.length === 0) {
|
|
320
318
|
return undefined;
|
|
321
319
|
}
|
|
@@ -336,9 +334,9 @@ export class SharedTreeBranch<
|
|
|
336
334
|
newCommits: [newHead],
|
|
337
335
|
} as const;
|
|
338
336
|
|
|
339
|
-
this.emit("beforeChange", changeEvent);
|
|
337
|
+
this.#events.emit("beforeChange", changeEvent);
|
|
340
338
|
this.head = newHead;
|
|
341
|
-
this.emit("afterChange", changeEvent);
|
|
339
|
+
this.#events.emit("afterChange", changeEvent);
|
|
342
340
|
return [commits, newHead];
|
|
343
341
|
}
|
|
344
342
|
|
|
@@ -356,9 +354,9 @@ export class SharedTreeBranch<
|
|
|
356
354
|
const [startCommit, commits] = this.popTransaction();
|
|
357
355
|
this.editor.exitTransaction();
|
|
358
356
|
|
|
359
|
-
this.emit("transactionAborted", this.transactions.size === 0);
|
|
357
|
+
this.#events.emit("transactionAborted", this.transactions.size === 0);
|
|
360
358
|
if (commits.length === 0) {
|
|
361
|
-
this.emit("transactionRolledBack", this.transactions.size === 0);
|
|
359
|
+
this.#events.emit("transactionRolledBack", this.transactions.size === 0);
|
|
362
360
|
return [undefined, []];
|
|
363
361
|
}
|
|
364
362
|
|
|
@@ -384,10 +382,10 @@ export class SharedTreeBranch<
|
|
|
384
382
|
removedCommits: commits,
|
|
385
383
|
} as const;
|
|
386
384
|
|
|
387
|
-
this.emit("beforeChange", changeEvent);
|
|
385
|
+
this.#events.emit("beforeChange", changeEvent);
|
|
388
386
|
this.head = startCommit;
|
|
389
|
-
this.emit("afterChange", changeEvent);
|
|
390
|
-
this.emit("transactionRolledBack", this.transactions.size === 0);
|
|
387
|
+
this.#events.emit("afterChange", changeEvent);
|
|
388
|
+
this.#events.emit("transactionRolledBack", this.transactions.size === 0);
|
|
391
389
|
return [change, commits];
|
|
392
390
|
}
|
|
393
391
|
|
|
@@ -435,7 +433,7 @@ export class SharedTreeBranch<
|
|
|
435
433
|
this.mintRevisionTag,
|
|
436
434
|
this.branchTrimmer,
|
|
437
435
|
);
|
|
438
|
-
this.emit("fork", fork);
|
|
436
|
+
this.#events.emit("fork", fork);
|
|
439
437
|
return fork;
|
|
440
438
|
}
|
|
441
439
|
|
|
@@ -483,9 +481,9 @@ export class SharedTreeBranch<
|
|
|
483
481
|
newCommits,
|
|
484
482
|
} as const;
|
|
485
483
|
|
|
486
|
-
this.emit("beforeChange", changeEvent);
|
|
484
|
+
this.#events.emit("beforeChange", changeEvent);
|
|
487
485
|
this.head = newSourceHead;
|
|
488
|
-
this.emit("afterChange", changeEvent);
|
|
486
|
+
this.#events.emit("afterChange", changeEvent);
|
|
489
487
|
return rebaseResult;
|
|
490
488
|
}
|
|
491
489
|
|
|
@@ -529,9 +527,9 @@ export class SharedTreeBranch<
|
|
|
529
527
|
newCommits: sourceCommits,
|
|
530
528
|
} as const;
|
|
531
529
|
|
|
532
|
-
this.emit("beforeChange", changeEvent);
|
|
530
|
+
this.#events.emit("beforeChange", changeEvent);
|
|
533
531
|
this.head = rebaseResult.newSourceHead;
|
|
534
|
-
this.emit("afterChange", changeEvent);
|
|
532
|
+
this.#events.emit("afterChange", changeEvent);
|
|
535
533
|
return [change, sourceCommits];
|
|
536
534
|
}
|
|
537
535
|
|
|
@@ -585,7 +583,7 @@ export class SharedTreeBranch<
|
|
|
585
583
|
this.unsubscribeBranchTrimmer?.();
|
|
586
584
|
|
|
587
585
|
this.disposed = true;
|
|
588
|
-
this.emit("dispose");
|
|
586
|
+
this.#events.emit("dispose");
|
|
589
587
|
}
|
|
590
588
|
|
|
591
589
|
private assertNotDisposed(): void {
|
|
@@ -594,20 +592,22 @@ export class SharedTreeBranch<
|
|
|
594
592
|
}
|
|
595
593
|
|
|
596
594
|
/**
|
|
597
|
-
* Registers an event listener that fires when the given
|
|
595
|
+
* Registers an event listener that fires when the given branch forks.
|
|
598
596
|
* The listener will also fire when any of those forks fork, and when those forks of forks fork, and so on.
|
|
599
|
-
* @param
|
|
597
|
+
* @param branch - the branch that will be listened to for forks
|
|
600
598
|
* @param onFork - the fork event listener
|
|
601
599
|
* @returns a function which when called will deregister all registrations (including transitive) created by this function.
|
|
602
600
|
* The deregister function has undefined behavior if called more than once.
|
|
603
601
|
*/
|
|
604
|
-
|
|
605
|
-
|
|
602
|
+
// Branches are invariant over TChange
|
|
603
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
604
|
+
export function onForkTransitive<T extends SharedTreeBranch<ChangeFamilyEditor, any>>(
|
|
605
|
+
branch: T,
|
|
606
606
|
onFork: (fork: T) => void,
|
|
607
607
|
): () => void {
|
|
608
608
|
const offs: (() => void)[] = [];
|
|
609
609
|
offs.push(
|
|
610
|
-
|
|
610
|
+
branch.events.on("fork", (fork: T) => {
|
|
611
611
|
offs.push(onForkTransitive(fork, onFork));
|
|
612
612
|
onFork(fork);
|
|
613
613
|
}),
|
|
@@ -191,7 +191,7 @@ export class EditManager<
|
|
|
191
191
|
this.telemetryEventBatcher,
|
|
192
192
|
);
|
|
193
193
|
|
|
194
|
-
this.localBranch.on("afterChange", (event) => {
|
|
194
|
+
this.localBranch.events.on("afterChange", (event) => {
|
|
195
195
|
if (event.type === "append") {
|
|
196
196
|
for (const commit of event.newCommits) {
|
|
197
197
|
this.localCommits.push(commit);
|
|
@@ -223,19 +223,19 @@ export class EditManager<
|
|
|
223
223
|
private registerBranch(branch: SharedTreeBranch<TEditor, TChangeset>): void {
|
|
224
224
|
this.trackBranch(branch);
|
|
225
225
|
// Whenever the branch is rebased, update our record of its base trunk commit
|
|
226
|
-
const offBeforeRebase = branch.on("beforeChange", (args) => {
|
|
226
|
+
const offBeforeRebase = branch.events.on("beforeChange", (args) => {
|
|
227
227
|
if (args.type === "replace" && getChangeReplaceType(args) === "rebase") {
|
|
228
228
|
this.untrackBranch(branch);
|
|
229
229
|
}
|
|
230
230
|
});
|
|
231
|
-
const offAfterRebase = branch.on("afterChange", (args) => {
|
|
231
|
+
const offAfterRebase = branch.events.on("afterChange", (args) => {
|
|
232
232
|
if (args.type === "replace" && getChangeReplaceType(args) === "rebase") {
|
|
233
233
|
this.trackBranch(branch);
|
|
234
234
|
this.trimTrunk();
|
|
235
235
|
}
|
|
236
236
|
});
|
|
237
237
|
// When the branch is disposed, update our branch set and trim the trunk
|
|
238
|
-
const offDispose = branch.on("dispose", () => {
|
|
238
|
+
const offDispose = branch.events.on("dispose", () => {
|
|
239
239
|
this.untrackBranch(branch);
|
|
240
240
|
this.trimTrunk();
|
|
241
241
|
offBeforeRebase();
|