@fluid-experimental/tree 0.59.3003 → 0.59.4000-71128

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 (86) hide show
  1. package/dist/Forest.js +1 -1
  2. package/dist/Forest.js.map +1 -1
  3. package/dist/SharedTree.d.ts +89 -30
  4. package/dist/SharedTree.d.ts.map +1 -1
  5. package/dist/SharedTree.js +93 -58
  6. package/dist/SharedTree.js.map +1 -1
  7. package/dist/SharedTreeEncoder.d.ts +1 -1
  8. package/dist/SharedTreeEncoder.d.ts.map +1 -1
  9. package/dist/SharedTreeEncoder.js.map +1 -1
  10. package/dist/id-compressor/IdCompressor.d.ts +19 -45
  11. package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
  12. package/dist/id-compressor/IdCompressor.js +151 -151
  13. package/dist/id-compressor/IdCompressor.js.map +1 -1
  14. package/dist/id-compressor/SessionIdNormalizer.d.ts +1 -16
  15. package/dist/id-compressor/SessionIdNormalizer.d.ts.map +1 -1
  16. package/dist/id-compressor/SessionIdNormalizer.js +23 -21
  17. package/dist/id-compressor/SessionIdNormalizer.js.map +1 -1
  18. package/dist/id-compressor/persisted-types/0.0.1.d.ts +23 -4
  19. package/dist/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
  20. package/dist/id-compressor/persisted-types/0.0.1.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/lib/Forest.js +1 -1
  25. package/lib/Forest.js.map +1 -1
  26. package/lib/SharedTree.d.ts +89 -30
  27. package/lib/SharedTree.d.ts.map +1 -1
  28. package/lib/SharedTree.js +94 -59
  29. package/lib/SharedTree.js.map +1 -1
  30. package/lib/SharedTreeEncoder.d.ts +1 -1
  31. package/lib/SharedTreeEncoder.d.ts.map +1 -1
  32. package/lib/SharedTreeEncoder.js.map +1 -1
  33. package/lib/id-compressor/IdCompressor.d.ts +19 -45
  34. package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
  35. package/lib/id-compressor/IdCompressor.js +152 -152
  36. package/lib/id-compressor/IdCompressor.js.map +1 -1
  37. package/lib/id-compressor/SessionIdNormalizer.d.ts +1 -16
  38. package/lib/id-compressor/SessionIdNormalizer.d.ts.map +1 -1
  39. package/lib/id-compressor/SessionIdNormalizer.js +23 -21
  40. package/lib/id-compressor/SessionIdNormalizer.js.map +1 -1
  41. package/lib/id-compressor/persisted-types/0.0.1.d.ts +23 -4
  42. package/lib/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
  43. package/lib/id-compressor/persisted-types/0.0.1.js.map +1 -1
  44. package/lib/index.d.ts +1 -1
  45. package/lib/index.d.ts.map +1 -1
  46. package/lib/index.js.map +1 -1
  47. package/lib/test/IdCompressor.perf.tests.js +47 -67
  48. package/lib/test/IdCompressor.perf.tests.js.map +1 -1
  49. package/lib/test/IdCompressor.tests.js +196 -101
  50. package/lib/test/IdCompressor.tests.js.map +1 -1
  51. package/lib/test/Summary.tests.d.ts +0 -1
  52. package/lib/test/Summary.tests.d.ts.map +1 -1
  53. package/lib/test/Summary.tests.js +0 -3
  54. package/lib/test/Summary.tests.js.map +1 -1
  55. package/lib/test/Virtualization.tests.js +0 -4
  56. package/lib/test/Virtualization.tests.js.map +1 -1
  57. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -1
  58. package/lib/test/fuzz/SharedTreeFuzzTests.js +3 -1
  59. package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -1
  60. package/lib/test/utilities/IdCompressorTestUtilities.d.ts +14 -7
  61. package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +1 -1
  62. package/lib/test/utilities/IdCompressorTestUtilities.js +40 -20
  63. package/lib/test/utilities/IdCompressorTestUtilities.js.map +1 -1
  64. package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
  65. package/lib/test/utilities/SharedTreeTests.js +27 -51
  66. package/lib/test/utilities/SharedTreeTests.js.map +1 -1
  67. package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -1
  68. package/lib/test/utilities/SharedTreeVersioningTests.js +19 -19
  69. package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -1
  70. package/lib/test/utilities/SummaryLoadPerfTests.js +1 -1
  71. package/lib/test/utilities/SummaryLoadPerfTests.js.map +1 -1
  72. package/lib/test/utilities/TestCommon.d.ts +4 -0
  73. package/lib/test/utilities/TestCommon.d.ts.map +1 -1
  74. package/lib/test/utilities/TestCommon.js +6 -0
  75. package/lib/test/utilities/TestCommon.js.map +1 -1
  76. package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
  77. package/lib/test/utilities/TestUtilities.js +4 -6
  78. package/lib/test/utilities/TestUtilities.js.map +1 -1
  79. package/package.json +24 -19
  80. package/src/Forest.ts +1 -1
  81. package/src/SharedTree.ts +195 -46
  82. package/src/SharedTreeEncoder.ts +1 -1
  83. package/src/id-compressor/IdCompressor.ts +171 -198
  84. package/src/id-compressor/SessionIdNormalizer.ts +29 -41
  85. package/src/id-compressor/persisted-types/0.0.1.ts +25 -4
  86. package/src/index.ts +4 -0
@@ -27,25 +27,15 @@ const ChangeTypes_1 = require("./ChangeTypes");
27
27
  const id_compressor_1 = require("./id-compressor");
28
28
  const IdConversion_1 = require("./IdConversion");
29
29
  const StringInterner_1 = require("./StringInterner");
30
+ const UuidUtilities_1 = require("./UuidUtilities");
30
31
  /**
31
32
  * Factory for SharedTree.
32
33
  * Includes history in the summary.
33
34
  * @public
34
35
  */
35
36
  class SharedTreeFactory {
36
- /**
37
- * Get a factory for SharedTree to register with the data store.
38
- * @param writeFormat - Determines the format version the SharedTree will write ops and summaries in. See [the write format
39
- * documentation](../docs/Write-Format.md) for more information.
40
- * @param summarizeHistory - Determines if the history is included in summaries and if edit chunks are uploaded when they are full.
41
- * See the [breaking change migration documentation](docs/Breaking-Change-Migration) for more details on this scheme.
42
- * @param expensiveValidation - Enables expensive asserts on SharedTree.
43
- * @returns A factory that creates `SharedTree`s and loads them from storage.
44
- */
45
- constructor(writeFormat, summarizeHistory = false, expensiveValidation = false) {
46
- this.writeFormat = writeFormat;
47
- this.summarizeHistory = summarizeHistory;
48
- this.expensiveValidation = expensiveValidation;
37
+ constructor(...args) {
38
+ this.args = args;
49
39
  }
50
40
  /**
51
41
  * {@inheritDoc @fluidframework/shared-object-base#ISharedObjectFactory."type"}
@@ -72,15 +62,21 @@ class SharedTreeFactory {
72
62
  * @param runtime - data store runtime that owns the new SharedTree
73
63
  * @param id - optional name for the SharedTree
74
64
  */
75
- create(runtime, id, expensiveValidation = false) {
76
- this.expensiveValidation = expensiveValidation;
65
+ create(runtime, id) {
77
66
  const sharedTree = this.createSharedTree(runtime, id);
78
67
  sharedTree.initializeLocal();
79
68
  return sharedTree;
80
69
  }
81
70
  createSharedTree(runtime, id) {
82
- const sharedTree = new SharedTree(runtime, id, this.writeFormat, this.summarizeHistory, this.expensiveValidation);
83
- return sharedTree;
71
+ const [writeFormat] = this.args;
72
+ switch (writeFormat) {
73
+ case persisted_types_1.WriteFormat.v0_0_2:
74
+ return new SharedTree(runtime, id, ...this.args);
75
+ case persisted_types_1.WriteFormat.v0_1_1:
76
+ return new SharedTree(runtime, id, ...this.args);
77
+ default:
78
+ (0, Common_1.fail)('Unknown write format');
79
+ }
84
80
  }
85
81
  }
86
82
  exports.SharedTreeFactory = SharedTreeFactory;
@@ -110,20 +106,9 @@ const sharedTreeTelemetryProperties = { all: { isSharedTreeEvent: true } };
110
106
  * @public
111
107
  */
112
108
  class SharedTree extends shared_object_base_1.SharedObject {
113
- /**
114
- * Create a new SharedTreeFactory.
115
- * @param runtime - The runtime the SharedTree will be associated with
116
- * @param id - Unique ID for the SharedTree
117
- * @param writeFormat - Determines the format version the SharedTree will write ops and summaries in. See [the write format
118
- * documentation](../docs/Write-Format.md) for more information.
119
- * @param summarizeHistory - Determines if the history is included in summaries and if edit chunks are uploaded when they are full.
120
- * @param expensiveValidation - Enable expensive asserts.
121
- */
122
- constructor(runtime, id, writeFormat, summarizeHistory = false, expensiveValidation = false) {
109
+ constructor(runtime, id, writeFormat, options = {}) {
123
110
  super(id, runtime, SharedTreeFactory.Attributes);
124
111
  this.writeFormat = writeFormat;
125
- this.expensiveValidation = expensiveValidation;
126
- this.idCompressor = new id_compressor_1.IdCompressor((0, id_compressor_1.createSessionId)(), persisted_types_1.reservedIdCount);
127
112
  this.idNormalizer = {
128
113
  tree: this,
129
114
  get localSessionId() {
@@ -166,8 +151,9 @@ class SharedTree extends shared_object_base_1.SharedObject {
166
151
  }
167
152
  }
168
153
  };
169
- this.summarizeHistory = summarizeHistory === false ? false : true;
170
- this.uploadEditChunks = summarizeHistory === false ? false : summarizeHistory.uploadEditChunks;
154
+ const historyPolicy = this.getHistoryPolicy(options);
155
+ this.summarizeHistory = historyPolicy.summarizeHistory;
156
+ this.uploadEditChunks = historyPolicy.uploadEditChunks;
171
157
  // This code is somewhat duplicated from OldestClientObserver because it currently depends on the container runtime
172
158
  // which SharedTree does not have access to.
173
159
  // TODO:#55900: Get rid of copy-pasted OldestClientObserver code
@@ -179,11 +165,12 @@ class SharedTree extends shared_object_base_1.SharedObject {
179
165
  runtime.on('disconnected', this.updateOldest);
180
166
  this.logger = telemetry_utils_1.ChildLogger.create(runtime.logger, 'SharedTree', sharedTreeTelemetryProperties);
181
167
  this.sequencedEditAppliedLogger = telemetry_utils_1.ChildLogger.create(this.logger, 'SequencedEditApplied', sharedTreeTelemetryProperties);
168
+ const attributionId = options.attributionId;
169
+ this.idCompressor = new id_compressor_1.IdCompressor((0, id_compressor_1.createSessionId)(), persisted_types_1.reservedIdCount, attributionId);
182
170
  const { editLog, cachingLogViewer } = this.initializeNewEditLogFromSummary({
183
171
  editChunks: [],
184
172
  editIds: [],
185
- }, undefined, this.idCompressor, // TODO: Attribution info
186
- this.processEditResult, this.processSequencedEditResult, persisted_types_1.WriteFormat.v0_1_1);
173
+ }, undefined, this.idCompressor, this.processEditResult, this.processSequencedEditResult, persisted_types_1.WriteFormat.v0_1_1);
187
174
  this.editLog = editLog;
188
175
  this.cachingLogViewer = cachingLogViewer;
189
176
  this.encoder_0_0_2 = new SharedTreeEncoder_1.SharedTreeEncoder_0_0_2(this.summarizeHistory);
@@ -195,31 +182,39 @@ class SharedTree extends shared_object_base_1.SharedObject {
195
182
  static create(runtime, id) {
196
183
  return runtime.createChannel(id, SharedTreeFactory.Type);
197
184
  }
198
- /**
199
- * Get a factory for SharedTree to register with the data store.
200
- * @param summarizeHistory - Determines if the history is included in summaries and if edit chunks are uploaded when they are full.
201
- *
202
- * On 0.1.1 documents, due to current code limitations, this parameter is only impactful for newly created documents.
203
- * `SharedTree`s which load existing documents will summarize history if and only if the loaded summary included history.
204
- *
205
- * The technical limitations here relate to clients with mixed versions collaborating.
206
- * In the future we may allow modification of whether or not a particular document saves history, but only via a consensus mechanism.
207
- * See the skipped test in SharedTreeFuzzTests.ts for more details on this issue.
208
- * See docs/Breaking-Change-Migration for more details on the consensus scheme.
209
- * @param writeFormat - Determines the format version the SharedTree will write ops and summaries in.
210
- * This format may be updated to a newer (supported) version at runtime if a collaborating shared-tree
211
- * that was initialized with a newer write version connects to the session. Care must be taken when changing this value,
212
- * as a staged rollout must of occurred such that all collaborating clients must have the code to read at least the version
213
- * written.
214
- * See [the write format documentation](../docs/Write-Format.md) for more information.
215
- * @returns A factory that creates `SharedTree`s and loads them from storage.
216
- */
217
- static getFactory(writeFormat, summarizeHistory = false) {
185
+ static getFactory(...args) {
186
+ const [writeFormat] = args;
218
187
  // On 0.1.1 documents, due to current code limitations, all clients MUST agree on the value of `summarizeHistory`.
219
188
  // Note that this means staged rollout changing this value should not be attempted.
220
189
  // It is possible to update shared-tree to correctly handle such a staged rollout, but that hasn't been implemented.
221
190
  // See the skipped test in SharedTreeFuzzTests.ts for more details on this issue.
222
- return new SharedTreeFactory(writeFormat, summarizeHistory);
191
+ switch (writeFormat) {
192
+ case persisted_types_1.WriteFormat.v0_0_2:
193
+ return new SharedTreeFactory(...args);
194
+ case persisted_types_1.WriteFormat.v0_1_1:
195
+ return new SharedTreeFactory(...args);
196
+ default:
197
+ (0, Common_1.fail)('Unknown write format');
198
+ }
199
+ }
200
+ /**
201
+ * The UUID used for attribution of nodes created by this SharedTree. All shared trees with a write format of 0.1.1 or
202
+ * greater have a unique attribution ID which may be configured in the constructor. All other shared trees (i.e. those
203
+ * with a write format of 0.0.2) use the nil UUID as their attribution ID.
204
+ * @public
205
+ */
206
+ get attributionId() {
207
+ switch (this.writeFormat) {
208
+ case persisted_types_1.WriteFormat.v0_0_2:
209
+ return UuidUtilities_1.nilUuid;
210
+ default: {
211
+ const { attributionId } = this.idCompressor;
212
+ if (attributionId === persisted_types_1.ghostSessionId) {
213
+ return UuidUtilities_1.nilUuid;
214
+ }
215
+ return attributionId;
216
+ }
217
+ }
223
218
  }
224
219
  /**
225
220
  * Viewer for trees defined by editLog. This allows access to views of the tree at different revisions (various points in time).
@@ -227,6 +222,27 @@ class SharedTree extends shared_object_base_1.SharedObject {
227
222
  get logViewer() {
228
223
  return this.cachingLogViewer;
229
224
  }
225
+ getHistoryPolicy(options) {
226
+ var _a;
227
+ const noCompatOptions = options;
228
+ if (typeof noCompatOptions.summarizeHistory === 'object') {
229
+ return {
230
+ summarizeHistory: true,
231
+ uploadEditChunks: noCompatOptions.summarizeHistory.uploadEditChunks,
232
+ };
233
+ }
234
+ else {
235
+ return {
236
+ summarizeHistory: (_a = noCompatOptions.summarizeHistory) !== null && _a !== void 0 ? _a : false,
237
+ uploadEditChunks: false,
238
+ };
239
+ }
240
+ }
241
+ /**
242
+ * The write format version currently used by this `SharedTree`. This is always initialized to the write format
243
+ * passed to the tree's constructor, but it may automatically upgrade over time (e.g. when connected to another
244
+ * SharedTree with a higher write format, or when loading a summary with a higher write format).
245
+ */
230
246
  getWriteFormat() {
231
247
  return this.writeFormat;
232
248
  }
@@ -323,6 +339,25 @@ class SharedTree extends shared_object_base_1.SharedObject {
323
339
  tryConvertToNodeId(id) {
324
340
  return this.idCompressor.tryRecompress(id);
325
341
  }
342
+ /**
343
+ * Returns the attribution ID associated with the SharedTree that generated the given node ID. This is generally only useful for clients
344
+ * with a write format of 0.1.1 or greater since older clients cannot be given an attribution ID and will always use the default
345
+ * `attributionId` of the tree.
346
+ * @public
347
+ */
348
+ attributeNodeId(id) {
349
+ switch (this.writeFormat) {
350
+ case persisted_types_1.WriteFormat.v0_0_2:
351
+ return UuidUtilities_1.nilUuid;
352
+ default: {
353
+ const attributionId = this.idCompressor.attributeId(id);
354
+ if (attributionId === persisted_types_1.ghostSessionId) {
355
+ return UuidUtilities_1.nilUuid;
356
+ }
357
+ return attributionId;
358
+ }
359
+ }
360
+ }
326
361
  /**
327
362
  * @returns the edit history of the tree.
328
363
  * @public
@@ -469,7 +504,7 @@ class SharedTree extends shared_object_base_1.SharedObject {
469
504
  let convertedSummary;
470
505
  switch (loadedSummaryVersion) {
471
506
  case persisted_types_1.WriteFormat.v0_0_2:
472
- convertedSummary = this.encoder_0_0_2.decodeSummary(summary);
507
+ convertedSummary = this.encoder_0_0_2.decodeSummary(summary, this.attributionId);
473
508
  break;
474
509
  case persisted_types_1.WriteFormat.v0_1_1: {
475
510
  const typedSummary = summary;
@@ -480,7 +515,7 @@ class SharedTree extends shared_object_base_1.SharedObject {
480
515
  this.uploadEditChunks = loadedSummaryIncludesHistory;
481
516
  this.encoder_0_1_1 = new SharedTreeEncoder_1.SharedTreeEncoder_0_1_1(this.summarizeHistory);
482
517
  }
483
- convertedSummary = this.encoder_0_1_1.decodeSummary(summary); // TODO:#461: pass attribution info
518
+ convertedSummary = this.encoder_0_1_1.decodeSummary(summary, this.attributionId);
484
519
  break;
485
520
  }
486
521
  default:
@@ -768,7 +803,7 @@ class SharedTree extends shared_object_base_1.SharedObject {
768
803
  this.interner = new StringInterner_1.MutableStringInterner([InitialTree_1.initialTree.definition]);
769
804
  const oldIdCompressor = this.idCompressor;
770
805
  // Create the IdCompressor that will be used after the upgrade
771
- const newIdCompressor = new id_compressor_1.IdCompressor((0, id_compressor_1.createSessionId)(), persisted_types_1.reservedIdCount); // TODO: attribution info
806
+ const newIdCompressor = new id_compressor_1.IdCompressor((0, id_compressor_1.createSessionId)(), persisted_types_1.reservedIdCount, this.attributionId);
772
807
  const newContext = (0, NodeIdUtilities_1.getNodeIdContext)(newIdCompressor);
773
808
  // Generate all local IDs in the new compressor that were in the old compressor and preserve their UUIDs.
774
809
  // This will allow the client to continue to use local IDs that were allocated pre-upgrade
@@ -782,7 +817,7 @@ class SharedTree extends shared_object_base_1.SharedObject {
782
817
  }
783
818
  };
784
819
  // Construct a temporary "ghost" compressor which is used to generate final IDs that will be consistent across all upgrading clients
785
- const ghostIdCompressor = new id_compressor_1.IdCompressor(persisted_types_1.ghostSessionId, persisted_types_1.reservedIdCount); // TODO: attribution info
820
+ const ghostIdCompressor = new id_compressor_1.IdCompressor(persisted_types_1.ghostSessionId, persisted_types_1.reservedIdCount);
786
821
  const ghostContext = (0, NodeIdUtilities_1.getNodeIdContext)(ghostIdCompressor);
787
822
  if (this.summarizeHistory) {
788
823
  // All clients have the full history, and can therefore all "generate" the same final IDs for every ID in the history