@fluidframework/container-runtime 1.0.1 → 1.1.0-75972

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 (60) hide show
  1. package/dist/connectionTelemetry.d.ts +19 -0
  2. package/dist/connectionTelemetry.d.ts.map +1 -1
  3. package/dist/connectionTelemetry.js +21 -21
  4. package/dist/connectionTelemetry.js.map +1 -1
  5. package/dist/containerRuntime.d.ts +13 -1
  6. package/dist/containerRuntime.d.ts.map +1 -1
  7. package/dist/containerRuntime.js +99 -11
  8. package/dist/containerRuntime.js.map +1 -1
  9. package/dist/dataStore.d.ts.map +1 -1
  10. package/dist/dataStore.js +14 -3
  11. package/dist/dataStore.js.map +1 -1
  12. package/dist/dataStoreRegistry.d.ts +0 -4
  13. package/dist/dataStoreRegistry.d.ts.map +1 -1
  14. package/dist/dataStoreRegistry.js +12 -1
  15. package/dist/dataStoreRegistry.js.map +1 -1
  16. package/dist/dataStores.d.ts.map +1 -1
  17. package/dist/dataStores.js +4 -4
  18. package/dist/dataStores.js.map +1 -1
  19. package/dist/garbageCollection.d.ts +20 -24
  20. package/dist/garbageCollection.d.ts.map +1 -1
  21. package/dist/garbageCollection.js +40 -117
  22. package/dist/garbageCollection.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.d.ts.map +1 -1
  25. package/dist/packageVersion.js +1 -1
  26. package/dist/packageVersion.js.map +1 -1
  27. package/lib/connectionTelemetry.d.ts +19 -0
  28. package/lib/connectionTelemetry.d.ts.map +1 -1
  29. package/lib/connectionTelemetry.js +21 -21
  30. package/lib/connectionTelemetry.js.map +1 -1
  31. package/lib/containerRuntime.d.ts +13 -1
  32. package/lib/containerRuntime.d.ts.map +1 -1
  33. package/lib/containerRuntime.js +101 -13
  34. package/lib/containerRuntime.js.map +1 -1
  35. package/lib/dataStore.d.ts.map +1 -1
  36. package/lib/dataStore.js +15 -4
  37. package/lib/dataStore.js.map +1 -1
  38. package/lib/dataStoreRegistry.d.ts +0 -4
  39. package/lib/dataStoreRegistry.d.ts.map +1 -1
  40. package/lib/dataStoreRegistry.js +12 -1
  41. package/lib/dataStoreRegistry.js.map +1 -1
  42. package/lib/dataStores.d.ts.map +1 -1
  43. package/lib/dataStores.js +5 -5
  44. package/lib/dataStores.js.map +1 -1
  45. package/lib/garbageCollection.d.ts +20 -24
  46. package/lib/garbageCollection.d.ts.map +1 -1
  47. package/lib/garbageCollection.js +39 -115
  48. package/lib/garbageCollection.js.map +1 -1
  49. package/lib/packageVersion.d.ts +1 -1
  50. package/lib/packageVersion.d.ts.map +1 -1
  51. package/lib/packageVersion.js +1 -1
  52. package/lib/packageVersion.js.map +1 -1
  53. package/package.json +19 -47
  54. package/src/connectionTelemetry.ts +58 -37
  55. package/src/containerRuntime.ts +119 -26
  56. package/src/dataStore.ts +21 -4
  57. package/src/dataStoreRegistry.ts +8 -1
  58. package/src/dataStores.ts +6 -5
  59. package/src/garbageCollection.ts +66 -158
  60. package/src/packageVersion.ts +1 -1
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.semverCompare = exports.GarbageCollector = exports.GCNodeType = exports.defaultSessionExpiryDurationMs = exports.trackGCStateMinimumVersionKey = exports.trackGCStateKey = exports.logUnknownOutboundReferencesKey = exports.disableSessionExpiryKey = exports.runSessionExpiryKey = exports.gcBlobPrefix = exports.gcTreeKey = void 0;
7
+ exports.GarbageCollector = exports.GCNodeType = exports.defaultSessionExpiryDurationMs = exports.trackGCStateKey = exports.disableSessionExpiryKey = exports.runSessionExpiryKey = exports.gcBlobPrefix = exports.gcTreeKey = void 0;
8
8
  const common_utils_1 = require("@fluidframework/common-utils");
9
9
  const container_utils_1 = require("@fluidframework/container-utils");
10
10
  const garbage_collector_1 = require("@fluidframework/garbage-collector");
@@ -14,7 +14,6 @@ const runtime_utils_1 = require("@fluidframework/runtime-utils");
14
14
  const telemetry_utils_1 = require("@fluidframework/telemetry-utils");
15
15
  const containerRuntime_1 = require("./containerRuntime");
16
16
  const dataStores_1 = require("./dataStores");
17
- const packageVersion_1 = require("./packageVersion");
18
17
  const summaryFormat_1 = require("./summaryFormat");
19
18
  /** This is the current version of garbage collection. */
20
19
  const GCVersion = 1;
@@ -34,12 +33,8 @@ const writeAtRootKey = "Fluid.GarbageCollection.WriteDataAtRoot";
34
33
  exports.runSessionExpiryKey = "Fluid.GarbageCollection.RunSessionExpiry";
35
34
  // Feature gate key to disable expiring session after a set period of time, even if expiry value is present
36
35
  exports.disableSessionExpiryKey = "Fluid.GarbageCollection.DisableSessionExpiry";
37
- // Feature gate key to log error messages if GC reference validation fails.
38
- exports.logUnknownOutboundReferencesKey = "Fluid.GarbageCollection.LogUnknownOutboundReferences";
39
36
  // Feature gate key to write the gc blob as a handle if the data is the same.
40
37
  exports.trackGCStateKey = "Fluid.GarbageCollection.TrackGCState";
41
- // Feature gate key to limit which versions can write the gc blob as a handle if the data is the same.
42
- exports.trackGCStateMinimumVersionKey = "Fluid.GarbageCollection.TrackGCState.MinVersion";
43
38
  const defaultInactiveTimeoutMs = 7 * 24 * 60 * 60 * 1000; // 7 days
44
39
  exports.defaultSessionExpiryDurationMs = 30 * 24 * 60 * 60 * 1000; // 30 days
45
40
  /** The types of GC nodes in the GC reference graph. */
@@ -117,21 +112,12 @@ class UnreferencedStateTracker {
117
112
  * NodeId = "dds1" NodeId = "dds2"
118
113
  */
119
114
  class GarbageCollector {
120
- constructor(runtime, gcOptions,
121
- /** For a given node path, returns the node's package path. */
122
- getNodePackagePath,
123
- /** Returns the timestamp of the last summary generated for this container. */
124
- getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata, isSummarizerClient = true) {
115
+ constructor(createParams) {
125
116
  var _a, _b, _c, _d, _e, _f, _g;
126
- this.runtime = runtime;
127
- this.gcOptions = gcOptions;
128
- this.getNodePackagePath = getNodePackagePath;
129
- this.getLastSummaryTimestampMs = getLastSummaryTimestampMs;
130
- this.isSummarizerClient = isSummarizerClient;
131
117
  /**
132
118
  * Tells whether the GC data should be written to the root of the summary tree.
133
119
  */
134
- this._writeDataAtRoot = false;
120
+ this._writeDataAtRoot = true;
135
121
  /**
136
122
  * Tells whether the initial GC state needs to be reset. This can happen under 2 conditions:
137
123
  * 1. The base snapshot contains GC state but GC is disabled. This will happen the first time GC is disabled after
@@ -157,7 +143,15 @@ class GarbageCollector {
157
143
  this.pendingEventsQueue = [];
158
144
  // The number of times GC has successfully completed on this instance of GarbageCollector.
159
145
  this.completedRuns = 0;
160
- this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(baseLogger, "GarbageCollector", { all: { completedGCRuns: () => this.completedRuns } }));
146
+ this.runtime = createParams.runtime;
147
+ this.isSummarizerClient = createParams.isSummarizerClient;
148
+ this.gcOptions = createParams.gcOptions;
149
+ this.getNodePackagePath = createParams.getNodePackagePath;
150
+ this.getLastSummaryTimestampMs = createParams.getLastSummaryTimestampMs;
151
+ const baseSnapshot = createParams.baseSnapshot;
152
+ const metadata = createParams.metadata;
153
+ const readAndParseBlob = createParams.readAndParseBlob;
154
+ this.mc = (0, telemetry_utils_1.loggerToMonitoringContext)(telemetry_utils_1.ChildLogger.create(createParams.baseLogger, "GarbageCollector", { all: { completedGCRuns: () => this.completedRuns } }));
161
155
  let prevSummaryGCVersion;
162
156
  /**
163
157
  * The following GC state is enabled during container creation and cannot be changed throughout its lifetime:
@@ -166,7 +160,7 @@ class GarbageCollector {
166
160
  * 3. Whether GC session expiry is enabled or not.
167
161
  * For existing containers, we get this information from the metadata blob of its summary.
168
162
  */
169
- if (existing) {
163
+ if (createParams.existing) {
170
164
  prevSummaryGCVersion = (0, summaryFormat_1.getGCVersion)(metadata);
171
165
  // Existing documents which did not have metadata blob or had GC disabled have version as 0. For all
172
166
  // other existing documents, GC is enabled.
@@ -177,14 +171,14 @@ class GarbageCollector {
177
171
  else {
178
172
  // Sweep should not be enabled without enabling GC mark phase. We could silently disable sweep in this
179
173
  // scenario but explicitly failing makes it clearer and promotes correct usage.
180
- if (gcOptions.sweepAllowed && gcOptions.gcAllowed === false) {
174
+ if (this.gcOptions.sweepAllowed && this.gcOptions.gcAllowed === false) {
181
175
  throw new container_utils_1.UsageError("GC sweep phase cannot be enabled without enabling GC mark phase");
182
176
  }
183
177
  // For new documents, GC is enabled by default. It can be explicitly disabled by setting the gcAllowed
184
178
  // flag in GC options to false.
185
- this.gcEnabled = gcOptions.gcAllowed !== false;
179
+ this.gcEnabled = this.gcOptions.gcAllowed !== false;
186
180
  // The sweep phase has to be explicitly enabled by setting the sweepAllowed flag in GC options to true.
187
- this.sweepEnabled = gcOptions.sweepAllowed === true;
181
+ this.sweepEnabled = this.gcOptions.sweepAllowed === true;
188
182
  // Set the Session Expiry only if the flag is enabled or the test option is set.
189
183
  if (this.mc.config.getBoolean(exports.runSessionExpiryKey) && this.gcEnabled) {
190
184
  this.sessionExpiryTimeoutMs = exports.defaultSessionExpiryDurationMs;
@@ -218,10 +212,8 @@ class GarbageCollector {
218
212
  // GC must be enabled for the document.
219
213
  this.gcEnabled
220
214
  // GC must not be disabled via GC options.
221
- && !gcOptions.disableGC);
222
- const minimumVersion = this.mc.config.getString(exports.trackGCStateMinimumVersionKey);
223
- const shouldTrackStateForVersion = meetsMinimumVersionRequirement(packageVersion_1.pkgVersion, minimumVersion);
224
- this.trackGCState = this.mc.config.getBoolean(exports.trackGCStateKey) === true && shouldTrackStateForVersion;
215
+ && !this.gcOptions.disableGC);
216
+ this.trackGCState = this.mc.config.getBoolean(exports.trackGCStateKey) === true;
225
217
  /**
226
218
  * Whether sweep should run or not. The following conditions have to be met to run sweep:
227
219
  * 1. Overall GC or mark phase must be enabled (this.shouldRunGC).
@@ -233,19 +225,15 @@ class GarbageCollector {
233
225
  this.inactiveTimeoutMs =
234
226
  (_e = (_d = this.mc.config.getNumber("Fluid.GarbageCollection.TestOverride.InactiveTimeoutMs")) !== null && _d !== void 0 ? _d : this.gcOptions.inactiveTimeoutMs) !== null && _e !== void 0 ? _e : defaultInactiveTimeoutMs;
235
227
  // Whether we are running in test mode. In this mode, unreferenced nodes are immediately deleted.
236
- this.testMode = (_f = this.mc.config.getBoolean(gcTestModeKey)) !== null && _f !== void 0 ? _f : gcOptions.runGCInTestMode === true;
237
- /**
238
- * Enable resetting initial state once the following issue is resolved:
239
- * https://github.com/microsoft/FluidFramework/issues/8878.
240
- * Currently, the GC tree is not written at root, so we don't know if the base snapshot contains GC tree or not.
241
- */
242
- // The GC state needs to be reset if the base snapshot contains GC tree and GC is disabled or it doesn't contain
243
- // GC tree and GC is enabled.
244
- // const gcTreePresent = baseSnapshot?.trees[gcTreeKey] !== undefined;
245
- // this.initialStateNeedsReset = gcTreePresent ? !this.shouldRunGC : this.shouldRunGC;
246
- // If `writeDataAtRoot` setting is true, write the GC data into the root of the summary tree. We do this so that
247
- // the roll out can be staged. Once its rolled out everywhere, we will start writing at root by default.
248
- this._writeDataAtRoot = (_g = this.mc.config.getBoolean(writeAtRootKey)) !== null && _g !== void 0 ? _g : this.gcOptions.writeDataAtRoot === true;
228
+ this.testMode = (_f = this.mc.config.getBoolean(gcTestModeKey)) !== null && _f !== void 0 ? _f : this.gcOptions.runGCInTestMode === true;
229
+ // GC state is written into root of the summary tree by default. Can be overridden via feature flag for now.
230
+ this._writeDataAtRoot = (_g = this.mc.config.getBoolean(writeAtRootKey)) !== null && _g !== void 0 ? _g : true;
231
+ if (this._writeDataAtRoot) {
232
+ // The GC state needs to be reset if the base snapshot contains GC tree and GC is disabled or it doesn't
233
+ // contain GC tree and GC is enabled.
234
+ const gcTreePresent = (baseSnapshot === null || baseSnapshot === void 0 ? void 0 : baseSnapshot.trees[exports.gcTreeKey]) !== undefined;
235
+ this.initialStateNeedsReset = gcTreePresent !== this.shouldRunGC;
236
+ }
249
237
  // Get the GC state from the GC blob in the base snapshot. Use LazyPromise because we only want to do
250
238
  // this once since it involves fetching blobs from storage which is expensive.
251
239
  const baseSummaryStateP = new common_utils_1.LazyPromise(async () => {
@@ -334,7 +322,7 @@ class GarbageCollector {
334
322
  // Run GC on the nodes in the base summary to get the routes used in each node in the container.
335
323
  // This is an optimization for space (vs performance) wherein we don't need to store the used routes of
336
324
  // each node in the summary.
337
- const usedRoutes = (0, garbage_collector_1.runGarbageCollection)(gcNodes, ["/"], this.mc.logger).referencedNodeIds;
325
+ const usedRoutes = (0, garbage_collector_1.runGarbageCollection)(gcNodes, ["/"]).referencedNodeIds;
338
326
  const baseGCDetailsMap = (0, garbage_collector_1.unpackChildNodesGCDetails)({ gcData: { gcNodes }, usedRoutes });
339
327
  // Currently, the nodes may write the GC data. So, we need to update it's base GC details with the
340
328
  // unreferenced timestamp. Once we start writing the GC data here, we won't need to do this anymore.
@@ -350,7 +338,7 @@ class GarbageCollector {
350
338
  });
351
339
  // Log all the GC options and the state determined by the garbage collector. This is interesting only for the
352
340
  // summarizer client since it is the only one that runs GC. It also helps keep the telemetry less noisy.
353
- const gcConfigProps = JSON.stringify(Object.assign({ gcEnabled: this.gcEnabled, sweepEnabled: this.sweepEnabled, runGC: this.shouldRunGC, runSweep: this.shouldRunSweep, writeAtRoot: this._writeDataAtRoot, testMode: this.testMode, sessionExpiry: this.sessionExpiryTimeoutMs, inactiveTimeout: this.inactiveTimeoutMs, existing }, this.gcOptions));
341
+ const gcConfigProps = JSON.stringify(Object.assign({ gcEnabled: this.gcEnabled, sweepEnabled: this.sweepEnabled, runGC: this.shouldRunGC, runSweep: this.shouldRunSweep, writeAtRoot: this._writeDataAtRoot, testMode: this.testMode, sessionExpiry: this.sessionExpiryTimeoutMs, inactiveTimeout: this.inactiveTimeoutMs, existing: createParams.existing }, this.gcOptions));
354
342
  if (this.isSummarizerClient) {
355
343
  this.mc.logger.sendTelemetryEvent({
356
344
  eventName: "GarbageCollectorLoaded",
@@ -366,8 +354,8 @@ class GarbageCollector {
366
354
  });
367
355
  }
368
356
  }
369
- static create(provider, gcOptions, getNodePackagePath, getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata, isSummarizerClient) {
370
- return new GarbageCollector(provider, gcOptions, getNodePackagePath, getLastSummaryTimestampMs, baseSnapshot, readAndParseBlob, baseLogger, existing, metadata, isSummarizerClient);
357
+ static create(createParams) {
358
+ return new GarbageCollector(createParams);
371
359
  }
372
360
  /**
373
361
  * Tells whether the GC state needs to be reset in the next summary. We need to do this if:
@@ -399,7 +387,7 @@ class GarbageCollector {
399
387
  await this.runtime.updateStateBeforeGC();
400
388
  // Get the runtime's GC data and run GC on the reference graph in it.
401
389
  const gcData = await this.runtime.getGCData(fullGC);
402
- const gcResult = (0, garbage_collector_1.runGarbageCollection)(gcData.gcNodes, ["/"], logger);
390
+ const gcResult = (0, garbage_collector_1.runGarbageCollection)(gcData.gcNodes, ["/"]);
403
391
  const gcStats = this.generateStatsAndLogEvents(gcResult, logger);
404
392
  // Update the state since the last GC run. There can be nodes that were referenced between the last and
405
393
  // the current run. We need to identify than and update their unreferenced state if needed.
@@ -488,9 +476,6 @@ class GarbageCollector {
488
476
  * latest summary tracked.
489
477
  */
490
478
  async latestSummaryStateRefreshed(result, readAndParseBlob) {
491
- // After a summary is successfully submitted and ack'd by this client, the GC state should have been reset in
492
- // the summary and doesn't need to be reset anymore.
493
- this.initialStateNeedsReset = false;
494
479
  if (!this.shouldRunGC || !result.latestSummaryUpdated) {
495
480
  return;
496
481
  }
@@ -498,6 +483,7 @@ class GarbageCollector {
498
483
  // Basically, it was written in the current GC version.
499
484
  if (result.wasSummaryTracked) {
500
485
  this.latestSummaryGCVersion = this.currentGCVersion;
486
+ this.initialStateNeedsReset = false;
501
487
  if (this.trackGCState) {
502
488
  this.latestSerializedSummaryState = this.pendingSerializedSummaryState;
503
489
  this.pendingSerializedSummaryState = undefined;
@@ -620,10 +606,7 @@ class GarbageCollector {
620
606
  }
621
607
  // Find any references that haven't been identified correctly.
622
608
  const missingExplicitReferences = this.findMissingExplicitReferences(currentGCData, this.previousGCDataFromLastRun, this.newReferencesSinceLastRun);
623
- // The following log will be enabled once this issue is resolved:
624
- // https://github.com/microsoft/FluidFramework/issues/8878.
625
- if (this.mc.config.getBoolean(exports.logUnknownOutboundReferencesKey) === true
626
- && missingExplicitReferences.length > 0) {
609
+ if (this.writeDataAtRoot && missingExplicitReferences.length > 0) {
627
610
  missingExplicitReferences.forEach((missingExplicitReference) => {
628
611
  const event = {
629
612
  eventName: "gcUnknownOutboundReferences",
@@ -667,7 +650,7 @@ class GarbageCollector {
667
650
  * unreferenced, stop tracking them and remove from unreferenced list.
668
651
  * Some of these nodes may be unreferenced now and if so, the current run will add unreferenced state for them.
669
652
  */
670
- const gcResult = (0, garbage_collector_1.runGarbageCollection)(gcDataSuperSet.gcNodes, ["/"], logger);
653
+ const gcResult = (0, garbage_collector_1.runGarbageCollection)(gcDataSuperSet.gcNodes, ["/"]);
671
654
  for (const nodeId of gcResult.referencedNodeIds) {
672
655
  const nodeStateTracker = this.unreferencedNodesState.get(nodeId);
673
656
  if (nodeStateTracker !== undefined) {
@@ -747,11 +730,10 @@ class GarbageCollector {
747
730
  };
748
731
  const updateNodeStats = (nodeId, referenced) => {
749
732
  gcStats.nodeCount++;
750
- /**
751
- * `this.unreferencedNodesState` has the previous unreferenced state of all nodes. `referenced` flag passed
752
- * here is current state of the give node. Check if the reference state of the changed.
753
- */
754
- const stateUpdated = this.unreferencedNodesState.has(nodeId) ? referenced : !referenced;
733
+ // If there is no previous GC data, every node's state is generated and is considered as updated.
734
+ // Otherwise, find out if any node went from referenced to unreferenced or vice-versa.
735
+ const stateUpdated = this.previousGCDataFromLastRun === undefined ||
736
+ this.unreferencedNodesState.has(nodeId) === referenced;
755
737
  if (stateUpdated) {
756
738
  gcStats.updatedNodeCount++;
757
739
  }
@@ -827,7 +809,7 @@ class GarbageCollector {
827
809
  // next time GC runs as the package data should be available then.
828
810
  const pkg = packagePath !== null && packagePath !== void 0 ? packagePath : this.getNodePackagePath(nodeId);
829
811
  if (pkg !== undefined) {
830
- this.mc.logger.sendErrorEvent(Object.assign(Object.assign({}, event), { pkg: { value: `/${pkg.join("/")}`, tag: telemetry_utils_1.TelemetryDataTag.PackageData } }));
812
+ this.mc.logger.sendErrorEvent(Object.assign(Object.assign({}, event), { pkg: { value: pkg.join("/"), tag: telemetry_utils_1.TelemetryDataTag.PackageData } }));
831
813
  }
832
814
  else {
833
815
  this.pendingEventsQueue.push(event);
@@ -887,63 +869,4 @@ function setLongTimeout(timeoutMs, timeoutFn, setTimerFn) {
887
869
  }
888
870
  setTimerFn(timer);
889
871
  }
890
- /**
891
- * meetsMinimumVersionRequirement is used determining if a feature version should be run. This is similar to feature
892
- * flags. The advantage of this is that if we ship a bug in version 0.1.1 and fix it in version 0.2.1. We can keep this
893
- * feature disabled for version 0.1.1 and enabled for 0.2.1. Older versions will run without the feature and new
894
- * versions will run with the feature.
895
- * @param currentVersion - the total time the timeout needs to last in ms
896
- * @param minimumVersion - the function to execute when the timer ends
897
- */
898
- function meetsMinimumVersionRequirement(currentVersion, minimumVersion) {
899
- return minimumVersion === undefined || semverCompare(currentVersion, minimumVersion) >= 0;
900
- }
901
- /**
902
- * Compare semver versions.
903
- * @param currentVersion - assumed to be any valid semver version
904
- * @param minimumVersion - must be [major].[minor].[patch], where major, minor, and patch are all numbers
905
- * as it complicates the algorithm if we allow comparisons against minimum pre-release versions.
906
- * @returns
907
- * 0 if the currentVersion equals the minimumVersion
908
- * 1 if the currentVersion is greater than the minimumVersion
909
- * -1 if the minimumVersion is greater than the currentVersion
910
- */
911
- function semverCompare(currentVersion, minimumVersion) {
912
- const minimumValues = minimumVersion.split(".").map((value) => {
913
- (0, common_utils_1.assert)(isNaN(+value) === false, 0x2f8 /* Expected real numbers in minimum version! */);
914
- return Number.parseInt(value, 10);
915
- });
916
- (0, common_utils_1.assert)(minimumValues.length === 3, 0x2f9 /* Expected minimumVersion to be [major].[minor].[patch] */);
917
- const [minMajor, minMinor, minPatch] = minimumValues;
918
- const currentValuesString = currentVersion.split(/\W/);
919
- (0, common_utils_1.assert)(currentValuesString.length >= 3, 0x2fa /* Expected version to match semver rules! */);
920
- const currentValues = currentValuesString.slice(0, 3).map((value) => {
921
- (0, common_utils_1.assert)(isNaN(+value) === false, 0x2fb /* Expected real numbers in minimum version! */);
922
- return Number.parseInt(value, 10);
923
- });
924
- const [cMajor, cMinor, cPatch] = currentValues;
925
- if (cMajor > minMajor) {
926
- return 1;
927
- }
928
- else if (minMajor > cMajor) {
929
- return -1;
930
- }
931
- if (cMinor > minMinor) {
932
- return 1;
933
- }
934
- else if (minMinor > cMinor) {
935
- return -1;
936
- }
937
- if (cPatch > minPatch) {
938
- return 1;
939
- }
940
- else if (minPatch > cPatch) {
941
- return -1;
942
- }
943
- if (currentValuesString.length === 3) {
944
- return 0;
945
- }
946
- return -1;
947
- }
948
- exports.semverCompare = semverCompare;
949
872
  //# sourceMappingURL=garbageCollection.js.map