@atlaspack/core 2.30.2 → 2.31.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 (41) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/Atlaspack.js +2 -0
  3. package/dist/Transformation.js +24 -1
  4. package/dist/atlaspack-v3/AtlaspackV3.js +3 -0
  5. package/dist/atlaspack-v3/NapiWorkerPool.js +10 -0
  6. package/dist/atlaspack-v3/worker/compat/plugin-config.js +10 -22
  7. package/dist/atlaspack-v3/worker/compat/plugin-options.js +15 -0
  8. package/dist/atlaspack-v3/worker/side-effect-detector.js +243 -0
  9. package/dist/atlaspack-v3/worker/worker.js +140 -66
  10. package/dist/requests/ConfigRequest.js +24 -0
  11. package/lib/Atlaspack.js +5 -1
  12. package/lib/Transformation.js +31 -1
  13. package/lib/atlaspack-v3/AtlaspackV3.js +3 -0
  14. package/lib/atlaspack-v3/NapiWorkerPool.js +10 -0
  15. package/lib/atlaspack-v3/worker/compat/plugin-config.js +8 -27
  16. package/lib/atlaspack-v3/worker/compat/plugin-options.js +15 -0
  17. package/lib/atlaspack-v3/worker/side-effect-detector.js +215 -0
  18. package/lib/atlaspack-v3/worker/worker.js +152 -72
  19. package/lib/requests/ConfigRequest.js +25 -0
  20. package/lib/types/InternalConfig.d.ts +1 -2
  21. package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +2 -1
  22. package/lib/types/atlaspack-v3/NapiWorkerPool.d.ts +1 -0
  23. package/lib/types/atlaspack-v3/index.d.ts +1 -0
  24. package/lib/types/atlaspack-v3/worker/compat/plugin-config.d.ts +3 -11
  25. package/lib/types/atlaspack-v3/worker/compat/plugin-options.d.ts +1 -0
  26. package/lib/types/atlaspack-v3/worker/side-effect-detector.d.ts +76 -0
  27. package/lib/types/atlaspack-v3/worker/worker.d.ts +26 -6
  28. package/lib/types/requests/ConfigRequest.d.ts +9 -1
  29. package/package.json +14 -14
  30. package/src/Atlaspack.ts +2 -0
  31. package/src/InternalConfig.ts +1 -1
  32. package/src/Transformation.ts +37 -2
  33. package/src/atlaspack-v3/AtlaspackV3.ts +8 -0
  34. package/src/atlaspack-v3/NapiWorkerPool.ts +17 -0
  35. package/src/atlaspack-v3/index.ts +1 -0
  36. package/src/atlaspack-v3/worker/compat/plugin-config.ts +8 -40
  37. package/src/atlaspack-v3/worker/compat/plugin-options.ts +15 -0
  38. package/src/atlaspack-v3/worker/side-effect-detector.ts +298 -0
  39. package/src/atlaspack-v3/worker/worker.ts +288 -172
  40. package/src/requests/ConfigRequest.ts +39 -0
  41. package/tsconfig.tsbuildinfo +1 -1
@@ -46,9 +46,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
46
46
  var __importDefault = (this && this.__importDefault) || function (mod) {
47
47
  return (mod && mod.__esModule) ? mod : { "default": mod };
48
48
  };
49
- var _AtlaspackWorker_resolvers, _AtlaspackWorker_transformers, _AtlaspackWorker_fs, _AtlaspackWorker_packageManager;
49
+ var _AtlaspackWorker_resolvers, _AtlaspackWorker_transformers, _AtlaspackWorker_fs, _AtlaspackWorker_packageManager, _AtlaspackWorker_options, _AtlaspackWorker_sideEffectDetector;
50
50
  Object.defineProperty(exports, "__esModule", { value: true });
51
51
  exports.AtlaspackWorker = void 0;
52
+ /* eslint-disable import/first */
53
+ const side_effect_detector_1 = require("./side-effect-detector");
54
+ // Install side effect detection patches BEFORE importing any modules that use fs
55
+ const sideEffectDetector = new side_effect_detector_1.SideEffectDetector();
56
+ sideEffectDetector.install();
52
57
  const assert_1 = __importDefault(require("assert"));
53
58
  const napi = __importStar(require("@atlaspack/rust"));
54
59
  const fs_1 = require("@atlaspack/fs");
@@ -64,7 +69,9 @@ class AtlaspackWorker {
64
69
  _AtlaspackWorker_transformers.set(this, void 0);
65
70
  _AtlaspackWorker_fs.set(this, void 0);
66
71
  _AtlaspackWorker_packageManager.set(this, void 0);
67
- this.loadPlugin = (0, jsCallable_1.jsCallable)(async ({ kind, specifier, resolveFrom, featureFlags }) => {
72
+ _AtlaspackWorker_options.set(this, void 0);
73
+ _AtlaspackWorker_sideEffectDetector.set(this, void 0);
74
+ this.loadPlugin = (0, jsCallable_1.jsCallable)(async ({ kind, specifier, resolveFrom, options }) => {
68
75
  // Use packageManager.require() instead of dynamic import() to support TypeScript plugins
69
76
  let resolvedModule = await __classPrivateFieldGet(this, _AtlaspackWorker_packageManager, "f").require(specifier, resolveFrom, { shouldAutoInstall: false });
70
77
  let instance = undefined;
@@ -85,57 +92,48 @@ class AtlaspackWorker {
85
92
  else {
86
93
  throw new Error(`Plugin could not be resolved\n\t${kind}\n\t${resolveFrom}\n\t${specifier}`);
87
94
  }
88
- // Set feature flags in the worker process
89
- // if (featureFlags) {
95
+ if (__classPrivateFieldGet(this, _AtlaspackWorker_options, "f") == null) {
96
+ __classPrivateFieldSet(this, _AtlaspackWorker_options, {
97
+ ...options,
98
+ inputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
99
+ outputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
100
+ packageManager: __classPrivateFieldGet(this, _AtlaspackWorker_packageManager, "f"),
101
+ shouldAutoInstall: false,
102
+ }, "f");
103
+ }
90
104
  // Set feature flags in the worker process
91
105
  let featureFlagsModule = await __classPrivateFieldGet(this, _AtlaspackWorker_packageManager, "f").require('@atlaspack/feature-flags', __filename, { shouldAutoInstall: false });
92
- featureFlagsModule.setFeatureFlags(featureFlags);
93
- // const {setFeatureFlags} = await import('@atlaspack/feature-flags');
94
- // setFeatureFlags(featureFlags);
95
- // }
106
+ featureFlagsModule.setFeatureFlags(options.featureFlags);
96
107
  switch (kind) {
97
108
  case 'resolver':
98
109
  __classPrivateFieldGet(this, _AtlaspackWorker_resolvers, "f").set(specifier, { resolver: instance });
99
110
  break;
100
- case 'transformer':
101
- __classPrivateFieldGet(this, _AtlaspackWorker_transformers, "f").set(specifier, { transformer: instance });
102
- break;
111
+ case 'transformer': {
112
+ return this.initializeTransformer(instance, specifier);
113
+ }
103
114
  }
104
115
  });
105
- this.runResolverResolve = (0, jsCallable_1.jsCallable)(async ({ key, dependency: napiDependency, specifier, pipeline, pluginOptions, }) => {
116
+ this.runResolverResolve = (0, jsCallable_1.jsCallable)(async ({ key, dependency: napiDependency, specifier, pipeline }) => {
106
117
  const state = __classPrivateFieldGet(this, _AtlaspackWorker_resolvers, "f").get(key);
107
118
  if (!state) {
108
119
  throw new Error(`Resolver not found: ${key}`);
109
120
  }
110
- let packageManager = state.packageManager;
111
- if (!packageManager) {
112
- packageManager = new package_manager_1.NodePackageManager(__classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"), pluginOptions.projectRoot);
113
- state.packageManager = packageManager;
114
- }
115
121
  const env = new compat_1.Environment(napiDependency.env);
116
122
  const dependency = new compat_1.Dependency(napiDependency, env);
117
123
  const defaultOptions = {
118
124
  logger: new compat_1.PluginLogger(),
119
125
  tracer: new compat_1.PluginTracer(),
120
- options: new compat_1.PluginOptions({
121
- ...pluginOptions,
122
- packageManager,
123
- shouldAutoInstall: false,
124
- inputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
125
- outputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
126
- }),
126
+ options: new compat_1.PluginOptions(this.options),
127
127
  };
128
128
  if (!('config' in state)) {
129
129
  // @ts-expect-error TS2345
130
130
  state.config = await state.resolver.loadConfig?.({
131
131
  config: new compat_1.PluginConfig({
132
- env,
132
+ env: napiDependency.env,
133
+ plugin: key,
133
134
  isSource: true,
134
- searchPath: specifier,
135
- projectRoot: pluginOptions.projectRoot,
136
- fs: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
137
- packageManager,
138
- }),
135
+ searchPath: 'index',
136
+ }, this.options),
139
137
  ...defaultOptions,
140
138
  });
141
139
  }
@@ -174,49 +172,48 @@ class AtlaspackWorker {
174
172
  },
175
173
  };
176
174
  });
177
- this.runTransformerTransform = (0, jsCallable_1.jsCallable)(async ({ key, env: napiEnv, options, asset: innerAsset }, contents, map) => {
178
- const state = __classPrivateFieldGet(this, _AtlaspackWorker_transformers, "f").get(key);
179
- if (!state) {
175
+ this.runTransformerTransform = (0, jsCallable_1.jsCallable)(async ({ key, asset: innerAsset }, contents, map) => {
176
+ const instance = __classPrivateFieldGet(this, _AtlaspackWorker_transformers, "f").get(key);
177
+ if (!instance) {
180
178
  throw new Error(`Transformer not found: ${key}`);
181
179
  }
182
- let packageManager = state.packageManager;
183
- if (!packageManager) {
184
- packageManager = new package_manager_1.NodePackageManager(__classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"), options.projectRoot);
185
- state.packageManager = packageManager;
186
- }
187
- const transformer = state.transformer;
180
+ let { transformer, config, allowedEnv = new Set() } = instance;
181
+ let cacheBailouts = [];
188
182
  const resolveFunc = (from, to) => {
189
183
  let customRequire = module.createRequire(from);
190
184
  let resolvedPath = customRequire.resolve(to);
185
+ // Tranformer not cacheable due to use of the resolve function
186
+ cacheBailouts.push(`resolve(${from}, ${to})`);
191
187
  return Promise.resolve(resolvedPath);
192
188
  };
193
- const env = new compat_1.Environment(napiEnv);
194
- const mutableAsset = new compat_1.MutableAsset(innerAsset,
189
+ const env = new compat_1.Environment(innerAsset.env);
190
+ let mutableAsset = new compat_1.MutableAsset(innerAsset,
195
191
  // @ts-expect-error TS2345
196
- contents, env, __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"), map, options.projectRoot);
192
+ contents, env, __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"), map, this.options.projectRoot);
193
+ const pluginOptions = new compat_1.PluginOptions(this.options);
197
194
  const defaultOptions = {
198
195
  logger: new compat_1.PluginLogger(),
199
196
  tracer: new compat_1.PluginTracer(),
200
- options: new compat_1.PluginOptions({
201
- ...options,
202
- packageManager,
203
- shouldAutoInstall: false,
204
- inputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
205
- outputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
206
- }),
197
+ options: pluginOptions,
207
198
  };
208
- // @ts-expect-error TS2345
209
- const config = await transformer.loadConfig?.({
210
- config: new compat_1.PluginConfig({
211
- env,
212
- isSource: true,
213
- searchPath: innerAsset.filePath,
214
- projectRoot: options.projectRoot,
215
- fs: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
216
- packageManager,
217
- }),
218
- ...defaultOptions,
219
- });
199
+ if (transformer.loadConfig) {
200
+ if (config != null) {
201
+ throw new Error(`Transformer (${key}) should not implement 'setup' and 'loadConfig'`);
202
+ }
203
+ // @ts-expect-error TS2345
204
+ config = await transformer.loadConfig({
205
+ config: new compat_1.PluginConfig({
206
+ plugin: key,
207
+ isSource: innerAsset.isSource,
208
+ searchPath: innerAsset.filePath,
209
+ env,
210
+ }, this.options),
211
+ ...defaultOptions,
212
+ });
213
+ // Transformer uses the deprecated loadConfig API, so mark as not
214
+ // cachable
215
+ cacheBailouts.push(`Transformer.loadConfig`);
216
+ }
220
217
  if (transformer.parse) {
221
218
  const ast = await transformer.parse({
222
219
  // @ts-expect-error TS2322
@@ -228,14 +225,29 @@ class AtlaspackWorker {
228
225
  if (ast) {
229
226
  mutableAsset.setAST(ast);
230
227
  }
228
+ cacheBailouts.push(`Transformer.parse`);
231
229
  }
232
- const result = await state.transformer.transform({
230
+ const [result, sideEffects] = await __classPrivateFieldGet(this, _AtlaspackWorker_sideEffectDetector, "f").monitorSideEffects(key, () => transformer.transform({
233
231
  // @ts-expect-error TS2322
234
232
  asset: mutableAsset,
235
233
  config,
236
234
  resolve: resolveFunc,
237
235
  ...defaultOptions,
238
- });
236
+ }));
237
+ if (sideEffects.envUsage.didEnumerate) {
238
+ cacheBailouts.push(`Env access: enumeration of process.env`);
239
+ }
240
+ for (let variable of sideEffects.envUsage.vars) {
241
+ if (variable in allowedEnv) {
242
+ continue;
243
+ }
244
+ cacheBailouts.push(`Env access: ${variable}`);
245
+ }
246
+ for (let { method, path } of sideEffects.fsUsage) {
247
+ cacheBailouts.push(`FS usage: ${method}(${path})`);
248
+ }
249
+ (0, assert_1.default)(result.length === 1, '[V3] Unimplemented: Multiple asset return from Node transformer');
250
+ (0, assert_1.default)(result[0] === mutableAsset, '[V3] Unimplemented: New asset returned from Node transformer');
239
251
  if (transformer.generate) {
240
252
  const ast = await mutableAsset.getAST();
241
253
  if (ast) {
@@ -260,14 +272,16 @@ class AtlaspackWorker {
260
272
  }
261
273
  }
262
274
  }
263
- (0, assert_1.default)(result.length === 1, '[V3] Unimplemented: Multiple asset return from Node transformer');
264
- (0, assert_1.default)(result[0] === mutableAsset, '[V3] Unimplemented: New asset returned from Node transformer');
265
275
  let assetBuffer = await mutableAsset.getBuffer();
266
276
  // If the asset has no code, we set the buffer to null, which we can
267
277
  // detect in Rust, to avoid passing back an empty buffer, which we can't.
268
278
  if (assetBuffer.length === 0) {
269
279
  assetBuffer = null;
270
280
  }
281
+ if (pluginOptions.used) {
282
+ // Plugin options accessed, so not cachable
283
+ cacheBailouts.push(`Plugin options accessed`);
284
+ }
271
285
  return [
272
286
  {
273
287
  id: mutableAsset.id,
@@ -291,17 +305,77 @@ class AtlaspackWorker {
291
305
  ? // @ts-expect-error TS2533
292
306
  JSON.stringify((await mutableAsset.getMap()).toVLQ())
293
307
  : '',
308
+ // Limit to first 10 bailouts
309
+ cacheBailouts.slice(0, 10),
294
310
  ];
295
311
  });
296
312
  __classPrivateFieldSet(this, _AtlaspackWorker_resolvers, new Map(), "f");
297
313
  __classPrivateFieldSet(this, _AtlaspackWorker_transformers, new Map(), "f");
298
314
  __classPrivateFieldSet(this, _AtlaspackWorker_fs, new fs_1.NodeFS(), "f");
299
315
  __classPrivateFieldSet(this, _AtlaspackWorker_packageManager, new package_manager_1.NodePackageManager(__classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"), '/'), "f");
316
+ __classPrivateFieldSet(this, _AtlaspackWorker_sideEffectDetector, sideEffectDetector, "f"); // Use the global detector that was installed before imports
317
+ }
318
+ clearState() {
319
+ __classPrivateFieldGet(this, _AtlaspackWorker_resolvers, "f").clear();
320
+ __classPrivateFieldGet(this, _AtlaspackWorker_transformers, "f").clear();
321
+ __classPrivateFieldSet(this, _AtlaspackWorker_options, undefined, "f");
322
+ }
323
+ get options() {
324
+ if (__classPrivateFieldGet(this, _AtlaspackWorker_options, "f") == null) {
325
+ throw new Error('Plugin options have not been initialized');
326
+ }
327
+ return __classPrivateFieldGet(this, _AtlaspackWorker_options, "f");
328
+ }
329
+ async initializeTransformer(instance, specifier) {
330
+ let transformer = instance;
331
+ let setup, config, allowedEnv;
332
+ let packageManager = new package_manager_1.NodePackageManager(__classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"), this.options.projectRoot);
333
+ if (transformer.setup) {
334
+ let setupResult = await transformer.setup({
335
+ logger: new compat_1.PluginLogger(),
336
+ options: new compat_1.PluginOptions({
337
+ ...this.options,
338
+ shouldAutoInstall: false,
339
+ inputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
340
+ outputFS: __classPrivateFieldGet(this, _AtlaspackWorker_fs, "f"),
341
+ packageManager,
342
+ }),
343
+ config: new compat_1.PluginConfig({
344
+ plugin: specifier,
345
+ searchPath: 'index',
346
+ // Consider project setup config as source
347
+ isSource: true,
348
+ }, this.options),
349
+ });
350
+ config = setupResult?.config;
351
+ allowedEnv = Object.fromEntries(setupResult?.env?.map((env) => [env, process.env[env]]) || []);
352
+ // Always add the following env vars to the cache key
353
+ allowedEnv['NODE_ENV'] = process.env['NODE_ENV'];
354
+ setup = {
355
+ conditions: setupResult?.conditions,
356
+ config,
357
+ env: allowedEnv,
358
+ };
359
+ }
360
+ __classPrivateFieldGet(this, _AtlaspackWorker_transformers, "f").set(specifier, {
361
+ transformer,
362
+ config,
363
+ packageManager,
364
+ allowedEnv,
365
+ });
366
+ return setup;
300
367
  }
301
368
  }
302
369
  exports.AtlaspackWorker = AtlaspackWorker;
303
- _AtlaspackWorker_resolvers = new WeakMap(), _AtlaspackWorker_transformers = new WeakMap(), _AtlaspackWorker_fs = new WeakMap(), _AtlaspackWorker_packageManager = new WeakMap();
370
+ _AtlaspackWorker_resolvers = new WeakMap(), _AtlaspackWorker_transformers = new WeakMap(), _AtlaspackWorker_fs = new WeakMap(), _AtlaspackWorker_packageManager = new WeakMap(), _AtlaspackWorker_options = new WeakMap(), _AtlaspackWorker_sideEffectDetector = new WeakMap();
304
371
  // Create napi worker and send it back to main thread
305
372
  const worker = new AtlaspackWorker();
306
373
  const napiWorker = napi.newNodejsWorker(worker);
307
374
  worker_threads_1.parentPort?.postMessage(napiWorker);
375
+ worker_threads_1.parentPort?.setMaxListeners(worker_threads_1.parentPort.getMaxListeners() + 1);
376
+ worker_threads_1.parentPort?.addListener('message', (message) => {
377
+ if (message === 'clearState') {
378
+ worker.clearState();
379
+ worker_threads_1.parentPort?.postMessage('stateCleared');
380
+ }
381
+ });
@@ -37,6 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.loadPluginConfig = loadPluginConfig;
40
+ exports.loadPluginSetup = loadPluginSetup;
40
41
  exports.getValueAtPath = getValueAtPath;
41
42
  exports.getConfigKeyContentHash = getConfigKeyContentHash;
42
43
  exports.runConfigRequest = runConfigRequest;
@@ -80,6 +81,29 @@ async function loadPluginConfig(loadedPlugin, config, options) {
80
81
  });
81
82
  }
82
83
  }
84
+ async function loadPluginSetup(pluginName, setup, config, options) {
85
+ try {
86
+ let result = await setup({
87
+ config: new Config_1.default(config, options),
88
+ options: new PluginOptions_1.default((0, utils_2.optionsProxy)(options, (option) => {
89
+ config.invalidateOnOptionChange.add(option);
90
+ })),
91
+ logger: new logger_1.PluginLogger({ origin: pluginName }),
92
+ tracer: new profiler_1.PluginTracer({
93
+ origin: pluginName,
94
+ category: 'setup',
95
+ }),
96
+ });
97
+ config.result = result.config;
98
+ }
99
+ catch (e) {
100
+ throw new diagnostic_1.default({
101
+ diagnostic: (0, diagnostic_1.errorToDiagnostic)(e, {
102
+ origin: pluginName,
103
+ }),
104
+ });
105
+ }
106
+ }
83
107
  /**
84
108
  * Return value at a given key path within an object.
85
109
  *
package/lib/Atlaspack.js CHANGED
@@ -408,6 +408,7 @@ class Atlaspack {
408
408
  }) {
409
409
  let options = (0, _nullthrows().default)(this.#resolvedOptions);
410
410
  try {
411
+ var _this$rustAtlaspack;
411
412
  if (options.shouldProfile) {
412
413
  await this.startProfiling();
413
414
  }
@@ -485,6 +486,7 @@ class Atlaspack {
485
486
  return result;
486
487
  },
487
488
  unstable_requestStats: this.#requestTracker.flushStats(),
489
+ nativeCacheStats: await ((_this$rustAtlaspack = this.rustAtlaspack) === null || _this$rustAtlaspack === void 0 ? void 0 : _this$rustAtlaspack.completeCacheSession()),
488
490
  scopeHoistingStats
489
491
  };
490
492
 
@@ -505,6 +507,7 @@ class Atlaspack {
505
507
  // @ts-expect-error TS2322
506
508
  return event;
507
509
  } catch (e) {
510
+ var _this$rustAtlaspack2;
508
511
  if (e instanceof _utils.BuildAbortError) {
509
512
  throw e;
510
513
  }
@@ -512,7 +515,8 @@ class Atlaspack {
512
515
  let event = {
513
516
  type: 'buildFailure',
514
517
  diagnostics: Array.isArray(diagnostic) ? diagnostic : [diagnostic],
515
- unstable_requestStats: this.#requestTracker.flushStats()
518
+ unstable_requestStats: this.#requestTracker.flushStats(),
519
+ nativeCacheStats: await ((_this$rustAtlaspack2 = this.rustAtlaspack) === null || _this$rustAtlaspack2 === void 0 ? void 0 : _this$rustAtlaspack2.completeCacheSession())
516
520
  };
517
521
 
518
522
  // @ts-expect-error TS2345
@@ -86,11 +86,21 @@ function _featureFlags() {
86
86
  };
87
87
  return data;
88
88
  }
89
+ function _buildCache() {
90
+ const data = require("@atlaspack/build-cache");
91
+ _buildCache = function () {
92
+ return data;
93
+ };
94
+ return data;
95
+ }
89
96
  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); }
90
97
  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; }
91
98
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
92
99
  // TODO: eventually call path request as sub requests
93
100
 
101
+ // Global setup config are not file-specific, so we only need to
102
+ // load them once per build.
103
+ const setupConfig = (0, _buildCache().createBuildCache)();
94
104
  class Transformation {
95
105
  constructor({
96
106
  request,
@@ -399,11 +409,31 @@ class Transformation {
399
409
  return nextPipeline;
400
410
  }
401
411
  async loadTransformerConfig(transformer, isSource) {
412
+ // Only load setup config for a transformer once per build.
413
+ let config = setupConfig.get(transformer.name);
414
+ if (config == null && transformer.plugin.setup != null) {
415
+ config = (0, _InternalConfig.createConfig)({
416
+ plugin: transformer.name,
417
+ searchPath: (0, _projectPath.toProjectPathUnsafe)('index'),
418
+ // Consider project setup config as source
419
+ isSource: true
420
+ });
421
+ await (0, _ConfigRequest.loadPluginSetup)(transformer.name, transformer.plugin.setup, config, this.options);
422
+ setupConfig.set(transformer.name, config);
423
+ }
424
+ if (config != null) {
425
+ for (let devDep of config.devDeps) {
426
+ await this.addDevDependency(devDep);
427
+ }
428
+
429
+ // `loadConfig` is not called for setup configs
430
+ return config;
431
+ }
402
432
  let loadConfig = transformer.plugin.loadConfig;
403
433
  if (!loadConfig) {
404
434
  return;
405
435
  }
406
- let config = (0, _InternalConfig.createConfig)({
436
+ config = (0, _InternalConfig.createConfig)({
407
437
  plugin: transformer.name,
408
438
  isSource,
409
439
  // @ts-expect-error TS2322
@@ -80,5 +80,8 @@ class AtlaspackV3 {
80
80
  }
81
81
  return needsRebuild;
82
82
  }
83
+ async completeCacheSession() {
84
+ return await (0, _rust().atlaspackNapiCompleteSession)(this._atlaspack_napi);
85
+ }
83
86
  }
84
87
  exports.AtlaspackV3 = AtlaspackV3;
@@ -62,6 +62,16 @@ class NapiWorkerPool {
62
62
  this.#napiWorkers.push(new Promise(res => worker.once('message', res)));
63
63
  }
64
64
  }
65
+ clearAllWorkerState() {
66
+ return Promise.all(this.#workers.map(worker => new Promise(res => {
67
+ worker.postMessage('clearState');
68
+ worker.once('message', message => {
69
+ if (message == 'stateCleared') {
70
+ res();
71
+ }
72
+ });
73
+ })));
74
+ }
65
75
  workerCount() {
66
76
  return this.#workerCount;
67
77
  }
@@ -5,36 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.PluginConfig = void 0;
7
7
  var _Config = _interopRequireDefault(require("../../../public/Config"));
8
+ var _InternalConfig = require("../../../InternalConfig");
8
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
10
  class PluginConfig {
10
- // @ts-expect-error TS2564
11
- #projectRoot;
12
11
  #inner;
13
- constructor({
14
- env,
15
- isSource,
16
- searchPath,
17
- projectRoot,
18
- fs,
19
- packageManager
20
- }) {
21
- this.env = env;
22
- this.isSource = isSource;
23
- this.searchPath = searchPath;
24
- this.#inner = new _Config.default(
25
- // @ts-expect-error TS2345
26
- {
27
- invalidateOnConfigKeyChange: [],
28
- invalidateOnFileCreate: [],
29
- invalidateOnFileChange: new Set(),
30
- devDeps: [],
31
- searchPath: searchPath.replace(projectRoot + '/', '')
32
- }, {
33
- projectRoot,
34
- inputFS: fs,
35
- outputFS: fs,
36
- packageManager
37
- });
12
+ constructor(configOpts, options) {
13
+ let internalConfig = (0, _InternalConfig.createConfig)(configOpts);
14
+ this.isSource = internalConfig.isSource;
15
+ this.searchPath = internalConfig.searchPath;
16
+ // @ts-expect-error TS2564
17
+ this.env = internalConfig.env;
18
+ this.#inner = new _Config.default(internalConfig, options);
38
19
  }
39
20
 
40
21
  // eslint-disable-next-line no-unused-vars
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.PluginOptions = void 0;
7
7
  class PluginOptions {
8
8
  #options;
9
+ used = false;
9
10
  get env() {
10
11
  if (!('env' in this.#options)) {
11
12
  return process.env;
@@ -18,18 +19,21 @@ class PluginOptions {
18
19
  if (!('projectRoot' in this.#options)) {
19
20
  throw new Error('PluginOptions.projectRoot');
20
21
  }
22
+ this.used = true;
21
23
  return this.#options.projectRoot;
22
24
  }
23
25
  get packageManager() {
24
26
  if (!('packageManager' in this.#options)) {
25
27
  throw new Error('PluginOptions.packageManager');
26
28
  }
29
+ this.used = true;
27
30
  return this.#options.packageManager;
28
31
  }
29
32
  get mode() {
30
33
  if (!('mode' in this.#options)) {
31
34
  throw new Error('PluginOptions.mode');
32
35
  }
36
+ this.used = true;
33
37
  return this.#options.mode;
34
38
  }
35
39
  get parcelVersion() {
@@ -38,30 +42,35 @@ class PluginOptions {
38
42
  // throw new Error('PluginOptions.parcelVersion');
39
43
  }
40
44
 
45
+ this.used = true;
41
46
  return this.#options.parcelVersion;
42
47
  }
43
48
  get hmrOptions() {
44
49
  if (!('hmrOptions' in this.#options)) {
45
50
  throw new Error('PluginOptions.hmrOptions');
46
51
  }
52
+ this.used = true;
47
53
  return this.#options.hmrOptions;
48
54
  }
49
55
  get serveOptions() {
50
56
  if (!('serveOptions' in this.#options)) {
51
57
  throw new Error('PluginOptions.serveOptions');
52
58
  }
59
+ this.used = true;
53
60
  return this.#options.serveOptions;
54
61
  }
55
62
  get shouldBuildLazily() {
56
63
  if (!('shouldBuildLazily' in this.#options)) {
57
64
  throw new Error('PluginOptions.shouldBuildLazily');
58
65
  }
66
+ this.used = true;
59
67
  return this.#options.shouldBuildLazily;
60
68
  }
61
69
  get shouldAutoInstall() {
62
70
  if (!('shouldAutoInstall' in this.#options)) {
63
71
  throw new Error('PluginOptions.shouldAutoInstall');
64
72
  }
73
+ this.used = true;
65
74
  return this.#options.shouldAutoInstall;
66
75
  }
67
76
  get logLevel() {
@@ -74,36 +83,42 @@ class PluginOptions {
74
83
  if (!('cacheDir' in this.#options)) {
75
84
  throw new Error('PluginOptions.cacheDir');
76
85
  }
86
+ this.used = true;
77
87
  return this.#options.cacheDir;
78
88
  }
79
89
  get inputFS() {
80
90
  if (!('inputFS' in this.#options)) {
81
91
  throw new Error('PluginOptions.inputFS');
82
92
  }
93
+ this.used = true;
83
94
  return this.#options.inputFS;
84
95
  }
85
96
  get outputFS() {
86
97
  if (!('outputFS' in this.#options)) {
87
98
  throw new Error('PluginOptions.outputFS');
88
99
  }
100
+ this.used = true;
89
101
  return this.#options.outputFS;
90
102
  }
91
103
  get instanceId() {
92
104
  if (!('instanceId' in this.#options)) {
93
105
  throw new Error('PluginOptions.instanceId');
94
106
  }
107
+ this.used = true;
95
108
  return this.#options.instanceId;
96
109
  }
97
110
  get detailedReport() {
98
111
  if (!('detailedReport' in this.#options)) {
99
112
  throw new Error('PluginOptions.detailedReport');
100
113
  }
114
+ this.used = true;
101
115
  return this.#options.detailedReport;
102
116
  }
103
117
  get featureFlags() {
104
118
  if (!('featureFlags' in this.#options)) {
105
119
  throw new Error('PluginOptions.featureFlags');
106
120
  }
121
+ this.used = true;
107
122
  return this.#options.featureFlags;
108
123
  }
109
124
  constructor(options) {