@animus-ui/next-plugin 0.1.25 → 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 +182 -64
- package/dist/index.mjs +184 -66
- package/dist/{loader-core-CAr8opFH.cjs → loader-core-Bz52QNm3.cjs} +15 -4
- package/dist/{loader-core-pACpByOT.mjs → loader-core-DU2uZEMQ.mjs} +16 -5
- package/dist/loader-core.d.ts +8 -3
- package/dist/loader-core.d.ts.map +1 -1
- package/dist/loader.cjs +13 -10
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.mjs +15 -12
- package/dist/plugin.d.ts +39 -4
- package/dist/plugin.d.ts.map +1 -1
- package/dist/same-directory.d.ts +5 -0
- package/dist/same-directory.d.ts.map +1 -0
- package/dist/{turbopack-config-BdfqxwT0.mjs → turbopack-config-3jtLDAIM.mjs} +0 -1
- package/dist/{turbopack-config-D-6BRBYi.cjs → turbopack-config-BoNfzhNu.cjs} +0 -1
- package/dist/turbopack-config.d.ts.map +1 -1
- package/dist/turbopack-loader.cjs +55 -55
- package/dist/turbopack-loader.d.ts +2 -1
- package/dist/turbopack-loader.d.ts.map +1 -1
- package/dist/turbopack-loader.mjs +57 -61
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/with-animus.d.ts +7 -0
- package/dist/with-animus.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
-
import { a as resolveTurbopackMode, i as resolveTurbopackLoaderPath, n as buildTurbopackConfig, o as turbopackSideEffectsLimits, r as isTurbopackDevelopment, s as resolveAnimusLoaderPath, t as ANIMUS_TURBOPACK_RULE_GLOB } from "./turbopack-config-
|
|
2
|
-
import { assembleStylesheet, assertKnownOptionKeys,
|
|
3
|
-
import { ANIMUS_CSS_MODULE_ID, ANIMUS_CSS_MODULE_ID as ANIMUS_CSS_MODULE_ID$1, ExtractionSession, TURBOPACK_SYSTEM_PROPS_ID, getAnalysisStartedPromise, getReplacementEpoch, getSharedCss, getSharedExternalDirs, getSharedExternalEntries, getSharedExternalSideEffects, replacementEpochPath, resetAnalysisStartedPromise, runSessionPipeline, sessionArtifactDir, setAnalysisStartedPromise,
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
5
|
-
import { dirname, join } from "path";
|
|
1
|
+
import { a as resolveTurbopackMode, i as resolveTurbopackLoaderPath, n as buildTurbopackConfig, o as turbopackSideEffectsLimits, r as isTurbopackDevelopment, s as resolveAnimusLoaderPath, t as ANIMUS_TURBOPACK_RULE_GLOB } from "./turbopack-config-3jtLDAIM.mjs";
|
|
2
|
+
import { AnimusConfigError, assembleStylesheet, assertKnownOptionKeys, assertSupportedEngine, buildPathAliasesJson, builtInAssetClassification, isEngineTransformExtension, isPathWithinRoot, keepsKitSourceEffects, nextImageAssetClassification, outputExclusion, resolveMode, sourceKitDependencies, turbopackExtensionPolicy, webpackExtensionPolicy } from "@animus-ui/extract/pipeline";
|
|
3
|
+
import { ANIMUS_CSS_MODULE_ID, ANIMUS_CSS_MODULE_ID as ANIMUS_CSS_MODULE_ID$1, ExtractionSession, TURBOPACK_SYSTEM_PROPS_ID, createBuildId, getAnalysisStartedPromise, getReplacementEpoch, getSharedCss, getSharedExternalDirs, getSharedExternalEntries, getSharedExternalSideEffects, replacementEpochPath, requireEngine, resetAnalysisStartedPromise, runSessionPipeline, sessionArtifactDir, setAnalysisStartedPromise, startTurbopackWatcher, stylesPath, systemPropsPath } from "@animus-ui/extract/session";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
|
|
5
|
+
import { dirname, join, resolve } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
+
//#region src/same-directory.ts
|
|
8
|
+
/** Whether two paths name one directory: by real path, which resolves a
|
|
9
|
+
* trailing slash, a symlink and the filesystem's own spelling, else by
|
|
10
|
+
* device and inode. */
|
|
11
|
+
function sameDirectory(a, b) {
|
|
12
|
+
const real = (path) => {
|
|
13
|
+
try {
|
|
14
|
+
return realpathSync.native(path);
|
|
15
|
+
} catch {
|
|
16
|
+
return resolve(path);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
if (real(a) === real(b)) return true;
|
|
20
|
+
try {
|
|
21
|
+
const left = statSync(a);
|
|
22
|
+
const right = statSync(b);
|
|
23
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
7
29
|
//#region src/plugin.ts
|
|
8
30
|
/** The value arrives from a consumer's `next.config`, so the union above is a
|
|
9
31
|
* model of what webpack accepts, not a proof about the value in hand. */
|
|
@@ -15,6 +37,9 @@ var AnimusWebpackPlugin = class {
|
|
|
15
37
|
options;
|
|
16
38
|
session;
|
|
17
39
|
initialized = false;
|
|
40
|
+
/** Left its build: the next turn joins again and catches up, retried
|
|
41
|
+
* until it succeeds, never reusing the startup it already consumed. */
|
|
42
|
+
rejoining = false;
|
|
18
43
|
aliasesExtracted = false;
|
|
19
44
|
animusLoaderPaths;
|
|
20
45
|
lastBuiltEpoch = null;
|
|
@@ -24,11 +49,10 @@ var AnimusWebpackPlugin = class {
|
|
|
24
49
|
watchFailure = null;
|
|
25
50
|
/** `development` is `next dev`: an error-level diagnostic reports and the
|
|
26
51
|
* compilation keeps publishing, whatever the emission mode. */
|
|
27
|
-
constructor(options, { development = false } = {}) {
|
|
52
|
+
constructor(options, { development = false, build } = {}) {
|
|
28
53
|
this.options = options;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.session = new ExtractionSession(options);
|
|
54
|
+
assertSupportedEngine(options.engine);
|
|
55
|
+
this.session = new ExtractionSession(options, { build });
|
|
32
56
|
this.session.development = development;
|
|
33
57
|
this.session.systemPropsModuleId = TURBOPACK_SYSTEM_PROPS_ID;
|
|
34
58
|
this.animusLoaderPaths = /* @__PURE__ */ new Set([resolveAnimusLoaderPath()]);
|
|
@@ -54,10 +78,18 @@ var AnimusWebpackPlugin = class {
|
|
|
54
78
|
else if (isWatchIgnoreMatcher(ignored)) watchOptions.ignored = (path) => path === epochPath || Boolean(ignored(path));
|
|
55
79
|
}
|
|
56
80
|
/** Webpack's export conditions select the system's kit files as they
|
|
57
|
-
* select the bundle's; `...`, webpack's own defaults, names none.
|
|
81
|
+
* select the bundle's; `...`, webpack's own defaults, names none. Its
|
|
82
|
+
* extension order and aliases are captured alongside. */
|
|
58
83
|
extractConditions(compiler) {
|
|
59
|
-
const
|
|
84
|
+
const resolve = compiler.options?.resolve;
|
|
85
|
+
const names = resolve?.conditionNames ?? [];
|
|
60
86
|
this.session.conditions = names.filter((name) => name !== "...");
|
|
87
|
+
const resolverFactory = compiler.resolverFactory;
|
|
88
|
+
if (resolverFactory !== void 0) this.session.hostResolve = (specifier, importer) => new Promise((done) => {
|
|
89
|
+
resolverFactory.get("normal", { dependencyType: "esm" }).resolve({}, importer === void 0 ? compiler.context : dirname(importer), specifier, {}, (error, result) => done(error !== null || !result ? null : result));
|
|
90
|
+
});
|
|
91
|
+
this.session.assetClassification = builtInAssetClassification("hostOptionUnreadable", "next-webpack rules not modelled");
|
|
92
|
+
this.session.extensionPolicy = webpackExtensionPolicy("next-webpack", resolve ?? {}, compiler.webpack?.version);
|
|
61
93
|
}
|
|
62
94
|
extractAliases(compiler) {
|
|
63
95
|
if (this.aliasesExtracted) return;
|
|
@@ -81,6 +113,13 @@ var AnimusWebpackPlugin = class {
|
|
|
81
113
|
if (built) this.session.pathAliasesJson = built.json;
|
|
82
114
|
}
|
|
83
115
|
apply(compiler) {
|
|
116
|
+
const leave = () => {
|
|
117
|
+
this.session.close();
|
|
118
|
+
this.initialized = false;
|
|
119
|
+
this.rejoining = true;
|
|
120
|
+
};
|
|
121
|
+
compiler.hooks.shutdown?.tap(PLUGIN_NAME, leave);
|
|
122
|
+
compiler.hooks.watchClose?.tap(PLUGIN_NAME, leave);
|
|
84
123
|
if (compiler.options?.name === "edge-server") return;
|
|
85
124
|
const NormalModule = compiler.webpack?.NormalModule;
|
|
86
125
|
if (NormalModule?.getCompilationHooks === void 0) throw new Error(UNSUPPORTED_WEBPACK_MESSAGE);
|
|
@@ -103,6 +142,7 @@ var AnimusWebpackPlugin = class {
|
|
|
103
142
|
const registerSystemDependencies = () => {
|
|
104
143
|
for (const dep of this.session.systemDependencyPaths) if (existsSync(dep)) compilation.fileDependencies.add(dep);
|
|
105
144
|
else compilation.missingDependencies.add(dep);
|
|
145
|
+
for (const path of this.session.systemMissingPaths) compilation.missingDependencies.add(path);
|
|
106
146
|
for (const dep of this.session.assetDependencyPaths) if (existsSync(dep)) compilation.fileDependencies.add(dep);
|
|
107
147
|
else compilation.missingDependencies.add(dep);
|
|
108
148
|
for (const root of this.session.externalWatchRoots) compilation.contextDependencies.add(root);
|
|
@@ -115,7 +155,7 @@ var AnimusWebpackPlugin = class {
|
|
|
115
155
|
stage
|
|
116
156
|
}, () => {
|
|
117
157
|
registerSystemDependencies();
|
|
118
|
-
const css = getSharedCss();
|
|
158
|
+
const css = this.session.rootDir ? getSharedCss(this.session.key) : "";
|
|
119
159
|
if (!css || !RawSource) return;
|
|
120
160
|
const rootDir = this.session.rootDir || compiler.context;
|
|
121
161
|
const cssPath = stylesPath(sessionArtifactDir(rootDir, this.session.sessionId));
|
|
@@ -130,13 +170,18 @@ var AnimusWebpackPlugin = class {
|
|
|
130
170
|
this.adoptCompilerContext(_compiler);
|
|
131
171
|
this.extractAliases(_compiler);
|
|
132
172
|
this.extractConditions(_compiler);
|
|
133
|
-
|
|
173
|
+
if (await this.rejoin()) {
|
|
174
|
+
this.session.agreeWithSystemAuthority();
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const existing = getAnalysisStartedPromise(this.session.key);
|
|
134
178
|
if (existing) {
|
|
135
179
|
await existing;
|
|
180
|
+
this.session.agreeWithSystemAuthority();
|
|
136
181
|
return;
|
|
137
182
|
}
|
|
138
183
|
const promise = this.session.runFullPipeline();
|
|
139
|
-
setAnalysisStartedPromise(promise);
|
|
184
|
+
setAnalysisStartedPromise(this.session.key, promise);
|
|
140
185
|
await promise;
|
|
141
186
|
});
|
|
142
187
|
compiler.hooks.watchRun.tapPromise(PLUGIN_NAME, async (_compiler) => {
|
|
@@ -153,21 +198,38 @@ var AnimusWebpackPlugin = class {
|
|
|
153
198
|
}
|
|
154
199
|
/** Rejects with the analysis error; the published generation stays the
|
|
155
200
|
* last successful one. */
|
|
201
|
+
/** Joins the build this compiler left and catches up with it: true when
|
|
202
|
+
* the build was live, false when it starts as at first. */
|
|
203
|
+
async rejoin() {
|
|
204
|
+
if (!this.rejoining) return false;
|
|
205
|
+
this.session.reattach();
|
|
206
|
+
const live = await this.session.catchUp();
|
|
207
|
+
this.rejoining = false;
|
|
208
|
+
return live;
|
|
209
|
+
}
|
|
156
210
|
async analyzeWatchTurn(compiler) {
|
|
211
|
+
if (!this.initialized && await this.rejoin()) {
|
|
212
|
+
this.session.agreeWithSystemAuthority();
|
|
213
|
+
this.initialized = true;
|
|
214
|
+
this.lastBuiltEpoch = getReplacementEpoch(this.session.key);
|
|
215
|
+
this.epochMovedForNextCompilation = true;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
157
218
|
if (!this.initialized) {
|
|
158
|
-
let startup = getAnalysisStartedPromise();
|
|
219
|
+
let startup = getAnalysisStartedPromise(this.session.key);
|
|
159
220
|
if (!startup) {
|
|
160
221
|
startup = this.session.runFullPipeline();
|
|
161
|
-
setAnalysisStartedPromise(startup);
|
|
222
|
+
setAnalysisStartedPromise(this.session.key, startup);
|
|
162
223
|
}
|
|
163
224
|
try {
|
|
164
225
|
await startup;
|
|
165
226
|
} catch (err) {
|
|
166
|
-
if (getAnalysisStartedPromise() === startup) resetAnalysisStartedPromise();
|
|
227
|
+
if (getAnalysisStartedPromise(this.session.key) === startup) resetAnalysisStartedPromise(this.session.key);
|
|
167
228
|
throw err;
|
|
168
229
|
}
|
|
230
|
+
this.session.agreeWithSystemAuthority();
|
|
169
231
|
this.initialized = true;
|
|
170
|
-
this.lastBuiltEpoch = getReplacementEpoch();
|
|
232
|
+
this.lastBuiltEpoch = getReplacementEpoch(this.session.key);
|
|
171
233
|
this.epochMovedForNextCompilation = this.watchFailure !== null;
|
|
172
234
|
return;
|
|
173
235
|
}
|
|
@@ -175,7 +237,8 @@ var AnimusWebpackPlugin = class {
|
|
|
175
237
|
modifiedFiles: compiler.modifiedFiles,
|
|
176
238
|
removedFiles: compiler.removedFiles
|
|
177
239
|
});
|
|
178
|
-
|
|
240
|
+
this.session.agreeWithSystemAuthority();
|
|
241
|
+
const epoch = getReplacementEpoch(this.session.key);
|
|
179
242
|
this.epochMovedForNextCompilation = this.lastBuiltEpoch !== null && epoch !== null && epoch !== this.lastBuiltEpoch;
|
|
180
243
|
if (epoch !== null) this.lastBuiltEpoch = epoch;
|
|
181
244
|
}
|
|
@@ -188,21 +251,23 @@ var AnimusWebpackPlugin = class {
|
|
|
188
251
|
setRootDir(rootDir) {
|
|
189
252
|
this.session.rootDir = rootDir;
|
|
190
253
|
}
|
|
191
|
-
|
|
254
|
+
/** Keeps Next's output directory out of discovery, whatever the user's
|
|
255
|
+
* exclude list says. Call after `setRootDir`. */
|
|
256
|
+
excludeOutputDir(outDir) {
|
|
257
|
+
const pattern = outputExclusion(this.session.rootDir, outDir);
|
|
258
|
+
if (pattern !== null) this.session.structuralExclude = [pattern];
|
|
259
|
+
}
|
|
192
260
|
/** Adopts `compiler.context` only when no config-time root exists: every
|
|
193
261
|
* frozen derivation came from that root, so an overwrite re-keys it.
|
|
194
262
|
* Stub path, css alias, virtual system-props target and watch-ignore are
|
|
195
|
-
* all frozen from it, so a disagreement
|
|
263
|
+
* all frozen from it, so a disagreement fails, never reconciled. */
|
|
196
264
|
adoptCompilerContext(compiler) {
|
|
197
265
|
const context = compiler.context;
|
|
198
266
|
if (!this.session.rootDir) {
|
|
199
267
|
this.session.rootDir = context;
|
|
200
268
|
return;
|
|
201
269
|
}
|
|
202
|
-
if (context && this.session.rootDir
|
|
203
|
-
this.warnedRootDivergence = true;
|
|
204
|
-
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`);
|
|
205
|
-
}
|
|
270
|
+
if (context && !sameDirectory(context, this.session.rootDir)) throw new 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.`);
|
|
206
271
|
}
|
|
207
272
|
get sessionDir() {
|
|
208
273
|
return this.session.sessionDir;
|
|
@@ -211,15 +276,20 @@ var AnimusWebpackPlugin = class {
|
|
|
211
276
|
return this.options;
|
|
212
277
|
}
|
|
213
278
|
getExternalPackageDirs() {
|
|
214
|
-
return this.session.externalPackageDirs.length > 0 ? this.session.externalPackageDirs : getSharedExternalDirs();
|
|
279
|
+
return this.session.externalPackageDirs.length > 0 ? this.session.externalPackageDirs : getSharedExternalDirs(this.session.key);
|
|
280
|
+
}
|
|
281
|
+
/** An import webpack resolved while bundling, with the resolve options of
|
|
282
|
+
* the rules its importer matches (spec §2.2 A4). */
|
|
283
|
+
reportHostResolution(importer, request, resolved) {
|
|
284
|
+
this.session.reportHostResolution(importer, request, resolved);
|
|
215
285
|
}
|
|
216
286
|
getExternalSourceEntries() {
|
|
217
|
-
return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceEntries : getSharedExternalEntries();
|
|
287
|
+
return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceEntries : getSharedExternalEntries(this.session.key);
|
|
218
288
|
}
|
|
219
289
|
/** The classification of the entries `getExternalSourceEntries` returns,
|
|
220
290
|
* from the same source. */
|
|
221
291
|
getExternalSourceSideEffects() {
|
|
222
|
-
return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceSideEffects : getSharedExternalSideEffects();
|
|
292
|
+
return this.session.externalSourceEntries.size > 0 ? this.session.externalSourceSideEffects : getSharedExternalSideEffects(this.session.key);
|
|
223
293
|
}
|
|
224
294
|
};
|
|
225
295
|
//#endregion
|
|
@@ -233,6 +303,7 @@ const PHASE_PRODUCTION_BUILD = "phase-production-build";
|
|
|
233
303
|
let warnedGitignore = false;
|
|
234
304
|
let warnedUnstableTurbopack = false;
|
|
235
305
|
function withAnimus(options) {
|
|
306
|
+
assertSupportedEngine(options.engine);
|
|
236
307
|
if (!options.system) throw new Error("[animus-extract] Missing required option `system`. Provide the path to your SystemInstance module: withAnimus({ system: \"./src/ds.ts\" })");
|
|
237
308
|
assertKnownOptionKeys({ ...options }, [
|
|
238
309
|
"cssImportTarget",
|
|
@@ -240,10 +311,7 @@ function withAnimus(options) {
|
|
|
240
311
|
"unstable_turbopack",
|
|
241
312
|
"loaderPath",
|
|
242
313
|
"phase"
|
|
243
|
-
], [{
|
|
244
|
-
key: "root",
|
|
245
|
-
reason: "this driver derives its own root — Next's `dir` under webpack, `process.cwd()` under Turbopack (Next passes no dir to a config module)"
|
|
246
|
-
}], {
|
|
314
|
+
], [], {
|
|
247
315
|
onUnknownKey: "warn",
|
|
248
316
|
warn: (message) => console.warn(`[animus-extract] ${message}`)
|
|
249
317
|
});
|
|
@@ -251,21 +319,31 @@ function withAnimus(options) {
|
|
|
251
319
|
warnedUnstableTurbopack = true;
|
|
252
320
|
console.warn("[animus-extract] `unstable_turbopack` is deprecated — rename it to `turbopack` (same shape)");
|
|
253
321
|
}
|
|
322
|
+
const build = createBuildId();
|
|
323
|
+
const appRoot = options.root === void 0 ? process.cwd() : resolve(options.root);
|
|
254
324
|
return (authoredConfig) => {
|
|
255
|
-
const nextConfig = withSourceKits(authoredConfig,
|
|
256
|
-
if (resolveTurbopackMode(options))
|
|
325
|
+
const nextConfig = withSourceKits(authoredConfig, appRoot);
|
|
326
|
+
if (resolveTurbopackMode(options)) {
|
|
327
|
+
warnTurbopackCwdRoot(options, appRoot);
|
|
328
|
+
return turbopackConfig(nextConfig, options, build, appRoot);
|
|
329
|
+
}
|
|
257
330
|
const existingWebpack = nextConfig.webpack;
|
|
258
331
|
return {
|
|
259
332
|
...nextConfig,
|
|
260
333
|
webpack(config, context) {
|
|
261
334
|
if (existingWebpack) config = existingWebpack(config, context);
|
|
262
|
-
|
|
335
|
+
if (context.dir?.length && !sameDirectory(context.dir, appRoot)) throw new 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.`);
|
|
336
|
+
const rootDir = appRoot;
|
|
263
337
|
const { mode } = resolveMode(options.mode, () => context.dev === true ? "development" : "production");
|
|
264
338
|
const plugin = new AnimusWebpackPlugin({
|
|
265
339
|
...options,
|
|
266
340
|
mode
|
|
267
|
-
}, {
|
|
341
|
+
}, {
|
|
342
|
+
development: context.dev === true,
|
|
343
|
+
build
|
|
344
|
+
});
|
|
268
345
|
plugin.setRootDir(rootDir);
|
|
346
|
+
if (nextConfig.distDir) plugin.excludeOutputDir(resolve(rootDir, nextConfig.distDir));
|
|
269
347
|
const sessionDir = plugin.sessionDir;
|
|
270
348
|
if (!existsSync(sessionDir)) mkdirSync(sessionDir, { recursive: true });
|
|
271
349
|
const stubCssPath = stylesPath(sessionDir);
|
|
@@ -310,6 +388,9 @@ function withAnimus(options) {
|
|
|
310
388
|
}
|
|
311
389
|
});
|
|
312
390
|
nmf.hooks.afterResolve.tap("AnimusVirtualResolve", (resolveData) => {
|
|
391
|
+
const issuer = resolveData.contextInfo?.issuer;
|
|
392
|
+
const resolved = resolveData.createData?.resource;
|
|
393
|
+
if (issuer && resolved !== void 0) plugin.reportHostResolution(issuer, resolveData.request, resolved);
|
|
313
394
|
const sideEffects = redirectSideEffects.get(resolveData);
|
|
314
395
|
const settings = resolveData.createData?.settings;
|
|
315
396
|
if (!settings) return;
|
|
@@ -335,9 +416,10 @@ function withAnimus(options) {
|
|
|
335
416
|
use: [{
|
|
336
417
|
loader: actualLoaderPath,
|
|
337
418
|
options: {
|
|
338
|
-
strict: options.strict,
|
|
339
419
|
development: context.dev === true,
|
|
340
|
-
cssImportTarget: options.cssImportTarget
|
|
420
|
+
cssImportTarget: options.cssImportTarget,
|
|
421
|
+
build,
|
|
422
|
+
root: rootDir
|
|
341
423
|
}
|
|
342
424
|
}]
|
|
343
425
|
});
|
|
@@ -358,17 +440,35 @@ function bindTurbopackWatchDeathReport(outcome, rootDir) {
|
|
|
358
440
|
* source, but Next's server keeps an installed package external, and so
|
|
359
441
|
* loads its runtime entry, unless the package is transpiled; transpiling
|
|
360
442
|
* also compiles its TypeScript source. */
|
|
443
|
+
let warnedTurbopackCwd = false;
|
|
444
|
+
/** Turbopack's loaders get no app dir either, so a cwd that is not the app
|
|
445
|
+
* cannot be detected later: warn at startup when the cwd holds no Next
|
|
446
|
+
* config and no `root` names the app. */
|
|
447
|
+
function warnTurbopackCwdRoot(options, appRoot) {
|
|
448
|
+
if (options.root !== void 0 || warnedTurbopackCwd) return;
|
|
449
|
+
if ([
|
|
450
|
+
"js",
|
|
451
|
+
"mjs",
|
|
452
|
+
"cjs",
|
|
453
|
+
"ts",
|
|
454
|
+
"mts"
|
|
455
|
+
].some((ext) => existsSync(join(appRoot, `next.config.${ext}`)))) return;
|
|
456
|
+
warnedTurbopackCwd = true;
|
|
457
|
+
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.`);
|
|
458
|
+
}
|
|
361
459
|
function withSourceKits(nextConfig, rootDir) {
|
|
362
460
|
const declared = nextConfig.transpilePackages ?? [];
|
|
363
|
-
const kits = sourceKitDependencies(rootDir).map((kit) => kit.name).filter((name) => !declared.includes(name));
|
|
461
|
+
const kits = sourceKitDependencies(rootDir, requireEngine()).map((kit) => kit.name).filter((name) => !declared.includes(name));
|
|
364
462
|
if (kits.length === 0) return nextConfig;
|
|
365
463
|
return {
|
|
366
464
|
...nextConfig,
|
|
367
465
|
transpilePackages: [...declared, ...kits]
|
|
368
466
|
};
|
|
369
467
|
}
|
|
370
|
-
function turbopackConfig(nextConfig, options) {
|
|
371
|
-
const
|
|
468
|
+
function turbopackConfig(nextConfig, options, build, appRoot) {
|
|
469
|
+
const resolveExtensions = nextConfig.turbopack?.resolveExtensions ?? nextConfig.experimental?.turbo?.resolveExtensions;
|
|
470
|
+
const outputExclude = nextConfig.distDir ? outputExclusion(appRoot, resolve(appRoot, nextConfig.distDir)) : null;
|
|
471
|
+
const load = (phase) => loadTurbopackFragment(options, phase, resolveExtensions, outputExclude, nextConfig.images?.disableStaticImages === true, build, appRoot).then((fragment) => mergeTurbopackFragment(nextConfig, fragment));
|
|
372
472
|
function then(onResolved, onRejected) {
|
|
373
473
|
const phase = options.phase ?? (isTurbopackDevelopment() ? PHASE_DEVELOPMENT_SERVER : PHASE_PRODUCTION_BUILD);
|
|
374
474
|
return load(phase).then(onResolved, onRejected);
|
|
@@ -377,49 +477,67 @@ function turbopackConfig(nextConfig, options) {
|
|
|
377
477
|
Object.defineProperty(config, "then", { enumerable: false });
|
|
378
478
|
return config;
|
|
379
479
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
480
|
+
/** Each wrapper's owner, by the build it created: another wrapper of the
|
|
481
|
+
* same root is another build and never shares or closes this one's. */
|
|
482
|
+
const turbopackOwners = /* @__PURE__ */ new Map();
|
|
483
|
+
function turbopackOwner(build) {
|
|
484
|
+
let owner = turbopackOwners.get(build);
|
|
485
|
+
if (owner === void 0) {
|
|
486
|
+
owner = {
|
|
487
|
+
session: null,
|
|
488
|
+
watcher: null,
|
|
489
|
+
load: null
|
|
490
|
+
};
|
|
491
|
+
turbopackOwners.set(build, owner);
|
|
492
|
+
}
|
|
493
|
+
return owner;
|
|
494
|
+
}
|
|
495
|
+
function loadTurbopackFragment(options, phase, resolveExtensions, outputExclude, disableStaticImages, build, rootDir) {
|
|
496
|
+
const key = JSON.stringify([
|
|
497
|
+
phase,
|
|
498
|
+
rootDir,
|
|
499
|
+
resolveExtensions ?? null,
|
|
500
|
+
disableStaticImages
|
|
501
|
+
]);
|
|
502
|
+
const owner = turbopackOwner(build);
|
|
503
|
+
if (owner.load?.key === key) return owner.load.fragment;
|
|
504
|
+
const fragment = analyzeForTurbopack(options, phase, rootDir, resolveExtensions, outputExclude, disableStaticImages, build);
|
|
392
505
|
const load = {
|
|
393
506
|
key,
|
|
394
507
|
fragment
|
|
395
508
|
};
|
|
396
|
-
|
|
509
|
+
owner.load = load;
|
|
397
510
|
fragment.catch(() => {
|
|
398
|
-
if (
|
|
511
|
+
if (owner.load === load) owner.load = null;
|
|
399
512
|
});
|
|
400
513
|
return fragment;
|
|
401
514
|
}
|
|
402
|
-
async function analyzeForTurbopack(options, phase, rootDir) {
|
|
515
|
+
async function analyzeForTurbopack(options, phase, rootDir, resolveExtensions, outputExclude, disableStaticImages, build) {
|
|
403
516
|
const development = phase === PHASE_DEVELOPMENT_SERVER;
|
|
404
517
|
const { mode } = resolveMode(options.mode, () => development ? "development" : "production");
|
|
405
518
|
const session = new ExtractionSession({
|
|
406
519
|
...options,
|
|
407
520
|
mode
|
|
408
|
-
}, {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
521
|
+
}, {
|
|
522
|
+
unbundledComputedImports: true,
|
|
523
|
+
build: `${build}-${phase}`
|
|
524
|
+
});
|
|
525
|
+
const owner = turbopackOwner(build);
|
|
526
|
+
owner.session?.close();
|
|
527
|
+
owner.watcher?.close();
|
|
528
|
+
owner.watcher = null;
|
|
529
|
+
owner.session = session;
|
|
413
530
|
session.development = development;
|
|
414
531
|
session.rootDir = rootDir;
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
532
|
+
if (outputExclude !== null) session.structuralExclude = [outputExclude];
|
|
533
|
+
session.extensionPolicy = turbopackExtensionPolicy(resolveExtensions);
|
|
534
|
+
session.assetClassification = nextImageAssetClassification(rootDir, disableStaticImages);
|
|
535
|
+
session.aliasesFromTsconfig = true;
|
|
418
536
|
await runSessionPipeline(session);
|
|
419
|
-
if (development &&
|
|
537
|
+
if (development && owner.session === session) {
|
|
420
538
|
const outcome = startTurbopackWatcher(session, rootDir);
|
|
421
539
|
bindTurbopackWatchDeathReport(outcome, rootDir);
|
|
422
|
-
if (outcome.kind === "started")
|
|
540
|
+
if (outcome.kind === "started") owner.watcher = outcome.handle;
|
|
423
541
|
}
|
|
424
542
|
for (const line of turbopackSideEffectsLimits(rootDir, session.externalSourceEntries, session.externalSourceSideEffects)) console.warn(line);
|
|
425
543
|
return buildTurbopackConfig({
|
|
@@ -61,12 +61,26 @@ function extensionLineage(files, analyzedHashes) {
|
|
|
61
61
|
const lineage = files.map((file) => `${file}\0${analyzedHashes?.get(file) ?? ""}`).join("\0");
|
|
62
62
|
return `\nvoid "animus-lineage:${(0, _animus_ui_extract_pipeline.contentHash)(lineage)}";\n`;
|
|
63
63
|
}
|
|
64
|
+
let parsedManifest = null;
|
|
65
|
+
/** What a manifest's transform serves, parsed once per manifest: every
|
|
66
|
+
* module of a compilation reads the same one. */
|
|
67
|
+
function manifestServedFiles(manifestJson) {
|
|
68
|
+
if (parsedManifest?.json !== manifestJson) parsedManifest = {
|
|
69
|
+
json: manifestJson,
|
|
70
|
+
served: (0, _animus_ui_extract_pipeline.servedFiles)(JSON.parse(manifestJson))
|
|
71
|
+
};
|
|
72
|
+
return parsedManifest.served;
|
|
73
|
+
}
|
|
64
74
|
function transformWithManifest(args) {
|
|
65
75
|
const { source, filename, manifestJson, engineApi, opts } = args;
|
|
66
76
|
const isRootEntry = isCssImportTarget(filename, opts.cssImportTarget);
|
|
67
77
|
try {
|
|
68
78
|
const { transformFile } = engineApi();
|
|
69
79
|
const result = transformFile(source, filename, manifestJson);
|
|
80
|
+
const served = manifestServedFiles(manifestJson);
|
|
81
|
+
const drop = served.dropped.get(filename);
|
|
82
|
+
if (drop !== void 0) throw new Error((0, _animus_ui_extract_pipeline.droppedExtensionMessage)(drop));
|
|
83
|
+
if (!result.hasComponents && served.listed.has(filename)) throw new Error(`the analysis extracted components from ${filename}, but its transform found none`);
|
|
70
84
|
let code = result.hasComponents ? result.code : source;
|
|
71
85
|
code = code.replace(CSS_IMPORT_RE, "");
|
|
72
86
|
if (isRootEntry && !code.includes(_animus_ui_extract_session.ANIMUS_CSS_MODULE_ID)) {
|
|
@@ -79,10 +93,7 @@ function transformWithManifest(args) {
|
|
|
79
93
|
return code;
|
|
80
94
|
} catch (e) {
|
|
81
95
|
const msg = e instanceof Error ? e.message : String(e);
|
|
82
|
-
|
|
83
|
-
if (opts.strict) console.error(`[animus-extract] Transform failed for ${filename}: ${msg}`);
|
|
84
|
-
else console.warn(`[animus-extract] Transform failed for ${filename}:`, msg);
|
|
85
|
-
return source;
|
|
96
|
+
throw new Error(`[animus-extract] Transform failed for ${filename}: ${msg}`, { cause: e });
|
|
86
97
|
}
|
|
87
98
|
}
|
|
88
99
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { contentHash } from "@animus-ui/extract/pipeline";
|
|
1
|
+
import { contentHash, droppedExtensionMessage, servedFiles } from "@animus-ui/extract/pipeline";
|
|
2
2
|
import { ANIMUS_CSS_MODULE_ID } from "@animus-ui/extract/session";
|
|
3
3
|
//#region src/loader-core.ts
|
|
4
4
|
/** Matches every already-emitted stylesheet import — arbitrary relative
|
|
@@ -61,12 +61,26 @@ function extensionLineage(files, analyzedHashes) {
|
|
|
61
61
|
const lineage = files.map((file) => `${file}\0${analyzedHashes?.get(file) ?? ""}`).join("\0");
|
|
62
62
|
return `\nvoid "animus-lineage:${contentHash(lineage)}";\n`;
|
|
63
63
|
}
|
|
64
|
+
let parsedManifest = null;
|
|
65
|
+
/** What a manifest's transform serves, parsed once per manifest: every
|
|
66
|
+
* module of a compilation reads the same one. */
|
|
67
|
+
function manifestServedFiles(manifestJson) {
|
|
68
|
+
if (parsedManifest?.json !== manifestJson) parsedManifest = {
|
|
69
|
+
json: manifestJson,
|
|
70
|
+
served: servedFiles(JSON.parse(manifestJson))
|
|
71
|
+
};
|
|
72
|
+
return parsedManifest.served;
|
|
73
|
+
}
|
|
64
74
|
function transformWithManifest(args) {
|
|
65
75
|
const { source, filename, manifestJson, engineApi, opts } = args;
|
|
66
76
|
const isRootEntry = isCssImportTarget(filename, opts.cssImportTarget);
|
|
67
77
|
try {
|
|
68
78
|
const { transformFile } = engineApi();
|
|
69
79
|
const result = transformFile(source, filename, manifestJson);
|
|
80
|
+
const served = manifestServedFiles(manifestJson);
|
|
81
|
+
const drop = served.dropped.get(filename);
|
|
82
|
+
if (drop !== void 0) throw new Error(droppedExtensionMessage(drop));
|
|
83
|
+
if (!result.hasComponents && served.listed.has(filename)) throw new Error(`the analysis extracted components from ${filename}, but its transform found none`);
|
|
70
84
|
let code = result.hasComponents ? result.code : source;
|
|
71
85
|
code = code.replace(CSS_IMPORT_RE, "");
|
|
72
86
|
if (isRootEntry && !code.includes(ANIMUS_CSS_MODULE_ID)) {
|
|
@@ -79,10 +93,7 @@ function transformWithManifest(args) {
|
|
|
79
93
|
return code;
|
|
80
94
|
} catch (e) {
|
|
81
95
|
const msg = e instanceof Error ? e.message : String(e);
|
|
82
|
-
|
|
83
|
-
if (opts.strict) console.error(`[animus-extract] Transform failed for ${filename}: ${msg}`);
|
|
84
|
-
else console.warn(`[animus-extract] Transform failed for ${filename}:`, msg);
|
|
85
|
-
return source;
|
|
96
|
+
throw new Error(`[animus-extract] Transform failed for ${filename}: ${msg}`, { cause: e });
|
|
86
97
|
}
|
|
87
98
|
}
|
|
88
99
|
//#endregion
|
package/dist/loader-core.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
export interface LoaderPolicyOptions {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
2
|
+
/** `next dev`: the Turbopack loader waits for and re-delivers the dev
|
|
3
|
+
* watcher's generations. A transform failure fails the module in every
|
|
4
|
+
* mode (SA1). */
|
|
5
5
|
development?: boolean;
|
|
6
6
|
cssImportTarget?: string;
|
|
7
|
+
/** The build the config wrapper created, which the loader reads the
|
|
8
|
+
* analysis of. */
|
|
9
|
+
build?: string;
|
|
10
|
+
/** The root that build's plugin analyses. */
|
|
11
|
+
root?: string;
|
|
7
12
|
}
|
|
8
13
|
export interface LoaderContextBase<O extends LoaderPolicyOptions = LoaderPolicyOptions> {
|
|
9
14
|
resourcePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-core.d.ts","sourceRoot":"","sources":["../src/loader-core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader-core.d.ts","sourceRoot":"","sources":["../src/loader-core.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,mBAAmB;IAClC;;sBAEkB;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;uBACmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,mBAAmB,GAAG,mBAAmB;IAEnD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AA0DD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,SAAS,MAAM,EAAE,CAKnB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAC7D,MAAM,CAMR;AAiBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IAErB,SAAS,EAAE,MAAM,GAAG,CAAC;IACrB,IAAI,EAAE,mBAAmB,CAAC;CAC3B,GAAG,MAAM,CAiDT"}
|
package/dist/loader.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_loader_core = require("./loader-core-
|
|
1
|
+
const require_loader_core = require("./loader-core-Bz52QNm3.cjs");
|
|
2
2
|
let _animus_ui_extract_pipeline = require("@animus-ui/extract/pipeline");
|
|
3
3
|
let _animus_ui_extract_session = require("@animus-ui/extract/session");
|
|
4
4
|
let fs = require("fs");
|
|
@@ -6,8 +6,11 @@ let path = require("path");
|
|
|
6
6
|
//#region src/loader.ts
|
|
7
7
|
const epochSeenForSessionDir = /* @__PURE__ */ new Set();
|
|
8
8
|
function animusLoader(source) {
|
|
9
|
+
const opts = this.getOptions?.() ?? {};
|
|
10
|
+
if (opts.build === void 0) throw new _animus_ui_extract_pipeline.AnimusConfigError(`[animus-extract] the Animus loader for ${(0, path.relative)(this.rootContext, this.resourcePath)} names no Animus build; it runs only as withAnimus() configures it.`);
|
|
11
|
+
const key = (0, _animus_ui_extract_session.sessionKey)(opts.build, opts.root ?? this.rootContext);
|
|
9
12
|
if (this.addDependency !== void 0) {
|
|
10
|
-
const sessionDir = (0, _animus_ui_extract_session.getSessionArtifactDir)();
|
|
13
|
+
const sessionDir = (0, _animus_ui_extract_session.getSessionArtifactDir)(key);
|
|
11
14
|
if (sessionDir) {
|
|
12
15
|
const epochPath = (0, _animus_ui_extract_session.replacementEpochPath)(sessionDir);
|
|
13
16
|
if (epochSeenForSessionDir.has(sessionDir) || (0, fs.existsSync)(epochPath)) {
|
|
@@ -16,29 +19,29 @@ function animusLoader(source) {
|
|
|
16
19
|
}
|
|
17
20
|
}
|
|
18
21
|
}
|
|
19
|
-
let manifestJson = (0, _animus_ui_extract_session.getManifestJson)();
|
|
20
|
-
if (!manifestJson)
|
|
22
|
+
let manifestJson = (0, _animus_ui_extract_session.getManifestJson)(key);
|
|
23
|
+
if (!manifestJson) throw new Error(`[animus-extract] no analysis is available to transform ${(0, path.relative)(this.rootContext, this.resourcePath)}: the project analysis failed; see the error above.`);
|
|
21
24
|
const filename = (0, path.relative)(this.rootContext, this.resourcePath);
|
|
22
|
-
const analyzedHash = (0, _animus_ui_extract_session.getAnalyzedHashes)()?.get(filename);
|
|
25
|
+
const analyzedHash = (0, _animus_ui_extract_session.getAnalyzedHashes)(key)?.get(filename);
|
|
23
26
|
if (analyzedHash !== void 0) {
|
|
24
27
|
const sourceHash = (0, _animus_ui_extract_pipeline.contentHash)(source);
|
|
25
28
|
if (sourceHash !== analyzedHash) {
|
|
26
|
-
const refreshedHash = (0, _animus_ui_extract_session.getAnalyzedHashes)()?.get(filename);
|
|
29
|
+
const refreshedHash = (0, _animus_ui_extract_session.getAnalyzedHashes)(key)?.get(filename);
|
|
27
30
|
if (refreshedHash === void 0 || sourceHash !== refreshedHash) throw new Error(`ANIMUS_ANALYSIS_CATCHING_UP: ${filename} changed after the current analysis; retrying on the next watch turn`);
|
|
28
|
-
manifestJson = (0, _animus_ui_extract_session.getManifestJson)() ?? manifestJson;
|
|
31
|
+
manifestJson = (0, _animus_ui_extract_session.getManifestJson)(key) ?? manifestJson;
|
|
29
32
|
}
|
|
30
33
|
}
|
|
31
34
|
const code = require_loader_core.transformWithManifest({
|
|
32
35
|
source,
|
|
33
36
|
filename,
|
|
34
37
|
manifestJson,
|
|
35
|
-
engineApi: _animus_ui_extract_session.engineApi,
|
|
36
|
-
opts
|
|
38
|
+
engineApi: () => (0, _animus_ui_extract_session.engineApi)(key),
|
|
39
|
+
opts
|
|
37
40
|
});
|
|
38
41
|
if (!(this.mode !== "production") || this.addDependency === void 0) return code;
|
|
39
42
|
const extended = require_loader_core.extendedFiles(manifestJson, filename);
|
|
40
43
|
for (const file of extended) this.addDependency((0, path.join)(this.rootContext, file));
|
|
41
|
-
return code + require_loader_core.extensionLineage(extended, (0, _animus_ui_extract_session.getAnalyzedHashes)());
|
|
44
|
+
return code + require_loader_core.extensionLineage(extended, (0, _animus_ui_extract_session.getAnalyzedHashes)(key));
|
|
42
45
|
}
|
|
43
46
|
//#endregion
|
|
44
47
|
module.exports = animusLoader;
|
package/dist/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIvD,KAAK,aAAa,GAAG,iBAAiB,GAAG;IACvC,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,GAAG,MAAM,CAAC;CAC9C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CAuER"}
|