@atlaspack/core 2.14.1-dev.144 → 2.14.1-dev.146

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 (67) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/lib/AssetGraph.js +17 -6
  3. package/lib/Atlaspack.js +24 -5
  4. package/lib/BundleGraph.js +6 -5
  5. package/lib/Dependency.js +6 -2
  6. package/lib/Environment.js +4 -3
  7. package/lib/EnvironmentManager.js +137 -0
  8. package/lib/InternalConfig.js +3 -2
  9. package/lib/PackagerRunner.js +52 -15
  10. package/lib/RequestTracker.js +337 -82
  11. package/lib/UncommittedAsset.js +20 -2
  12. package/lib/applyRuntimes.js +2 -1
  13. package/lib/assetUtils.js +2 -1
  14. package/lib/atlaspack-v3/worker/worker.js +8 -0
  15. package/lib/public/Asset.js +3 -2
  16. package/lib/public/Bundle.js +2 -1
  17. package/lib/public/BundleGraph.js +21 -5
  18. package/lib/public/Config.js +98 -3
  19. package/lib/public/Dependency.js +2 -1
  20. package/lib/public/MutableBundleGraph.js +2 -1
  21. package/lib/public/Target.js +2 -1
  22. package/lib/requests/AssetGraphRequest.js +13 -1
  23. package/lib/requests/AssetRequest.js +2 -1
  24. package/lib/requests/BundleGraphRequest.js +13 -1
  25. package/lib/requests/ConfigRequest.js +27 -4
  26. package/lib/requests/TargetRequest.js +18 -16
  27. package/lib/requests/WriteBundleRequest.js +15 -3
  28. package/lib/requests/WriteBundlesRequest.js +1 -0
  29. package/lib/resolveOptions.js +5 -6
  30. package/package.json +22 -18
  31. package/src/AssetGraph.js +12 -6
  32. package/src/Atlaspack.js +29 -13
  33. package/src/BundleGraph.js +13 -8
  34. package/src/Dependency.js +13 -5
  35. package/src/Environment.js +8 -5
  36. package/src/EnvironmentManager.js +145 -0
  37. package/src/InternalConfig.js +6 -5
  38. package/src/PackagerRunner.js +72 -20
  39. package/src/RequestTracker.js +567 -131
  40. package/src/UncommittedAsset.js +23 -3
  41. package/src/applyRuntimes.js +6 -1
  42. package/src/assetUtils.js +4 -3
  43. package/src/atlaspack-v3/worker/compat/plugin-config.js +9 -5
  44. package/src/atlaspack-v3/worker/worker.js +7 -0
  45. package/src/public/Asset.js +9 -2
  46. package/src/public/Bundle.js +2 -1
  47. package/src/public/BundleGraph.js +22 -5
  48. package/src/public/Config.js +129 -14
  49. package/src/public/Dependency.js +2 -1
  50. package/src/public/MutableBundleGraph.js +2 -1
  51. package/src/public/Target.js +2 -1
  52. package/src/requests/AssetGraphRequest.js +13 -3
  53. package/src/requests/AssetRequest.js +2 -1
  54. package/src/requests/BundleGraphRequest.js +13 -3
  55. package/src/requests/ConfigRequest.js +33 -9
  56. package/src/requests/TargetRequest.js +19 -25
  57. package/src/requests/WriteBundleRequest.js +14 -8
  58. package/src/requests/WriteBundlesRequest.js +1 -0
  59. package/src/resolveOptions.js +6 -8
  60. package/src/types.js +9 -7
  61. package/test/Environment.test.js +43 -34
  62. package/test/EnvironmentManager.test.js +192 -0
  63. package/test/PublicEnvironment.test.js +10 -7
  64. package/test/RequestTracker.test.js +115 -3
  65. package/test/public/Config.test.js +108 -0
  66. package/test/requests/ConfigRequest.test.js +187 -3
  67. package/test/test-utils.js +4 -9
@@ -61,6 +61,14 @@ function _profiler() {
61
61
  return data;
62
62
  }
63
63
  var _RequestTracker = require("../RequestTracker");
64
+ function _featureFlags() {
65
+ const data = require("@atlaspack/feature-flags");
66
+ _featureFlags = function () {
67
+ return data;
68
+ };
69
+ return data;
70
+ }
71
+ var _EnvironmentManager = require("../EnvironmentManager");
64
72
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
65
73
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
66
74
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -114,7 +122,8 @@ async function run({
114
122
  let cacheKeys = info.cacheKeys;
115
123
  let mapKey = cacheKeys.map;
116
124
  let fullPath = (0, _projectPath.fromProjectPath)(options.projectRoot, filePath);
117
- if (mapKey && bundle.env.sourceMap && !bundle.env.sourceMap.inline) {
125
+ const env = (0, _EnvironmentManager.fromEnvironmentId)(bundle.env);
126
+ if (mapKey && env.sourceMap && !env.sourceMap.inline) {
118
127
  api.invalidateOnFileDelete((0, _projectPath.toProjectPath)(options.projectRoot, fullPath + '.map'));
119
128
  }
120
129
  let dir = _path().default.dirname(fullPath);
@@ -145,11 +154,14 @@ async function run({
145
154
  } = await (0, _DevDepRequest.getDevDepRequests)(api);
146
155
  (0, _DevDepRequest.invalidateDevDeps)(invalidDevDeps, options, config);
147
156
  await writeFiles(contentStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api);
148
- if (mapKey && bundle.env.sourceMap && !bundle.env.sourceMap.inline && (await options.cache.has(mapKey))) {
149
- await writeFiles((0, _utils().blobToStream)(await options.cache.getBlob(mapKey)), info, hashRefToNameHash, options, config, outputFS, (0, _projectPath.toProjectPathUnsafe)((0, _projectPath.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
157
+ const hasSourceMap = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.hasLargeBlob(mapKey) : await options.cache.has(mapKey);
158
+ if (mapKey && env.sourceMap && !env.sourceMap.inline && hasSourceMap) {
159
+ const mapEntry = (0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements') ? await options.cache.getLargeBlob(mapKey) : await options.cache.getBlob(mapKey);
160
+ await writeFiles((0, _utils().blobToStream)(mapEntry), info, hashRefToNameHash, options, config, outputFS, (0, _projectPath.toProjectPathUnsafe)((0, _projectPath.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
150
161
  }
151
162
  let res = {
152
163
  filePath,
164
+ bundleId: bundle.id,
153
165
  type: info.type,
154
166
  stats: {
155
167
  size,
@@ -76,6 +76,7 @@ async function run({
76
76
  let name = (0, _nullthrows().default)(bundle.name, `Expected ${bundle.type} bundle to have a name`).replace(bundle.hashReference, hash);
77
77
  res.set(bundle.id, {
78
78
  filePath: (0, _projectPath.joinProjectPath)(bundle.target.distDir, name),
79
+ bundleId: bundle.id,
79
80
  type: bundle.type,
80
81
  // FIXME: this is wrong if the packager changes the type...
81
82
  stats: {
@@ -145,13 +145,12 @@ async function resolveOptions(initialOptions) {
145
145
  return initialOptions.cache;
146
146
  }
147
147
  const needsRustLmdbCache = (0, _featureFlags().getFeatureFlag)('atlaspackV3');
148
- if (!needsRustLmdbCache && !(outputFS instanceof _fs().NodeFS)) {
149
- return new (_cache().FSCache)(outputFS, cacheDir);
148
+ if (!(0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
149
+ if (!needsRustLmdbCache && !(outputFS instanceof _fs().NodeFS)) {
150
+ return new (_cache().FSCache)(outputFS, cacheDir);
151
+ }
150
152
  }
151
- if (needsRustLmdbCache || (0, _featureFlags().getFeatureFlag)('useLmdbJsLite')) {
152
- return new (_cache().LMDBLiteCache)(cacheDir);
153
- }
154
- return new (_cache().LMDBCache)(cacheDir);
153
+ return new (_cache().LMDBLiteCache)(cacheDir);
155
154
  }();
156
155
  let mode = initialOptions.mode ?? 'development';
157
156
  let shouldOptimize = (initialOptions === null || initialOptions === void 0 || (_initialOptions$defau = initialOptions.defaultTargetOptions) === null || _initialOptions$defau === void 0 ? void 0 : _initialOptions$defau.shouldOptimize) ?? mode === 'production';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/core",
3
- "version": "2.14.1-dev.144+ea7d58b70",
3
+ "version": "2.14.1-dev.146+33cba81e9",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,6 +10,7 @@
10
10
  "url": "https://github.com/atlassian-labs/atlaspack.git"
11
11
  },
12
12
  "main": "lib/index.js",
13
+ "types": "index.d.ts",
13
14
  "source": "src/index.js",
14
15
  "engines": {
15
16
  "node": ">= 16.0.0"
@@ -20,21 +21,21 @@
20
21
  "check-ts": "tsc --noEmit index.d.ts"
21
22
  },
22
23
  "dependencies": {
23
- "@atlaspack/build-cache": "2.13.3-dev.144+ea7d58b70",
24
- "@atlaspack/cache": "2.13.3-dev.144+ea7d58b70",
25
- "@atlaspack/diagnostic": "2.14.1-dev.144+ea7d58b70",
26
- "@atlaspack/events": "2.14.1-dev.144+ea7d58b70",
27
- "@atlaspack/feature-flags": "2.14.1-dev.144+ea7d58b70",
28
- "@atlaspack/fs": "2.14.1-dev.144+ea7d58b70",
29
- "@atlaspack/graph": "3.4.1-dev.144+ea7d58b70",
30
- "@atlaspack/logger": "2.14.1-dev.144+ea7d58b70",
31
- "@atlaspack/package-manager": "2.14.1-dev.144+ea7d58b70",
32
- "@atlaspack/plugin": "2.14.1-dev.144+ea7d58b70",
33
- "@atlaspack/profiler": "2.14.1-dev.144+ea7d58b70",
34
- "@atlaspack/rust": "3.0.1-dev.144+ea7d58b70",
35
- "@atlaspack/types": "2.14.1-dev.144+ea7d58b70",
36
- "@atlaspack/utils": "2.14.1-dev.144+ea7d58b70",
37
- "@atlaspack/workers": "2.14.1-dev.144+ea7d58b70",
24
+ "@atlaspack/build-cache": "2.13.3-dev.146+33cba81e9",
25
+ "@atlaspack/cache": "2.13.3-dev.146+33cba81e9",
26
+ "@atlaspack/diagnostic": "2.14.1-dev.146+33cba81e9",
27
+ "@atlaspack/events": "2.14.1-dev.146+33cba81e9",
28
+ "@atlaspack/feature-flags": "2.14.1-dev.146+33cba81e9",
29
+ "@atlaspack/fs": "2.14.1-dev.146+33cba81e9",
30
+ "@atlaspack/graph": "3.4.1-dev.146+33cba81e9",
31
+ "@atlaspack/logger": "2.14.1-dev.146+33cba81e9",
32
+ "@atlaspack/package-manager": "2.14.1-dev.146+33cba81e9",
33
+ "@atlaspack/plugin": "2.14.1-dev.146+33cba81e9",
34
+ "@atlaspack/profiler": "2.14.1-dev.146+33cba81e9",
35
+ "@atlaspack/rust": "3.0.1-dev.146+33cba81e9",
36
+ "@atlaspack/types": "2.14.1-dev.146+33cba81e9",
37
+ "@atlaspack/utils": "2.14.1-dev.146+33cba81e9",
38
+ "@atlaspack/workers": "2.14.1-dev.146+33cba81e9",
38
39
  "@mischnic/json-sourcemap": "^0.1.0",
39
40
  "@parcel/source-map": "^2.1.1",
40
41
  "base-x": "^3.0.8",
@@ -57,7 +58,10 @@
57
58
  },
58
59
  "exports": {
59
60
  "./*": "./*",
60
- ".": "./lib/index.js",
61
+ ".": {
62
+ "types": "./index.d.ts",
63
+ "default": "./lib/index.js"
64
+ },
61
65
  "./worker": {
62
66
  "@atlaspack::sources": "./src/worker.js",
63
67
  "default": "./lib/worker.js"
@@ -70,5 +74,5 @@
70
74
  "./src/serializerCore.js": "./src/serializerCore.browser.js"
71
75
  },
72
76
  "type": "commonjs",
73
- "gitHead": "ea7d58b70fbe4bbc6324d4053ac673ea307b7bf6"
77
+ "gitHead": "33cba81e98b6eb098014f5a19d7932821b95f075"
74
78
  }
package/src/AssetGraph.js CHANGED
@@ -29,6 +29,8 @@ import nullthrows from 'nullthrows';
29
29
  import {ContentGraph} from '@atlaspack/graph';
30
30
  import {createDependency} from './Dependency';
31
31
  import {type ProjectPath, fromProjectPathRelative} from './projectPath';
32
+ import {fromEnvironmentId, toEnvironmentId} from './EnvironmentManager';
33
+ import {getFeatureFlag} from '@atlaspack/feature-flags';
32
34
 
33
35
  type InitOpts = {|
34
36
  entries?: Array<ProjectPath>,
@@ -65,7 +67,7 @@ export function nodeFromAssetGroup(assetGroup: AssetGroup): AssetGroupNode {
65
67
  return {
66
68
  id: hashString(
67
69
  fromProjectPathRelative(assetGroup.filePath) +
68
- assetGroup.env.id +
70
+ toEnvironmentId(assetGroup.env) +
69
71
  String(assetGroup.isSource) +
70
72
  String(assetGroup.sideEffects) +
71
73
  (assetGroup.code ?? '') +
@@ -149,14 +151,18 @@ export default class AssetGraph extends ContentGraph<AssetGraphNode> {
149
151
 
150
152
  // Deduplicates Environments by making them referentially equal
151
153
  normalizeEnvironment(input: Asset | Dependency | AssetGroup) {
152
- let {id, context} = input.env;
154
+ if (getFeatureFlag('environmentDeduplication')) {
155
+ return;
156
+ }
157
+
158
+ let {id, context} = fromEnvironmentId(input.env);
153
159
  let idAndContext = `${id}-${context}`;
154
160
 
155
161
  let env = this.envCache.get(idAndContext);
156
162
  if (env) {
157
163
  input.env = env;
158
164
  } else {
159
- this.envCache.set(idAndContext, input.env);
165
+ this.envCache.set(idAndContext, fromEnvironmentId(input.env));
160
166
  }
161
167
  }
162
168
 
@@ -235,13 +241,13 @@ export default class AssetGraph extends ContentGraph<AssetGraphNode> {
235
241
  env: target.env,
236
242
  isEntry: true,
237
243
  needsStableName: true,
238
- symbols: target.env.isLibrary
244
+ symbols: fromEnvironmentId(target.env).isLibrary
239
245
  ? new Map([['*', {local: '*', isWeak: true, loc: null}]])
240
246
  : undefined,
241
247
  }),
242
248
  );
243
249
 
244
- if (node.value.env.isLibrary) {
250
+ if (fromEnvironmentId(node.value.env).isLibrary) {
245
251
  // in library mode, all of the entry's symbols are "used"
246
252
  node.usedSymbolsDown.add('*');
247
253
  node.usedSymbolsUp.set('*', undefined);
@@ -428,7 +434,7 @@ export default class AssetGraph extends ContentGraph<AssetGraphNode> {
428
434
 
429
435
  let depIsDeferrable =
430
436
  d.symbols &&
431
- !(d.env.isLibrary && d.isEntry) &&
437
+ !(fromEnvironmentId(d.env).isLibrary && d.isEntry) &&
432
438
  !d.symbols.has('*') &&
433
439
  ![...d.symbols.keys()].some((symbol) => {
434
440
  let assetSymbol = resolvedAsset.symbols?.get(symbol)?.local;
package/src/Atlaspack.js CHANGED
@@ -58,11 +58,7 @@ import {
58
58
  fromProjectPathRelative,
59
59
  } from './projectPath';
60
60
  import {tracer} from '@atlaspack/profiler';
61
- import {
62
- getFeatureFlag,
63
- setFeatureFlags,
64
- DEFAULT_FEATURE_FLAGS,
65
- } from '@atlaspack/feature-flags';
61
+ import {setFeatureFlags, DEFAULT_FEATURE_FLAGS} from '@atlaspack/feature-flags';
66
62
  import {AtlaspackV3, FileSystemV3} from './atlaspack-v3';
67
63
  import createAssetGraphRequestJS from './requests/AssetGraphRequest';
68
64
  import {createAssetGraphRequestRust} from './requests/AssetGraphRequestRust';
@@ -125,9 +121,7 @@ export default class Atlaspack {
125
121
  };
126
122
  setFeatureFlags(featureFlags);
127
123
 
128
- if (getFeatureFlag('enableRustWorkerThreadDylibHack')) {
129
- loadRustWorkerThreadDylibHack();
130
- }
124
+ loadRustWorkerThreadDylibHack();
131
125
 
132
126
  await initSourcemaps;
133
127
  await initRust?.();
@@ -174,9 +168,16 @@ export default class Atlaspack {
174
168
  const version = require('../package.json').version;
175
169
  await lmdb.put('current_session_version', Buffer.from(version));
176
170
 
171
+ let threads = undefined;
172
+ if (process.env.ATLASPACK_NATIVE_THREADS !== undefined) {
173
+ threads = parseInt(process.env.ATLASPACK_NATIVE_THREADS, 10);
174
+ } else if (process.env.NODE_ENV === 'test') {
175
+ threads = 2;
176
+ }
177
+
177
178
  rustAtlaspack = await AtlaspackV3.create({
178
179
  ...options,
179
- threads: process.env.NODE_ENV === 'test' ? 2 : undefined,
180
+ threads,
180
181
  entries: Array.isArray(entries)
181
182
  ? entries
182
183
  : entries == null
@@ -534,10 +535,11 @@ export default class Atlaspack {
534
535
  nativeInvalid = await this.rustAtlaspack.respondToFsEvents(events);
535
536
  }
536
537
 
537
- let isInvalid = await this.#requestTracker.respondToFSEvents(
538
- events,
539
- Number.POSITIVE_INFINITY,
540
- );
538
+ let {didInvalidate: isInvalid} =
539
+ await this.#requestTracker.respondToFSEvents(
540
+ events,
541
+ Number.POSITIVE_INFINITY,
542
+ );
541
543
 
542
544
  if (
543
545
  (nativeInvalid || isInvalid) &&
@@ -647,6 +649,20 @@ export default class Atlaspack {
647
649
  return result;
648
650
  }
649
651
 
652
+ /**
653
+ * Copy the cache to a new directory and compact it.
654
+ */
655
+ async unstable_compactCache(): Promise<void> {
656
+ await this._init();
657
+
658
+ const cache = nullthrows(this.#resolvedOptions).cache;
659
+ if (cache instanceof LMDBLiteCache) {
660
+ await cache.compact('parcel-cache-compacted');
661
+ } else {
662
+ throw new Error('Cache is not an LMDBLiteCache');
663
+ }
664
+ }
665
+
650
666
  async unstable_transform(
651
667
  options: AtlaspackTransformOptions,
652
668
  ): Promise<Array<Asset>> {
@@ -24,7 +24,6 @@ import type {
24
24
  BundleNode,
25
25
  Dependency,
26
26
  DependencyNode,
27
- Environment,
28
27
  InternalSourceLocation,
29
28
  Target,
30
29
  Condition,
@@ -49,6 +48,8 @@ import {ISOLATED_ENVS} from './public/Environment';
49
48
  import {fromProjectPath, fromProjectPathRelative} from './projectPath';
50
49
  import {HASH_REF_PREFIX} from './constants';
51
50
  import {getFeatureFlag} from '@atlaspack/feature-flags';
51
+ import {fromEnvironmentId} from './EnvironmentManager';
52
+ import type {EnvironmentRef} from './EnvironmentManager';
52
53
 
53
54
  export const bundleGraphEdgeTypes = {
54
55
  // A lack of an edge type indicates to follow the edge while traversing
@@ -283,7 +284,7 @@ export default class BundleGraph {
283
284
  if (
284
285
  node.type === 'dependency' &&
285
286
  node.value.symbols != null &&
286
- node.value.env.shouldScopeHoist &&
287
+ fromEnvironmentId(node.value.env).shouldScopeHoist &&
287
288
  // Disable in dev mode because this feature is at odds with safeToIncrementallyBundle
288
289
  isProduction
289
290
  ) {
@@ -555,11 +556,11 @@ export default class BundleGraph {
555
556
  +needsStableName?: ?boolean,
556
557
  +bundleBehavior?: ?IBundleBehavior,
557
558
  +shouldContentHash: boolean,
558
- +env: Environment,
559
+ +env: EnvironmentRef,
559
560
  |}
560
561
  | {|
561
562
  +type: string,
562
- +env: Environment,
563
+ +env: EnvironmentRef,
563
564
  +uniqueKey: string,
564
565
  +target: Target,
565
566
  +needsStableName?: ?boolean,
@@ -1366,7 +1367,8 @@ export default class BundleGraph {
1366
1367
 
1367
1368
  if (
1368
1369
  descendant.type !== bundle.type ||
1369
- descendant.env.context !== bundle.env.context
1370
+ fromEnvironmentId(descendant.env).context !==
1371
+ fromEnvironmentId(bundle.env).context
1370
1372
  ) {
1371
1373
  actions.skipChildren();
1372
1374
  return;
@@ -1407,7 +1409,7 @@ export default class BundleGraph {
1407
1409
  // If a bundle's environment is isolated, it can't access assets present
1408
1410
  // in any ancestor bundles. Don't consider any assets reachable.
1409
1411
  if (
1410
- ISOLATED_ENVS.has(bundle.env.context) ||
1412
+ ISOLATED_ENVS.has(fromEnvironmentId(bundle.env).context) ||
1411
1413
  !bundle.isSplittable ||
1412
1414
  bundle.bundleBehavior === BundleBehavior.isolated ||
1413
1415
  bundle.bundleBehavior === BundleBehavior.inline
@@ -1461,7 +1463,8 @@ export default class BundleGraph {
1461
1463
  node.type === 'root' ||
1462
1464
  (node.type === 'bundle' &&
1463
1465
  (node.value.id === bundle.id ||
1464
- node.value.env.context !== bundle.env.context))
1466
+ fromEnvironmentId(node.value.env).context !==
1467
+ fromEnvironmentId(bundle.env).context))
1465
1468
  ) {
1466
1469
  isReachable = false;
1467
1470
  actions.stop();
@@ -2135,7 +2138,9 @@ export default class BundleGraph {
2135
2138
  hash.writeString(referencedBundle.id);
2136
2139
  }
2137
2140
 
2138
- hash.writeString(JSON.stringify(objectSortedEntriesDeep(bundle.env)));
2141
+ hash.writeString(
2142
+ JSON.stringify(objectSortedEntriesDeep(fromEnvironmentId(bundle.env))),
2143
+ );
2139
2144
  return hash.finish();
2140
2145
  }
2141
2146
 
package/src/Dependency.js CHANGED
@@ -8,7 +8,7 @@ import type {
8
8
  BundleBehavior as IBundleBehavior,
9
9
  SemverRange,
10
10
  } from '@atlaspack/types';
11
- import type {Dependency, Environment, Target} from './types';
11
+ import type {Dependency, Target} from './types';
12
12
  import {createDependencyId as createDependencyIdRust} from '@atlaspack/rust';
13
13
  import {
14
14
  SpecifierType,
@@ -21,6 +21,8 @@ import {toInternalSourceLocation} from './utils';
21
21
  import {toProjectPath} from './projectPath';
22
22
  import assert from 'assert';
23
23
  import {identifierRegistry} from './IdentifierRegistry';
24
+ import {fromEnvironmentId, toEnvironmentId} from './EnvironmentManager';
25
+ import type {EnvironmentRef} from './EnvironmentManager';
24
26
 
25
27
  type DependencyOpts = {|
26
28
  id?: string,
@@ -34,7 +36,7 @@ type DependencyOpts = {|
34
36
  isEntry?: boolean,
35
37
  isOptional?: boolean,
36
38
  loc?: SourceLocation,
37
- env: Environment,
39
+ env: EnvironmentRef,
38
40
  packageConditions?: Array<string>,
39
41
  meta?: Meta,
40
42
  resolveFrom?: FilePath,
@@ -60,7 +62,7 @@ export function createDependencyId({
60
62
  }: {|
61
63
  sourceAssetId?: string | void,
62
64
  specifier: DependencySpecifier,
63
- env: Environment,
65
+ env: EnvironmentRef,
64
66
  target?: Target | void,
65
67
  pipeline?: ?string,
66
68
  specifierType: $Keys<typeof SpecifierType>,
@@ -73,8 +75,14 @@ export function createDependencyId({
73
75
  const params = {
74
76
  sourceAssetId,
75
77
  specifier,
76
- environmentId: env.id,
77
- target,
78
+ environmentId: toEnvironmentId(env),
79
+ target:
80
+ target != null
81
+ ? {
82
+ ...target,
83
+ env: fromEnvironmentId(target.env),
84
+ }
85
+ : null,
78
86
  pipeline,
79
87
  specifierType: SpecifierType[specifierType],
80
88
  bundleBehavior,
@@ -10,6 +10,8 @@ import {toInternalSourceLocation} from './utils';
10
10
  import PublicEnvironment from './public/Environment';
11
11
  import {environmentToInternalEnvironment} from './public/Environment';
12
12
  import {identifierRegistry} from './IdentifierRegistry';
13
+ import {toEnvironmentRef} from './EnvironmentManager';
14
+ import type {EnvironmentRef} from './EnvironmentManager';
13
15
 
14
16
  const DEFAULT_ENGINES = {
15
17
  browsers: ['> 0.25%'],
@@ -35,7 +37,7 @@ export function createEnvironment({
35
37
  loc,
36
38
  }: EnvironmentOpts = {
37
39
  /*::...null*/
38
- }): Environment {
40
+ }): EnvironmentRef {
39
41
  if (context == null) {
40
42
  if (engines?.node) {
41
43
  context = 'node';
@@ -112,21 +114,22 @@ export function createEnvironment({
112
114
  };
113
115
 
114
116
  res.id = getEnvironmentHash(res);
115
- return Object.freeze(res);
117
+
118
+ return toEnvironmentRef(Object.freeze(res));
116
119
  }
117
120
 
118
121
  export function mergeEnvironments(
119
122
  projectRoot: FilePath,
120
123
  a: Environment,
121
124
  b: ?(EnvironmentOptions | IEnvironment),
122
- ): Environment {
125
+ ): EnvironmentRef {
123
126
  // If merging the same object, avoid copying.
124
127
  if (a === b || !b) {
125
- return a;
128
+ return toEnvironmentRef(a);
126
129
  }
127
130
 
128
131
  if (b instanceof PublicEnvironment) {
129
- return environmentToInternalEnvironment(b);
132
+ return toEnvironmentRef(environmentToInternalEnvironment(b));
130
133
  }
131
134
 
132
135
  // $FlowFixMe - ignore the `id` that is already on a
@@ -0,0 +1,145 @@
1
+ // @flow strict-local
2
+ /*!
3
+ * At the moment we're doing this change for `CoreEnvironment`,
4
+ * but the same change must be made for `TypesEnvironment` in @atlaspack/types.
5
+ */
6
+ import type {Environment as CoreEnvironment} from './types';
7
+ import {type Cache} from '@atlaspack/cache';
8
+ import {
9
+ addEnvironment,
10
+ getEnvironment,
11
+ getAllEnvironments,
12
+ setAllEnvironments,
13
+ } from '@atlaspack/rust';
14
+ import {getFeatureFlag} from '@atlaspack/feature-flags';
15
+ import {instrument} from '@atlaspack/logger';
16
+ import {ATLASPACK_VERSION} from './constants';
17
+
18
+ const localEnvironmentCache = new Map<string, CoreEnvironment>();
19
+
20
+ export opaque type EnvironmentId = string;
21
+ /**
22
+ * When deduplication is cleaned-up this will always be a string.
23
+ */
24
+ export type EnvironmentRef = EnvironmentId | CoreEnvironment;
25
+
26
+ /**
27
+ * Convert environment to a ref.
28
+ * This is what we should be using to store environments.
29
+ */
30
+ export function toEnvironmentRef(env: CoreEnvironment): EnvironmentRef {
31
+ if (!getFeatureFlag('environmentDeduplication')) {
32
+ return env;
33
+ }
34
+
35
+ const id = toEnvironmentId(env);
36
+ return id;
37
+ }
38
+
39
+ /**
40
+ * Convert environment to a string ID
41
+ */
42
+ export function toEnvironmentId(
43
+ /**
44
+ * Redundant type during roll-out
45
+ */
46
+ env: CoreEnvironment | EnvironmentRef,
47
+ ): string {
48
+ if (!getFeatureFlag('environmentDeduplication')) {
49
+ return typeof env === 'string' ? env : env.id;
50
+ }
51
+
52
+ if (typeof env === 'string') {
53
+ return env;
54
+ }
55
+
56
+ addEnvironment(env);
57
+ return env.id;
58
+ }
59
+
60
+ export function fromEnvironmentId(id: EnvironmentRef): CoreEnvironment {
61
+ if (!getFeatureFlag('environmentDeduplication')) {
62
+ if (typeof id === 'string') {
63
+ throw new Error(
64
+ 'This should never happen when environmentDeduplication feature-flag is off',
65
+ );
66
+ } else {
67
+ return id;
68
+ }
69
+ }
70
+
71
+ if (typeof id !== 'string') {
72
+ return id;
73
+ }
74
+
75
+ const localEnv = localEnvironmentCache.get(id);
76
+
77
+ if (localEnv) {
78
+ return localEnv;
79
+ }
80
+
81
+ const env = Object.freeze(getEnvironment(id));
82
+ localEnvironmentCache.set(id, env);
83
+ return env;
84
+ }
85
+
86
+ /**
87
+ * Writes all environments and their IDs to the cache
88
+ * @param {Cache} cache
89
+ * @returns {Promise<void>}
90
+ */
91
+ export async function writeEnvironmentsToCache(cache: Cache): Promise<void> {
92
+ const environments = getAllEnvironments();
93
+ const environmentIds = new Set<string>();
94
+
95
+ // Store each environment individually
96
+ for (const env of environments) {
97
+ environmentIds.add(env.id);
98
+ const envKey = `Environment/${ATLASPACK_VERSION}/${env.id}`;
99
+
100
+ await instrument(
101
+ `RequestTracker::writeToCache::cache.put(${envKey})`,
102
+ async () => {
103
+ await cache.set(envKey, env);
104
+ },
105
+ );
106
+ }
107
+
108
+ // Store the list of environment IDs
109
+ await instrument(
110
+ `RequestTracker::writeToCache::cache.put(${`EnvironmentManager/${ATLASPACK_VERSION}`})`,
111
+ async () => {
112
+ await cache.set(
113
+ `EnvironmentManager/${ATLASPACK_VERSION}`,
114
+ Array.from(environmentIds),
115
+ );
116
+ },
117
+ );
118
+ }
119
+
120
+ /**
121
+ * Loads all environments and their IDs from the cache
122
+ * @param {Cache} cache
123
+ * @returns {Promise<void>}
124
+ */
125
+ export async function loadEnvironmentsFromCache(cache: Cache): Promise<void> {
126
+ const cachedEnvIds = await cache.get(
127
+ `EnvironmentManager/${ATLASPACK_VERSION}`,
128
+ );
129
+
130
+ if (cachedEnvIds == null) {
131
+ return;
132
+ }
133
+
134
+ const environments = [];
135
+ for (const envId of cachedEnvIds) {
136
+ const envKey = `Environment/${ATLASPACK_VERSION}/${envId}`;
137
+ const cachedEnv = await cache.get(envKey);
138
+ if (cachedEnv != null) {
139
+ environments.push(cachedEnv);
140
+ }
141
+ }
142
+ if (environments.length > 0) {
143
+ setAllEnvironments(environments);
144
+ }
145
+ }
@@ -3,7 +3,6 @@
3
3
  import type {PackageName, ConfigResult} from '@atlaspack/types';
4
4
  import type {
5
5
  Config,
6
- Environment,
7
6
  InternalFileCreateInvalidation,
8
7
  InternalDevDepOptions,
9
8
  } from './types';
@@ -13,17 +12,19 @@ import {fromProjectPathRelative} from './projectPath';
13
12
  import {createEnvironment} from './Environment';
14
13
  import {hashString} from '@atlaspack/rust';
15
14
  import {identifierRegistry} from './IdentifierRegistry';
15
+ import type {EnvironmentRef} from './EnvironmentManager';
16
+ import {toEnvironmentId} from './EnvironmentManager';
16
17
 
17
18
  type ConfigOpts = {|
18
19
  plugin: PackageName,
19
20
  searchPath: ProjectPath,
20
21
  isSource?: boolean,
21
- env?: Environment,
22
+ env?: EnvironmentRef,
22
23
  result?: ConfigResult,
23
24
  invalidateOnFileChange?: Set<ProjectPath>,
24
25
  invalidateOnConfigKeyChange?: Array<{|
25
26
  filePath: ProjectPath,
26
- configKey: string,
27
+ configKey: string[],
27
28
  |}>,
28
29
  invalidateOnFileCreate?: Array<InternalFileCreateInvalidation>,
29
30
  invalidateOnEnvChange?: Set<string>,
@@ -52,13 +53,13 @@ export function createConfig({
52
53
  const configId = hashString(
53
54
  plugin +
54
55
  fromProjectPathRelative(searchPath) +
55
- environment.id +
56
+ toEnvironmentId(environment) +
56
57
  String(isSource),
57
58
  );
58
59
  identifierRegistry.addIdentifier('config_request', configId, {
59
60
  plugin,
60
61
  searchPath,
61
- environmentId: environment.id,
62
+ environmentId: toEnvironmentId(environment),
62
63
  isSource,
63
64
  });
64
65
  return {