@animus-ui/next-plugin 0.1.24 → 0.1.26

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.
package/dist/index.cjs CHANGED
@@ -1,10 +1,32 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_turbopack_config = require("./turbopack-config-D-6BRBYi.cjs");
2
+ const require_turbopack_config = require("./turbopack-config-BoNfzhNu.cjs");
3
3
  let _animus_ui_extract_pipeline = require("@animus-ui/extract/pipeline");
4
4
  let _animus_ui_extract_session = require("@animus-ui/extract/session");
5
5
  let fs = require("fs");
6
6
  let path = require("path");
7
7
  let url = require("url");
8
+ //#region src/same-directory.ts
9
+ /** Whether two paths name one directory: by real path, which resolves a
10
+ * trailing slash, a symlink and the filesystem's own spelling, else by
11
+ * device and inode. */
12
+ function sameDirectory(a, b) {
13
+ const real = (path$4) => {
14
+ try {
15
+ return fs.realpathSync.native(path$4);
16
+ } catch {
17
+ return (0, path.resolve)(path$4);
18
+ }
19
+ };
20
+ if (real(a) === real(b)) return true;
21
+ try {
22
+ const left = (0, fs.statSync)(a);
23
+ const right = (0, fs.statSync)(b);
24
+ return left.dev === right.dev && left.ino === right.ino;
25
+ } catch {
26
+ return false;
27
+ }
28
+ }
29
+ //#endregion
8
30
  //#region src/plugin.ts
9
31
  /** The value arrives from a consumer's `next.config`, so the union above is a
10
32
  * model of what webpack accepts, not a proof about the value in hand. */
@@ -16,6 +38,9 @@ var AnimusWebpackPlugin = class {
16
38
  options;
17
39
  session;
18
40
  initialized = false;
41
+ /** Left its build: the next turn joins again and catches up, retried
42
+ * until it succeeds, never reusing the startup it already consumed. */
43
+ rejoining = false;
19
44
  aliasesExtracted = false;
20
45
  animusLoaderPaths;
21
46
  lastBuiltEpoch = null;
@@ -25,11 +50,10 @@ var AnimusWebpackPlugin = class {
25
50
  watchFailure = null;
26
51
  /** `development` is `next dev`: an error-level diagnostic reports and the
27
52
  * compilation keeps publishing, whatever the emission mode. */
28
- constructor(options, { development = false } = {}) {
53
+ constructor(options, { development = false, build } = {}) {
29
54
  this.options = options;
30
- (0, _animus_ui_extract_pipeline.assertNoRetiredEngineSelection)(options.engine);
31
- (0, _animus_ui_extract_session.setSharedEngine)(options.engine ?? "v2");
32
- this.session = new _animus_ui_extract_session.ExtractionSession(options);
55
+ (0, _animus_ui_extract_pipeline.assertSupportedEngine)(options.engine);
56
+ this.session = new _animus_ui_extract_session.ExtractionSession(options, { build });
33
57
  this.session.development = development;
34
58
  this.session.systemPropsModuleId = _animus_ui_extract_session.TURBOPACK_SYSTEM_PROPS_ID;
35
59
  this.animusLoaderPaths = /* @__PURE__ */ new Set([require_turbopack_config.resolveAnimusLoaderPath()]);
@@ -51,14 +75,22 @@ var AnimusWebpackPlugin = class {
51
75
  else if (Array.isArray(ignored)) {
52
76
  if (!ignored.includes(epochPath)) ignored.push(epochPath);
53
77
  } else if (isWatchIgnoreString(ignored)) watchOptions.ignored = [ignored, epochPath];
54
- else if (ignored instanceof RegExp) watchOptions.ignored = (path) => path === epochPath || ignored.test(path);
55
- else if (isWatchIgnoreMatcher(ignored)) watchOptions.ignored = (path) => path === epochPath || Boolean(ignored(path));
78
+ else if (ignored instanceof RegExp) watchOptions.ignored = (path$1) => path$1 === epochPath || ignored.test(path$1);
79
+ else if (isWatchIgnoreMatcher(ignored)) watchOptions.ignored = (path$2) => path$2 === epochPath || Boolean(ignored(path$2));
56
80
  }
57
81
  /** Webpack's export conditions select the system's kit files as they
58
- * select the bundle's; `...`, webpack's own defaults, names none. */
82
+ * select the bundle's; `...`, webpack's own defaults, names none. Its
83
+ * extension order and aliases are captured alongside. */
59
84
  extractConditions(compiler) {
60
- const names = compiler.options?.resolve?.conditionNames ?? [];
85
+ const resolve = compiler.options?.resolve;
86
+ const names = resolve?.conditionNames ?? [];
61
87
  this.session.conditions = names.filter((name) => name !== "...");
88
+ const resolverFactory = compiler.resolverFactory;
89
+ if (resolverFactory !== void 0) this.session.hostResolve = (specifier, importer) => new Promise((done) => {
90
+ resolverFactory.get("normal", { dependencyType: "esm" }).resolve({}, importer === void 0 ? compiler.context : (0, path.dirname)(importer), specifier, {}, (error, result) => done(error !== null || !result ? null : result));
91
+ });
92
+ this.session.assetClassification = (0, _animus_ui_extract_pipeline.builtInAssetClassification)("hostOptionUnreadable", "next-webpack rules not modelled");
93
+ this.session.extensionPolicy = (0, _animus_ui_extract_pipeline.webpackExtensionPolicy)("next-webpack", resolve ?? {}, compiler.webpack?.version);
62
94
  }
63
95
  extractAliases(compiler) {
64
96
  if (this.aliasesExtracted) return;
@@ -82,6 +114,13 @@ var AnimusWebpackPlugin = class {
82
114
  if (built) this.session.pathAliasesJson = built.json;
83
115
  }
84
116
  apply(compiler) {
117
+ const leave = () => {
118
+ this.session.close();
119
+ this.initialized = false;
120
+ this.rejoining = true;
121
+ };
122
+ compiler.hooks.shutdown?.tap(PLUGIN_NAME, leave);
123
+ compiler.hooks.watchClose?.tap(PLUGIN_NAME, leave);
85
124
  if (compiler.options?.name === "edge-server") return;
86
125
  const NormalModule = compiler.webpack?.NormalModule;
87
126
  if (NormalModule?.getCompilationHooks === void 0) throw new Error(UNSUPPORTED_WEBPACK_MESSAGE);
@@ -104,6 +143,7 @@ var AnimusWebpackPlugin = class {
104
143
  const registerSystemDependencies = () => {
105
144
  for (const dep of this.session.systemDependencyPaths) if ((0, fs.existsSync)(dep)) compilation.fileDependencies.add(dep);
106
145
  else compilation.missingDependencies.add(dep);
146
+ for (const path$3 of this.session.systemMissingPaths) compilation.missingDependencies.add(path$3);
107
147
  for (const dep of this.session.assetDependencyPaths) if ((0, fs.existsSync)(dep)) compilation.fileDependencies.add(dep);
108
148
  else compilation.missingDependencies.add(dep);
109
149
  for (const root of this.session.externalWatchRoots) compilation.contextDependencies.add(root);
@@ -116,7 +156,7 @@ var AnimusWebpackPlugin = class {
116
156
  stage
117
157
  }, () => {
118
158
  registerSystemDependencies();
119
- const css = (0, _animus_ui_extract_session.getSharedCss)();
159
+ const css = this.session.rootDir ? (0, _animus_ui_extract_session.getSharedCss)(this.session.key) : "";
120
160
  if (!css || !RawSource) return;
121
161
  const rootDir = this.session.rootDir || compiler.context;
122
162
  const cssPath = (0, _animus_ui_extract_session.stylesPath)((0, _animus_ui_extract_session.sessionArtifactDir)(rootDir, this.session.sessionId));
@@ -131,13 +171,18 @@ var AnimusWebpackPlugin = class {
131
171
  this.adoptCompilerContext(_compiler);
132
172
  this.extractAliases(_compiler);
133
173
  this.extractConditions(_compiler);
134
- const existing = (0, _animus_ui_extract_session.getAnalysisStartedPromise)();
174
+ if (await this.rejoin()) {
175
+ this.session.agreeWithSystemAuthority();
176
+ return;
177
+ }
178
+ const existing = (0, _animus_ui_extract_session.getAnalysisStartedPromise)(this.session.key);
135
179
  if (existing) {
136
180
  await existing;
181
+ this.session.agreeWithSystemAuthority();
137
182
  return;
138
183
  }
139
184
  const promise = this.session.runFullPipeline();
140
- (0, _animus_ui_extract_session.setAnalysisStartedPromise)(promise);
185
+ (0, _animus_ui_extract_session.setAnalysisStartedPromise)(this.session.key, promise);
141
186
  await promise;
142
187
  });
143
188
  compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async (_compiler) => {
@@ -154,21 +199,38 @@ var AnimusWebpackPlugin = class {
154
199
  }
155
200
  /** Rejects with the analysis error; the published generation stays the
156
201
  * last successful one. */
202
+ /** Joins the build this compiler left and catches up with it: true when
203
+ * the build was live, false when it starts as at first. */
204
+ async rejoin() {
205
+ if (!this.rejoining) return false;
206
+ this.session.reattach();
207
+ const live = await this.session.catchUp();
208
+ this.rejoining = false;
209
+ return live;
210
+ }
157
211
  async analyzeWatchTurn(compiler) {
212
+ if (!this.initialized && await this.rejoin()) {
213
+ this.session.agreeWithSystemAuthority();
214
+ this.initialized = true;
215
+ this.lastBuiltEpoch = (0, _animus_ui_extract_session.getReplacementEpoch)(this.session.key);
216
+ this.epochMovedForNextCompilation = true;
217
+ return;
218
+ }
158
219
  if (!this.initialized) {
159
- let startup = (0, _animus_ui_extract_session.getAnalysisStartedPromise)();
220
+ let startup = (0, _animus_ui_extract_session.getAnalysisStartedPromise)(this.session.key);
160
221
  if (!startup) {
161
222
  startup = this.session.runFullPipeline();
162
- (0, _animus_ui_extract_session.setAnalysisStartedPromise)(startup);
223
+ (0, _animus_ui_extract_session.setAnalysisStartedPromise)(this.session.key, startup);
163
224
  }
164
225
  try {
165
226
  await startup;
166
227
  } catch (err) {
167
- if ((0, _animus_ui_extract_session.getAnalysisStartedPromise)() === startup) (0, _animus_ui_extract_session.resetAnalysisStartedPromise)();
228
+ if ((0, _animus_ui_extract_session.getAnalysisStartedPromise)(this.session.key) === startup) (0, _animus_ui_extract_session.resetAnalysisStartedPromise)(this.session.key);
168
229
  throw err;
169
230
  }
231
+ this.session.agreeWithSystemAuthority();
170
232
  this.initialized = true;
171
- this.lastBuiltEpoch = (0, _animus_ui_extract_session.getReplacementEpoch)();
233
+ this.lastBuiltEpoch = (0, _animus_ui_extract_session.getReplacementEpoch)(this.session.key);
172
234
  this.epochMovedForNextCompilation = this.watchFailure !== null;
173
235
  return;
174
236
  }
@@ -176,7 +238,8 @@ var AnimusWebpackPlugin = class {
176
238
  modifiedFiles: compiler.modifiedFiles,
177
239
  removedFiles: compiler.removedFiles
178
240
  });
179
- const epoch = (0, _animus_ui_extract_session.getReplacementEpoch)();
241
+ this.session.agreeWithSystemAuthority();
242
+ const epoch = (0, _animus_ui_extract_session.getReplacementEpoch)(this.session.key);
180
243
  this.epochMovedForNextCompilation = this.lastBuiltEpoch !== null && epoch !== null && epoch !== this.lastBuiltEpoch;
181
244
  if (epoch !== null) this.lastBuiltEpoch = epoch;
182
245
  }
@@ -189,21 +252,23 @@ var AnimusWebpackPlugin = class {
189
252
  setRootDir(rootDir) {
190
253
  this.session.rootDir = rootDir;
191
254
  }
192
- warnedRootDivergence = false;
255
+ /** Keeps Next's output directory out of discovery, whatever the user's
256
+ * exclude list says. Call after `setRootDir`. */
257
+ excludeOutputDir(outDir) {
258
+ const pattern = (0, _animus_ui_extract_pipeline.outputExclusion)(this.session.rootDir, outDir);
259
+ if (pattern !== null) this.session.structuralExclude = [pattern];
260
+ }
193
261
  /** Adopts `compiler.context` only when no config-time root exists: every
194
262
  * frozen derivation came from that root, so an overwrite re-keys it.
195
263
  * Stub path, css alias, virtual system-props target and watch-ignore are
196
- * all frozen from it, so a disagreement is warned, never reconciled. */
264
+ * all frozen from it, so a disagreement fails, never reconciled. */
197
265
  adoptCompilerContext(compiler) {
198
266
  const context = compiler.context;
199
267
  if (!this.session.rootDir) {
200
268
  this.session.rootDir = context;
201
269
  return;
202
270
  }
203
- if (context && this.session.rootDir !== context && !this.warnedRootDivergence) {
204
- this.warnedRootDivergence = true;
205
- console.warn(`[animus-extract] compiler.context (${context}) differs from the configured project root (${this.session.rootDir}); keeping the configured root — run next against the app directory (or align your custom webpack context) so both agree`);
206
- }
271
+ if (context && !sameDirectory(context, this.session.rootDir)) throw new _animus_ui_extract_pipeline.AnimusConfigError(`[animus-extract] compiler.context (${context}) differs from the configured project root (${this.session.rootDir}). Run next against the app directory, or align your custom webpack context, so both agree.`);
207
272
  }
208
273
  get sessionDir() {
209
274
  return this.session.sessionDir;
@@ -212,15 +277,20 @@ var AnimusWebpackPlugin = class {
212
277
  return this.options;
213
278
  }
214
279
  getExternalPackageDirs() {
215
- return this.session.externalPackageDirs.length > 0 ? this.session.externalPackageDirs : (0, _animus_ui_extract_session.getSharedExternalDirs)();
280
+ return this.session.externalPackageDirs.length > 0 ? this.session.externalPackageDirs : (0, _animus_ui_extract_session.getSharedExternalDirs)(this.session.key);
281
+ }
282
+ /** An import webpack resolved while bundling, with the resolve options of
283
+ * the rules its importer matches (spec §2.2 A4). */
284
+ reportHostResolution(importer, request, resolved) {
285
+ this.session.reportHostResolution(importer, request, resolved);
216
286
  }
217
287
  getExternalSourceEntries() {
218
- return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceEntries : (0, _animus_ui_extract_session.getSharedExternalEntries)();
288
+ return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceEntries : (0, _animus_ui_extract_session.getSharedExternalEntries)(this.session.key);
219
289
  }
220
290
  /** The classification of the entries `getExternalSourceEntries` returns,
221
291
  * from the same source. */
222
292
  getExternalSourceSideEffects() {
223
- return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceSideEffects : (0, _animus_ui_extract_session.getSharedExternalSideEffects)();
293
+ return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceSideEffects : (0, _animus_ui_extract_session.getSharedExternalSideEffects)(this.session.key);
224
294
  }
225
295
  };
226
296
  //#endregion
@@ -234,6 +304,7 @@ const PHASE_PRODUCTION_BUILD = "phase-production-build";
234
304
  let warnedGitignore = false;
235
305
  let warnedUnstableTurbopack = false;
236
306
  function withAnimus(options) {
307
+ (0, _animus_ui_extract_pipeline.assertSupportedEngine)(options.engine);
237
308
  if (!options.system) throw new Error("[animus-extract] Missing required option `system`. Provide the path to your SystemInstance module: withAnimus({ system: \"./src/ds.ts\" })");
238
309
  (0, _animus_ui_extract_pipeline.assertKnownOptionKeys)({ ...options }, [
239
310
  "cssImportTarget",
@@ -241,10 +312,7 @@ function withAnimus(options) {
241
312
  "unstable_turbopack",
242
313
  "loaderPath",
243
314
  "phase"
244
- ], [{
245
- key: "root",
246
- reason: "this driver derives its own root — Next's `dir` under webpack, `process.cwd()` under Turbopack (Next passes no dir to a config module)"
247
- }], {
315
+ ], [], {
248
316
  onUnknownKey: "warn",
249
317
  warn: (message) => console.warn(`[animus-extract] ${message}`)
250
318
  });
@@ -252,21 +320,31 @@ function withAnimus(options) {
252
320
  warnedUnstableTurbopack = true;
253
321
  console.warn("[animus-extract] `unstable_turbopack` is deprecated — rename it to `turbopack` (same shape)");
254
322
  }
323
+ const build = (0, _animus_ui_extract_session.createBuildId)();
324
+ const appRoot = options.root === void 0 ? process.cwd() : (0, path.resolve)(options.root);
255
325
  return (authoredConfig) => {
256
- const nextConfig = withSourceKits(authoredConfig, process.cwd());
257
- if (require_turbopack_config.resolveTurbopackMode(options)) return turbopackConfig(nextConfig, options);
326
+ const nextConfig = withSourceKits(authoredConfig, appRoot);
327
+ if (require_turbopack_config.resolveTurbopackMode(options)) {
328
+ warnTurbopackCwdRoot(options, appRoot);
329
+ return turbopackConfig(nextConfig, options, build, appRoot);
330
+ }
258
331
  const existingWebpack = nextConfig.webpack;
259
332
  return {
260
333
  ...nextConfig,
261
334
  webpack(config, context) {
262
335
  if (existingWebpack) config = existingWebpack(config, context);
263
- const rootDir = context.dir?.length ? context.dir : process.cwd();
336
+ if (context.dir?.length && !sameDirectory(context.dir, appRoot)) throw new _animus_ui_extract_pipeline.AnimusConfigError(`[animus-extract] Next builds ${context.dir}, but Animus read the app's source kits from ${appRoot}. Run next from the app directory, or pass withAnimus({ root }) naming it.`);
337
+ const rootDir = appRoot;
264
338
  const { mode } = (0, _animus_ui_extract_pipeline.resolveMode)(options.mode, () => context.dev === true ? "development" : "production");
265
339
  const plugin = new AnimusWebpackPlugin({
266
340
  ...options,
267
341
  mode
268
- }, { development: context.dev === true });
342
+ }, {
343
+ development: context.dev === true,
344
+ build
345
+ });
269
346
  plugin.setRootDir(rootDir);
347
+ if (nextConfig.distDir) plugin.excludeOutputDir((0, path.resolve)(rootDir, nextConfig.distDir));
270
348
  const sessionDir = plugin.sessionDir;
271
349
  if (!(0, fs.existsSync)(sessionDir)) (0, fs.mkdirSync)(sessionDir, { recursive: true });
272
350
  const stubCssPath = (0, _animus_ui_extract_session.stylesPath)(sessionDir);
@@ -311,6 +389,9 @@ function withAnimus(options) {
311
389
  }
312
390
  });
313
391
  nmf.hooks.afterResolve.tap("AnimusVirtualResolve", (resolveData) => {
392
+ const issuer = resolveData.contextInfo?.issuer;
393
+ const resolved = resolveData.createData?.resource;
394
+ if (issuer && resolved !== void 0) plugin.reportHostResolution(issuer, resolveData.request, resolved);
314
395
  const sideEffects = redirectSideEffects.get(resolveData);
315
396
  const settings = resolveData.createData?.settings;
316
397
  if (!settings) return;
@@ -336,9 +417,10 @@ function withAnimus(options) {
336
417
  use: [{
337
418
  loader: actualLoaderPath,
338
419
  options: {
339
- strict: options.strict,
340
420
  development: context.dev === true,
341
- cssImportTarget: options.cssImportTarget
421
+ cssImportTarget: options.cssImportTarget,
422
+ build,
423
+ root: rootDir
342
424
  }
343
425
  }]
344
426
  });
@@ -359,17 +441,35 @@ function bindTurbopackWatchDeathReport(outcome, rootDir) {
359
441
  * source, but Next's server keeps an installed package external, and so
360
442
  * loads its runtime entry, unless the package is transpiled; transpiling
361
443
  * also compiles its TypeScript source. */
444
+ let warnedTurbopackCwd = false;
445
+ /** Turbopack's loaders get no app dir either, so a cwd that is not the app
446
+ * cannot be detected later: warn at startup when the cwd holds no Next
447
+ * config and no `root` names the app. */
448
+ function warnTurbopackCwdRoot(options, appRoot) {
449
+ if (options.root !== void 0 || warnedTurbopackCwd) return;
450
+ if ([
451
+ "js",
452
+ "mjs",
453
+ "cjs",
454
+ "ts",
455
+ "mts"
456
+ ].some((ext) => (0, fs.existsSync)((0, path.join)(appRoot, `next.config.${ext}`)))) return;
457
+ warnedTurbopackCwd = true;
458
+ console.warn(`[animus-extract] the current directory (${appRoot}) holds no next.config: under Turbopack, Animus reads the app from the current directory. Run next from the app directory, or pass withAnimus({ root }) naming it.`);
459
+ }
362
460
  function withSourceKits(nextConfig, rootDir) {
363
461
  const declared = nextConfig.transpilePackages ?? [];
364
- const kits = (0, _animus_ui_extract_pipeline.sourceKitDependencies)(rootDir).map((kit) => kit.name).filter((name) => !declared.includes(name));
462
+ const kits = (0, _animus_ui_extract_pipeline.sourceKitDependencies)(rootDir, (0, _animus_ui_extract_session.requireEngine)()).map((kit) => kit.name).filter((name) => !declared.includes(name));
365
463
  if (kits.length === 0) return nextConfig;
366
464
  return {
367
465
  ...nextConfig,
368
466
  transpilePackages: [...declared, ...kits]
369
467
  };
370
468
  }
371
- function turbopackConfig(nextConfig, options) {
372
- const load = (phase) => loadTurbopackFragment(options, phase).then((fragment) => mergeTurbopackFragment(nextConfig, fragment));
469
+ function turbopackConfig(nextConfig, options, build, appRoot) {
470
+ const resolveExtensions = nextConfig.turbopack?.resolveExtensions ?? nextConfig.experimental?.turbo?.resolveExtensions;
471
+ const outputExclude = nextConfig.distDir ? (0, _animus_ui_extract_pipeline.outputExclusion)(appRoot, (0, path.resolve)(appRoot, nextConfig.distDir)) : null;
472
+ const load = (phase) => loadTurbopackFragment(options, phase, resolveExtensions, outputExclude, nextConfig.images?.disableStaticImages === true, build, appRoot).then((fragment) => mergeTurbopackFragment(nextConfig, fragment));
373
473
  function then(onResolved, onRejected) {
374
474
  const phase = options.phase ?? (require_turbopack_config.isTurbopackDevelopment() ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_BUILD);
375
475
  return load(phase).then(onResolved, onRejected);
@@ -378,49 +478,67 @@ function turbopackConfig(nextConfig, options) {
378
478
  Object.defineProperty(config, "then", { enumerable: false });
379
479
  return config;
380
480
  }
381
- let liveTurbopackSession = null;
382
- let liveTurbopackWatcher = null;
383
- /** The load the live session came from. Next loads the config again after
384
- * Ready (validateTurboNextConfig), and a user config may await this one
385
- * besides: the same phase and root share one analysis and keep the watcher.
386
- * A rejected load is dropped, so a repaired source loads again. */
387
- let liveTurbopackLoad = null;
388
- function loadTurbopackFragment(options, phase) {
389
- const rootDir = process.cwd();
390
- const key = JSON.stringify([phase, rootDir]);
391
- if (liveTurbopackLoad?.key === key) return liveTurbopackLoad.fragment;
392
- const fragment = analyzeForTurbopack(options, phase, rootDir);
481
+ /** Each wrapper's owner, by the build it created: another wrapper of the
482
+ * same root is another build and never shares or closes this one's. */
483
+ const turbopackOwners = /* @__PURE__ */ new Map();
484
+ function turbopackOwner(build) {
485
+ let owner = turbopackOwners.get(build);
486
+ if (owner === void 0) {
487
+ owner = {
488
+ session: null,
489
+ watcher: null,
490
+ load: null
491
+ };
492
+ turbopackOwners.set(build, owner);
493
+ }
494
+ return owner;
495
+ }
496
+ function loadTurbopackFragment(options, phase, resolveExtensions, outputExclude, disableStaticImages, build, rootDir) {
497
+ const key = JSON.stringify([
498
+ phase,
499
+ rootDir,
500
+ resolveExtensions ?? null,
501
+ disableStaticImages
502
+ ]);
503
+ const owner = turbopackOwner(build);
504
+ if (owner.load?.key === key) return owner.load.fragment;
505
+ const fragment = analyzeForTurbopack(options, phase, rootDir, resolveExtensions, outputExclude, disableStaticImages, build);
393
506
  const load = {
394
507
  key,
395
508
  fragment
396
509
  };
397
- liveTurbopackLoad = load;
510
+ owner.load = load;
398
511
  fragment.catch(() => {
399
- if (liveTurbopackLoad === load) liveTurbopackLoad = null;
512
+ if (owner.load === load) owner.load = null;
400
513
  });
401
514
  return fragment;
402
515
  }
403
- async function analyzeForTurbopack(options, phase, rootDir) {
516
+ async function analyzeForTurbopack(options, phase, rootDir, resolveExtensions, outputExclude, disableStaticImages, build) {
404
517
  const development = phase === PHASE_DEVELOPMENT_SERVER;
405
518
  const { mode } = (0, _animus_ui_extract_pipeline.resolveMode)(options.mode, () => development ? "development" : "production");
406
519
  const session = new _animus_ui_extract_session.ExtractionSession({
407
520
  ...options,
408
521
  mode
409
- }, { unbundledComputedImports: true });
410
- liveTurbopackSession?.close();
411
- liveTurbopackWatcher?.close();
412
- liveTurbopackWatcher = null;
413
- liveTurbopackSession = session;
522
+ }, {
523
+ unbundledComputedImports: true,
524
+ build: `${build}-${phase}`
525
+ });
526
+ const owner = turbopackOwner(build);
527
+ owner.session?.close();
528
+ owner.watcher?.close();
529
+ owner.watcher = null;
530
+ owner.session = session;
414
531
  session.development = development;
415
532
  session.rootDir = rootDir;
416
- const aliasPairs = (0, _animus_ui_extract_pipeline.readTsconfigAliasPairs)(rootDir);
417
- const builtAliases = (0, _animus_ui_extract_pipeline.buildPathAliasesJson)(aliasPairs, rootDir);
418
- if (builtAliases) session.pathAliasesJson = builtAliases.json;
533
+ if (outputExclude !== null) session.structuralExclude = [outputExclude];
534
+ session.extensionPolicy = (0, _animus_ui_extract_pipeline.turbopackExtensionPolicy)(resolveExtensions);
535
+ session.assetClassification = (0, _animus_ui_extract_pipeline.nextImageAssetClassification)(rootDir, disableStaticImages);
536
+ session.aliasesFromTsconfig = true;
419
537
  await (0, _animus_ui_extract_session.runSessionPipeline)(session);
420
- if (development && liveTurbopackSession === session) {
538
+ if (development && owner.session === session) {
421
539
  const outcome = (0, _animus_ui_extract_session.startTurbopackWatcher)(session, rootDir);
422
540
  bindTurbopackWatchDeathReport(outcome, rootDir);
423
- if (outcome.kind === "started") liveTurbopackWatcher = outcome.handle;
541
+ if (outcome.kind === "started") owner.watcher = outcome.handle;
424
542
  }
425
543
  for (const line of require_turbopack_config.turbopackSideEffectsLimits(rootDir, session.externalSourceEntries, session.externalSourceSideEffects)) console.warn(line);
426
544
  return require_turbopack_config.buildTurbopackConfig({