@fluidframework/tree 2.3.0 → 2.4.0-294316
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/api-report/tree.alpha.api.md +21 -12
- package/api-report/tree.beta.api.md +14 -5
- package/api-report/tree.legacy.alpha.api.md +14 -5
- package/api-report/tree.legacy.public.api.md +14 -5
- package/api-report/tree.public.api.md +14 -5
- package/dist/alpha.d.ts +1 -0
- package/dist/beta.d.ts +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/rebase/index.d.ts +1 -1
- package/dist/core/rebase/index.d.ts.map +1 -1
- package/dist/core/rebase/index.js +2 -1
- package/dist/core/rebase/index.js.map +1 -1
- package/dist/core/rebase/types.d.ts +1 -0
- package/dist/core/rebase/types.d.ts.map +1 -1
- package/dist/core/rebase/types.js +8 -1
- package/dist/core/rebase/types.js.map +1 -1
- package/dist/core/schema-stored/schema.d.ts.map +1 -1
- package/dist/core/schema-stored/schema.js.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +7 -0
- package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js +61 -17
- package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/compose.js +3 -0
- package/dist/feature-libraries/sequence-field/compose.js.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/dist/feature-libraries/sequence-field/utils.js +1 -4
- package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/public.d.ts +1 -0
- 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 +3 -0
- package/dist/shared-tree/schematizingTreeView.js.map +1 -1
- package/dist/simple-tree/api/jsonSchema.d.ts +13 -14
- package/dist/simple-tree/api/jsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/jsonSchema.js.map +1 -1
- package/dist/simple-tree/api/schemaFactory.d.ts +8 -2
- package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/dist/simple-tree/api/schemaFactory.js +6 -0
- package/dist/simple-tree/api/schemaFactory.js.map +1 -1
- package/dist/simple-tree/api/simpleSchema.d.ts +4 -0
- package/dist/simple-tree/api/simpleSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchema.js.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js +30 -17
- package/dist/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/dist/simple-tree/api/tree.d.ts +4 -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/api/viewSchemaToSimpleSchema.js +4 -0
- package/dist/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
- package/dist/simple-tree/index.d.ts +1 -1
- package/dist/simple-tree/index.d.ts.map +1 -1
- package/dist/simple-tree/index.js.map +1 -1
- package/dist/simple-tree/schemaTypes.d.ts +44 -4
- package/dist/simple-tree/schemaTypes.d.ts.map +1 -1
- package/dist/simple-tree/schemaTypes.js +10 -0
- package/dist/simple-tree/schemaTypes.js.map +1 -1
- package/lib/alpha.d.ts +1 -0
- package/lib/beta.d.ts +1 -0
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +1 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/rebase/index.d.ts +1 -1
- package/lib/core/rebase/index.d.ts.map +1 -1
- package/lib/core/rebase/index.js +1 -1
- package/lib/core/rebase/index.js.map +1 -1
- package/lib/core/rebase/types.d.ts +1 -0
- package/lib/core/rebase/types.d.ts.map +1 -1
- package/lib/core/rebase/types.js +6 -0
- package/lib/core/rebase/types.js.map +1 -1
- package/lib/core/schema-stored/schema.d.ts.map +1 -1
- package/lib/core/schema-stored/schema.js.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +7 -0
- package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js +62 -18
- package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/compose.js +3 -0
- package/lib/feature-libraries/sequence-field/compose.js.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.d.ts.map +1 -1
- package/lib/feature-libraries/sequence-field/utils.js +2 -5
- package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -0
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +1 -0
- 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 +3 -0
- package/lib/shared-tree/schematizingTreeView.js.map +1 -1
- package/lib/simple-tree/api/jsonSchema.d.ts +13 -14
- package/lib/simple-tree/api/jsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/jsonSchema.js.map +1 -1
- package/lib/simple-tree/api/schemaFactory.d.ts +8 -2
- package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
- package/lib/simple-tree/api/schemaFactory.js +6 -0
- package/lib/simple-tree/api/schemaFactory.js.map +1 -1
- package/lib/simple-tree/api/simpleSchema.d.ts +4 -0
- package/lib/simple-tree/api/simpleSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchema.js.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.d.ts.map +1 -1
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js +31 -18
- package/lib/simple-tree/api/simpleSchemaToJsonSchema.js.map +1 -1
- package/lib/simple-tree/api/tree.d.ts +4 -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/api/viewSchemaToSimpleSchema.js +4 -0
- package/lib/simple-tree/api/viewSchemaToSimpleSchema.js.map +1 -1
- package/lib/simple-tree/index.d.ts +1 -1
- package/lib/simple-tree/index.d.ts.map +1 -1
- package/lib/simple-tree/index.js.map +1 -1
- package/lib/simple-tree/schemaTypes.d.ts +44 -4
- package/lib/simple-tree/schemaTypes.d.ts.map +1 -1
- package/lib/simple-tree/schemaTypes.js +10 -0
- package/lib/simple-tree/schemaTypes.js.map +1 -1
- package/package.json +32 -22
- package/src/core/index.ts +1 -0
- package/src/core/rebase/index.ts +1 -0
- package/src/core/rebase/types.ts +11 -0
- package/src/core/schema-stored/schema.ts +1 -0
- package/src/feature-libraries/modular-schema/modularChangeFamily.ts +97 -10
- package/src/feature-libraries/sequence-field/compose.ts +3 -0
- package/src/feature-libraries/sequence-field/utils.ts +2 -4
- package/src/index.ts +1 -0
- package/src/packageVersion.ts +1 -1
- package/src/shared-tree/schematizingTreeView.ts +4 -0
- package/src/simple-tree/api/jsonSchema.ts +19 -17
- package/src/simple-tree/api/schemaFactory.ts +12 -6
- package/src/simple-tree/api/simpleSchema.ts +5 -0
- package/src/simple-tree/api/simpleSchemaToJsonSchema.ts +40 -19
- package/src/simple-tree/api/tree.ts +5 -0
- package/src/simple-tree/api/viewSchemaToSimpleSchema.ts +7 -2
- package/src/simple-tree/index.ts +1 -0
- package/src/simple-tree/schemaTypes.ts +55 -5
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
revisionMetadataSourceFromInfo,
|
|
39
39
|
areEqualChangeAtomIds,
|
|
40
40
|
type ChangeAtomId,
|
|
41
|
+
areEqualChangeAtomIdOpts,
|
|
41
42
|
} from "../../core/index.js";
|
|
42
43
|
import {
|
|
43
44
|
type IdAllocationState,
|
|
@@ -263,8 +264,6 @@ export class ModularChangeFamily
|
|
|
263
264
|
const genId: IdAllocator = idAllocatorFromState(idState);
|
|
264
265
|
const revisionMetadata: RevisionMetadataSource = revisionMetadataSourceFromInfo(revInfos);
|
|
265
266
|
|
|
266
|
-
const crossFieldTable = newComposeTable(change1, change2);
|
|
267
|
-
|
|
268
267
|
// We merge nodeChanges, nodeToParent, and nodeAliases from the two changesets.
|
|
269
268
|
// The merged tables will have correct entries for all nodes which are only referenced in one of the input changesets.
|
|
270
269
|
// During composeFieldMaps and composeInvalidatedElements we will find all nodes referenced in both input changesets
|
|
@@ -284,9 +283,12 @@ export class ModularChangeFamily
|
|
|
284
283
|
mergeBTrees(change1.nodeAliases, change2.nodeAliases),
|
|
285
284
|
);
|
|
286
285
|
|
|
286
|
+
const crossFieldTable = newComposeTable(change1, change2, composedNodeToParent);
|
|
287
|
+
|
|
287
288
|
const composedFields = this.composeFieldMaps(
|
|
288
289
|
change1.fieldChanges,
|
|
289
290
|
change2.fieldChanges,
|
|
291
|
+
undefined,
|
|
290
292
|
genId,
|
|
291
293
|
crossFieldTable,
|
|
292
294
|
revisionMetadata,
|
|
@@ -321,7 +323,7 @@ export class ModularChangeFamily
|
|
|
321
323
|
): void {
|
|
322
324
|
const context = crossFieldTable.fieldToContext.get(fieldChange);
|
|
323
325
|
assert(context !== undefined, 0x8cc /* Should have context for every invalidated field */);
|
|
324
|
-
const { change1: fieldChange1, change2: fieldChange2, composedChange } = context;
|
|
326
|
+
const { fieldId, change1: fieldChange1, change2: fieldChange2, composedChange } = context;
|
|
325
327
|
|
|
326
328
|
const rebaser = getChangeHandler(this.fieldKinds, composedChange.fieldKind).rebaser;
|
|
327
329
|
const composeNodes = (child1: NodeId | undefined, child2: NodeId | undefined): NodeId => {
|
|
@@ -342,7 +344,7 @@ export class ModularChangeFamily
|
|
|
342
344
|
fieldChange2,
|
|
343
345
|
composeNodes,
|
|
344
346
|
genId,
|
|
345
|
-
new ComposeManager(crossFieldTable, fieldChange, false),
|
|
347
|
+
new ComposeManager(crossFieldTable, fieldChange, fieldId, false),
|
|
346
348
|
revisionMetadata,
|
|
347
349
|
);
|
|
348
350
|
composedChange.change = brand(amendedChange);
|
|
@@ -470,7 +472,14 @@ export class ModularChangeFamily
|
|
|
470
472
|
? [fieldChange, emptyChange]
|
|
471
473
|
: [emptyChange, fieldChange];
|
|
472
474
|
|
|
473
|
-
const composedField = this.composeFieldChanges(
|
|
475
|
+
const composedField = this.composeFieldChanges(
|
|
476
|
+
fieldId,
|
|
477
|
+
change1,
|
|
478
|
+
change2,
|
|
479
|
+
genId,
|
|
480
|
+
table,
|
|
481
|
+
metadata,
|
|
482
|
+
);
|
|
474
483
|
|
|
475
484
|
if (fieldId.nodeId === undefined) {
|
|
476
485
|
composedFields.set(fieldId.field, composedField);
|
|
@@ -499,6 +508,7 @@ export class ModularChangeFamily
|
|
|
499
508
|
private composeFieldMaps(
|
|
500
509
|
change1: FieldChangeMap | undefined,
|
|
501
510
|
change2: FieldChangeMap | undefined,
|
|
511
|
+
parentId: NodeId | undefined,
|
|
502
512
|
genId: IdAllocator,
|
|
503
513
|
crossFieldTable: ComposeTable,
|
|
504
514
|
revisionMetadata: RevisionMetadataSource,
|
|
@@ -509,10 +519,12 @@ export class ModularChangeFamily
|
|
|
509
519
|
}
|
|
510
520
|
|
|
511
521
|
for (const [field, fieldChange1] of change1) {
|
|
522
|
+
const fieldId: FieldId = { nodeId: parentId, field };
|
|
512
523
|
const fieldChange2 = change2.get(field);
|
|
513
524
|
const composedField =
|
|
514
525
|
fieldChange2 !== undefined
|
|
515
526
|
? this.composeFieldChanges(
|
|
527
|
+
fieldId,
|
|
516
528
|
fieldChange1,
|
|
517
529
|
fieldChange2,
|
|
518
530
|
genId,
|
|
@@ -545,6 +557,7 @@ export class ModularChangeFamily
|
|
|
545
557
|
* Any composed `FieldChange` which is invalidated by new cross-field information will be added to `crossFieldTable.invalidatedFields`.
|
|
546
558
|
*/
|
|
547
559
|
private composeFieldChanges(
|
|
560
|
+
fieldId: FieldId,
|
|
548
561
|
change1: FieldChange,
|
|
549
562
|
change2: FieldChange,
|
|
550
563
|
idAllocator: IdAllocator,
|
|
@@ -558,7 +571,7 @@ export class ModularChangeFamily
|
|
|
558
571
|
change2: change2Normalized,
|
|
559
572
|
} = this.normalizeFieldChanges(change1, change2, idAllocator, revisionMetadata);
|
|
560
573
|
|
|
561
|
-
const manager = new ComposeManager(crossFieldTable, change1);
|
|
574
|
+
const manager = new ComposeManager(crossFieldTable, change1, fieldId);
|
|
562
575
|
|
|
563
576
|
const composedChange = changeHandler.rebaser.compose(
|
|
564
577
|
change1Normalized,
|
|
@@ -581,6 +594,7 @@ export class ModularChangeFamily
|
|
|
581
594
|
};
|
|
582
595
|
|
|
583
596
|
crossFieldTable.fieldToContext.set(change1, {
|
|
597
|
+
fieldId,
|
|
584
598
|
change1: change1Normalized,
|
|
585
599
|
change2: change2Normalized,
|
|
586
600
|
composedChange: composedField,
|
|
@@ -605,6 +619,7 @@ export class ModularChangeFamily
|
|
|
605
619
|
const nodeChangeset1 = nodeChangeFromId(nodeChanges1, id1);
|
|
606
620
|
const nodeChangeset2 = nodeChangeFromId(nodeChanges2, id2);
|
|
607
621
|
const composedNodeChangeset = this.composeNodeChanges(
|
|
622
|
+
id1,
|
|
608
623
|
nodeChangeset1,
|
|
609
624
|
nodeChangeset2,
|
|
610
625
|
idAllocator,
|
|
@@ -627,6 +642,7 @@ export class ModularChangeFamily
|
|
|
627
642
|
}
|
|
628
643
|
|
|
629
644
|
private composeNodeChanges(
|
|
645
|
+
nodeId: NodeId,
|
|
630
646
|
change1: NodeChangeset,
|
|
631
647
|
change2: NodeChangeset,
|
|
632
648
|
genId: IdAllocator,
|
|
@@ -638,6 +654,7 @@ export class ModularChangeFamily
|
|
|
638
654
|
const composedFieldChanges = this.composeFieldMaps(
|
|
639
655
|
change1.fieldChanges,
|
|
640
656
|
change2.fieldChanges,
|
|
657
|
+
nodeId,
|
|
641
658
|
genId,
|
|
642
659
|
crossFieldTable,
|
|
643
660
|
revisionMetadata,
|
|
@@ -887,7 +904,7 @@ export class ModularChangeFamily
|
|
|
887
904
|
rebasedNodes,
|
|
888
905
|
);
|
|
889
906
|
|
|
890
|
-
|
|
907
|
+
const rebased = makeModularChangeset(
|
|
891
908
|
this.pruneFieldMap(rebasedFields, rebasedNodes),
|
|
892
909
|
rebasedNodes,
|
|
893
910
|
crossFieldTable.rebasedNodeToParent,
|
|
@@ -900,6 +917,8 @@ export class ModularChangeFamily
|
|
|
900
917
|
change.destroys,
|
|
901
918
|
change.refreshers,
|
|
902
919
|
);
|
|
920
|
+
|
|
921
|
+
return rebased;
|
|
903
922
|
}
|
|
904
923
|
|
|
905
924
|
// This performs a first pass on all fields which have both new and base changes.
|
|
@@ -1584,6 +1603,57 @@ export class ModularChangeFamily
|
|
|
1584
1603
|
const emptyChange = getChangeHandler(this.fieldKinds, fieldKind).createEmpty();
|
|
1585
1604
|
return { fieldKind, change: brand(emptyChange) };
|
|
1586
1605
|
}
|
|
1606
|
+
|
|
1607
|
+
public validateChangeset(change: ModularChangeset): void {
|
|
1608
|
+
let numNodes = this.validateFieldChanges(change, change.fieldChanges, undefined);
|
|
1609
|
+
|
|
1610
|
+
for (const [[revision, localId], node] of change.nodeChanges.entries()) {
|
|
1611
|
+
if (node.fieldChanges === undefined) {
|
|
1612
|
+
continue;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
const nodeId: NodeId = { revision, localId };
|
|
1616
|
+
const numChildren = this.validateFieldChanges(change, node.fieldChanges, nodeId);
|
|
1617
|
+
|
|
1618
|
+
numNodes += numChildren;
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
assert(numNodes === change.nodeChanges.size, "Node table contains unparented nodes");
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1624
|
+
/**
|
|
1625
|
+
* Asserts that each child and cross field key in each field has a correct entry in
|
|
1626
|
+
* `nodeToParent` or `crossFieldKeyTable`.
|
|
1627
|
+
* @returns the number of children found.
|
|
1628
|
+
*/
|
|
1629
|
+
private validateFieldChanges(
|
|
1630
|
+
change: ModularChangeset,
|
|
1631
|
+
fieldChanges: FieldChangeMap,
|
|
1632
|
+
nodeParent: NodeId | undefined,
|
|
1633
|
+
): number {
|
|
1634
|
+
let numChildren = 0;
|
|
1635
|
+
for (const [field, fieldChange] of fieldChanges.entries()) {
|
|
1636
|
+
const fieldId = { nodeId: nodeParent, field };
|
|
1637
|
+
const handler = getChangeHandler(this.fieldKinds, fieldChange.fieldKind);
|
|
1638
|
+
for (const [child, _index] of handler.getNestedChanges(fieldChange.change)) {
|
|
1639
|
+
const parentFieldId = getParentFieldId(change, child);
|
|
1640
|
+
assert(areEqualFieldIds(parentFieldId, fieldId), "Inconsistent node parentage");
|
|
1641
|
+
numChildren += 1;
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
for (const keyRange of handler.getCrossFieldKeys(fieldChange.change)) {
|
|
1645
|
+
const fields = getFieldsForCrossFieldKey(change, keyRange);
|
|
1646
|
+
assert(
|
|
1647
|
+
fields.length === 1 &&
|
|
1648
|
+
fields[0] !== undefined &&
|
|
1649
|
+
areEqualFieldIds(fields[0], fieldId),
|
|
1650
|
+
"Inconsistent cross field keys",
|
|
1651
|
+
);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
return numChildren;
|
|
1656
|
+
}
|
|
1587
1657
|
}
|
|
1588
1658
|
|
|
1589
1659
|
function replaceCrossFieldKeyTableRevisions(
|
|
@@ -2059,6 +2129,7 @@ interface RebaseFieldContext {
|
|
|
2059
2129
|
function newComposeTable(
|
|
2060
2130
|
baseChange: ModularChangeset,
|
|
2061
2131
|
newChange: ModularChangeset,
|
|
2132
|
+
composedNodeToParent: ChangeAtomIdBTree<FieldId>,
|
|
2062
2133
|
): ComposeTable {
|
|
2063
2134
|
return {
|
|
2064
2135
|
...newCrossFieldTable<FieldChange>(),
|
|
@@ -2068,6 +2139,7 @@ function newComposeTable(
|
|
|
2068
2139
|
newFieldToBaseField: new Map(),
|
|
2069
2140
|
newToBaseNodeId: newTupleBTree(),
|
|
2070
2141
|
composedNodes: new Set(),
|
|
2142
|
+
composedNodeToParent,
|
|
2071
2143
|
pendingCompositions: {
|
|
2072
2144
|
nodeIdsToCompose: [],
|
|
2073
2145
|
affectedBaseFields: newTupleBTree(),
|
|
@@ -2087,6 +2159,7 @@ interface ComposeTable extends CrossFieldTable<FieldChange> {
|
|
|
2087
2159
|
readonly newFieldToBaseField: Map<FieldChange, FieldChange>;
|
|
2088
2160
|
readonly newToBaseNodeId: ChangeAtomIdBTree<NodeId>;
|
|
2089
2161
|
readonly composedNodes: Set<NodeChangeset>;
|
|
2162
|
+
readonly composedNodeToParent: ChangeAtomIdBTree<FieldId>;
|
|
2090
2163
|
readonly pendingCompositions: PendingCompositions;
|
|
2091
2164
|
}
|
|
2092
2165
|
|
|
@@ -2109,6 +2182,10 @@ interface PendingCompositions {
|
|
|
2109
2182
|
}
|
|
2110
2183
|
|
|
2111
2184
|
interface ComposeFieldContext {
|
|
2185
|
+
/**
|
|
2186
|
+
* The field ID for this field in the composed changeset.
|
|
2187
|
+
*/
|
|
2188
|
+
fieldId: FieldId;
|
|
2112
2189
|
change1: FieldChangeset;
|
|
2113
2190
|
change2: FieldChangeset;
|
|
2114
2191
|
composedChange: FieldChange;
|
|
@@ -2324,7 +2401,12 @@ class RebaseManager extends CrossFieldManagerI<FieldChange> {
|
|
|
2324
2401
|
|
|
2325
2402
|
// TODO: Deduplicate this with RebaseTable
|
|
2326
2403
|
class ComposeManager extends CrossFieldManagerI<FieldChange> {
|
|
2327
|
-
public constructor(
|
|
2404
|
+
public constructor(
|
|
2405
|
+
table: ComposeTable,
|
|
2406
|
+
currentField: FieldChange,
|
|
2407
|
+
private readonly fieldId: FieldId,
|
|
2408
|
+
allowInval = true,
|
|
2409
|
+
) {
|
|
2328
2410
|
super(table, currentField, allowInval);
|
|
2329
2411
|
}
|
|
2330
2412
|
|
|
@@ -2377,15 +2459,16 @@ class ComposeManager extends CrossFieldManagerI<FieldChange> {
|
|
|
2377
2459
|
}
|
|
2378
2460
|
|
|
2379
2461
|
public override onMoveIn(id: ChangeAtomId): void {
|
|
2380
|
-
|
|
2462
|
+
setInChangeAtomIdMap(this.table.composedNodeToParent, id, this.fieldId);
|
|
2381
2463
|
}
|
|
2464
|
+
|
|
2382
2465
|
public override moveKey(
|
|
2383
2466
|
target: CrossFieldTarget,
|
|
2384
2467
|
revision: RevisionTag | undefined,
|
|
2385
2468
|
id: ChangesetLocalId,
|
|
2386
2469
|
count: number,
|
|
2387
2470
|
): void {
|
|
2388
|
-
throw new Error("
|
|
2471
|
+
throw new Error("Moving cross-field keys during compose is currently unsupported");
|
|
2389
2472
|
}
|
|
2390
2473
|
|
|
2391
2474
|
private get table(): ComposeTable {
|
|
@@ -3022,3 +3105,7 @@ function getFromChangeAtomIdMap<T>(
|
|
|
3022
3105
|
function setInChangeAtomIdMap<T>(map: ChangeAtomIdBTree<T>, id: ChangeAtomId, value: T): void {
|
|
3023
3106
|
map.set([id.revision, id.localId], value);
|
|
3024
3107
|
}
|
|
3108
|
+
|
|
3109
|
+
function areEqualFieldIds(a: FieldId, b: FieldId): boolean {
|
|
3110
|
+
return areEqualChangeAtomIdOpts(a.nodeId, b.nodeId) && a.field === b.field;
|
|
3111
|
+
}
|
|
@@ -576,6 +576,9 @@ export class ComposeQueue {
|
|
|
576
576
|
private dequeueBase(length: number = Infinity): ComposeMarks {
|
|
577
577
|
const baseMark = this.baseMarks.dequeueUpTo(length);
|
|
578
578
|
const movedChanges = getMovedChangesFromMark(this.moveEffects, baseMark);
|
|
579
|
+
if (movedChanges !== undefined) {
|
|
580
|
+
this.moveEffects.onMoveIn(movedChanges);
|
|
581
|
+
}
|
|
579
582
|
|
|
580
583
|
const newMark = createNoopMark(baseMark.count, movedChanges, getOutputCellId(baseMark));
|
|
581
584
|
return { baseMark, newMark };
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type ChangesetLocalId,
|
|
11
11
|
type RevisionMetadataSource,
|
|
12
12
|
type RevisionTag,
|
|
13
|
+
areEqualChangeAtomIdOpts,
|
|
13
14
|
areEqualChangeAtomIds,
|
|
14
15
|
makeChangeAtomId,
|
|
15
16
|
} from "../../core/index.js";
|
|
@@ -118,10 +119,7 @@ export function isActiveReattach(
|
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
export function areEqualCellIds(a: CellId | undefined, b: CellId | undefined): boolean {
|
|
121
|
-
|
|
122
|
-
return a === b;
|
|
123
|
-
}
|
|
124
|
-
return areEqualChangeAtomIds(a, b);
|
|
122
|
+
return areEqualChangeAtomIdOpts(a, b);
|
|
125
123
|
}
|
|
126
124
|
|
|
127
125
|
export function getInputCellId(mark: Mark): CellId | undefined {
|
package/src/index.ts
CHANGED
package/src/packageVersion.ts
CHANGED
|
@@ -123,6 +123,10 @@ export class SchematizingSimpleTreeView<in out TRootSchema extends ImplicitField
|
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
public get schema(): TRootSchema {
|
|
127
|
+
return this.config.schema;
|
|
128
|
+
}
|
|
129
|
+
|
|
126
130
|
public initialize(content: InsertableTreeFieldFromImplicitField<TRootSchema>): void {
|
|
127
131
|
this.ensureUndisposed();
|
|
128
132
|
|
|
@@ -103,18 +103,10 @@ export interface JsonObjectNodeSchema extends JsonNodeSchemaBase<NodeKind.Object
|
|
|
103
103
|
export interface JsonArrayNodeSchema extends JsonNodeSchemaBase<NodeKind.Array, "array"> {
|
|
104
104
|
/**
|
|
105
105
|
* The kinds of items allowed under the array.
|
|
106
|
-
* @remarks Always represented via references to {@link JsonTreeSchema.$defs}.
|
|
107
106
|
*
|
|
108
107
|
* @see {@link https://json-schema.org/draft/2020-12/json-schema-core#name-items}.
|
|
109
108
|
*/
|
|
110
|
-
readonly items:
|
|
111
|
-
/**
|
|
112
|
-
* The kinds of items allowed under the array.
|
|
113
|
-
* @remarks Always represented via references to {@link JsonTreeSchema.$defs}.
|
|
114
|
-
* @see {@link https://json-schema.org/draft/2020-12/json-schema-core#name-anyof}.
|
|
115
|
-
*/
|
|
116
|
-
anyOf: JsonSchemaRef[];
|
|
117
|
-
};
|
|
109
|
+
readonly items: JsonFieldSchema;
|
|
118
110
|
}
|
|
119
111
|
|
|
120
112
|
/**
|
|
@@ -191,14 +183,24 @@ export type JsonNodeSchema =
|
|
|
191
183
|
* @sealed
|
|
192
184
|
* @alpha
|
|
193
185
|
*/
|
|
194
|
-
export
|
|
186
|
+
export type JsonFieldSchema = {
|
|
195
187
|
/**
|
|
196
|
-
*
|
|
197
|
-
* @remarks
|
|
198
|
-
* @see {@link https://json-schema.org/draft/2020-12/json-schema-
|
|
188
|
+
* Description of the field.
|
|
189
|
+
* @remarks Derived from {@link FieldSchemaMetadata.description}.
|
|
190
|
+
* @see {@link https://json-schema.org/draft/2020-12/json-schema-validation#name-title-and-description}
|
|
199
191
|
*/
|
|
200
|
-
readonly
|
|
201
|
-
}
|
|
192
|
+
readonly description?: string | undefined;
|
|
193
|
+
} & (
|
|
194
|
+
| {
|
|
195
|
+
/**
|
|
196
|
+
* The kinds of items allowed under the field, for polymorphic types.
|
|
197
|
+
* @remarks Always represented via references to {@link JsonTreeSchema.$defs}.
|
|
198
|
+
* @see {@link https://json-schema.org/draft/2020-12/json-schema-core#name-anyof}.
|
|
199
|
+
*/
|
|
200
|
+
readonly anyOf: JsonSchemaRef[];
|
|
201
|
+
}
|
|
202
|
+
| JsonSchemaRef
|
|
203
|
+
);
|
|
202
204
|
|
|
203
205
|
/**
|
|
204
206
|
* {@link https://json-schema.org/draft/2020-12/json-schema-core | JSON Schema} representation of a tree schema.
|
|
@@ -221,10 +223,10 @@ export interface JsonFieldSchema {
|
|
|
221
223
|
* @sealed
|
|
222
224
|
* @alpha
|
|
223
225
|
*/
|
|
224
|
-
export
|
|
226
|
+
export type JsonTreeSchema = JsonFieldSchema & {
|
|
225
227
|
/**
|
|
226
228
|
* The set of definitions reachable from this schema's root.
|
|
227
229
|
* @see {@link https://json-schema.org/draft/2020-12/json-schema-core#name-schema-re-use-with-defs}
|
|
228
230
|
*/
|
|
229
231
|
readonly $defs: Record<JsonSchemaId, JsonNodeSchema>;
|
|
230
|
-
}
|
|
232
|
+
};
|
|
@@ -552,11 +552,14 @@ export class SchemaFactory<
|
|
|
552
552
|
*
|
|
553
553
|
* @param t - The types allowed under the field.
|
|
554
554
|
* @param props - Optional properties to associate with the field.
|
|
555
|
+
*
|
|
556
|
+
* @typeParam TCustomMetadata - Custom metadata properties to associate with the field.
|
|
557
|
+
* See {@link FieldSchemaMetadata.custom}.
|
|
555
558
|
*/
|
|
556
|
-
public optional<const T extends ImplicitAllowedTypes>(
|
|
559
|
+
public optional<const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(
|
|
557
560
|
t: T,
|
|
558
|
-
props?: Omit<FieldProps
|
|
559
|
-
): FieldSchema<FieldKind.Optional, T> {
|
|
561
|
+
props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">,
|
|
562
|
+
): FieldSchema<FieldKind.Optional, T, TCustomMetadata> {
|
|
560
563
|
const defaultOptionalProvider: DefaultProvider = getDefaultProvider(() => {
|
|
561
564
|
return undefined;
|
|
562
565
|
});
|
|
@@ -575,11 +578,14 @@ export class SchemaFactory<
|
|
|
575
578
|
* @remarks
|
|
576
579
|
* Fields are required by default, but this API can be used to make the required nature explicit in the schema,
|
|
577
580
|
* and allows associating custom {@link FieldProps | properties} with the field.
|
|
581
|
+
*
|
|
582
|
+
* @typeParam TCustomMetadata - Custom metadata properties to associate with the field.
|
|
583
|
+
* See {@link FieldSchemaMetadata.custom}.
|
|
578
584
|
*/
|
|
579
|
-
public required<const T extends ImplicitAllowedTypes>(
|
|
585
|
+
public required<const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(
|
|
580
586
|
t: T,
|
|
581
|
-
props?: Omit<FieldProps
|
|
582
|
-
): FieldSchema<FieldKind.Required, T> {
|
|
587
|
+
props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">,
|
|
588
|
+
): FieldSchema<FieldKind.Required, T, TCustomMetadata> {
|
|
583
589
|
return createFieldSchema(FieldKind.Required, t, props);
|
|
584
590
|
}
|
|
585
591
|
|
|
@@ -110,6 +110,11 @@ export interface SimpleFieldSchema {
|
|
|
110
110
|
* A {@link SimpleTreeSchema} is needed to resolve these identifiers to their schema {@link SimpleTreeSchema.definitions}.
|
|
111
111
|
*/
|
|
112
112
|
readonly allowedTypes: ReadonlySet<string>;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* {@inheritDoc FieldSchemaMetadata.description}
|
|
116
|
+
*/
|
|
117
|
+
readonly description?: string | undefined;
|
|
113
118
|
}
|
|
114
119
|
|
|
115
120
|
/**
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { unreachableCase } from "@fluidframework/core-utils/internal";
|
|
6
|
+
import { oob, unreachableCase } from "@fluidframework/core-utils/internal";
|
|
7
7
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
8
8
|
import { ValueSchema } from "../../core/index.js";
|
|
9
|
-
import { getOrCreate } from "../../util/index.js";
|
|
9
|
+
import { getOrCreate, type Mutable } from "../../util/index.js";
|
|
10
10
|
import type {
|
|
11
11
|
JsonArrayNodeSchema,
|
|
12
12
|
JsonFieldSchema,
|
|
@@ -37,15 +37,20 @@ import { NodeKind } from "../core/index.js";
|
|
|
37
37
|
export function toJsonSchema(schema: SimpleTreeSchema): JsonTreeSchema {
|
|
38
38
|
const definitions = convertDefinitions(schema.definitions);
|
|
39
39
|
|
|
40
|
-
const
|
|
40
|
+
const allowedTypes: JsonSchemaRef[] = [];
|
|
41
41
|
for (const allowedType of schema.allowedTypes) {
|
|
42
|
-
|
|
42
|
+
allowedTypes.push(createSchemaRef(allowedType));
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
return allowedTypes.length === 1
|
|
46
|
+
? {
|
|
47
|
+
...(allowedTypes[0] ?? oob()),
|
|
48
|
+
$defs: definitions,
|
|
49
|
+
}
|
|
50
|
+
: {
|
|
51
|
+
$defs: definitions,
|
|
52
|
+
anyOf: allowedTypes,
|
|
53
|
+
};
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
function convertDefinitions(
|
|
@@ -90,12 +95,14 @@ function convertArrayNodeSchema(schema: SimpleArrayNodeSchema): JsonArrayNodeSch
|
|
|
90
95
|
schema.allowedTypes.forEach((type) => {
|
|
91
96
|
allowedTypes.push(createSchemaRef(type));
|
|
92
97
|
});
|
|
98
|
+
|
|
99
|
+
const items: JsonFieldSchema =
|
|
100
|
+
allowedTypes.length === 1 ? allowedTypes[0] ?? oob() : { anyOf: allowedTypes };
|
|
101
|
+
|
|
93
102
|
return {
|
|
94
103
|
type: "array",
|
|
95
104
|
_treeNodeSchemaKind: NodeKind.Array,
|
|
96
|
-
items
|
|
97
|
-
anyOf: allowedTypes,
|
|
98
|
-
},
|
|
105
|
+
items,
|
|
99
106
|
};
|
|
100
107
|
}
|
|
101
108
|
|
|
@@ -130,14 +137,25 @@ function convertObjectNodeSchema(schema: SimpleObjectNodeSchema): JsonObjectNode
|
|
|
130
137
|
const properties: Record<string, JsonFieldSchema> = {};
|
|
131
138
|
const required: string[] = [];
|
|
132
139
|
for (const [key, value] of Object.entries(schema.fields)) {
|
|
133
|
-
const
|
|
140
|
+
const allowedTypes: JsonSchemaRef[] = [];
|
|
134
141
|
for (const allowedType of value.allowedTypes) {
|
|
135
|
-
|
|
142
|
+
allowedTypes.push(createSchemaRef(allowedType));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const output: Mutable<JsonFieldSchema> =
|
|
146
|
+
allowedTypes.length === 1
|
|
147
|
+
? allowedTypes[0] ?? oob()
|
|
148
|
+
: {
|
|
149
|
+
anyOf: allowedTypes,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Don't include "description" property at all if it's not present in the input.
|
|
153
|
+
if (value.description !== undefined) {
|
|
154
|
+
output.description = value.description;
|
|
136
155
|
}
|
|
137
156
|
|
|
138
|
-
properties[key] =
|
|
139
|
-
|
|
140
|
-
};
|
|
157
|
+
properties[key] = output;
|
|
158
|
+
|
|
141
159
|
if (value.kind === FieldKind.Required) {
|
|
142
160
|
required.push(key);
|
|
143
161
|
}
|
|
@@ -160,9 +178,12 @@ function convertMapNodeSchema(schema: SimpleMapNodeSchema): JsonMapNodeSchema {
|
|
|
160
178
|
type: "object",
|
|
161
179
|
_treeNodeSchemaKind: NodeKind.Map,
|
|
162
180
|
patternProperties: {
|
|
163
|
-
"^.*$":
|
|
164
|
-
|
|
165
|
-
|
|
181
|
+
"^.*$":
|
|
182
|
+
allowedTypes.length === 1
|
|
183
|
+
? allowedTypes[0] ?? oob()
|
|
184
|
+
: {
|
|
185
|
+
anyOf: allowedTypes,
|
|
186
|
+
},
|
|
166
187
|
},
|
|
167
188
|
};
|
|
168
189
|
}
|
|
@@ -411,6 +411,11 @@ export interface TreeView<TSchema extends ImplicitFieldSchema> extends IDisposab
|
|
|
411
411
|
* Events for the tree.
|
|
412
412
|
*/
|
|
413
413
|
readonly events: Listenable<TreeViewEvents>;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* The view schema used by this TreeView.
|
|
417
|
+
*/
|
|
418
|
+
readonly schema: TSchema;
|
|
414
419
|
}
|
|
415
420
|
|
|
416
421
|
/**
|
|
@@ -19,7 +19,7 @@ import type {
|
|
|
19
19
|
SimpleTreeSchema,
|
|
20
20
|
} from "./simpleSchema.js";
|
|
21
21
|
import type { ValueSchema } from "../../core/index.js";
|
|
22
|
-
import { getOrCreate } from "../../util/index.js";
|
|
22
|
+
import { getOrCreate, type Mutable } from "../../util/index.js";
|
|
23
23
|
import { isObjectNodeSchema, type ObjectNodeSchema } from "../objectNodeTypes.js";
|
|
24
24
|
import { NodeKind, type TreeNodeSchema } from "../core/index.js";
|
|
25
25
|
|
|
@@ -126,11 +126,16 @@ function fieldSchemaToSimpleSchema(schema: FieldSchema): SimpleFieldSchema {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
const allowedTypes = allowedTypesFromFieldSchema(schema);
|
|
129
|
-
const result = {
|
|
129
|
+
const result: Mutable<SimpleFieldSchema> = {
|
|
130
130
|
kind: schema.kind,
|
|
131
131
|
allowedTypes,
|
|
132
132
|
};
|
|
133
133
|
|
|
134
|
+
// Don't include "description" property at all if it's not present.
|
|
135
|
+
if (schema.metadata?.description !== undefined) {
|
|
136
|
+
result.description = schema.metadata.description;
|
|
137
|
+
}
|
|
138
|
+
|
|
134
139
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
135
140
|
(schema as any)[simpleFieldSchemaCacheSymbol] = result;
|
|
136
141
|
|
package/src/simple-tree/index.ts
CHANGED