@fluidframework/tree 2.10.0-306579 → 2.10.0-307399

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.
Files changed (110) hide show
  1. package/api-report/tree.alpha.api.md +11 -9
  2. package/api-report/tree.beta.api.md +2 -0
  3. package/api-report/tree.legacy.alpha.api.md +2 -0
  4. package/api-report/tree.legacy.public.api.md +2 -0
  5. package/api-report/tree.public.api.md +2 -0
  6. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts +26 -5
  7. package/dist/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  8. package/dist/feature-libraries/chunked-forest/basicChunk.js +15 -5
  9. package/dist/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  10. package/dist/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  11. package/dist/feature-libraries/chunked-forest/chunkedForest.js +5 -0
  12. package/dist/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  13. package/dist/feature-libraries/index.d.ts +1 -1
  14. package/dist/feature-libraries/index.d.ts.map +1 -1
  15. package/dist/feature-libraries/index.js +2 -2
  16. package/dist/feature-libraries/index.js.map +1 -1
  17. package/dist/feature-libraries/modular-schema/discrepancies.d.ts +27 -27
  18. package/dist/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
  19. package/dist/feature-libraries/modular-schema/discrepancies.js +152 -193
  20. package/dist/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  21. package/dist/feature-libraries/modular-schema/index.d.ts +1 -1
  22. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  23. package/dist/feature-libraries/modular-schema/index.js +2 -2
  24. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  25. package/dist/packageVersion.d.ts +1 -1
  26. package/dist/packageVersion.js +1 -1
  27. package/dist/packageVersion.js.map +1 -1
  28. package/dist/shared-tree/treeApi.js +4 -1
  29. package/dist/shared-tree/treeApi.js.map +1 -1
  30. package/dist/simple-tree/api/schemaCreationUtilities.d.ts +12 -14
  31. package/dist/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  32. package/dist/simple-tree/api/schemaCreationUtilities.js +9 -7
  33. package/dist/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  34. package/dist/simple-tree/api/schemaFactory.d.ts +2 -0
  35. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  36. package/dist/simple-tree/api/schemaFactory.js +4 -1
  37. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  38. package/dist/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  39. package/dist/simple-tree/core/treeNodeKernel.d.ts +4 -5
  40. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  41. package/dist/simple-tree/core/treeNodeKernel.js +63 -67
  42. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  43. package/dist/simple-tree/objectNode.d.ts +1 -1
  44. package/dist/simple-tree/objectNode.js.map +1 -1
  45. package/dist/simple-tree/objectNodeTypes.d.ts +3 -0
  46. package/dist/simple-tree/objectNodeTypes.d.ts.map +1 -1
  47. package/dist/simple-tree/objectNodeTypes.js +3 -1
  48. package/dist/simple-tree/objectNodeTypes.js.map +1 -1
  49. package/docs/.attachments/object-merge-semantics.drawio +145 -0
  50. package/docs/user-facing/array-merge-semantics.md +344 -0
  51. package/docs/user-facing/map-merge-semantics.md +128 -0
  52. package/docs/user-facing/merge-semantics.md +7 -3
  53. package/docs/user-facing/object-merge-semantics.md +77 -0
  54. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts +26 -5
  55. package/lib/feature-libraries/chunked-forest/basicChunk.d.ts.map +1 -1
  56. package/lib/feature-libraries/chunked-forest/basicChunk.js +15 -5
  57. package/lib/feature-libraries/chunked-forest/basicChunk.js.map +1 -1
  58. package/lib/feature-libraries/chunked-forest/chunkedForest.d.ts.map +1 -1
  59. package/lib/feature-libraries/chunked-forest/chunkedForest.js +5 -0
  60. package/lib/feature-libraries/chunked-forest/chunkedForest.js.map +1 -1
  61. package/lib/feature-libraries/index.d.ts +1 -1
  62. package/lib/feature-libraries/index.d.ts.map +1 -1
  63. package/lib/feature-libraries/index.js +1 -1
  64. package/lib/feature-libraries/index.js.map +1 -1
  65. package/lib/feature-libraries/modular-schema/discrepancies.d.ts +27 -27
  66. package/lib/feature-libraries/modular-schema/discrepancies.d.ts.map +1 -1
  67. package/lib/feature-libraries/modular-schema/discrepancies.js +150 -191
  68. package/lib/feature-libraries/modular-schema/discrepancies.js.map +1 -1
  69. package/lib/feature-libraries/modular-schema/index.d.ts +1 -1
  70. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  71. package/lib/feature-libraries/modular-schema/index.js +1 -1
  72. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  73. package/lib/packageVersion.d.ts +1 -1
  74. package/lib/packageVersion.js +1 -1
  75. package/lib/packageVersion.js.map +1 -1
  76. package/lib/shared-tree/treeApi.js +5 -2
  77. package/lib/shared-tree/treeApi.js.map +1 -1
  78. package/lib/simple-tree/api/schemaCreationUtilities.d.ts +12 -14
  79. package/lib/simple-tree/api/schemaCreationUtilities.d.ts.map +1 -1
  80. package/lib/simple-tree/api/schemaCreationUtilities.js +9 -7
  81. package/lib/simple-tree/api/schemaCreationUtilities.js.map +1 -1
  82. package/lib/simple-tree/api/schemaFactory.d.ts +2 -0
  83. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  84. package/lib/simple-tree/api/schemaFactory.js +4 -1
  85. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  86. package/lib/simple-tree/api/schemaFactoryRecursive.js.map +1 -1
  87. package/lib/simple-tree/core/treeNodeKernel.d.ts +4 -5
  88. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  89. package/lib/simple-tree/core/treeNodeKernel.js +64 -68
  90. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  91. package/lib/simple-tree/objectNode.d.ts +1 -1
  92. package/lib/simple-tree/objectNode.js.map +1 -1
  93. package/lib/simple-tree/objectNodeTypes.d.ts +3 -0
  94. package/lib/simple-tree/objectNodeTypes.d.ts.map +1 -1
  95. package/lib/simple-tree/objectNodeTypes.js +3 -1
  96. package/lib/simple-tree/objectNodeTypes.js.map +1 -1
  97. package/package.json +23 -31
  98. package/src/feature-libraries/chunked-forest/basicChunk.ts +12 -4
  99. package/src/feature-libraries/chunked-forest/chunkedForest.ts +5 -0
  100. package/src/feature-libraries/index.ts +1 -1
  101. package/src/feature-libraries/modular-schema/discrepancies.ts +202 -241
  102. package/src/feature-libraries/modular-schema/index.ts +4 -1
  103. package/src/packageVersion.ts +1 -1
  104. package/src/shared-tree/treeApi.ts +7 -5
  105. package/src/simple-tree/api/schemaCreationUtilities.ts +29 -17
  106. package/src/simple-tree/api/schemaFactory.ts +25 -18
  107. package/src/simple-tree/api/schemaFactoryRecursive.ts +1 -1
  108. package/src/simple-tree/core/treeNodeKernel.ts +62 -64
  109. package/src/simple-tree/objectNode.ts +1 -1
  110. package/src/simple-tree/objectNodeTypes.ts +3 -1
@@ -6,39 +6,39 @@ import { type FieldKindIdentifier, type TreeStoredSchema, type ValueSchema } fro
6
6
  /**
7
7
  * @remarks
8
8
  *
9
- * 1. FieldIncompatibility
9
+ * 1. FieldDiscrepancy
10
10
  *
11
- * `FieldIncompatibility` represents the differences between two `TreeFieldStoredSchema` objects. It consists of
11
+ * `FieldDiscrepancy` represents the differences between two `TreeFieldStoredSchema` objects. It consists of
12
12
  * three types of incompatibilities:
13
13
  *
14
- * - FieldKindIncompatibility: Indicates the differences in `FieldKindIdentifier` between two `TreeFieldStoredSchema`
14
+ * - FieldKindDiscrepancy: Indicates the differences in `FieldKindIdentifier` between two `TreeFieldStoredSchema`
15
15
  * objects (e.g., optional, required, sequence, etc.).
16
- * - AllowedTypesIncompatibility: Indicates the differences in the allowed child types between the two schemas.
17
- * - ValueSchemaIncompatibility: Specifically indicates the differences in the `ValueSchema` of two
16
+ * - AllowedTypesDiscrepancy: Indicates the differences in the allowed child types between the two schemas.
17
+ * - ValueSchemaDiscrepancy: Specifically indicates the differences in the `ValueSchema` of two
18
18
  * `LeafNodeStoredSchema` objects.
19
19
  *
20
- * 2. NodeIncompatibility
20
+ * 2. NodeDiscrepancy
21
21
  *
22
- * `NodeIncompatibility` represents the differences between two `TreeNodeStoredSchema` objects and includes:
22
+ * `NodeDiscrepancy` represents the differences between two `TreeNodeStoredSchema` objects and includes:
23
23
  *
24
- * - NodeKindIncompatibility: Indicates the differences in the types of `TreeNodeStoredSchema` (currently supports
24
+ * - NodeKindDiscrepancy: Indicates the differences in the types of `TreeNodeStoredSchema` (currently supports
25
25
  * `ObjectNodeStoredSchema`, `MapNodeStoredSchema`, and `LeafNodeStoredSchema`).
26
- * - NodeFieldsIncompatibility: Indicates the `FieldIncompatibility` of `TreeFieldStoredSchema` within two
27
- * `TreeNodeStoredSchema`. It includes an array of `FieldIncompatibility` instances in the `differences` field.
26
+ * - NodeFieldsDiscrepancy: Indicates the `FieldDiscrepancy` of `TreeFieldStoredSchema` within two
27
+ * `TreeNodeStoredSchema`. It includes an array of `FieldDiscrepancy` instances in the `differences` field.
28
28
  *
29
29
  * When comparing two nodes for compatibility, it only makes sense to compare their fields if the nodes are of
30
30
  * the same kind (map, object, leaf).
31
31
  *
32
- * 3. Incompatibility
32
+ * 3. Discrepancy
33
33
  *
34
- * Incompatibility consists of both `NodeIncompatibility` and `FieldIncompatibility`, representing any kind of
35
- * schema differences. See {@link getAllowedContentIncompatibilities} for more details about how we process it
34
+ * Discrepancy consists of both `NodeDiscrepancy` and `FieldDiscrepancy`, representing any kind of
35
+ * schema differences. See {@link getAllowedContentDiscrepancies} for more details about how we process it
36
36
  * and the ordering.
37
37
  */
38
- export type Incompatibility = FieldIncompatibility | NodeIncompatibility;
39
- export type NodeIncompatibility = NodeKindIncompatibility | NodeFieldsIncompatibility;
40
- export type FieldIncompatibility = AllowedTypeIncompatibility | FieldKindIncompatibility | ValueSchemaIncompatibility;
41
- export interface AllowedTypeIncompatibility {
38
+ export type Discrepancy = FieldDiscrepancy | NodeDiscrepancy;
39
+ export type NodeDiscrepancy = NodeKindDiscrepancy | NodeFieldsDiscrepancy;
40
+ export type FieldDiscrepancy = AllowedTypeDiscrepancy | FieldKindDiscrepancy | ValueSchemaDiscrepancy;
41
+ export interface AllowedTypeDiscrepancy {
42
42
  identifier: string | undefined;
43
43
  mismatch: "allowedTypes";
44
44
  /**
@@ -50,48 +50,48 @@ export interface AllowedTypeIncompatibility {
50
50
  */
51
51
  stored: string[];
52
52
  }
53
- export interface FieldKindIncompatibility {
53
+ export interface FieldKindDiscrepancy {
54
54
  identifier: string | undefined;
55
55
  mismatch: "fieldKind";
56
56
  view: FieldKindIdentifier;
57
57
  stored: FieldKindIdentifier;
58
58
  }
59
- export interface ValueSchemaIncompatibility {
59
+ export interface ValueSchemaDiscrepancy {
60
60
  identifier: string;
61
61
  mismatch: "valueSchema";
62
62
  view: ValueSchema | undefined;
63
63
  stored: ValueSchema | undefined;
64
64
  }
65
- export interface NodeKindIncompatibility {
65
+ export interface NodeKindDiscrepancy {
66
66
  identifier: string;
67
67
  mismatch: "nodeKind";
68
68
  view: SchemaFactoryNodeKind | undefined;
69
69
  stored: SchemaFactoryNodeKind | undefined;
70
70
  }
71
- export interface NodeFieldsIncompatibility {
71
+ export interface NodeFieldsDiscrepancy {
72
72
  identifier: string;
73
73
  mismatch: "fields";
74
- differences: FieldIncompatibility[];
74
+ differences: FieldDiscrepancy[];
75
75
  }
76
76
  type SchemaFactoryNodeKind = "object" | "leaf" | "map";
77
77
  /**
78
- * @remarks
78
+ * Finds and reports discrepancies between a view schema and a stored schema.
79
79
  *
80
80
  * The workflow for finding schema incompatibilities:
81
- * 1. Compare the two root schemas to identify any `FieldIncompatibility`.
81
+ * 1. Compare the two root schemas to identify any `FieldDiscrepancy`.
82
82
  *
83
83
  * 2. For each node schema in the `view`:
84
84
  * - Verify if the node schema exists in the stored. If it does, ensure that the `SchemaFactoryNodeKind` are
85
- * consistent. Otherwise this difference is treated as `NodeKindIncompatibility`
85
+ * consistent. Otherwise this difference is treated as `NodeKindDiscrepancy`
86
86
  * - If a node schema with the same identifier exists in both view and stored, and their `SchemaFactoryNodeKind`
87
- * are consistent, perform a exhaustive validation to identify all `FieldIncompatibility`.
87
+ * are consistent, perform a exhaustive validation to identify all `FieldDiscrepancy`.
88
88
  *
89
89
  * 3. For each node schema in the stored, verify if it exists in the view. The overlapping parts were already
90
90
  * addressed in the previous step.
91
91
  *
92
92
  * @returns the discrepancies between two TreeStoredSchema objects
93
93
  */
94
- export declare function getAllowedContentIncompatibilities(view: TreeStoredSchema, stored: TreeStoredSchema): Incompatibility[];
94
+ export declare function getAllowedContentDiscrepancies(view: TreeStoredSchema, stored: TreeStoredSchema): Iterable<Discrepancy>;
95
95
  /**
96
96
  * @remarks
97
97
  *
@@ -1 +1 @@
1
- {"version":3,"file":"discrepancies.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/modular-schema/discrepancies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAEN,KAAK,mBAAmB,EAOxB,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAChB,MAAM,qBAAqB,CAAC;AAO7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,MAAM,eAAe,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;AAEzE,MAAM,MAAM,mBAAmB,GAAG,uBAAuB,GAAG,yBAAyB,CAAC;AAEtF,MAAM,MAAM,oBAAoB,GAC7B,0BAA0B,GAC1B,wBAAwB,GACxB,0BAA0B,CAAC;AAE9B,MAAM,WAAW,0BAA0B;IAC1C,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACxC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,WAAW,CAAC;IACtB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,mBAAmB,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACxC,MAAM,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,yBAAyB;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACpC;AAED,KAAK,qBAAqB,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kCAAkC,CACjD,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,gBAAgB,GACtB,eAAe,EAAE,CA8JnB;AAwGD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAkCxF"}
1
+ {"version":3,"file":"discrepancies.d.ts","sourceRoot":"","sources":["../../../src/feature-libraries/modular-schema/discrepancies.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,KAAK,mBAAmB,EAQxB,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAChB,MAAM,qBAAqB,CAAC;AAO7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAE7D,MAAM,MAAM,eAAe,GAAG,mBAAmB,GAAG,qBAAqB,CAAC;AAE1E,MAAM,MAAM,gBAAgB,GACzB,sBAAsB,GACtB,oBAAoB,GACpB,sBAAsB,CAAC;AAE1B,MAAM,WAAW,sBAAsB;IACtC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACpC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,EAAE,WAAW,CAAC;IACtB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,MAAM,EAAE,mBAAmB,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC;IACxB,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACxC,MAAM,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,qBAAqB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,KAAK,qBAAqB,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;AAavD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAiB,8BAA8B,CAC9C,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,gBAAgB,GACtB,QAAQ,CAAC,WAAW,CAAC,CAkCvB;AAkLD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAkCxF"}
@@ -5,209 +5,144 @@
5
5
  import { assert } from "@fluidframework/core-utils/internal";
6
6
  import { LeafNodeStoredSchema, MapNodeStoredSchema, ObjectNodeStoredSchema, storedEmptyFieldSchema, } from "../../core/index.js";
7
7
  import { brand } from "../../util/index.js";
8
+ function getNodeSchemaType(nodeSchema) {
9
+ if (nodeSchema instanceof ObjectNodeStoredSchema) {
10
+ return "object";
11
+ }
12
+ else if (nodeSchema instanceof MapNodeStoredSchema) {
13
+ return "map";
14
+ }
15
+ else if (nodeSchema instanceof LeafNodeStoredSchema) {
16
+ return "leaf";
17
+ }
18
+ throwUnsupportedNodeType(nodeSchema.constructor.name);
19
+ }
8
20
  /**
9
- * @remarks
21
+ * Finds and reports discrepancies between a view schema and a stored schema.
10
22
  *
11
23
  * The workflow for finding schema incompatibilities:
12
- * 1. Compare the two root schemas to identify any `FieldIncompatibility`.
24
+ * 1. Compare the two root schemas to identify any `FieldDiscrepancy`.
13
25
  *
14
26
  * 2. For each node schema in the `view`:
15
27
  * - Verify if the node schema exists in the stored. If it does, ensure that the `SchemaFactoryNodeKind` are
16
- * consistent. Otherwise this difference is treated as `NodeKindIncompatibility`
28
+ * consistent. Otherwise this difference is treated as `NodeKindDiscrepancy`
17
29
  * - If a node schema with the same identifier exists in both view and stored, and their `SchemaFactoryNodeKind`
18
- * are consistent, perform a exhaustive validation to identify all `FieldIncompatibility`.
30
+ * are consistent, perform a exhaustive validation to identify all `FieldDiscrepancy`.
19
31
  *
20
32
  * 3. For each node schema in the stored, verify if it exists in the view. The overlapping parts were already
21
33
  * addressed in the previous step.
22
34
  *
23
35
  * @returns the discrepancies between two TreeStoredSchema objects
24
36
  */
25
- export function getAllowedContentIncompatibilities(view, stored) {
26
- const incompatibilities = [];
37
+ export function* getAllowedContentDiscrepancies(view, stored) {
27
38
  // check root schema discrepancies
28
- incompatibilities.push(...trackFieldDiscrepancies(view.rootFieldSchema, stored.rootFieldSchema));
29
- // Verify the existence and type of a node schema given its identifier (key), then determine if
30
- // an exhaustive search is necessary.
31
- const viewNodeKeys = new Set();
32
- for (const [key, viewNodeSchema] of view.nodeSchema) {
33
- viewNodeKeys.add(key);
34
- if (viewNodeSchema instanceof ObjectNodeStoredSchema) {
35
- if (!stored.nodeSchema.has(key)) {
36
- incompatibilities.push({
37
- identifier: key,
39
+ yield* getFieldDiscrepancies(view.rootFieldSchema, stored.rootFieldSchema);
40
+ for (const result of compareMaps(view.nodeSchema, stored.nodeSchema)) {
41
+ switch (result.type) {
42
+ case "aExtra": {
43
+ const viewType = getNodeSchemaType(result.value);
44
+ yield {
45
+ identifier: result.key,
38
46
  mismatch: "nodeKind",
39
- view: "object",
47
+ view: viewType,
40
48
  stored: undefined,
41
- });
42
- }
43
- else {
44
- const storedNodeSchema = stored.nodeSchema.get(key);
45
- assert(storedNodeSchema !== undefined, 0x9be /* The storedNodeSchema in stored.nodeSchema should not be undefined */);
46
- if (storedNodeSchema instanceof MapNodeStoredSchema) {
47
- incompatibilities.push({
48
- identifier: key,
49
- mismatch: "nodeKind",
50
- view: "object",
51
- stored: "map",
52
- });
53
- }
54
- else if (storedNodeSchema instanceof LeafNodeStoredSchema) {
55
- incompatibilities.push({
56
- identifier: key,
57
- mismatch: "nodeKind",
58
- view: "object",
59
- stored: "leaf",
60
- });
61
- }
62
- else if (storedNodeSchema instanceof ObjectNodeStoredSchema) {
63
- const differences = trackObjectNodeDiscrepancies(viewNodeSchema, storedNodeSchema);
64
- if (differences.length > 0) {
65
- incompatibilities.push({
66
- identifier: key,
67
- mismatch: "fields",
68
- differences,
69
- });
70
- }
71
- }
72
- else {
73
- throwUnsupportedNodeType(storedNodeSchema.constructor.name);
74
- }
49
+ };
50
+ break;
75
51
  }
76
- }
77
- else if (viewNodeSchema instanceof MapNodeStoredSchema) {
78
- if (!stored.nodeSchema.has(key)) {
79
- incompatibilities.push({
80
- identifier: key,
52
+ case "bExtra": {
53
+ const storedType = getNodeSchemaType(result.value);
54
+ yield {
55
+ identifier: result.key,
81
56
  mismatch: "nodeKind",
82
- view: "map",
83
- stored: undefined,
84
- });
57
+ view: undefined,
58
+ stored: storedType,
59
+ };
60
+ break;
85
61
  }
86
- else {
87
- const storedNodeSchema = stored.nodeSchema.get(key);
88
- assert(storedNodeSchema !== undefined, 0x9bf /* The storedNodeSchema in stored.nodeSchema should not be undefined */);
89
- if (storedNodeSchema instanceof ObjectNodeStoredSchema) {
90
- incompatibilities.push({
91
- identifier: key,
92
- mismatch: "nodeKind",
93
- view: "map",
94
- stored: "object",
95
- });
96
- }
97
- else if (storedNodeSchema instanceof LeafNodeStoredSchema) {
98
- incompatibilities.push({
99
- identifier: key,
100
- mismatch: "nodeKind",
101
- view: "map",
102
- stored: "leaf",
103
- });
104
- }
105
- else if (storedNodeSchema instanceof MapNodeStoredSchema) {
106
- incompatibilities.push(...trackFieldDiscrepancies(viewNodeSchema.mapFields, storedNodeSchema.mapFields, key));
107
- }
108
- else {
109
- throwUnsupportedNodeType(storedNodeSchema.constructor.name);
110
- }
62
+ case "both": {
63
+ yield* getNodeDiscrepancies(result.key, result.valueA, result.valueB);
64
+ break;
111
65
  }
66
+ default:
67
+ break;
112
68
  }
113
- else if (viewNodeSchema instanceof LeafNodeStoredSchema) {
114
- if (!stored.nodeSchema.has(key)) {
115
- incompatibilities.push({
116
- identifier: key,
117
- mismatch: "nodeKind",
118
- view: "leaf",
119
- stored: undefined,
120
- });
121
- }
122
- else {
123
- const storedNodeSchema = stored.nodeSchema.get(key);
124
- assert(storedNodeSchema !== undefined, 0x9c0 /* The storedNodeSchema in stored.nodeSchema should not be undefined */);
125
- if (storedNodeSchema instanceof MapNodeStoredSchema) {
126
- incompatibilities.push({
127
- identifier: key,
128
- mismatch: "nodeKind",
129
- view: "leaf",
130
- stored: "map",
131
- });
132
- }
133
- else if (storedNodeSchema instanceof ObjectNodeStoredSchema) {
134
- incompatibilities.push({
135
- identifier: key,
136
- mismatch: "nodeKind",
137
- view: "leaf",
138
- stored: "object",
139
- });
140
- }
141
- else if (storedNodeSchema instanceof LeafNodeStoredSchema) {
142
- if (viewNodeSchema.leafValue !== storedNodeSchema.leafValue) {
143
- incompatibilities.push({
144
- identifier: key,
145
- mismatch: "valueSchema",
146
- view: viewNodeSchema.leafValue,
147
- stored: storedNodeSchema.leafValue,
148
- });
149
- }
150
- }
151
- else {
152
- throwUnsupportedNodeType(storedNodeSchema.constructor.name);
153
- }
69
+ }
70
+ }
71
+ function* getNodeDiscrepancies(identifier, view, stored) {
72
+ const viewType = getNodeSchemaType(view);
73
+ const storedType = getNodeSchemaType(stored);
74
+ if (viewType !== storedType) {
75
+ yield {
76
+ identifier,
77
+ mismatch: "nodeKind",
78
+ view: viewType,
79
+ stored: storedType,
80
+ };
81
+ return;
82
+ }
83
+ switch (viewType) {
84
+ case "object": {
85
+ const differences = Array.from(trackObjectNodeDiscrepancies(view, stored));
86
+ if (differences.length > 0) {
87
+ yield {
88
+ identifier,
89
+ mismatch: "fields",
90
+ differences,
91
+ };
154
92
  }
93
+ break;
155
94
  }
156
- else {
157
- throwUnsupportedNodeType(viewNodeSchema.constructor.name);
158
- }
159
- }
160
- for (const [key, storedNodeSchema] of stored.nodeSchema) {
161
- if (!viewNodeKeys.has(key)) {
162
- incompatibilities.push({
163
- identifier: key,
164
- mismatch: "nodeKind",
165
- view: undefined,
166
- stored: storedNodeSchema instanceof MapNodeStoredSchema
167
- ? "map"
168
- : storedNodeSchema instanceof ObjectNodeStoredSchema
169
- ? "object"
170
- : "leaf",
171
- });
95
+ case "map":
96
+ yield* getFieldDiscrepancies(view.mapFields, stored.mapFields, identifier);
97
+ break;
98
+ case "leaf": {
99
+ const viewValue = view.leafValue;
100
+ const storedValue = stored.leafValue;
101
+ if (viewValue !== storedValue) {
102
+ yield {
103
+ identifier,
104
+ mismatch: "valueSchema",
105
+ view: viewValue,
106
+ stored: storedValue,
107
+ };
108
+ }
109
+ break;
172
110
  }
111
+ default:
112
+ break;
173
113
  }
174
- return incompatibilities;
175
114
  }
176
115
  /**
177
116
  * The function to track the discrepancies between two field stored schemas.
178
117
  *
179
118
  * @param keyOrRoot - If the key is missing, it indicates that this is the root field schema.
180
119
  */
181
- function trackFieldDiscrepancies(view, stored, keyOrRoot) {
182
- const differences = [];
120
+ function* getFieldDiscrepancies(view, stored, keyOrRoot) {
183
121
  // Only track the symmetric differences of two sets.
184
122
  const findSetDiscrepancies = (a, b) => {
185
123
  const aDiff = [...a].filter((value) => !b.has(value));
186
124
  const bDiff = [...b].filter((value) => !a.has(value));
187
125
  return [aDiff, bDiff];
188
126
  };
189
- const allowedTypesDiscrepancies = findSetDiscrepancies(view.types, stored.types);
190
- if (allowedTypesDiscrepancies[0].length > 0 || allowedTypesDiscrepancies[1].length > 0) {
191
- differences.push({
127
+ const [viewExtra, storedExtra] = findSetDiscrepancies(view.types, stored.types);
128
+ if (viewExtra.length > 0 || storedExtra.length > 0) {
129
+ yield {
192
130
  identifier: keyOrRoot,
193
131
  mismatch: "allowedTypes",
194
- view: allowedTypesDiscrepancies[0],
195
- stored: allowedTypesDiscrepancies[1],
196
- });
132
+ view: viewExtra,
133
+ stored: storedExtra,
134
+ };
197
135
  }
198
136
  if (view.kind !== stored.kind) {
199
- differences.push({
137
+ yield {
200
138
  identifier: keyOrRoot,
201
139
  mismatch: "fieldKind",
202
140
  view: view.kind,
203
141
  stored: stored.kind,
204
- });
142
+ };
205
143
  }
206
- return differences;
207
144
  }
208
- function trackObjectNodeDiscrepancies(view, stored) {
209
- const differences = [];
210
- const viewFieldKeys = new Set();
145
+ function* trackObjectNodeDiscrepancies(view, stored) {
211
146
  /**
212
147
  * Similar to the logic used for tracking discrepancies between two node schemas, we will identify
213
148
  * three types of differences:
@@ -218,35 +153,59 @@ function trackObjectNodeDiscrepancies(view, stored) {
218
153
  * First, the view schema is iterated to track the first two types of differences.
219
154
  * Then, the stored schema is iterated to find the third type.
220
155
  */
221
- for (const [fieldKey, fieldStoredSchema] of view.objectNodeFields) {
222
- viewFieldKeys.add(fieldKey);
223
- if (!stored.objectNodeFields.has(fieldKey) &&
224
- fieldStoredSchema.kind !== storedEmptyFieldSchema.kind) {
225
- differences.push({
226
- identifier: fieldKey,
227
- mismatch: "fieldKind",
228
- view: fieldStoredSchema.kind,
229
- stored: storedEmptyFieldSchema.kind,
230
- });
231
- }
232
- else {
233
- differences.push(...trackFieldDiscrepancies(view.objectNodeFields.get(fieldKey), stored.objectNodeFields.get(fieldKey), fieldKey));
156
+ for (const result of compareMaps(view.objectNodeFields, stored.objectNodeFields)) {
157
+ const fieldKey = result.key;
158
+ switch (result.type) {
159
+ case "aExtra": {
160
+ if (result.value.kind === storedEmptyFieldSchema.kind) {
161
+ // In one of view/stored, this field is explicitly forbidden, but in the other it is implicitly forbidden
162
+ // (by way of omission). We treat these identically anyway.
163
+ break;
164
+ }
165
+ yield {
166
+ identifier: fieldKey,
167
+ mismatch: "fieldKind",
168
+ view: result.value.kind,
169
+ stored: storedEmptyFieldSchema.kind,
170
+ };
171
+ break;
172
+ }
173
+ case "bExtra": {
174
+ if (result.value.kind === storedEmptyFieldSchema.kind) {
175
+ // In one of view/stored, this field is explicitly forbidden, but in the other it is implicitly forbidden
176
+ // (by way of omission). We treat these identically anyway.
177
+ break;
178
+ }
179
+ yield {
180
+ identifier: fieldKey,
181
+ mismatch: "fieldKind",
182
+ view: storedEmptyFieldSchema.kind,
183
+ stored: result.value.kind,
184
+ };
185
+ break;
186
+ }
187
+ case "both": {
188
+ yield* getFieldDiscrepancies(result.valueA, result.valueB, fieldKey);
189
+ break;
190
+ }
191
+ default: {
192
+ break;
193
+ }
234
194
  }
235
195
  }
236
- for (const [fieldKey, fieldStoredSchema] of stored.objectNodeFields) {
237
- if (viewFieldKeys.has(fieldKey)) {
238
- continue;
239
- }
240
- if (fieldStoredSchema.kind !== storedEmptyFieldSchema.kind) {
241
- differences.push({
242
- identifier: fieldKey,
243
- mismatch: "fieldKind",
244
- view: storedEmptyFieldSchema.kind,
245
- stored: fieldStoredSchema.kind,
246
- });
196
+ }
197
+ function* compareMaps(a, b) {
198
+ for (const [key, valueA] of a) {
199
+ const valueB = b.get(key);
200
+ yield valueB === undefined
201
+ ? { type: "aExtra", key, value: valueA }
202
+ : { type: "both", key, valueA, valueB };
203
+ }
204
+ for (const [key, valueB] of b) {
205
+ if (!a.has(key)) {
206
+ yield { type: "bExtra", key, value: valueB };
247
207
  }
248
208
  }
249
- return differences;
250
209
  }
251
210
  /**
252
211
  * @remarks
@@ -266,11 +225,11 @@ function trackObjectNodeDiscrepancies(view, stored) {
266
225
  * validating internal fields.
267
226
  */
268
227
  export function isRepoSuperset(view, stored) {
269
- const incompatibilities = getAllowedContentIncompatibilities(view, stored);
270
- for (const incompatibility of incompatibilities) {
271
- switch (incompatibility.mismatch) {
228
+ const discrepancies = getAllowedContentDiscrepancies(view, stored);
229
+ for (const discrepancy of discrepancies) {
230
+ switch (discrepancy.mismatch) {
272
231
  case "nodeKind": {
273
- if (incompatibility.stored !== undefined) {
232
+ if (discrepancy.stored !== undefined) {
274
233
  // It's fine for the view schema to know of a node type that the stored schema doesn't know about.
275
234
  return false;
276
235
  }
@@ -279,13 +238,13 @@ export function isRepoSuperset(view, stored) {
279
238
  case "valueSchema":
280
239
  case "allowedTypes":
281
240
  case "fieldKind": {
282
- if (!validateFieldIncompatibility(incompatibility)) {
241
+ if (!isFieldDiscrepancyCompatible(discrepancy)) {
283
242
  return false;
284
243
  }
285
244
  break;
286
245
  }
287
246
  case "fields": {
288
- if (incompatibility.differences.some((difference) => !validateFieldIncompatibility(difference))) {
247
+ if (discrepancy.differences.some((difference) => !isFieldDiscrepancyCompatible(difference))) {
289
248
  return false;
290
249
  }
291
250
  break;
@@ -295,16 +254,16 @@ export function isRepoSuperset(view, stored) {
295
254
  }
296
255
  return true;
297
256
  }
298
- function validateFieldIncompatibility(incompatibility) {
299
- switch (incompatibility.mismatch) {
257
+ function isFieldDiscrepancyCompatible(discrepancy) {
258
+ switch (discrepancy.mismatch) {
300
259
  case "allowedTypes": {
301
260
  // Since we only track the symmetric difference between the allowed types in the view and
302
261
  // stored schemas, it's sufficient to check if any extra allowed types still exist in the
303
262
  // stored schema.
304
- return incompatibility.stored.length === 0;
263
+ return discrepancy.stored.length === 0;
305
264
  }
306
265
  case "fieldKind": {
307
- return posetLte(incompatibility.stored, incompatibility.view, fieldRealizer);
266
+ return posetLte(discrepancy.stored, discrepancy.view, fieldRealizer);
308
267
  }
309
268
  case "valueSchema": {
310
269
  return false;