@atlaspack/core 2.17.4 → 2.18.0

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 (54) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/lib/AssetGraph.js +17 -6
  3. package/lib/BundleGraph.js +6 -5
  4. package/lib/Dependency.js +6 -2
  5. package/lib/Environment.js +4 -3
  6. package/lib/EnvironmentManager.js +137 -0
  7. package/lib/InternalConfig.js +3 -2
  8. package/lib/PackagerRunner.js +10 -7
  9. package/lib/RequestTracker.js +20 -5
  10. package/lib/UncommittedAsset.js +3 -2
  11. package/lib/applyRuntimes.js +2 -1
  12. package/lib/assetUtils.js +2 -1
  13. package/lib/public/Asset.js +3 -2
  14. package/lib/public/Bundle.js +2 -1
  15. package/lib/public/Config.js +86 -19
  16. package/lib/public/Dependency.js +2 -1
  17. package/lib/public/MutableBundleGraph.js +2 -1
  18. package/lib/public/Target.js +2 -1
  19. package/lib/requests/AssetRequest.js +2 -1
  20. package/lib/requests/ConfigRequest.js +27 -4
  21. package/lib/requests/TargetRequest.js +18 -16
  22. package/lib/requests/WriteBundleRequest.js +5 -2
  23. package/lib/requests/WriteBundlesRequest.js +1 -0
  24. package/package.json +11 -11
  25. package/src/AssetGraph.js +12 -6
  26. package/src/BundleGraph.js +13 -8
  27. package/src/Dependency.js +13 -5
  28. package/src/Environment.js +8 -5
  29. package/src/EnvironmentManager.js +145 -0
  30. package/src/InternalConfig.js +6 -5
  31. package/src/PackagerRunner.js +12 -11
  32. package/src/RequestTracker.js +39 -13
  33. package/src/UncommittedAsset.js +7 -2
  34. package/src/applyRuntimes.js +6 -1
  35. package/src/assetUtils.js +4 -3
  36. package/src/atlaspack-v3/worker/compat/plugin-config.js +1 -1
  37. package/src/public/Asset.js +9 -2
  38. package/src/public/Bundle.js +2 -1
  39. package/src/public/Config.js +110 -29
  40. package/src/public/Dependency.js +2 -1
  41. package/src/public/MutableBundleGraph.js +2 -1
  42. package/src/public/Target.js +2 -1
  43. package/src/requests/AssetRequest.js +2 -1
  44. package/src/requests/ConfigRequest.js +33 -9
  45. package/src/requests/TargetRequest.js +19 -25
  46. package/src/requests/WriteBundleRequest.js +6 -7
  47. package/src/requests/WriteBundlesRequest.js +1 -0
  48. package/src/types.js +9 -7
  49. package/test/Environment.test.js +43 -34
  50. package/test/EnvironmentManager.test.js +192 -0
  51. package/test/PublicEnvironment.test.js +10 -7
  52. package/test/public/Config.test.js +108 -0
  53. package/test/requests/ConfigRequest.test.js +187 -3
  54. package/test/test-utils.js +3 -2
@@ -21,12 +21,89 @@ import {
21
21
  import Environment from './Environment';
22
22
  import {fromProjectPath, toProjectPath} from '../projectPath';
23
23
  import {getFeatureFlag} from '@atlaspack/feature-flags';
24
+ import {fromEnvironmentId} from '../EnvironmentManager';
24
25
 
25
26
  const internalConfigToConfig: DefaultWeakMap<
26
27
  AtlaspackOptions,
27
28
  WeakMap<Config, PublicConfig>,
28
29
  > = new DefaultWeakMap(() => new WeakMap());
29
30
 
31
+ /**
32
+ * Implements read tracking over an object.
33
+ *
34
+ * Calling this function with a non-trivial object like a class instance will fail to work.
35
+ *
36
+ * We track reads to fields that resolve to:
37
+ *
38
+ * - primitive values
39
+ * - arrays
40
+ *
41
+ * That is, reading a nested field `a.b.c` will make a single call to `onRead` with the path
42
+ * `['a', 'b', 'c']`.
43
+ *
44
+ * In case the value is null or an array, we will track the read as well.
45
+ *
46
+ * Iterating over `Object.keys(obj.field)` will register a read for the `['field']` path.
47
+ * Other reads work normally.
48
+ *
49
+ * @example
50
+ *
51
+ * const usedPaths = new Set();
52
+ * const onRead = (path) => {
53
+ * usedPaths.add(path);
54
+ * };
55
+ *
56
+ * const config = makeConfigProxy(onRead, {a: {b: {c: 'd'}}})
57
+ * console.log(config.a.b.c);
58
+ * console.log(Array.from(usedPaths));
59
+ * // We get a single read for the path
60
+ * // ['a', 'b', 'c']
61
+ *
62
+ */
63
+ export function makeConfigProxy<T>(
64
+ onRead: (path: string[]) => void,
65
+ config: T,
66
+ ): T {
67
+ const reportedPaths = new Set();
68
+ const reportPath = (path) => {
69
+ if (reportedPaths.has(path)) {
70
+ return;
71
+ }
72
+ reportedPaths.add(path);
73
+ onRead(path);
74
+ };
75
+
76
+ const makeProxy = (target, path) => {
77
+ return new Proxy(target, {
78
+ ownKeys(target) {
79
+ reportPath(path);
80
+
81
+ // $FlowFixMe
82
+ return Object.getOwnPropertyNames(target);
83
+ },
84
+ get(target, prop) {
85
+ // $FlowFixMe
86
+ const value = target[prop];
87
+
88
+ if (
89
+ typeof value === 'object' &&
90
+ value != null &&
91
+ !Array.isArray(value)
92
+ ) {
93
+ return makeProxy(value, [...path, prop]);
94
+ }
95
+
96
+ reportPath([...path, prop]);
97
+
98
+ return value;
99
+ },
100
+ });
101
+ };
102
+
103
+ // $FlowFixMe
104
+ return makeProxy(config, []);
105
+ }
106
+
30
107
  export default class PublicConfig implements IConfig {
31
108
  #config /*: Config */;
32
109
  #pkg /*: ?PackageJSON */;
@@ -46,7 +123,7 @@ export default class PublicConfig implements IConfig {
46
123
  }
47
124
 
48
125
  get env(): Environment {
49
- return new Environment(this.#config.env, this.#options);
126
+ return new Environment(fromEnvironmentId(this.#config.env), this.#options);
50
127
  }
51
128
 
52
129
  get searchPath(): FilePath {
@@ -76,7 +153,7 @@ export default class PublicConfig implements IConfig {
76
153
  );
77
154
  }
78
155
 
79
- invalidateOnConfigKeyChange(filePath: FilePath, configKey: string) {
156
+ invalidateOnConfigKeyChange(filePath: FilePath, configKey: string[]) {
80
157
  this.#config.invalidateOnConfigKeyChange.push({
81
158
  filePath: toProjectPath(this.#options.projectRoot, filePath),
82
159
  configKey,
@@ -144,9 +221,10 @@ export default class PublicConfig implements IConfig {
144
221
  |}
145
222
  | ?{|
146
223
  /**
147
- * If specified, only invalidate when this config key changes.
224
+ * If specified, this function will return a proxy object that will track reads to
225
+ * config fields and only register invalidations for when those keys change.
148
226
  */
149
- configKey?: string,
227
+ readTracking?: boolean,
150
228
  |},
151
229
  ): Promise<?ConfigResultWithFilePath<T>> {
152
230
  let packageKey = options?.packageKey;
@@ -157,7 +235,7 @@ export default class PublicConfig implements IConfig {
157
235
 
158
236
  if (pkg && pkg.contents[packageKey]) {
159
237
  // Invalidate only when the package key changes
160
- this.invalidateOnConfigKeyChange(pkg.filePath, packageKey);
238
+ this.invalidateOnConfigKeyChange(pkg.filePath, [packageKey]);
161
239
 
162
240
  return {
163
241
  contents: pkg.contents[packageKey],
@@ -166,27 +244,24 @@ export default class PublicConfig implements IConfig {
166
244
  }
167
245
  }
168
246
 
169
- if (getFeatureFlag('granularTsConfigInvalidation')) {
170
- const configKey = options?.configKey;
171
- if (configKey != null) {
172
- for (let fileName of fileNames) {
173
- let config = await this.getConfigFrom(searchPath, [fileName], {
174
- exclude: true,
247
+ const readTracking = options?.readTracking;
248
+ if (readTracking === true) {
249
+ for (let fileName of fileNames) {
250
+ const config = await this.getConfigFrom(searchPath, [fileName], {
251
+ exclude: true,
252
+ });
253
+
254
+ if (config != null) {
255
+ return Promise.resolve({
256
+ contents: makeConfigProxy((keyPath) => {
257
+ this.invalidateOnConfigKeyChange(config.filePath, keyPath);
258
+ }, config.contents),
259
+ filePath: config.filePath,
175
260
  });
176
-
177
- if (config && config.contents[configKey]) {
178
- // Invalidate only when the package key changes
179
- this.invalidateOnConfigKeyChange(config.filePath, configKey);
180
-
181
- return {
182
- contents: config.contents[configKey],
183
- filePath: config.filePath,
184
- };
185
- }
186
261
  }
187
-
188
- // fall through so that file above invalidations are registered
189
262
  }
263
+
264
+ // fall through so that file above invalidations are registered
190
265
  }
191
266
 
192
267
  if (fileNames.length === 0) {
@@ -268,11 +343,15 @@ export default class PublicConfig implements IConfig {
268
343
 
269
344
  getConfig<T>(
270
345
  filePaths: Array<FilePath>,
271
- options: ?{|
272
- packageKey?: string,
273
- parse?: boolean,
274
- exclude?: boolean,
275
- |},
346
+ options:
347
+ | ?{|
348
+ packageKey?: string,
349
+ parse?: boolean,
350
+ exclude?: boolean,
351
+ |}
352
+ | {|
353
+ readTracking?: boolean,
354
+ |},
276
355
  ): Promise<?ConfigResultWithFilePath<T>> {
277
356
  return this.getConfigFrom(this.searchPath, filePaths, options);
278
357
  }
@@ -282,7 +361,9 @@ export default class PublicConfig implements IConfig {
282
361
  return this.#pkg;
283
362
  }
284
363
 
285
- let pkgConfig = await this.getConfig<PackageJSON>(['package.json']);
364
+ let pkgConfig = await this.getConfig<PackageJSON>(['package.json'], {
365
+ readTracking: getFeatureFlag('granularTsConfigInvalidation'),
366
+ });
286
367
  if (!pkgConfig) {
287
368
  return null;
288
369
  }
@@ -27,6 +27,7 @@ import {
27
27
  } from '../types';
28
28
  import {fromProjectPath} from '../projectPath';
29
29
  import {fromInternalSourceLocation} from '../utils';
30
+ import {fromEnvironmentId} from '../EnvironmentManager';
30
31
 
31
32
  const SpecifierTypeNames = Object.keys(SpecifierTypeMap);
32
33
  const PriorityNames = Object.keys(Priority);
@@ -112,7 +113,7 @@ export default class Dependency implements IDependency {
112
113
  }
113
114
 
114
115
  get env(): IEnvironment {
115
- return new Environment(this.#dep.env, this.#options);
116
+ return new Environment(fromEnvironmentId(this.#dep.env), this.#options);
116
117
  }
117
118
 
118
119
  get packageConditions(): ?Array<string> {
@@ -32,6 +32,7 @@ import {BundleBehavior} from '../types';
32
32
  import BundleGroup, {bundleGroupToInternalBundleGroup} from './BundleGroup';
33
33
  import type {ProjectPath} from '../projectPath';
34
34
  import {identifierRegistry} from '../IdentifierRegistry';
35
+ import {toEnvironmentRef} from '../EnvironmentManager';
35
36
 
36
37
  function createBundleId(data: {|
37
38
  entryAssetId: string | null,
@@ -236,7 +237,7 @@ export default class MutableBundleGraph
236
237
  : bundleId.slice(-8),
237
238
  type: opts.entryAsset ? opts.entryAsset.type : opts.type,
238
239
  env: opts.env
239
- ? environmentToInternalEnvironment(opts.env)
240
+ ? toEnvironmentRef(environmentToInternalEnvironment(opts.env))
240
241
  : nullthrows(entryAsset).env,
241
242
  entryAssetIds: entryAsset ? [entryAsset.id] : [],
242
243
  mainEntryId: entryAsset?.id,
@@ -11,6 +11,7 @@ import nullthrows from 'nullthrows';
11
11
  import Environment from './Environment';
12
12
  import {fromProjectPath} from '../projectPath';
13
13
  import {fromInternalSourceLocation} from '../utils';
14
+ import {fromEnvironmentId} from '../EnvironmentManager';
14
15
 
15
16
  const inspect = Symbol.for('nodejs.util.inspect.custom');
16
17
 
@@ -46,7 +47,7 @@ export default class Target implements ITarget {
46
47
  }
47
48
 
48
49
  get env(): IEnvironment {
49
- return new Environment(this.#target.env, this.#options);
50
+ return new Environment(fromEnvironmentId(this.#target.env), this.#options);
50
51
  }
51
52
 
52
53
  get name(): string {
@@ -21,6 +21,7 @@ import {fromProjectPath, fromProjectPathRelative} from '../projectPath';
21
21
  import {report} from '../ReporterRunner';
22
22
  import {requestTypes} from '../RequestTracker';
23
23
  import type {DevDepRequestResult} from './DevDepRequest';
24
+ import {toEnvironmentId} from '../EnvironmentManager';
24
25
 
25
26
  type RunInput<TResult> = {|
26
27
  input: AssetRequestInput,
@@ -51,7 +52,7 @@ function getId(input: AssetRequestInput) {
51
52
  return hashString(
52
53
  type +
53
54
  fromProjectPathRelative(input.filePath) +
54
- input.env.id +
55
+ toEnvironmentId(input.env) +
55
56
  String(input.isSource) +
56
57
  String(input.sideEffects) +
57
58
  (input.code ?? '') +
@@ -63,7 +63,7 @@ export type ConfigRequest = {
63
63
  invalidateOnFileChange: Set<ProjectPath>,
64
64
  invalidateOnConfigKeyChange: Array<{|
65
65
  filePath: ProjectPath,
66
- configKey: string,
66
+ configKey: string[],
67
67
  |}>,
68
68
  invalidateOnFileCreate: Array<InternalFileCreateInvalidation>,
69
69
  invalidateOnEnvChange: Set<string>,
@@ -108,34 +108,58 @@ export async function loadPluginConfig<T: PluginWithLoadConfig>(
108
108
  }
109
109
  }
110
110
 
111
+ /**
112
+ * Return value at a given key path within an object.
113
+ *
114
+ * @example
115
+ * const obj = { a: { b: { c: 'd' } } };
116
+ * getValueAtPath(obj, ['a', 'b', 'c']); // 'd'
117
+ * getValueAtPath(obj, ['a', 'b', 'd']); // undefined
118
+ * getValueAtPath(obj, ['a', 'b']); // { c: 'd' }
119
+ * getValueAtPath(obj, ['a', 'b', 'c', 'd']); // undefined
120
+ */
121
+ export function getValueAtPath(obj: Object, key: string[]): any {
122
+ let current = obj;
123
+ for (let part of key) {
124
+ if (current == null) {
125
+ return undefined;
126
+ }
127
+ current = current[part];
128
+ }
129
+ return current;
130
+ }
131
+
111
132
  const configKeyCache = createBuildCache();
112
133
 
113
134
  export async function getConfigKeyContentHash(
114
135
  filePath: ProjectPath,
115
- configKey: string,
136
+ configKey: string[],
116
137
  options: AtlaspackOptions,
117
138
  ): Async<string> {
118
- let cacheKey = `${fromProjectPathRelative(filePath)}:${configKey}`;
139
+ let cacheKey = `${fromProjectPathRelative(filePath)}:${JSON.stringify(
140
+ configKey,
141
+ )}`;
119
142
  let cachedValue = configKeyCache.get(cacheKey);
120
143
 
121
144
  if (cachedValue) {
122
145
  return cachedValue;
123
146
  }
124
147
 
125
- let conf = await readConfig(
148
+ const conf = await readConfig(
126
149
  options.inputFS,
127
150
  fromProjectPath(options.projectRoot, filePath),
128
151
  );
129
152
 
130
- if (conf == null || conf.config[configKey] == null) {
153
+ const value = getValueAtPath(conf?.config, configKey);
154
+ if (conf == null || value == null) {
131
155
  // This can occur when a config key has been removed entirely during `respondToFSEvents`
132
156
  return '';
133
157
  }
134
158
 
135
- let contentHash =
136
- typeof conf.config[configKey] === 'object'
137
- ? hashObject(conf.config[configKey])
138
- : hashString(JSON.stringify(conf.config[configKey]));
159
+ const contentHash =
160
+ typeof value === 'object'
161
+ ? hashObject(value)
162
+ : hashString(JSON.stringify(value));
139
163
 
140
164
  configKeyCache.set(cacheKey, contentHash);
141
165
 
@@ -49,6 +49,7 @@ import {BROWSER_ENVS} from '../public/Environment';
49
49
  import {optionsProxy, toInternalSourceLocation} from '../utils';
50
50
  import {fromProjectPath, toProjectPath, joinProjectPath} from '../projectPath';
51
51
  import {requestTypes} from '../RequestTracker';
52
+ import {fromEnvironmentId} from '../EnvironmentManager';
52
53
 
53
54
  type RunOpts<TResult> = {|
54
55
  input: Entry,
@@ -345,7 +346,7 @@ export class TargetResolver {
345
346
  },
346
347
  });
347
348
  }
348
- if (!BROWSER_ENVS.has(targets[0].env.context)) {
349
+ if (!BROWSER_ENVS.has(fromEnvironmentId(targets[0].env).context)) {
349
350
  throw new ThrowableDiagnostic({
350
351
  diagnostic: {
351
352
  message: `Only browser targets are supported in serve mode`,
@@ -1491,21 +1492,22 @@ async function debugResolvedTargets(input, targets, targetInfo, options) {
1491
1492
 
1492
1493
  // Resolve relevant engines for context.
1493
1494
  let engines;
1494
- switch (target.env.context) {
1495
+ const env = fromEnvironmentId(target.env);
1496
+ switch (env.context) {
1495
1497
  case 'browser':
1496
1498
  case 'web-worker':
1497
1499
  case 'service-worker':
1498
1500
  case 'worklet': {
1499
- let browsers = target.env.engines.browsers;
1501
+ let browsers = env.engines.browsers;
1500
1502
  engines = Array.isArray(browsers) ? browsers.join(', ') : browsers;
1501
1503
  break;
1502
1504
  }
1503
1505
  case 'node':
1504
- engines = target.env.engines.node;
1506
+ engines = env.engines.node;
1505
1507
  break;
1506
1508
  case 'electron-main':
1507
1509
  case 'electron-renderer':
1508
- engines = target.env.engines.electron;
1510
+ engines = env.engines.electron;
1509
1511
  break;
1510
1512
  }
1511
1513
 
@@ -1547,9 +1549,7 @@ async function debugResolvedTargets(input, targets, targetInfo, options) {
1547
1549
  }
1548
1550
 
1549
1551
  if (keyInfo.inferred) {
1550
- highlight.inferred.push(
1551
- md`${key} to be ${JSON.stringify(target.env[key])}`,
1552
- );
1552
+ highlight.inferred.push(md`${key} to be ${JSON.stringify(env[key])}`);
1553
1553
  }
1554
1554
  }
1555
1555
 
@@ -1578,22 +1578,20 @@ async function debugResolvedTargets(input, targets, targetInfo, options) {
1578
1578
 
1579
1579
  // Format includeNodeModules to be human readable.
1580
1580
  let includeNodeModules;
1581
- if (typeof target.env.includeNodeModules === 'boolean') {
1582
- includeNodeModules = String(target.env.includeNodeModules);
1583
- } else if (Array.isArray(target.env.includeNodeModules)) {
1581
+ if (typeof env.includeNodeModules === 'boolean') {
1582
+ includeNodeModules = String(env.includeNodeModules);
1583
+ } else if (Array.isArray(env.includeNodeModules)) {
1584
1584
  includeNodeModules =
1585
1585
  'only ' +
1586
- listFormat.format(
1587
- target.env.includeNodeModules.map((m) => JSON.stringify(m)),
1588
- );
1586
+ listFormat.format(env.includeNodeModules.map((m) => JSON.stringify(m)));
1589
1587
  } else if (
1590
- target.env.includeNodeModules &&
1591
- typeof target.env.includeNodeModules === 'object'
1588
+ env.includeNodeModules &&
1589
+ typeof env.includeNodeModules === 'object'
1592
1590
  ) {
1593
1591
  includeNodeModules =
1594
1592
  'all except ' +
1595
1593
  listFormat.format(
1596
- Object.entries(target.env.includeNodeModules)
1594
+ Object.entries(env.includeNodeModules)
1597
1595
  .filter(([, v]) => v === false)
1598
1596
  .map(([k]) => JSON.stringify(k)),
1599
1597
  );
@@ -1609,18 +1607,14 @@ async function debugResolvedTargets(input, targets, targetInfo, options) {
1609
1607
  fromProjectPath(options.projectRoot, input.filePath),
1610
1608
  )}
1611
1609
  **Output**: ${path.relative(process.cwd(), output)}
1612
- **Format**: ${target.env.outputFormat} ${format(
1613
- info.outputFormat,
1614
- )}
1615
- **Context**: ${target.env.context} ${format(info.context)}
1610
+ **Format**: ${env.outputFormat} ${format(info.outputFormat)}
1611
+ **Context**: ${env.context} ${format(info.context)}
1616
1612
  **Engines**: ${engines || ''} ${format(info.engines)}
1617
- **Library Mode**: ${String(target.env.isLibrary)} ${format(
1618
- info.isLibrary,
1619
- )}
1613
+ **Library Mode**: ${String(env.isLibrary)} ${format(info.isLibrary)}
1620
1614
  **Include Node Modules**: ${includeNodeModules} ${format(
1621
1615
  info.includeNodeModules,
1622
1616
  )}
1623
- **Optimize**: ${String(target.env.shouldOptimize)} ${format(
1617
+ **Optimize**: ${String(env.shouldOptimize)} ${format(
1624
1618
  info.shouldOptimize,
1625
1619
  )}`,
1626
1620
  codeFrames: target.loc
@@ -41,6 +41,7 @@ import ThrowableDiagnostic, {errorToDiagnostic} from '@atlaspack/diagnostic';
41
41
  import {PluginTracer, tracer} from '@atlaspack/profiler';
42
42
  import {requestTypes} from '../RequestTracker';
43
43
  import {getFeatureFlag} from '@atlaspack/feature-flags';
44
+ import {fromEnvironmentId} from '../EnvironmentManager';
44
45
 
45
46
  const HASH_REF_PREFIX_LEN = HASH_REF_PREFIX.length;
46
47
  const BOUNDARY_LENGTH = HASH_REF_PREFIX.length + 32 - 1;
@@ -111,7 +112,9 @@ async function run({input, options, api}) {
111
112
  let cacheKeys = info.cacheKeys;
112
113
  let mapKey = cacheKeys.map;
113
114
  let fullPath = fromProjectPath(options.projectRoot, filePath);
114
- if (mapKey && bundle.env.sourceMap && !bundle.env.sourceMap.inline) {
115
+ const env = fromEnvironmentId(bundle.env);
116
+
117
+ if (mapKey && env.sourceMap && !env.sourceMap.inline) {
115
118
  api.invalidateOnFileDelete(
116
119
  toProjectPath(options.projectRoot, fullPath + '.map'),
117
120
  );
@@ -171,12 +174,7 @@ async function run({input, options, api}) {
171
174
  const hasSourceMap = getFeatureFlag('cachePerformanceImprovements')
172
175
  ? await options.cache.hasLargeBlob(mapKey)
173
176
  : await options.cache.has(mapKey);
174
- if (
175
- mapKey &&
176
- bundle.env.sourceMap &&
177
- !bundle.env.sourceMap.inline &&
178
- hasSourceMap
179
- ) {
177
+ if (mapKey && env.sourceMap && !env.sourceMap.inline && hasSourceMap) {
180
178
  const mapEntry = getFeatureFlag('cachePerformanceImprovements')
181
179
  ? await options.cache.getLargeBlob(mapKey)
182
180
  : await options.cache.getBlob(mapKey);
@@ -196,6 +194,7 @@ async function run({input, options, api}) {
196
194
 
197
195
  let res = {
198
196
  filePath,
197
+ bundleId: bundle.id,
199
198
  type: info.type,
200
199
  stats: {
201
200
  size,
@@ -84,6 +84,7 @@ async function run({input, api, farm, options}) {
84
84
  ).replace(bundle.hashReference, hash);
85
85
  res.set(bundle.id, {
86
86
  filePath: joinProjectPath(bundle.target.distDir, name),
87
+ bundleId: bundle.id,
87
88
  type: bundle.type, // FIXME: this is wrong if the packager changes the type...
88
89
  stats: {
89
90
  time: 0,
package/src/types.js CHANGED
@@ -34,6 +34,7 @@ import type {ProjectPath} from './projectPath';
34
34
  import type {Event} from '@parcel/watcher';
35
35
  import type {FeatureFlags} from '@atlaspack/feature-flags';
36
36
  import type {BackendType} from '@parcel/watcher';
37
+ import type {EnvironmentRef} from './EnvironmentManager';
37
38
 
38
39
  export type AtlaspackPluginNode = {|
39
40
  packageName: PackageName,
@@ -97,7 +98,7 @@ export type InternalSourceLocation = {|
97
98
  export type Target = {|
98
99
  distEntry?: ?FilePath,
99
100
  distDir: ProjectPath,
100
- env: Environment,
101
+ env: EnvironmentRef,
101
102
  name: string,
102
103
  publicUrl: string,
103
104
  loc?: ?InternalSourceLocation,
@@ -139,7 +140,7 @@ export type Dependency = {|
139
140
  isEntry: boolean,
140
141
  isOptional: boolean,
141
142
  loc: ?InternalSourceLocation,
142
- env: Environment,
143
+ env: EnvironmentRef,
143
144
  packageConditions?: number,
144
145
  customPackageConditions?: Array<string>,
145
146
  meta: Meta,
@@ -180,7 +181,7 @@ export type Asset = {|
180
181
  bundleBehavior: ?$Values<typeof BundleBehavior>,
181
182
  isBundleSplittable: boolean,
182
183
  isSource: boolean,
183
- env: Environment,
184
+ env: EnvironmentRef,
184
185
  meta: Meta,
185
186
  stats: Stats,
186
187
  contentKey: ?string,
@@ -388,7 +389,7 @@ export type RootNode = {|id: ContentKey, +type: 'root', value: string | null|};
388
389
  export type AssetRequestInput = {|
389
390
  name?: string, // AssetGraph name, needed so that different graphs can isolated requests since the results are not stored
390
391
  filePath: ProjectPath,
391
- env: Environment,
392
+ env: EnvironmentRef,
392
393
  isSource?: boolean,
393
394
  canDefer?: boolean,
394
395
  sideEffects?: boolean,
@@ -492,13 +493,13 @@ export type Config = {|
492
493
  id: string,
493
494
  isSource: boolean,
494
495
  searchPath: ProjectPath,
495
- env: Environment,
496
+ env: EnvironmentRef,
496
497
  cacheKey: ?string,
497
498
  result: ConfigResult,
498
499
  invalidateOnFileChange: Set<ProjectPath>,
499
500
  invalidateOnConfigKeyChange: Array<{|
500
501
  filePath: ProjectPath,
501
- configKey: string,
502
+ configKey: string[],
502
503
  |}>,
503
504
  invalidateOnFileCreate: Array<InternalFileCreateInvalidation>,
504
505
  invalidateOnEnvChange: Set<string>,
@@ -539,7 +540,7 @@ export type Bundle = {|
539
540
  publicId: ?string,
540
541
  hashReference: string,
541
542
  type: string,
542
- env: Environment,
543
+ env: EnvironmentRef,
543
544
  entryAssetIds: Array<ContentKey>,
544
545
  mainEntryId: ?ContentKey,
545
546
  needsStableName: ?boolean,
@@ -573,6 +574,7 @@ export type BundleGroupNode = {|
573
574
 
574
575
  export type PackagedBundleInfo = {|
575
576
  filePath: ProjectPath,
577
+ bundleId: ContentKey,
576
578
  type: string,
577
579
  stats: Stats,
578
580
  |};