@fluidframework/tree 2.10.0-307060 → 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.
@@ -91,7 +91,7 @@ type SchemaFactoryNodeKind = "object" | "leaf" | "map";
91
91
  *
92
92
  * @returns the discrepancies between two TreeStoredSchema objects
93
93
  */
94
- export declare function getAllowedContentDiscrepancies(view: TreeStoredSchema, stored: TreeStoredSchema): Discrepancy[];
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,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;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,8BAA8B,CAC7C,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,gBAAgB,GACtB,WAAW,EAAE,CA4Jf;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"}
@@ -8,6 +8,18 @@ exports.isRepoSuperset = exports.getAllowedContentDiscrepancies = void 0;
8
8
  const internal_1 = require("@fluidframework/core-utils/internal");
9
9
  const index_js_1 = require("../../core/index.js");
10
10
  const index_js_2 = require("../../util/index.js");
11
+ function getNodeSchemaType(nodeSchema) {
12
+ if (nodeSchema instanceof index_js_1.ObjectNodeStoredSchema) {
13
+ return "object";
14
+ }
15
+ else if (nodeSchema instanceof index_js_1.MapNodeStoredSchema) {
16
+ return "map";
17
+ }
18
+ else if (nodeSchema instanceof index_js_1.LeafNodeStoredSchema) {
19
+ return "leaf";
20
+ }
21
+ throwUnsupportedNodeType(nodeSchema.constructor.name);
22
+ }
11
23
  /**
12
24
  * Finds and reports discrepancies between a view schema and a stored schema.
13
25
  *
@@ -25,193 +37,116 @@ const index_js_2 = require("../../util/index.js");
25
37
  *
26
38
  * @returns the discrepancies between two TreeStoredSchema objects
27
39
  */
28
- function getAllowedContentDiscrepancies(view, stored) {
29
- const discrepancies = [];
40
+ function* getAllowedContentDiscrepancies(view, stored) {
30
41
  // check root schema discrepancies
31
- discrepancies.push(...trackFieldDiscrepancies(view.rootFieldSchema, stored.rootFieldSchema));
32
- // Verify the existence and type of a node schema given its identifier (key), then determine if
33
- // an exhaustive search is necessary.
34
- const viewNodeKeys = new Set();
35
- for (const [key, viewNodeSchema] of view.nodeSchema) {
36
- viewNodeKeys.add(key);
37
- if (viewNodeSchema instanceof index_js_1.ObjectNodeStoredSchema) {
38
- if (!stored.nodeSchema.has(key)) {
39
- discrepancies.push({
40
- identifier: key,
42
+ yield* getFieldDiscrepancies(view.rootFieldSchema, stored.rootFieldSchema);
43
+ for (const result of compareMaps(view.nodeSchema, stored.nodeSchema)) {
44
+ switch (result.type) {
45
+ case "aExtra": {
46
+ const viewType = getNodeSchemaType(result.value);
47
+ yield {
48
+ identifier: result.key,
41
49
  mismatch: "nodeKind",
42
- view: "object",
50
+ view: viewType,
43
51
  stored: undefined,
44
- });
45
- }
46
- else {
47
- const storedNodeSchema = stored.nodeSchema.get(key);
48
- (0, internal_1.assert)(storedNodeSchema !== undefined, 0x9be /* The storedNodeSchema in stored.nodeSchema should not be undefined */);
49
- if (storedNodeSchema instanceof index_js_1.MapNodeStoredSchema) {
50
- discrepancies.push({
51
- identifier: key,
52
- mismatch: "nodeKind",
53
- view: "object",
54
- stored: "map",
55
- });
56
- }
57
- else if (storedNodeSchema instanceof index_js_1.LeafNodeStoredSchema) {
58
- discrepancies.push({
59
- identifier: key,
60
- mismatch: "nodeKind",
61
- view: "object",
62
- stored: "leaf",
63
- });
64
- }
65
- else if (storedNodeSchema instanceof index_js_1.ObjectNodeStoredSchema) {
66
- const differences = trackObjectNodeDiscrepancies(viewNodeSchema, storedNodeSchema);
67
- if (differences.length > 0) {
68
- discrepancies.push({
69
- identifier: key,
70
- mismatch: "fields",
71
- differences,
72
- });
73
- }
74
- }
75
- else {
76
- throwUnsupportedNodeType(storedNodeSchema.constructor.name);
77
- }
52
+ };
53
+ break;
78
54
  }
79
- }
80
- else if (viewNodeSchema instanceof index_js_1.MapNodeStoredSchema) {
81
- if (!stored.nodeSchema.has(key)) {
82
- discrepancies.push({
83
- identifier: key,
55
+ case "bExtra": {
56
+ const storedType = getNodeSchemaType(result.value);
57
+ yield {
58
+ identifier: result.key,
84
59
  mismatch: "nodeKind",
85
- view: "map",
86
- stored: undefined,
87
- });
60
+ view: undefined,
61
+ stored: storedType,
62
+ };
63
+ break;
88
64
  }
89
- else {
90
- const storedNodeSchema = stored.nodeSchema.get(key);
91
- (0, internal_1.assert)(storedNodeSchema !== undefined, 0x9bf /* The storedNodeSchema in stored.nodeSchema should not be undefined */);
92
- if (storedNodeSchema instanceof index_js_1.ObjectNodeStoredSchema) {
93
- discrepancies.push({
94
- identifier: key,
95
- mismatch: "nodeKind",
96
- view: "map",
97
- stored: "object",
98
- });
99
- }
100
- else if (storedNodeSchema instanceof index_js_1.LeafNodeStoredSchema) {
101
- discrepancies.push({
102
- identifier: key,
103
- mismatch: "nodeKind",
104
- view: "map",
105
- stored: "leaf",
106
- });
107
- }
108
- else if (storedNodeSchema instanceof index_js_1.MapNodeStoredSchema) {
109
- discrepancies.push(...trackFieldDiscrepancies(viewNodeSchema.mapFields, storedNodeSchema.mapFields, key));
110
- }
111
- else {
112
- throwUnsupportedNodeType(storedNodeSchema.constructor.name);
113
- }
65
+ case "both": {
66
+ yield* getNodeDiscrepancies(result.key, result.valueA, result.valueB);
67
+ break;
114
68
  }
69
+ default:
70
+ break;
115
71
  }
116
- else if (viewNodeSchema instanceof index_js_1.LeafNodeStoredSchema) {
117
- if (!stored.nodeSchema.has(key)) {
118
- discrepancies.push({
119
- identifier: key,
120
- mismatch: "nodeKind",
121
- view: "leaf",
122
- stored: undefined,
123
- });
124
- }
125
- else {
126
- const storedNodeSchema = stored.nodeSchema.get(key);
127
- (0, internal_1.assert)(storedNodeSchema !== undefined, 0x9c0 /* The storedNodeSchema in stored.nodeSchema should not be undefined */);
128
- if (storedNodeSchema instanceof index_js_1.MapNodeStoredSchema) {
129
- discrepancies.push({
130
- identifier: key,
131
- mismatch: "nodeKind",
132
- view: "leaf",
133
- stored: "map",
134
- });
135
- }
136
- else if (storedNodeSchema instanceof index_js_1.ObjectNodeStoredSchema) {
137
- discrepancies.push({
138
- identifier: key,
139
- mismatch: "nodeKind",
140
- view: "leaf",
141
- stored: "object",
142
- });
143
- }
144
- else if (storedNodeSchema instanceof index_js_1.LeafNodeStoredSchema) {
145
- if (viewNodeSchema.leafValue !== storedNodeSchema.leafValue) {
146
- discrepancies.push({
147
- identifier: key,
148
- mismatch: "valueSchema",
149
- view: viewNodeSchema.leafValue,
150
- stored: storedNodeSchema.leafValue,
151
- });
152
- }
153
- }
154
- else {
155
- throwUnsupportedNodeType(storedNodeSchema.constructor.name);
156
- }
72
+ }
73
+ }
74
+ exports.getAllowedContentDiscrepancies = getAllowedContentDiscrepancies;
75
+ function* getNodeDiscrepancies(identifier, view, stored) {
76
+ const viewType = getNodeSchemaType(view);
77
+ const storedType = getNodeSchemaType(stored);
78
+ if (viewType !== storedType) {
79
+ yield {
80
+ identifier,
81
+ mismatch: "nodeKind",
82
+ view: viewType,
83
+ stored: storedType,
84
+ };
85
+ return;
86
+ }
87
+ switch (viewType) {
88
+ case "object": {
89
+ const differences = Array.from(trackObjectNodeDiscrepancies(view, stored));
90
+ if (differences.length > 0) {
91
+ yield {
92
+ identifier,
93
+ mismatch: "fields",
94
+ differences,
95
+ };
157
96
  }
97
+ break;
158
98
  }
159
- else {
160
- throwUnsupportedNodeType(viewNodeSchema.constructor.name);
161
- }
162
- }
163
- for (const [key, storedNodeSchema] of stored.nodeSchema) {
164
- if (!viewNodeKeys.has(key)) {
165
- discrepancies.push({
166
- identifier: key,
167
- mismatch: "nodeKind",
168
- view: undefined,
169
- stored: storedNodeSchema instanceof index_js_1.MapNodeStoredSchema
170
- ? "map"
171
- : storedNodeSchema instanceof index_js_1.ObjectNodeStoredSchema
172
- ? "object"
173
- : "leaf",
174
- });
99
+ case "map":
100
+ yield* getFieldDiscrepancies(view.mapFields, stored.mapFields, identifier);
101
+ break;
102
+ case "leaf": {
103
+ const viewValue = view.leafValue;
104
+ const storedValue = stored.leafValue;
105
+ if (viewValue !== storedValue) {
106
+ yield {
107
+ identifier,
108
+ mismatch: "valueSchema",
109
+ view: viewValue,
110
+ stored: storedValue,
111
+ };
112
+ }
113
+ break;
175
114
  }
115
+ default:
116
+ break;
176
117
  }
177
- return discrepancies;
178
118
  }
179
- exports.getAllowedContentDiscrepancies = getAllowedContentDiscrepancies;
180
119
  /**
181
120
  * The function to track the discrepancies between two field stored schemas.
182
121
  *
183
122
  * @param keyOrRoot - If the key is missing, it indicates that this is the root field schema.
184
123
  */
185
- function trackFieldDiscrepancies(view, stored, keyOrRoot) {
186
- const differences = [];
124
+ function* getFieldDiscrepancies(view, stored, keyOrRoot) {
187
125
  // Only track the symmetric differences of two sets.
188
126
  const findSetDiscrepancies = (a, b) => {
189
127
  const aDiff = [...a].filter((value) => !b.has(value));
190
128
  const bDiff = [...b].filter((value) => !a.has(value));
191
129
  return [aDiff, bDiff];
192
130
  };
193
- const allowedTypesDiscrepancies = findSetDiscrepancies(view.types, stored.types);
194
- if (allowedTypesDiscrepancies[0].length > 0 || allowedTypesDiscrepancies[1].length > 0) {
195
- differences.push({
131
+ const [viewExtra, storedExtra] = findSetDiscrepancies(view.types, stored.types);
132
+ if (viewExtra.length > 0 || storedExtra.length > 0) {
133
+ yield {
196
134
  identifier: keyOrRoot,
197
135
  mismatch: "allowedTypes",
198
- view: allowedTypesDiscrepancies[0],
199
- stored: allowedTypesDiscrepancies[1],
200
- });
136
+ view: viewExtra,
137
+ stored: storedExtra,
138
+ };
201
139
  }
202
140
  if (view.kind !== stored.kind) {
203
- differences.push({
141
+ yield {
204
142
  identifier: keyOrRoot,
205
143
  mismatch: "fieldKind",
206
144
  view: view.kind,
207
145
  stored: stored.kind,
208
- });
146
+ };
209
147
  }
210
- return differences;
211
148
  }
212
- function trackObjectNodeDiscrepancies(view, stored) {
213
- const differences = [];
214
- const viewFieldKeys = new Set();
149
+ function* trackObjectNodeDiscrepancies(view, stored) {
215
150
  /**
216
151
  * Similar to the logic used for tracking discrepancies between two node schemas, we will identify
217
152
  * three types of differences:
@@ -222,35 +157,59 @@ function trackObjectNodeDiscrepancies(view, stored) {
222
157
  * First, the view schema is iterated to track the first two types of differences.
223
158
  * Then, the stored schema is iterated to find the third type.
224
159
  */
225
- for (const [fieldKey, fieldStoredSchema] of view.objectNodeFields) {
226
- viewFieldKeys.add(fieldKey);
227
- if (!stored.objectNodeFields.has(fieldKey) &&
228
- fieldStoredSchema.kind !== index_js_1.storedEmptyFieldSchema.kind) {
229
- differences.push({
230
- identifier: fieldKey,
231
- mismatch: "fieldKind",
232
- view: fieldStoredSchema.kind,
233
- stored: index_js_1.storedEmptyFieldSchema.kind,
234
- });
235
- }
236
- else {
237
- differences.push(...trackFieldDiscrepancies(view.objectNodeFields.get(fieldKey), stored.objectNodeFields.get(fieldKey), fieldKey));
160
+ for (const result of compareMaps(view.objectNodeFields, stored.objectNodeFields)) {
161
+ const fieldKey = result.key;
162
+ switch (result.type) {
163
+ case "aExtra": {
164
+ if (result.value.kind === index_js_1.storedEmptyFieldSchema.kind) {
165
+ // In one of view/stored, this field is explicitly forbidden, but in the other it is implicitly forbidden
166
+ // (by way of omission). We treat these identically anyway.
167
+ break;
168
+ }
169
+ yield {
170
+ identifier: fieldKey,
171
+ mismatch: "fieldKind",
172
+ view: result.value.kind,
173
+ stored: index_js_1.storedEmptyFieldSchema.kind,
174
+ };
175
+ break;
176
+ }
177
+ case "bExtra": {
178
+ if (result.value.kind === index_js_1.storedEmptyFieldSchema.kind) {
179
+ // In one of view/stored, this field is explicitly forbidden, but in the other it is implicitly forbidden
180
+ // (by way of omission). We treat these identically anyway.
181
+ break;
182
+ }
183
+ yield {
184
+ identifier: fieldKey,
185
+ mismatch: "fieldKind",
186
+ view: index_js_1.storedEmptyFieldSchema.kind,
187
+ stored: result.value.kind,
188
+ };
189
+ break;
190
+ }
191
+ case "both": {
192
+ yield* getFieldDiscrepancies(result.valueA, result.valueB, fieldKey);
193
+ break;
194
+ }
195
+ default: {
196
+ break;
197
+ }
238
198
  }
239
199
  }
240
- for (const [fieldKey, fieldStoredSchema] of stored.objectNodeFields) {
241
- if (viewFieldKeys.has(fieldKey)) {
242
- continue;
243
- }
244
- if (fieldStoredSchema.kind !== index_js_1.storedEmptyFieldSchema.kind) {
245
- differences.push({
246
- identifier: fieldKey,
247
- mismatch: "fieldKind",
248
- view: index_js_1.storedEmptyFieldSchema.kind,
249
- stored: fieldStoredSchema.kind,
250
- });
200
+ }
201
+ function* compareMaps(a, b) {
202
+ for (const [key, valueA] of a) {
203
+ const valueB = b.get(key);
204
+ yield valueB === undefined
205
+ ? { type: "aExtra", key, value: valueA }
206
+ : { type: "both", key, valueA, valueB };
207
+ }
208
+ for (const [key, valueB] of b) {
209
+ if (!a.has(key)) {
210
+ yield { type: "bExtra", key, value: valueB };
251
211
  }
252
212
  }
253
- return differences;
254
213
  }
255
214
  /**
256
215
  * @remarks
@@ -283,13 +242,13 @@ function isRepoSuperset(view, stored) {
283
242
  case "valueSchema":
284
243
  case "allowedTypes":
285
244
  case "fieldKind": {
286
- if (!validateFieldIncompatibility(discrepancy)) {
245
+ if (!isFieldDiscrepancyCompatible(discrepancy)) {
287
246
  return false;
288
247
  }
289
248
  break;
290
249
  }
291
250
  case "fields": {
292
- if (discrepancy.differences.some((difference) => !validateFieldIncompatibility(difference))) {
251
+ if (discrepancy.differences.some((difference) => !isFieldDiscrepancyCompatible(difference))) {
293
252
  return false;
294
253
  }
295
254
  break;
@@ -300,7 +259,7 @@ function isRepoSuperset(view, stored) {
300
259
  return true;
301
260
  }
302
261
  exports.isRepoSuperset = isRepoSuperset;
303
- function validateFieldIncompatibility(discrepancy) {
262
+ function isFieldDiscrepancyCompatible(discrepancy) {
304
263
  switch (discrepancy.mismatch) {
305
264
  case "allowedTypes": {
306
265
  // Since we only track the symmetric difference between the allowed types in the view and
@@ -1 +1 @@
1
- {"version":3,"file":"discrepancies.js","sourceRoot":"","sources":["../../../src/feature-libraries/modular-schema/discrepancies.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype FieldKey,\n\ttype FieldKindIdentifier,\n\tLeafNodeStoredSchema,\n\tMapNodeStoredSchema,\n\tObjectNodeStoredSchema,\n\tstoredEmptyFieldSchema,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype TreeStoredSchema,\n\ttype TreeTypeSet,\n\ttype ValueSchema,\n} from \"../../core/index.js\";\nimport { brand } from \"../../util/index.js\";\n\n// TODO:\n// The comparisons in this file seem redundant with those in comparison.ts.\n// Rather than both existing, one of which just returns boolean and the other which returns additional details, a simple comparison which returns everything needed should be used.\n\n/**\n * @remarks\n *\n * 1. FieldDiscrepancy\n *\n * `FieldDiscrepancy` represents the differences between two `TreeFieldStoredSchema` objects. It consists of\n * three types of incompatibilities:\n *\n * - FieldKindDiscrepancy: Indicates the differences in `FieldKindIdentifier` between two `TreeFieldStoredSchema`\n * objects (e.g., optional, required, sequence, etc.).\n * - AllowedTypesDiscrepancy: Indicates the differences in the allowed child types between the two schemas.\n * - ValueSchemaDiscrepancy: Specifically indicates the differences in the `ValueSchema` of two\n * `LeafNodeStoredSchema` objects.\n *\n * 2. NodeDiscrepancy\n *\n * `NodeDiscrepancy` represents the differences between two `TreeNodeStoredSchema` objects and includes:\n *\n * - NodeKindDiscrepancy: Indicates the differences in the types of `TreeNodeStoredSchema` (currently supports\n * `ObjectNodeStoredSchema`, `MapNodeStoredSchema`, and `LeafNodeStoredSchema`).\n * - NodeFieldsDiscrepancy: Indicates the `FieldDiscrepancy` of `TreeFieldStoredSchema` within two\n * `TreeNodeStoredSchema`. It includes an array of `FieldDiscrepancy` instances in the `differences` field.\n *\n * When comparing two nodes for compatibility, it only makes sense to compare their fields if the nodes are of\n * the same kind (map, object, leaf).\n *\n * 3. Discrepancy\n *\n * Discrepancy consists of both `NodeDiscrepancy` and `FieldDiscrepancy`, representing any kind of\n * schema differences. See {@link getAllowedContentDiscrepancies} for more details about how we process it\n * and the ordering.\n */\nexport type Discrepancy = FieldDiscrepancy | NodeDiscrepancy;\n\nexport type NodeDiscrepancy = NodeKindDiscrepancy | NodeFieldsDiscrepancy;\n\nexport type FieldDiscrepancy =\n\t| AllowedTypeDiscrepancy\n\t| FieldKindDiscrepancy\n\t| ValueSchemaDiscrepancy;\n\nexport interface AllowedTypeDiscrepancy {\n\tidentifier: string | undefined; // undefined indicates root field schema\n\tmismatch: \"allowedTypes\";\n\t/**\n\t * List of allowed type identifiers in viewed schema\n\t */\n\tview: string[];\n\t/**\n\t * List of allowed type identifiers in stored schema\n\t */\n\tstored: string[];\n}\n\nexport interface FieldKindDiscrepancy {\n\tidentifier: string | undefined; // undefined indicates root field schema\n\tmismatch: \"fieldKind\";\n\tview: FieldKindIdentifier;\n\tstored: FieldKindIdentifier;\n}\n\nexport interface ValueSchemaDiscrepancy {\n\tidentifier: string;\n\tmismatch: \"valueSchema\";\n\tview: ValueSchema | undefined;\n\tstored: ValueSchema | undefined;\n}\n\nexport interface NodeKindDiscrepancy {\n\tidentifier: string;\n\tmismatch: \"nodeKind\";\n\tview: SchemaFactoryNodeKind | undefined;\n\tstored: SchemaFactoryNodeKind | undefined;\n}\n\nexport interface NodeFieldsDiscrepancy {\n\tidentifier: string;\n\tmismatch: \"fields\";\n\tdifferences: FieldDiscrepancy[];\n}\n\ntype SchemaFactoryNodeKind = \"object\" | \"leaf\" | \"map\";\n\n/**\n * Finds and reports discrepancies between a view schema and a stored schema.\n *\n * The workflow for finding schema incompatibilities:\n * 1. Compare the two root schemas to identify any `FieldDiscrepancy`.\n *\n * 2. For each node schema in the `view`:\n * - Verify if the node schema exists in the stored. If it does, ensure that the `SchemaFactoryNodeKind` are\n * consistent. Otherwise this difference is treated as `NodeKindDiscrepancy`\n * - If a node schema with the same identifier exists in both view and stored, and their `SchemaFactoryNodeKind`\n * are consistent, perform a exhaustive validation to identify all `FieldDiscrepancy`.\n *\n * 3. For each node schema in the stored, verify if it exists in the view. The overlapping parts were already\n * addressed in the previous step.\n *\n * @returns the discrepancies between two TreeStoredSchema objects\n */\nexport function getAllowedContentDiscrepancies(\n\tview: TreeStoredSchema,\n\tstored: TreeStoredSchema,\n): Discrepancy[] {\n\tconst discrepancies: Discrepancy[] = [];\n\n\t// check root schema discrepancies\n\tdiscrepancies.push(...trackFieldDiscrepancies(view.rootFieldSchema, stored.rootFieldSchema));\n\n\t// Verify the existence and type of a node schema given its identifier (key), then determine if\n\t// an exhaustive search is necessary.\n\tconst viewNodeKeys = new Set<TreeNodeSchemaIdentifier>();\n\tfor (const [key, viewNodeSchema] of view.nodeSchema) {\n\t\tviewNodeKeys.add(key);\n\n\t\tif (viewNodeSchema instanceof ObjectNodeStoredSchema) {\n\t\t\tif (!stored.nodeSchema.has(key)) {\n\t\t\t\tdiscrepancies.push({\n\t\t\t\t\tidentifier: key,\n\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\tview: \"object\",\n\t\t\t\t\tstored: undefined,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst storedNodeSchema = stored.nodeSchema.get(key);\n\t\t\t\tassert(\n\t\t\t\t\tstoredNodeSchema !== undefined,\n\t\t\t\t\t0x9be /* The storedNodeSchema in stored.nodeSchema should not be undefined */,\n\t\t\t\t);\n\t\t\t\tif (storedNodeSchema instanceof MapNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\t\tview: \"object\",\n\t\t\t\t\t\tstored: \"map\",\n\t\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t\t} else if (storedNodeSchema instanceof LeafNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\t\tview: \"object\",\n\t\t\t\t\t\tstored: \"leaf\",\n\t\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t\t} else if (storedNodeSchema instanceof ObjectNodeStoredSchema) {\n\t\t\t\t\tconst differences = trackObjectNodeDiscrepancies(viewNodeSchema, storedNodeSchema);\n\t\t\t\t\tif (differences.length > 0) {\n\t\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\t\tmismatch: \"fields\",\n\t\t\t\t\t\t\tdifferences,\n\t\t\t\t\t\t} satisfies NodeFieldsDiscrepancy);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthrowUnsupportedNodeType(storedNodeSchema.constructor.name);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (viewNodeSchema instanceof MapNodeStoredSchema) {\n\t\t\tif (!stored.nodeSchema.has(key)) {\n\t\t\t\tdiscrepancies.push({\n\t\t\t\t\tidentifier: key,\n\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\tview: \"map\",\n\t\t\t\t\tstored: undefined,\n\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t} else {\n\t\t\t\tconst storedNodeSchema = stored.nodeSchema.get(key);\n\t\t\t\tassert(\n\t\t\t\t\tstoredNodeSchema !== undefined,\n\t\t\t\t\t0x9bf /* The storedNodeSchema in stored.nodeSchema should not be undefined */,\n\t\t\t\t);\n\t\t\t\tif (storedNodeSchema instanceof ObjectNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\t\tview: \"map\",\n\t\t\t\t\t\tstored: \"object\",\n\t\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t\t} else if (storedNodeSchema instanceof LeafNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\t\tview: \"map\",\n\t\t\t\t\t\tstored: \"leaf\",\n\t\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t\t} else if (storedNodeSchema instanceof MapNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push(\n\t\t\t\t\t\t...trackFieldDiscrepancies(\n\t\t\t\t\t\t\tviewNodeSchema.mapFields,\n\t\t\t\t\t\t\tstoredNodeSchema.mapFields,\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthrowUnsupportedNodeType(storedNodeSchema.constructor.name);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (viewNodeSchema instanceof LeafNodeStoredSchema) {\n\t\t\tif (!stored.nodeSchema.has(key)) {\n\t\t\t\tdiscrepancies.push({\n\t\t\t\t\tidentifier: key,\n\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\tview: \"leaf\",\n\t\t\t\t\tstored: undefined,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tconst storedNodeSchema = stored.nodeSchema.get(key);\n\t\t\t\tassert(\n\t\t\t\t\tstoredNodeSchema !== undefined,\n\t\t\t\t\t0x9c0 /* The storedNodeSchema in stored.nodeSchema should not be undefined */,\n\t\t\t\t);\n\t\t\t\tif (storedNodeSchema instanceof MapNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\t\tview: \"leaf\",\n\t\t\t\t\t\tstored: \"map\",\n\t\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t\t} else if (storedNodeSchema instanceof ObjectNodeStoredSchema) {\n\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\t\tview: \"leaf\",\n\t\t\t\t\t\tstored: \"object\",\n\t\t\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t\t\t} else if (storedNodeSchema instanceof LeafNodeStoredSchema) {\n\t\t\t\t\tif (viewNodeSchema.leafValue !== storedNodeSchema.leafValue) {\n\t\t\t\t\t\tdiscrepancies.push({\n\t\t\t\t\t\t\tidentifier: key,\n\t\t\t\t\t\t\tmismatch: \"valueSchema\",\n\t\t\t\t\t\t\tview: viewNodeSchema.leafValue,\n\t\t\t\t\t\t\tstored: storedNodeSchema.leafValue,\n\t\t\t\t\t\t} satisfies ValueSchemaDiscrepancy);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tthrowUnsupportedNodeType(storedNodeSchema.constructor.name);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrowUnsupportedNodeType(viewNodeSchema.constructor.name);\n\t\t}\n\t}\n\n\tfor (const [key, storedNodeSchema] of stored.nodeSchema) {\n\t\tif (!viewNodeKeys.has(key)) {\n\t\t\tdiscrepancies.push({\n\t\t\t\tidentifier: key,\n\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\tview: undefined,\n\t\t\t\tstored:\n\t\t\t\t\tstoredNodeSchema instanceof MapNodeStoredSchema\n\t\t\t\t\t\t? \"map\"\n\t\t\t\t\t\t: storedNodeSchema instanceof ObjectNodeStoredSchema\n\t\t\t\t\t\t\t? \"object\"\n\t\t\t\t\t\t\t: \"leaf\",\n\t\t\t} satisfies NodeKindDiscrepancy);\n\t\t}\n\t}\n\n\treturn discrepancies;\n}\n\n/**\n * The function to track the discrepancies between two field stored schemas.\n *\n * @param keyOrRoot - If the key is missing, it indicates that this is the root field schema.\n */\nfunction trackFieldDiscrepancies(\n\tview: TreeFieldStoredSchema,\n\tstored: TreeFieldStoredSchema,\n\tkeyOrRoot?: string,\n): FieldDiscrepancy[] {\n\tconst differences: FieldDiscrepancy[] = [];\n\n\t// Only track the symmetric differences of two sets.\n\tconst findSetDiscrepancies = (\n\t\ta: TreeTypeSet,\n\t\tb: TreeTypeSet,\n\t): [TreeNodeSchemaIdentifier[], TreeNodeSchemaIdentifier[]] => {\n\t\tconst aDiff = [...a].filter((value) => !b.has(value));\n\t\tconst bDiff = [...b].filter((value) => !a.has(value));\n\t\treturn [aDiff, bDiff];\n\t};\n\n\tconst allowedTypesDiscrepancies = findSetDiscrepancies(view.types, stored.types);\n\tif (allowedTypesDiscrepancies[0].length > 0 || allowedTypesDiscrepancies[1].length > 0) {\n\t\tdifferences.push({\n\t\t\tidentifier: keyOrRoot,\n\t\t\tmismatch: \"allowedTypes\",\n\t\t\tview: allowedTypesDiscrepancies[0],\n\t\t\tstored: allowedTypesDiscrepancies[1],\n\t\t} satisfies AllowedTypeDiscrepancy);\n\t}\n\n\tif (view.kind !== stored.kind) {\n\t\tdifferences.push({\n\t\t\tidentifier: keyOrRoot,\n\t\t\tmismatch: \"fieldKind\",\n\t\t\tview: view.kind,\n\t\t\tstored: stored.kind,\n\t\t} satisfies FieldKindDiscrepancy);\n\t}\n\n\treturn differences;\n}\n\nfunction trackObjectNodeDiscrepancies(\n\tview: ObjectNodeStoredSchema,\n\tstored: ObjectNodeStoredSchema,\n): FieldDiscrepancy[] {\n\tconst differences: FieldDiscrepancy[] = [];\n\tconst viewFieldKeys = new Set<FieldKey>();\n\t/**\n\t * Similar to the logic used for tracking discrepancies between two node schemas, we will identify\n\t * three types of differences:\n\t * 1. Fields that exist in the view schema but not in the stored schema.\n\t * 2. Fields that exist in both schemas but have different contents.\n\t * 3. Fields that exist in the stored schema but not in the view schema.\n\t *\n\t * First, the view schema is iterated to track the first two types of differences.\n\t * Then, the stored schema is iterated to find the third type.\n\t */\n\n\tfor (const [fieldKey, fieldStoredSchema] of view.objectNodeFields) {\n\t\tviewFieldKeys.add(fieldKey);\n\t\tif (\n\t\t\t!stored.objectNodeFields.has(fieldKey) &&\n\t\t\tfieldStoredSchema.kind !== storedEmptyFieldSchema.kind\n\t\t) {\n\t\t\tdifferences.push({\n\t\t\t\tidentifier: fieldKey,\n\t\t\t\tmismatch: \"fieldKind\",\n\t\t\t\tview: fieldStoredSchema.kind,\n\t\t\t\tstored: storedEmptyFieldSchema.kind,\n\t\t\t} satisfies FieldKindDiscrepancy);\n\t\t} else {\n\t\t\tdifferences.push(\n\t\t\t\t...trackFieldDiscrepancies(\n\t\t\t\t\tview.objectNodeFields.get(fieldKey) as TreeFieldStoredSchema,\n\t\t\t\t\tstored.objectNodeFields.get(fieldKey) as TreeFieldStoredSchema,\n\t\t\t\t\tfieldKey,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\tfor (const [fieldKey, fieldStoredSchema] of stored.objectNodeFields) {\n\t\tif (viewFieldKeys.has(fieldKey)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (fieldStoredSchema.kind !== storedEmptyFieldSchema.kind) {\n\t\t\tdifferences.push({\n\t\t\t\tidentifier: fieldKey,\n\t\t\t\tmismatch: \"fieldKind\",\n\t\t\t\tview: storedEmptyFieldSchema.kind,\n\t\t\t\tstored: fieldStoredSchema.kind,\n\t\t\t} satisfies FieldKindDiscrepancy);\n\t\t}\n\t}\n\n\treturn differences;\n}\n\n/**\n * @remarks\n *\n * This function uses incompatibilities to determine if changes to a document schema are backward-compatible, i.e., it determines\n * whether the `view` schema allows a superset of the documents that the `stored` schema allows.\n * According to the policy of schema evolution, `isRepoSuperset` supports three types of changes:\n * 1. Adding an optional field to an object node.\n * 2. Expanding the set of allowed types for a field.\n * 3. Relaxing a field kind to a more general field kind.\n *\n * Notes: We expect isRepoSuperset to return consistent results with allowsRepoSuperset. However, currently there are some scenarios\n * where the inconsistency will occur:\n *\n * - Different Node Kinds: If a and b have different node kinds (e.g., a is an objectNodeSchema and b is a mapNodeSchema),\n * `isRepoSuperset` will determine that a can never be the superset of b. In contrast, `allowsRepoSuperset` will continue\n * validating internal fields.\n */\nexport function isRepoSuperset(view: TreeStoredSchema, stored: TreeStoredSchema): boolean {\n\tconst discrepancies = getAllowedContentDiscrepancies(view, stored);\n\n\tfor (const discrepancy of discrepancies) {\n\t\tswitch (discrepancy.mismatch) {\n\t\t\tcase \"nodeKind\": {\n\t\t\t\tif (discrepancy.stored !== undefined) {\n\t\t\t\t\t// It's fine for the view schema to know of a node type that the stored schema doesn't know about.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"valueSchema\":\n\t\t\tcase \"allowedTypes\":\n\t\t\tcase \"fieldKind\": {\n\t\t\t\tif (!validateFieldIncompatibility(discrepancy)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"fields\": {\n\t\t\t\tif (\n\t\t\t\t\tdiscrepancy.differences.some(\n\t\t\t\t\t\t(difference) => !validateFieldIncompatibility(difference),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction validateFieldIncompatibility(discrepancy: FieldDiscrepancy): boolean {\n\tswitch (discrepancy.mismatch) {\n\t\tcase \"allowedTypes\": {\n\t\t\t// Since we only track the symmetric difference between the allowed types in the view and\n\t\t\t// stored schemas, it's sufficient to check if any extra allowed types still exist in the\n\t\t\t// stored schema.\n\t\t\treturn discrepancy.stored.length === 0;\n\t\t}\n\t\tcase \"fieldKind\": {\n\t\t\treturn posetLte(discrepancy.stored, discrepancy.view, fieldRealizer);\n\t\t}\n\t\tcase \"valueSchema\": {\n\t\t\treturn false;\n\t\t}\n\t\t// No default\n\t}\n\treturn false;\n}\n\n/**\n * A linear extension of a partially-ordered set of `T`s. See:\n * https://en.wikipedia.org/wiki/Linear_extension\n *\n * The linear extension is represented as a lookup from each poset element to its index in the linear extension.\n */\ntype LinearExtension<T> = Map<T, number>;\n\n/**\n * A realizer for a partially-ordered set. See:\n * https://en.wikipedia.org/wiki/Order_dimension\n */\ntype Realizer<T> = LinearExtension<T>[];\n\n/**\n * @privateRemarks\n * TODO: Knowledge of specific field kinds is not appropriate for modular schema.\n * This bit of field comparison should be dependency injected by default-schema if this comparison logic remains in modular-schema\n * (this is analogous to what is done in comparison.ts).\n */\nconst FieldKindIdentifiers = {\n\tforbidden: brand<FieldKindIdentifier>(\"Forbidden\"),\n\trequired: brand<FieldKindIdentifier>(\"Value\"),\n\tidentifier: brand<FieldKindIdentifier>(\"Identifier\"),\n\toptional: brand<FieldKindIdentifier>(\"Optional\"),\n\tsequence: brand<FieldKindIdentifier>(\"Sequence\"),\n};\n\n/**\n * A realizer for the partial order of field kind relaxability.\n *\n * It seems extremely likely that this partial order will remain dimension 2 over time (i.e. the set of allowed relaxations can be visualized\n * with a [dominance drawing](https://en.wikipedia.org/wiki/Dominance_drawing)), so this strategy allows efficient comarison between field kinds\n * without excessive casework.\n *\n * Hasse diagram for the partial order is shown below (lower fields can be relaxed to higher fields):\n * ```\n * sequence\n * |\n * optional\n * | \\\n * required forbidden\n * |\n * identifier\n * ```\n */\nconst fieldRealizer: Realizer<FieldKindIdentifier> = [\n\t[\n\t\tFieldKindIdentifiers.forbidden,\n\t\tFieldKindIdentifiers.identifier,\n\t\tFieldKindIdentifiers.required,\n\t\tFieldKindIdentifiers.optional,\n\t\tFieldKindIdentifiers.sequence,\n\t],\n\t[\n\t\tFieldKindIdentifiers.identifier,\n\t\tFieldKindIdentifiers.required,\n\t\tFieldKindIdentifiers.forbidden,\n\t\tFieldKindIdentifiers.optional,\n\t\tFieldKindIdentifiers.sequence,\n\t],\n].map((extension) => new Map(extension.map((identifier, index) => [identifier, index])));\n\nconst PosetComparisonResult = {\n\tLess: \"<\",\n\tGreater: \">\",\n\tEqual: \"=\",\n\tIncomparable: \"||\",\n} as const;\ntype PosetComparisonResult =\n\t(typeof PosetComparisonResult)[keyof typeof PosetComparisonResult];\n\nfunction comparePosetElements<T>(a: T, b: T, realizer: Realizer<T>): PosetComparisonResult {\n\tlet hasLessThanResult = false;\n\tlet hasGreaterThanResult = false;\n\tfor (const extension of realizer) {\n\t\tconst aIndex = extension.get(a);\n\t\tconst bIndex = extension.get(b);\n\t\tassert(aIndex !== undefined && bIndex !== undefined, \"Invalid realizer\");\n\t\tif (aIndex < bIndex) {\n\t\t\thasLessThanResult = true;\n\t\t} else if (aIndex > bIndex) {\n\t\t\thasGreaterThanResult = true;\n\t\t}\n\t}\n\n\treturn hasLessThanResult\n\t\t? hasGreaterThanResult\n\t\t\t? PosetComparisonResult.Incomparable\n\t\t\t: PosetComparisonResult.Less\n\t\t: hasGreaterThanResult\n\t\t\t? PosetComparisonResult.Greater\n\t\t\t: PosetComparisonResult.Equal;\n}\n\nfunction posetLte<T>(a: T, b: T, realizer: Realizer<T>): boolean {\n\tconst comparison = comparePosetElements(a, b, realizer);\n\treturn (\n\t\tcomparison === PosetComparisonResult.Less || comparison === PosetComparisonResult.Equal\n\t);\n}\n\nfunction throwUnsupportedNodeType(type: string): never {\n\tthrow new TypeError(`Unsupported node stored schema type: ${type}`);\n}\n"]}
1
+ {"version":3,"file":"discrepancies.js","sourceRoot":"","sources":["../../../src/feature-libraries/modular-schema/discrepancies.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport {\n\ttype FieldKindIdentifier,\n\tLeafNodeStoredSchema,\n\tMapNodeStoredSchema,\n\tObjectNodeStoredSchema,\n\tstoredEmptyFieldSchema,\n\ttype TreeFieldStoredSchema,\n\ttype TreeNodeSchemaIdentifier,\n\ttype TreeNodeStoredSchema,\n\ttype TreeStoredSchema,\n\ttype TreeTypeSet,\n\ttype ValueSchema,\n} from \"../../core/index.js\";\nimport { brand } from \"../../util/index.js\";\n\n// TODO:\n// The comparisons in this file seem redundant with those in comparison.ts.\n// Rather than both existing, one of which just returns boolean and the other which returns additional details, a simple comparison which returns everything needed should be used.\n\n/**\n * @remarks\n *\n * 1. FieldDiscrepancy\n *\n * `FieldDiscrepancy` represents the differences between two `TreeFieldStoredSchema` objects. It consists of\n * three types of incompatibilities:\n *\n * - FieldKindDiscrepancy: Indicates the differences in `FieldKindIdentifier` between two `TreeFieldStoredSchema`\n * objects (e.g., optional, required, sequence, etc.).\n * - AllowedTypesDiscrepancy: Indicates the differences in the allowed child types between the two schemas.\n * - ValueSchemaDiscrepancy: Specifically indicates the differences in the `ValueSchema` of two\n * `LeafNodeStoredSchema` objects.\n *\n * 2. NodeDiscrepancy\n *\n * `NodeDiscrepancy` represents the differences between two `TreeNodeStoredSchema` objects and includes:\n *\n * - NodeKindDiscrepancy: Indicates the differences in the types of `TreeNodeStoredSchema` (currently supports\n * `ObjectNodeStoredSchema`, `MapNodeStoredSchema`, and `LeafNodeStoredSchema`).\n * - NodeFieldsDiscrepancy: Indicates the `FieldDiscrepancy` of `TreeFieldStoredSchema` within two\n * `TreeNodeStoredSchema`. It includes an array of `FieldDiscrepancy` instances in the `differences` field.\n *\n * When comparing two nodes for compatibility, it only makes sense to compare their fields if the nodes are of\n * the same kind (map, object, leaf).\n *\n * 3. Discrepancy\n *\n * Discrepancy consists of both `NodeDiscrepancy` and `FieldDiscrepancy`, representing any kind of\n * schema differences. See {@link getAllowedContentDiscrepancies} for more details about how we process it\n * and the ordering.\n */\nexport type Discrepancy = FieldDiscrepancy | NodeDiscrepancy;\n\nexport type NodeDiscrepancy = NodeKindDiscrepancy | NodeFieldsDiscrepancy;\n\nexport type FieldDiscrepancy =\n\t| AllowedTypeDiscrepancy\n\t| FieldKindDiscrepancy\n\t| ValueSchemaDiscrepancy;\n\nexport interface AllowedTypeDiscrepancy {\n\tidentifier: string | undefined; // undefined indicates root field schema\n\tmismatch: \"allowedTypes\";\n\t/**\n\t * List of allowed type identifiers in viewed schema\n\t */\n\tview: string[];\n\t/**\n\t * List of allowed type identifiers in stored schema\n\t */\n\tstored: string[];\n}\n\nexport interface FieldKindDiscrepancy {\n\tidentifier: string | undefined; // undefined indicates root field schema\n\tmismatch: \"fieldKind\";\n\tview: FieldKindIdentifier;\n\tstored: FieldKindIdentifier;\n}\n\nexport interface ValueSchemaDiscrepancy {\n\tidentifier: string;\n\tmismatch: \"valueSchema\";\n\tview: ValueSchema | undefined;\n\tstored: ValueSchema | undefined;\n}\n\nexport interface NodeKindDiscrepancy {\n\tidentifier: string;\n\tmismatch: \"nodeKind\";\n\tview: SchemaFactoryNodeKind | undefined;\n\tstored: SchemaFactoryNodeKind | undefined;\n}\n\nexport interface NodeFieldsDiscrepancy {\n\tidentifier: string;\n\tmismatch: \"fields\";\n\tdifferences: FieldDiscrepancy[];\n}\n\ntype SchemaFactoryNodeKind = \"object\" | \"leaf\" | \"map\";\n\nfunction getNodeSchemaType(nodeSchema: TreeNodeStoredSchema): SchemaFactoryNodeKind {\n\tif (nodeSchema instanceof ObjectNodeStoredSchema) {\n\t\treturn \"object\";\n\t} else if (nodeSchema instanceof MapNodeStoredSchema) {\n\t\treturn \"map\";\n\t} else if (nodeSchema instanceof LeafNodeStoredSchema) {\n\t\treturn \"leaf\";\n\t}\n\tthrowUnsupportedNodeType(nodeSchema.constructor.name);\n}\n\n/**\n * Finds and reports discrepancies between a view schema and a stored schema.\n *\n * The workflow for finding schema incompatibilities:\n * 1. Compare the two root schemas to identify any `FieldDiscrepancy`.\n *\n * 2. For each node schema in the `view`:\n * - Verify if the node schema exists in the stored. If it does, ensure that the `SchemaFactoryNodeKind` are\n * consistent. Otherwise this difference is treated as `NodeKindDiscrepancy`\n * - If a node schema with the same identifier exists in both view and stored, and their `SchemaFactoryNodeKind`\n * are consistent, perform a exhaustive validation to identify all `FieldDiscrepancy`.\n *\n * 3. For each node schema in the stored, verify if it exists in the view. The overlapping parts were already\n * addressed in the previous step.\n *\n * @returns the discrepancies between two TreeStoredSchema objects\n */\nexport function* getAllowedContentDiscrepancies(\n\tview: TreeStoredSchema,\n\tstored: TreeStoredSchema,\n): Iterable<Discrepancy> {\n\t// check root schema discrepancies\n\tyield* getFieldDiscrepancies(view.rootFieldSchema, stored.rootFieldSchema);\n\n\tfor (const result of compareMaps(view.nodeSchema, stored.nodeSchema)) {\n\t\tswitch (result.type) {\n\t\t\tcase \"aExtra\": {\n\t\t\t\tconst viewType = getNodeSchemaType(result.value);\n\t\t\t\tyield {\n\t\t\t\t\tidentifier: result.key,\n\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\tview: viewType,\n\t\t\t\t\tstored: undefined,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"bExtra\": {\n\t\t\t\tconst storedType = getNodeSchemaType(result.value);\n\t\t\t\tyield {\n\t\t\t\t\tidentifier: result.key,\n\t\t\t\t\tmismatch: \"nodeKind\",\n\t\t\t\t\tview: undefined,\n\t\t\t\t\tstored: storedType,\n\t\t\t\t};\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"both\": {\n\t\t\t\tyield* getNodeDiscrepancies(result.key, result.valueA, result.valueB);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\nfunction* getNodeDiscrepancies(\n\tidentifier: TreeNodeSchemaIdentifier,\n\tview: TreeNodeStoredSchema,\n\tstored: TreeNodeStoredSchema,\n): Iterable<Discrepancy> {\n\tconst viewType = getNodeSchemaType(view);\n\tconst storedType = getNodeSchemaType(stored);\n\tif (viewType !== storedType) {\n\t\tyield {\n\t\t\tidentifier,\n\t\t\tmismatch: \"nodeKind\",\n\t\t\tview: viewType,\n\t\t\tstored: storedType,\n\t\t};\n\t\treturn;\n\t}\n\n\tswitch (viewType) {\n\t\tcase \"object\": {\n\t\t\tconst differences = Array.from(\n\t\t\t\ttrackObjectNodeDiscrepancies(\n\t\t\t\t\tview as ObjectNodeStoredSchema,\n\t\t\t\t\tstored as ObjectNodeStoredSchema,\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (differences.length > 0) {\n\t\t\t\tyield {\n\t\t\t\t\tidentifier,\n\t\t\t\t\tmismatch: \"fields\",\n\t\t\t\t\tdifferences,\n\t\t\t\t} satisfies NodeFieldsDiscrepancy;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase \"map\":\n\t\t\tyield* getFieldDiscrepancies(\n\t\t\t\t(view as MapNodeStoredSchema).mapFields,\n\t\t\t\t(stored as MapNodeStoredSchema).mapFields,\n\t\t\t\tidentifier,\n\t\t\t);\n\t\t\tbreak;\n\t\tcase \"leaf\": {\n\t\t\tconst viewValue = (view as LeafNodeStoredSchema).leafValue;\n\t\t\tconst storedValue = (stored as LeafNodeStoredSchema).leafValue;\n\t\t\tif (viewValue !== storedValue) {\n\t\t\t\tyield {\n\t\t\t\t\tidentifier,\n\t\t\t\t\tmismatch: \"valueSchema\",\n\t\t\t\t\tview: viewValue,\n\t\t\t\t\tstored: storedValue,\n\t\t\t\t};\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\n/**\n * The function to track the discrepancies between two field stored schemas.\n *\n * @param keyOrRoot - If the key is missing, it indicates that this is the root field schema.\n */\nfunction* getFieldDiscrepancies(\n\tview: TreeFieldStoredSchema,\n\tstored: TreeFieldStoredSchema,\n\tkeyOrRoot?: string,\n): Iterable<FieldDiscrepancy> {\n\t// Only track the symmetric differences of two sets.\n\tconst findSetDiscrepancies = (\n\t\ta: TreeTypeSet,\n\t\tb: TreeTypeSet,\n\t): [TreeNodeSchemaIdentifier[], TreeNodeSchemaIdentifier[]] => {\n\t\tconst aDiff = [...a].filter((value) => !b.has(value));\n\t\tconst bDiff = [...b].filter((value) => !a.has(value));\n\t\treturn [aDiff, bDiff];\n\t};\n\n\tconst [viewExtra, storedExtra] = findSetDiscrepancies(view.types, stored.types);\n\tif (viewExtra.length > 0 || storedExtra.length > 0) {\n\t\tyield {\n\t\t\tidentifier: keyOrRoot,\n\t\t\tmismatch: \"allowedTypes\",\n\t\t\tview: viewExtra,\n\t\t\tstored: storedExtra,\n\t\t} satisfies AllowedTypeDiscrepancy;\n\t}\n\n\tif (view.kind !== stored.kind) {\n\t\tyield {\n\t\t\tidentifier: keyOrRoot,\n\t\t\tmismatch: \"fieldKind\",\n\t\t\tview: view.kind,\n\t\t\tstored: stored.kind,\n\t\t} satisfies FieldKindDiscrepancy;\n\t}\n}\n\nfunction* trackObjectNodeDiscrepancies(\n\tview: ObjectNodeStoredSchema,\n\tstored: ObjectNodeStoredSchema,\n): Iterable<FieldDiscrepancy> {\n\t/**\n\t * Similar to the logic used for tracking discrepancies between two node schemas, we will identify\n\t * three types of differences:\n\t * 1. Fields that exist in the view schema but not in the stored schema.\n\t * 2. Fields that exist in both schemas but have different contents.\n\t * 3. Fields that exist in the stored schema but not in the view schema.\n\t *\n\t * First, the view schema is iterated to track the first two types of differences.\n\t * Then, the stored schema is iterated to find the third type.\n\t */\n\n\tfor (const result of compareMaps(view.objectNodeFields, stored.objectNodeFields)) {\n\t\tconst fieldKey = result.key;\n\t\tswitch (result.type) {\n\t\t\tcase \"aExtra\": {\n\t\t\t\tif (result.value.kind === storedEmptyFieldSchema.kind) {\n\t\t\t\t\t// In one of view/stored, this field is explicitly forbidden, but in the other it is implicitly forbidden\n\t\t\t\t\t// (by way of omission). We treat these identically anyway.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tyield {\n\t\t\t\t\tidentifier: fieldKey,\n\t\t\t\t\tmismatch: \"fieldKind\",\n\t\t\t\t\tview: result.value.kind,\n\t\t\t\t\tstored: storedEmptyFieldSchema.kind,\n\t\t\t\t} satisfies FieldKindDiscrepancy;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"bExtra\": {\n\t\t\t\tif (result.value.kind === storedEmptyFieldSchema.kind) {\n\t\t\t\t\t// In one of view/stored, this field is explicitly forbidden, but in the other it is implicitly forbidden\n\t\t\t\t\t// (by way of omission). We treat these identically anyway.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tyield {\n\t\t\t\t\tidentifier: fieldKey,\n\t\t\t\t\tmismatch: \"fieldKind\",\n\t\t\t\t\tview: storedEmptyFieldSchema.kind,\n\t\t\t\t\tstored: result.value.kind,\n\t\t\t\t} satisfies FieldKindDiscrepancy;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"both\": {\n\t\t\t\tyield* getFieldDiscrepancies(result.valueA, result.valueB, fieldKey);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction* compareMaps<K, V1, V2>(\n\ta: ReadonlyMap<K, V1>,\n\tb: ReadonlyMap<K, V2>,\n): Iterable<\n\t| { type: \"aExtra\"; key: K; value: V1 }\n\t| { type: \"bExtra\"; key: K; value: V2 }\n\t| { type: \"both\"; key: K; valueA: V1; valueB: V2 }\n> {\n\tfor (const [key, valueA] of a) {\n\t\tconst valueB = b.get(key);\n\t\tyield valueB === undefined\n\t\t\t? { type: \"aExtra\", key, value: valueA }\n\t\t\t: { type: \"both\", key, valueA, valueB };\n\t}\n\tfor (const [key, valueB] of b) {\n\t\tif (!a.has(key)) {\n\t\t\tyield { type: \"bExtra\", key, value: valueB };\n\t\t}\n\t}\n}\n/**\n * @remarks\n *\n * This function uses incompatibilities to determine if changes to a document schema are backward-compatible, i.e., it determines\n * whether the `view` schema allows a superset of the documents that the `stored` schema allows.\n * According to the policy of schema evolution, `isRepoSuperset` supports three types of changes:\n * 1. Adding an optional field to an object node.\n * 2. Expanding the set of allowed types for a field.\n * 3. Relaxing a field kind to a more general field kind.\n *\n * Notes: We expect isRepoSuperset to return consistent results with allowsRepoSuperset. However, currently there are some scenarios\n * where the inconsistency will occur:\n *\n * - Different Node Kinds: If a and b have different node kinds (e.g., a is an objectNodeSchema and b is a mapNodeSchema),\n * `isRepoSuperset` will determine that a can never be the superset of b. In contrast, `allowsRepoSuperset` will continue\n * validating internal fields.\n */\nexport function isRepoSuperset(view: TreeStoredSchema, stored: TreeStoredSchema): boolean {\n\tconst discrepancies = getAllowedContentDiscrepancies(view, stored);\n\n\tfor (const discrepancy of discrepancies) {\n\t\tswitch (discrepancy.mismatch) {\n\t\t\tcase \"nodeKind\": {\n\t\t\t\tif (discrepancy.stored !== undefined) {\n\t\t\t\t\t// It's fine for the view schema to know of a node type that the stored schema doesn't know about.\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"valueSchema\":\n\t\t\tcase \"allowedTypes\":\n\t\t\tcase \"fieldKind\": {\n\t\t\t\tif (!isFieldDiscrepancyCompatible(discrepancy)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"fields\": {\n\t\t\t\tif (\n\t\t\t\t\tdiscrepancy.differences.some(\n\t\t\t\t\t\t(difference) => !isFieldDiscrepancyCompatible(difference),\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// No default\n\t\t}\n\t}\n\treturn true;\n}\n\nfunction isFieldDiscrepancyCompatible(discrepancy: FieldDiscrepancy): boolean {\n\tswitch (discrepancy.mismatch) {\n\t\tcase \"allowedTypes\": {\n\t\t\t// Since we only track the symmetric difference between the allowed types in the view and\n\t\t\t// stored schemas, it's sufficient to check if any extra allowed types still exist in the\n\t\t\t// stored schema.\n\t\t\treturn discrepancy.stored.length === 0;\n\t\t}\n\t\tcase \"fieldKind\": {\n\t\t\treturn posetLte(discrepancy.stored, discrepancy.view, fieldRealizer);\n\t\t}\n\t\tcase \"valueSchema\": {\n\t\t\treturn false;\n\t\t}\n\t\t// No default\n\t}\n\treturn false;\n}\n\n/**\n * A linear extension of a partially-ordered set of `T`s. See:\n * https://en.wikipedia.org/wiki/Linear_extension\n *\n * The linear extension is represented as a lookup from each poset element to its index in the linear extension.\n */\ntype LinearExtension<T> = Map<T, number>;\n\n/**\n * A realizer for a partially-ordered set. See:\n * https://en.wikipedia.org/wiki/Order_dimension\n */\ntype Realizer<T> = LinearExtension<T>[];\n\n/**\n * @privateRemarks\n * TODO: Knowledge of specific field kinds is not appropriate for modular schema.\n * This bit of field comparison should be dependency injected by default-schema if this comparison logic remains in modular-schema\n * (this is analogous to what is done in comparison.ts).\n */\nconst FieldKindIdentifiers = {\n\tforbidden: brand<FieldKindIdentifier>(\"Forbidden\"),\n\trequired: brand<FieldKindIdentifier>(\"Value\"),\n\tidentifier: brand<FieldKindIdentifier>(\"Identifier\"),\n\toptional: brand<FieldKindIdentifier>(\"Optional\"),\n\tsequence: brand<FieldKindIdentifier>(\"Sequence\"),\n};\n\n/**\n * A realizer for the partial order of field kind relaxability.\n *\n * It seems extremely likely that this partial order will remain dimension 2 over time (i.e. the set of allowed relaxations can be visualized\n * with a [dominance drawing](https://en.wikipedia.org/wiki/Dominance_drawing)), so this strategy allows efficient comarison between field kinds\n * without excessive casework.\n *\n * Hasse diagram for the partial order is shown below (lower fields can be relaxed to higher fields):\n * ```\n * sequence\n * |\n * optional\n * | \\\n * required forbidden\n * |\n * identifier\n * ```\n */\nconst fieldRealizer: Realizer<FieldKindIdentifier> = [\n\t[\n\t\tFieldKindIdentifiers.forbidden,\n\t\tFieldKindIdentifiers.identifier,\n\t\tFieldKindIdentifiers.required,\n\t\tFieldKindIdentifiers.optional,\n\t\tFieldKindIdentifiers.sequence,\n\t],\n\t[\n\t\tFieldKindIdentifiers.identifier,\n\t\tFieldKindIdentifiers.required,\n\t\tFieldKindIdentifiers.forbidden,\n\t\tFieldKindIdentifiers.optional,\n\t\tFieldKindIdentifiers.sequence,\n\t],\n].map((extension) => new Map(extension.map((identifier, index) => [identifier, index])));\n\nconst PosetComparisonResult = {\n\tLess: \"<\",\n\tGreater: \">\",\n\tEqual: \"=\",\n\tIncomparable: \"||\",\n} as const;\ntype PosetComparisonResult =\n\t(typeof PosetComparisonResult)[keyof typeof PosetComparisonResult];\n\nfunction comparePosetElements<T>(a: T, b: T, realizer: Realizer<T>): PosetComparisonResult {\n\tlet hasLessThanResult = false;\n\tlet hasGreaterThanResult = false;\n\tfor (const extension of realizer) {\n\t\tconst aIndex = extension.get(a);\n\t\tconst bIndex = extension.get(b);\n\t\tassert(aIndex !== undefined && bIndex !== undefined, \"Invalid realizer\");\n\t\tif (aIndex < bIndex) {\n\t\t\thasLessThanResult = true;\n\t\t} else if (aIndex > bIndex) {\n\t\t\thasGreaterThanResult = true;\n\t\t}\n\t}\n\n\treturn hasLessThanResult\n\t\t? hasGreaterThanResult\n\t\t\t? PosetComparisonResult.Incomparable\n\t\t\t: PosetComparisonResult.Less\n\t\t: hasGreaterThanResult\n\t\t\t? PosetComparisonResult.Greater\n\t\t\t: PosetComparisonResult.Equal;\n}\n\nfunction posetLte<T>(a: T, b: T, realizer: Realizer<T>): boolean {\n\tconst comparison = comparePosetElements(a, b, realizer);\n\treturn (\n\t\tcomparison === PosetComparisonResult.Less || comparison === PosetComparisonResult.Equal\n\t);\n}\n\nfunction throwUnsupportedNodeType(type: string): never {\n\tthrow new TypeError(`Unsupported node stored schema type: ${type}`);\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/tree";
8
- export declare const pkgVersion = "2.10.0-307060";
8
+ export declare const pkgVersion = "2.10.0-307399";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -8,5 +8,5 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.pkgVersion = exports.pkgName = void 0;
10
10
  exports.pkgName = "@fluidframework/tree";
11
- exports.pkgVersion = "2.10.0-307060";
11
+ exports.pkgVersion = "2.10.0-307399";
12
12
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,sBAAsB,CAAC;AACjC,QAAA,UAAU,GAAG,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/tree\";\nexport const pkgVersion = \"2.10.0-307060\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEU,QAAA,OAAO,GAAG,sBAAsB,CAAC;AACjC,QAAA,UAAU,GAAG,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/tree\";\nexport const pkgVersion = \"2.10.0-307399\";\n"]}
@@ -91,7 +91,7 @@ type SchemaFactoryNodeKind = "object" | "leaf" | "map";
91
91
  *
92
92
  * @returns the discrepancies between two TreeStoredSchema objects
93
93
  */
94
- export declare function getAllowedContentDiscrepancies(view: TreeStoredSchema, stored: TreeStoredSchema): Discrepancy[];
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,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;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,8BAA8B,CAC7C,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,gBAAgB,GACtB,WAAW,EAAE,CA4Jf;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"}