@animus-ui/next-plugin 0.1.31 → 0.1.32

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
@@ -10,11 +10,11 @@ let url = require("url");
10
10
  * trailing slash, a symlink and the filesystem's own spelling, else by
11
11
  * device and inode. */
12
12
  function sameDirectory(a, b) {
13
- const real = (path$5) => {
13
+ const real = (path$11) => {
14
14
  try {
15
- return fs.realpathSync.native(path$5);
15
+ return fs.realpathSync.native(path$11);
16
16
  } catch {
17
- return (0, path.resolve)(path$5);
17
+ return (0, path.resolve)(path$11);
18
18
  }
19
19
  };
20
20
  if (real(a) === real(b)) return true;
@@ -27,11 +27,97 @@ function sameDirectory(a, b) {
27
27
  }
28
28
  }
29
29
  //#endregion
30
- //#region src/plugin.ts
30
+ //#region src/watch-ignored.ts
31
+ /**
32
+ * webpack's `watchOptions.ignored`, read as Watchpack reads it, so Animus can
33
+ * wrap it: its own epoch file stays ignored, and the files and directories it
34
+ * registers are watched whatever the host ignores (Next ignores every
35
+ * `node_modules` path, where an installed source kit lives).
36
+ */
31
37
  /** The value arrives from a consumer's `next.config`, so the union above is a
32
38
  * model of what webpack accepts, not a proof about the value in hand. */
33
39
  const isWatchIgnoreString = (ignored) => Object.prototype.toString.call(ignored) === "[object String]";
34
40
  const isWatchIgnoreMatcher = (ignored) => Object.prototype.toString.call(ignored) === "[object Function]";
41
+ /** A glob as Watchpack compiles it (`glob-to-regexp` with `globstar` and
42
+ * `extended`, then matching the path or anything under it). */
43
+ function globSource(glob) {
44
+ let source = "";
45
+ let inGroup = false;
46
+ for (let index = 0; index < glob.length; index++) {
47
+ const char = glob[index];
48
+ switch (char) {
49
+ case "/":
50
+ case "$":
51
+ case "^":
52
+ case "+":
53
+ case ".":
54
+ case "(":
55
+ case ")":
56
+ case "=":
57
+ case "!":
58
+ case "|":
59
+ source += `\\${char}`;
60
+ break;
61
+ case "?":
62
+ source += ".";
63
+ break;
64
+ case "{":
65
+ inGroup = true;
66
+ source += "(";
67
+ break;
68
+ case "}":
69
+ inGroup = false;
70
+ source += ")";
71
+ break;
72
+ case ",":
73
+ source += inGroup ? "|" : "\\,";
74
+ break;
75
+ case "*": {
76
+ const before = glob[index - 1];
77
+ let stars = 1;
78
+ while (glob[index + 1] === "*") {
79
+ stars += 1;
80
+ index += 1;
81
+ }
82
+ const after = glob[index + 1];
83
+ if (stars > 1 && (before === "/" || before === void 0) && (after === "/" || after === void 0)) {
84
+ source += "((?:[^/]*(?:/|$))*)";
85
+ index += 1;
86
+ } else source += "([^/]*)";
87
+ break;
88
+ }
89
+ default: source += char;
90
+ }
91
+ }
92
+ return `^${source}(?:$|\\/)`;
93
+ }
94
+ /** What `ignored` ignores, as Watchpack decides it; nothing when unset. */
95
+ function ignoredMatcher(ignored) {
96
+ const slashed = (path$5) => path$5.replace(/\\/g, "/");
97
+ if (ignored === void 0 || ignored === null) return () => false;
98
+ if (isWatchIgnoreMatcher(ignored)) return (path$6) => Boolean(ignored(path$6));
99
+ if (ignored instanceof RegExp) return (path$7) => ignored.test(slashed(path$7));
100
+ const sources = (isWatchIgnoreString(ignored) ? [ignored] : ignored).map((entry) => entry instanceof RegExp ? entry.source : entry.length > 0 ? globSource(entry) : null).filter((source) => source !== null);
101
+ if (sources.length === 0) return () => false;
102
+ const pattern = new RegExp(sources.join("|"));
103
+ return (path$8) => pattern.test(slashed(path$8));
104
+ }
105
+ /** Windows paths compare without case, as `path.win32.relative` does. */
106
+ const comparable = process.platform === "win32" ? (path$9) => path$9.toLowerCase() : (path$10) => path$10;
107
+ /** Whether a path is one of `directories` or lies under one where a kit's
108
+ * sources can live: never in the kit's own `node_modules` or another path
109
+ * ingestion excludes, which stay as the host decides. A prefix test:
110
+ * webpack's watcher asks for every path it watches. */
111
+ function withinDirectories(directories) {
112
+ const prefixes = directories.map((dir) => comparable(dir.endsWith(path.sep) ? dir : dir + path.sep)).sort((a, b) => b.length - a.length);
113
+ return (path$4) => {
114
+ const key = comparable(path$4) + path.sep;
115
+ const prefix = prefixes.find((candidate) => key.startsWith(candidate));
116
+ return prefix !== void 0 && !(0, _animus_ui_extract_pipeline.isExcludedPackageRelativePath)(key.slice(prefix.length));
117
+ };
118
+ }
119
+ //#endregion
120
+ //#region src/plugin.ts
35
121
  const UNSUPPORTED_WEBPACK_MESSAGE = "[animus-extract] Unsupported webpack: NormalModule.getCompilationHooks(compilation).needBuild is required for dev transform coherence and this webpack does not expose it. Use a Next.js version whose webpack exposes this hook.";
36
122
  const PLUGIN_NAME = "AnimusWebpackPlugin";
37
123
  var AnimusWebpackPlugin = class {
@@ -48,6 +134,14 @@ var AnimusWebpackPlugin = class {
48
134
  /** This turn's rejected analysis. A rejection must fail the compilation,
49
135
  * never `watchRun`: webpack stops watching after a failed `watchRun`. */
50
136
  watchFailure = null;
137
+ /** What the Session's watch plan last registered: `watchIgnored` never
138
+ * ignores it. */
139
+ registered = {
140
+ files: /* @__PURE__ */ new Set(),
141
+ directories: () => false
142
+ };
143
+ /** The webpack config Next hands its watcher, when withAnimus made it. */
144
+ watchedConfig;
51
145
  /** `development` is `next dev`: an error-level diagnostic reports and the
52
146
  * compilation keeps publishing, whatever the emission mode. */
53
147
  constructor(options, { development = false, build } = {}) {
@@ -67,19 +161,34 @@ var AnimusWebpackPlugin = class {
67
161
  if (!Array.isArray(loaders)) return false;
68
162
  return loaders.some((entry) => entry?.loader !== void 0 && this.animusLoaderPaths.has(entry.loader));
69
163
  }
70
- appendEpochWatchIgnore(compiler) {
71
- const options = compiler.options;
72
- if (!options) return;
73
- const epochPath = (0, _animus_ui_extract_session.replacementEpochPath)((0, _animus_ui_extract_session.sessionArtifactDir)(this.session.rootDir ?? compiler.context, this.session.sessionId));
74
- options.watchOptions ??= {};
75
- const watchOptions = options.watchOptions;
76
- const ignored = watchOptions.ignored;
77
- if (ignored === void 0 || ignored === null) watchOptions.ignored = [epochPath];
78
- else if (Array.isArray(ignored)) {
79
- if (!ignored.includes(epochPath)) ignored.push(epochPath);
80
- } else if (isWatchIgnoreString(ignored)) watchOptions.ignored = [ignored, epochPath];
81
- else if (ignored instanceof RegExp) watchOptions.ignored = (path$1) => path$1 === epochPath || ignored.test(path$1);
82
- else if (isWatchIgnoreMatcher(ignored)) watchOptions.ignored = (path$2) => path$2 === epochPath || Boolean(ignored(path$2));
164
+ /** The webpack config whose watch options the host's watcher reads,
165
+ * rewritten when the plugin is applied. */
166
+ watchConfig(config) {
167
+ this.watchedConfig = config;
168
+ }
169
+ /**
170
+ * `watchOptions.ignored` for the host's own `ignored`: this session's epoch
171
+ * file stays ignored, and every file and directory the Session's watch plan
172
+ * registers is watched, whatever the host ignores. Next ignores every
173
+ * `node_modules` path, where an installed source kit and its system live.
174
+ */
175
+ watchIgnored(ignored, context) {
176
+ const hostIgnores = ignoredMatcher(ignored);
177
+ let epochRoot;
178
+ let epochPath;
179
+ const epoch = () => {
180
+ const root = this.session.rootDir ?? context;
181
+ if (root !== epochRoot) {
182
+ epochRoot = root;
183
+ epochPath = root === void 0 ? void 0 : (0, _animus_ui_extract_session.replacementEpochPath)((0, _animus_ui_extract_session.sessionArtifactDir)(root, this.session.sessionId));
184
+ }
185
+ return epochPath;
186
+ };
187
+ return (path$1) => {
188
+ if (path$1 === epoch()) return true;
189
+ if (this.registered.files.has(path$1) || this.registered.directories(path$1)) return false;
190
+ return hostIgnores(path$1);
191
+ };
83
192
  }
84
193
  /** Webpack's export conditions select the system's kit files as they
85
194
  * select the bundle's; `...`, webpack's own defaults, names none. Its
@@ -127,7 +236,15 @@ var AnimusWebpackPlugin = class {
127
236
  if (compiler.options?.name === "edge-server") return;
128
237
  const NormalModule = compiler.webpack?.NormalModule;
129
238
  if (NormalModule?.getCompilationHooks === void 0) throw new Error(UNSUPPORTED_WEBPACK_MESSAGE);
130
- this.appendEpochWatchIgnore(compiler);
239
+ const options = compiler.options;
240
+ if (options) {
241
+ options.watchOptions ??= {};
242
+ options.watchOptions.ignored = this.watchIgnored(options.watchOptions.ignored, compiler.context);
243
+ }
244
+ if (this.watchedConfig) this.watchedConfig.watchOptions = {
245
+ ...this.watchedConfig.watchOptions,
246
+ ignored: this.watchIgnored(this.watchedConfig.watchOptions?.ignored, compiler.context)
247
+ };
131
248
  compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
132
249
  const epochMoved = this.epochMovedForNextCompilation;
133
250
  this.epochMovedForNextCompilation = false;
@@ -145,9 +262,13 @@ var AnimusWebpackPlugin = class {
145
262
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
146
263
  const registerSystemDependencies = () => {
147
264
  const plan = this.session.watchPlan();
148
- for (const path$3 of plan.files) if ((0, fs.existsSync)(path$3)) compilation.fileDependencies.add(path$3);
149
- else compilation.missingDependencies.add(path$3);
150
- for (const path$4 of plan.missing) compilation.missingDependencies.add(path$4);
265
+ this.registered = {
266
+ files: /* @__PURE__ */ new Set([...plan.files, ...plan.missing]),
267
+ directories: withinDirectories(plan.directories)
268
+ };
269
+ for (const path$2 of plan.files) if ((0, fs.existsSync)(path$2)) compilation.fileDependencies.add(path$2);
270
+ else compilation.missingDependencies.add(path$2);
271
+ for (const path$3 of plan.missing) compilation.missingDependencies.add(path$3);
151
272
  for (const root of plan.directories) compilation.contextDependencies.add(root);
152
273
  };
153
274
  registerSystemDependencies();
@@ -371,6 +492,7 @@ function withAnimus(options) {
371
492
  const isExternalPackageFile = (filePath) => plugin.getExternalPackageDirs().some((dir) => (0, _animus_ui_extract_pipeline.isPathWithinRoot)(dir, filePath));
372
493
  config.plugins = config.plugins || [];
373
494
  config.plugins.push(plugin);
495
+ plugin.watchConfig(config);
374
496
  const DefinePlugin = context.webpack?.DefinePlugin;
375
497
  if (DefinePlugin) config.plugins.push(new DefinePlugin({ __ANIMUS_DEV__: JSON.stringify(mode === "development") }));
376
498
  config.resolve = config.resolve || {};
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
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";
2
+ import { AnimusConfigError, assembleStylesheet, assertKnownOptionKeys, assertSupportedEngine, buildPathAliasesJson, builtInAssetClassification, isEngineTransformExtension, isExcludedPackageRelativePath, isPathWithinRoot, keepsKitSourceEffects, nextImageAssetClassification, outputExclusion, resolveMode, sourceKitDependencies, turbopackExtensionPolicy, webpackExtensionPolicy } from "@animus-ui/extract/pipeline";
3
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
4
  import { existsSync, mkdirSync, readFileSync, realpathSync, statSync, writeFileSync } from "fs";
5
- import { dirname, join, resolve } from "path";
5
+ import { dirname, join, resolve, sep } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  //#region src/same-directory.ts
8
8
  /** Whether two paths name one directory: by real path, which resolves a
@@ -26,11 +26,97 @@ function sameDirectory(a, b) {
26
26
  }
27
27
  }
28
28
  //#endregion
29
- //#region src/plugin.ts
29
+ //#region src/watch-ignored.ts
30
+ /**
31
+ * webpack's `watchOptions.ignored`, read as Watchpack reads it, so Animus can
32
+ * wrap it: its own epoch file stays ignored, and the files and directories it
33
+ * registers are watched whatever the host ignores (Next ignores every
34
+ * `node_modules` path, where an installed source kit lives).
35
+ */
30
36
  /** The value arrives from a consumer's `next.config`, so the union above is a
31
37
  * model of what webpack accepts, not a proof about the value in hand. */
32
38
  const isWatchIgnoreString = (ignored) => Object.prototype.toString.call(ignored) === "[object String]";
33
39
  const isWatchIgnoreMatcher = (ignored) => Object.prototype.toString.call(ignored) === "[object Function]";
40
+ /** A glob as Watchpack compiles it (`glob-to-regexp` with `globstar` and
41
+ * `extended`, then matching the path or anything under it). */
42
+ function globSource(glob) {
43
+ let source = "";
44
+ let inGroup = false;
45
+ for (let index = 0; index < glob.length; index++) {
46
+ const char = glob[index];
47
+ switch (char) {
48
+ case "/":
49
+ case "$":
50
+ case "^":
51
+ case "+":
52
+ case ".":
53
+ case "(":
54
+ case ")":
55
+ case "=":
56
+ case "!":
57
+ case "|":
58
+ source += `\\${char}`;
59
+ break;
60
+ case "?":
61
+ source += ".";
62
+ break;
63
+ case "{":
64
+ inGroup = true;
65
+ source += "(";
66
+ break;
67
+ case "}":
68
+ inGroup = false;
69
+ source += ")";
70
+ break;
71
+ case ",":
72
+ source += inGroup ? "|" : "\\,";
73
+ break;
74
+ case "*": {
75
+ const before = glob[index - 1];
76
+ let stars = 1;
77
+ while (glob[index + 1] === "*") {
78
+ stars += 1;
79
+ index += 1;
80
+ }
81
+ const after = glob[index + 1];
82
+ if (stars > 1 && (before === "/" || before === void 0) && (after === "/" || after === void 0)) {
83
+ source += "((?:[^/]*(?:/|$))*)";
84
+ index += 1;
85
+ } else source += "([^/]*)";
86
+ break;
87
+ }
88
+ default: source += char;
89
+ }
90
+ }
91
+ return `^${source}(?:$|\\/)`;
92
+ }
93
+ /** What `ignored` ignores, as Watchpack decides it; nothing when unset. */
94
+ function ignoredMatcher(ignored) {
95
+ const slashed = (path) => path.replace(/\\/g, "/");
96
+ if (ignored === void 0 || ignored === null) return () => false;
97
+ if (isWatchIgnoreMatcher(ignored)) return (path) => Boolean(ignored(path));
98
+ if (ignored instanceof RegExp) return (path) => ignored.test(slashed(path));
99
+ const sources = (isWatchIgnoreString(ignored) ? [ignored] : ignored).map((entry) => entry instanceof RegExp ? entry.source : entry.length > 0 ? globSource(entry) : null).filter((source) => source !== null);
100
+ if (sources.length === 0) return () => false;
101
+ const pattern = new RegExp(sources.join("|"));
102
+ return (path) => pattern.test(slashed(path));
103
+ }
104
+ /** Windows paths compare without case, as `path.win32.relative` does. */
105
+ const comparable = process.platform === "win32" ? (path) => path.toLowerCase() : (path) => path;
106
+ /** Whether a path is one of `directories` or lies under one where a kit's
107
+ * sources can live: never in the kit's own `node_modules` or another path
108
+ * ingestion excludes, which stay as the host decides. A prefix test:
109
+ * webpack's watcher asks for every path it watches. */
110
+ function withinDirectories(directories) {
111
+ const prefixes = directories.map((dir) => comparable(dir.endsWith(sep) ? dir : dir + sep)).sort((a, b) => b.length - a.length);
112
+ return (path) => {
113
+ const key = comparable(path) + sep;
114
+ const prefix = prefixes.find((candidate) => key.startsWith(candidate));
115
+ return prefix !== void 0 && !isExcludedPackageRelativePath(key.slice(prefix.length));
116
+ };
117
+ }
118
+ //#endregion
119
+ //#region src/plugin.ts
34
120
  const UNSUPPORTED_WEBPACK_MESSAGE = "[animus-extract] Unsupported webpack: NormalModule.getCompilationHooks(compilation).needBuild is required for dev transform coherence and this webpack does not expose it. Use a Next.js version whose webpack exposes this hook.";
35
121
  const PLUGIN_NAME = "AnimusWebpackPlugin";
36
122
  var AnimusWebpackPlugin = class {
@@ -47,6 +133,14 @@ var AnimusWebpackPlugin = class {
47
133
  /** This turn's rejected analysis. A rejection must fail the compilation,
48
134
  * never `watchRun`: webpack stops watching after a failed `watchRun`. */
49
135
  watchFailure = null;
136
+ /** What the Session's watch plan last registered: `watchIgnored` never
137
+ * ignores it. */
138
+ registered = {
139
+ files: /* @__PURE__ */ new Set(),
140
+ directories: () => false
141
+ };
142
+ /** The webpack config Next hands its watcher, when withAnimus made it. */
143
+ watchedConfig;
50
144
  /** `development` is `next dev`: an error-level diagnostic reports and the
51
145
  * compilation keeps publishing, whatever the emission mode. */
52
146
  constructor(options, { development = false, build } = {}) {
@@ -66,19 +160,34 @@ var AnimusWebpackPlugin = class {
66
160
  if (!Array.isArray(loaders)) return false;
67
161
  return loaders.some((entry) => entry?.loader !== void 0 && this.animusLoaderPaths.has(entry.loader));
68
162
  }
69
- appendEpochWatchIgnore(compiler) {
70
- const options = compiler.options;
71
- if (!options) return;
72
- const epochPath = replacementEpochPath(sessionArtifactDir(this.session.rootDir ?? compiler.context, this.session.sessionId));
73
- options.watchOptions ??= {};
74
- const watchOptions = options.watchOptions;
75
- const ignored = watchOptions.ignored;
76
- if (ignored === void 0 || ignored === null) watchOptions.ignored = [epochPath];
77
- else if (Array.isArray(ignored)) {
78
- if (!ignored.includes(epochPath)) ignored.push(epochPath);
79
- } else if (isWatchIgnoreString(ignored)) watchOptions.ignored = [ignored, epochPath];
80
- else if (ignored instanceof RegExp) watchOptions.ignored = (path) => path === epochPath || ignored.test(path);
81
- else if (isWatchIgnoreMatcher(ignored)) watchOptions.ignored = (path) => path === epochPath || Boolean(ignored(path));
163
+ /** The webpack config whose watch options the host's watcher reads,
164
+ * rewritten when the plugin is applied. */
165
+ watchConfig(config) {
166
+ this.watchedConfig = config;
167
+ }
168
+ /**
169
+ * `watchOptions.ignored` for the host's own `ignored`: this session's epoch
170
+ * file stays ignored, and every file and directory the Session's watch plan
171
+ * registers is watched, whatever the host ignores. Next ignores every
172
+ * `node_modules` path, where an installed source kit and its system live.
173
+ */
174
+ watchIgnored(ignored, context) {
175
+ const hostIgnores = ignoredMatcher(ignored);
176
+ let epochRoot;
177
+ let epochPath;
178
+ const epoch = () => {
179
+ const root = this.session.rootDir ?? context;
180
+ if (root !== epochRoot) {
181
+ epochRoot = root;
182
+ epochPath = root === void 0 ? void 0 : replacementEpochPath(sessionArtifactDir(root, this.session.sessionId));
183
+ }
184
+ return epochPath;
185
+ };
186
+ return (path) => {
187
+ if (path === epoch()) return true;
188
+ if (this.registered.files.has(path) || this.registered.directories(path)) return false;
189
+ return hostIgnores(path);
190
+ };
82
191
  }
83
192
  /** Webpack's export conditions select the system's kit files as they
84
193
  * select the bundle's; `...`, webpack's own defaults, names none. Its
@@ -126,7 +235,15 @@ var AnimusWebpackPlugin = class {
126
235
  if (compiler.options?.name === "edge-server") return;
127
236
  const NormalModule = compiler.webpack?.NormalModule;
128
237
  if (NormalModule?.getCompilationHooks === void 0) throw new Error(UNSUPPORTED_WEBPACK_MESSAGE);
129
- this.appendEpochWatchIgnore(compiler);
238
+ const options = compiler.options;
239
+ if (options) {
240
+ options.watchOptions ??= {};
241
+ options.watchOptions.ignored = this.watchIgnored(options.watchOptions.ignored, compiler.context);
242
+ }
243
+ if (this.watchedConfig) this.watchedConfig.watchOptions = {
244
+ ...this.watchedConfig.watchOptions,
245
+ ignored: this.watchIgnored(this.watchedConfig.watchOptions?.ignored, compiler.context)
246
+ };
130
247
  compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
131
248
  const epochMoved = this.epochMovedForNextCompilation;
132
249
  this.epochMovedForNextCompilation = false;
@@ -144,6 +261,10 @@ var AnimusWebpackPlugin = class {
144
261
  compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
145
262
  const registerSystemDependencies = () => {
146
263
  const plan = this.session.watchPlan();
264
+ this.registered = {
265
+ files: /* @__PURE__ */ new Set([...plan.files, ...plan.missing]),
266
+ directories: withinDirectories(plan.directories)
267
+ };
147
268
  for (const path of plan.files) if (existsSync(path)) compilation.fileDependencies.add(path);
148
269
  else compilation.missingDependencies.add(path);
149
270
  for (const path of plan.missing) compilation.missingDependencies.add(path);
@@ -370,6 +491,7 @@ function withAnimus(options) {
370
491
  const isExternalPackageFile = (filePath) => plugin.getExternalPackageDirs().some((dir) => isPathWithinRoot(dir, filePath));
371
492
  config.plugins = config.plugins || [];
372
493
  config.plugins.push(plugin);
494
+ plugin.watchConfig(config);
373
495
  const DefinePlugin = context.webpack?.DefinePlugin;
374
496
  if (DefinePlugin) config.plugins.push(new DefinePlugin({ __ANIMUS_DEV__: JSON.stringify(mode === "development") }));
375
497
  config.resolve = config.resolve || {};
package/dist/plugin.d.ts CHANGED
@@ -1,12 +1,10 @@
1
1
  import type { AnimusNextOptions } from './types';
2
+ import type { WatchIgnored, WatchIgnoreMatcher, WatchOptions } from './watch-ignored';
2
3
  export { ANIMUS_CSS_MODULE_ID } from '@animus-ui/extract/session';
3
4
  type WebpackSource = {
4
5
  source(): string | Buffer;
5
6
  size(): number;
6
7
  };
7
- type WatchIgnoreEntry = string | RegExp;
8
- type WatchIgnoreMatcher = (path: string) => boolean;
9
- type WatchIgnored = WatchIgnoreEntry | WatchIgnoreEntry[] | WatchIgnoreMatcher | null | undefined;
10
8
  type WebpackAliasMap = Record<string, string | string[] | false>;
11
9
  type Compilation = {
12
10
  hooks: {
@@ -95,9 +93,7 @@ type Compiler = {
95
93
  extensionAlias?: Record<string, string | string[]>;
96
94
  } | undefined>;
97
95
  };
98
- watchOptions?: {
99
- ignored?: WatchIgnored;
100
- };
96
+ watchOptions?: WatchOptions;
101
97
  };
102
98
  webpack?: {
103
99
  version?: string;
@@ -128,6 +124,11 @@ export declare class AnimusWebpackPlugin {
128
124
  /** This turn's rejected analysis. A rejection must fail the compilation,
129
125
  * never `watchRun`: webpack stops watching after a failed `watchRun`. */
130
126
  private watchFailure;
127
+ /** What the Session's watch plan last registered: `watchIgnored` never
128
+ * ignores it. */
129
+ private registered;
130
+ /** The webpack config Next hands its watcher, when withAnimus made it. */
131
+ private watchedConfig;
131
132
  /** `development` is `next dev`: an error-level diagnostic reports and the
132
133
  * compilation keeps publishing, whatever the emission mode. */
133
134
  constructor(options: AnimusNextOptions, { development, build, }?: {
@@ -135,7 +136,18 @@ export declare class AnimusWebpackPlugin {
135
136
  build?: string;
136
137
  });
137
138
  private moduleUsesAnimusLoader;
138
- private appendEpochWatchIgnore;
139
+ /** The webpack config whose watch options the host's watcher reads,
140
+ * rewritten when the plugin is applied. */
141
+ watchConfig(config: {
142
+ watchOptions?: WatchOptions;
143
+ }): void;
144
+ /**
145
+ * `watchOptions.ignored` for the host's own `ignored`: this session's epoch
146
+ * file stays ignored, and every file and directory the Session's watch plan
147
+ * registers is watched, whatever the host ignores. Next ignores every
148
+ * `node_modules` path, where an installed source kit and its system live.
149
+ */
150
+ watchIgnored(ignored: WatchIgnored, context?: string): WatchIgnoreMatcher;
139
151
  /** Webpack's export conditions select the system's kit files as they
140
152
  * select the bundle's; `...`, webpack's own defaults, names none. Its
141
153
  * extension order and aliases are captured alongside. */
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -2,6 +2,11 @@ import type { ClosedDynamicImport, DiagnosticLevels, StaticCssConfig } from '@an
2
2
  export interface AnimusNextOptions {
3
3
  /** Path to a module exporting a SystemInstance from `@animus-ui/system`. */
4
4
  system: string;
5
+ /** The system's export name in the `system` module. The loader runs only
6
+ * what that export reaches, and finds it itself when exactly one export
7
+ * is a sealed system (`.seal()`) and every other export is plainly not
8
+ * one; otherwise it asks for this option by name. */
9
+ systemExport?: string;
5
10
  /** The app's directory, for a `next` run from another directory. Next
6
11
  * passes no dir to a config module, so the app's root is the current
7
12
  * directory without it. Its source kits and analysis read this root; under
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;;;;;6CAKyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;+EAC2E;IAC3E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;mDAG+C;IAC/C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;mDAI+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B;0EACsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B;;sDAEkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;gBAEY;IACZ,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;yEACqE;IACrE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;mDAC+C;IAC/C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;wDACoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;yEACqE;IACrE,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC;gFAC4E;IAC5E,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;qEACiE;IACjE,SAAS,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAAA;KAAE,CAAC;IAC7C;;;;sBAIkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;sCACkC;IAClC,kBAAkB,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACtD;qEACiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;+EAC2E;IAC3E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;sEAEkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;4EAEwE;IACxE,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC9C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,gBAAgB,EAChB,eAAe,EAChB,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;;;0DAGsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;6CAKyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;+EAC2E;IAC3E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;mDAG+C;IAC/C,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;mDAI+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B;0EACsE;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B;;sDAEkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;gBAEY;IACZ,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;yEACqE;IACrE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;mDAC+C;IAC/C,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B;wDACoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;yEACqE;IACrE,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC;gFAC4E;IAC5E,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;qEACiE;IACjE,SAAS,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAAA;KAAE,CAAC;IAC7C;;;;sBAIkB;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;sCACkC;IAClC,kBAAkB,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACtD;qEACiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;+EAC2E;IAC3E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;sEAEkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;4EAEwE;IACxE,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC9C"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * webpack's `watchOptions.ignored`, read as Watchpack reads it, so Animus can
3
+ * wrap it: its own epoch file stays ignored, and the files and directories it
4
+ * registers are watched whatever the host ignores (Next ignores every
5
+ * `node_modules` path, where an installed source kit lives).
6
+ */
7
+ export type WatchIgnoreEntry = string | RegExp;
8
+ export type WatchIgnoreMatcher = (path: string) => boolean;
9
+ export type WatchIgnored = WatchIgnoreEntry | WatchIgnoreEntry[] | WatchIgnoreMatcher | null | undefined;
10
+ /** A webpack config's watch options, as far as Animus reads them. */
11
+ export interface WatchOptions {
12
+ ignored?: WatchIgnored;
13
+ }
14
+ /** What `ignored` ignores, as Watchpack decides it; nothing when unset. */
15
+ export declare function ignoredMatcher(ignored: WatchIgnored): WatchIgnoreMatcher;
16
+ /** Whether a path is one of `directories` or lies under one where a kit's
17
+ * sources can live: never in the kit's own `node_modules` or another path
18
+ * ingestion excludes, which stay as the host decides. A prefix test:
19
+ * webpack's watcher asks for every path it watches. */
20
+ export declare function withinDirectories(directories: readonly string[]): (path: string) => boolean;
21
+ //# sourceMappingURL=watch-ignored.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-ignored.d.ts","sourceRoot":"","sources":["../src/watch-ignored.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;AAE3D,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,gBAAgB,EAAE,GAClB,kBAAkB,GAClB,IAAI,GACJ,SAAS,CAAC;AAEd,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAyED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,kBAAkB,CAkBxE;AAQD;;;wDAGwD;AACxD,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAc3B"}
@@ -1,4 +1,5 @@
1
1
  import type { AnimusNextOptions } from './types';
2
+ import type { WatchOptions } from './watch-ignored';
2
3
  import type { TurbopackWatchOutcome } from '@animus-ui/extract/session';
3
4
  import type { NextConfig as NextOwnedConfig, TurbopackOptions } from 'next/dist/server/config-shared';
4
5
  type WebpackPluginEntry = object | false | null | undefined;
@@ -14,6 +15,8 @@ interface WebpackRule {
14
15
  }
15
16
  interface WebpackConfig {
16
17
  plugins?: WebpackPluginEntry[];
18
+ /** Next's watcher reads these, not the compiler's normalized copy. */
19
+ watchOptions?: WatchOptions;
17
20
  resolve?: {
18
21
  alias?: Record<string, string>;
19
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"with-animus.d.ts","sourceRoot":"","sources":["../src/with-animus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"with-animus.d.ts","sourceRoot":"","sources":["../src/with-animus.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAEV,qBAAqB,EACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,UAAU,IAAI,eAAe,EAC7B,gBAAgB,EACjB,MAAM,gCAAgC,CAAC;AAKxC,KAAK,kBAAkB,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AAE5D,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAED,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAC1B;AAED,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC/B,sEAAsE;IACtE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,OAAO,CAAC,EAAE;QACR,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;KACvB,CAAC;CACH;AAED,KAAK,uBAAuB,GAAG,KAC7B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAChC,MAAM,CAAC;AAEZ,UAAU,kBAAkB;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE;QACR,YAAY,CAAC,EAAE,uBAAuB,CAAC;KACxC,CAAC;CACH;AAED,KAAK,eAAe,GAAG,CACrB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,kBAAkB,KACxB,aAAa,CAAC;AAEnB,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B;iEAC6D;IAC7D,YAAY,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE;YAAE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAA;KAAE,CAAC;CAC7D;AAED,KAAK,kBAAkB,GAAG,CACxB,GAAG,IAAI,EAAE,KAAK,EAAE,KACb,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAIhD,YAAY,EAAE,kBAAkB,IAAI,wBAAwB,EAAE,CAAC;AAE/D,MAAM,MAAM,eAAe,CAAC,MAAM,SAAS,eAAe,IACxD,MAAM,SAAS,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,kBAAkB,CAAC;AAE1E,MAAM,MAAM,iBAAiB,CAAC,MAAM,SAAS,eAAe,IAAI,IAAI,CAClE,MAAM,EACN,SAAS,CACV,GAAG;IACF,OAAO,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,yBAAyB,CAAC,MAAM,SAAS,eAAe,IAAI,IAAI,CAC1E,MAAM,EACN,WAAW,CACZ,GAAG;IACF,SAAS,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAEF;;;;4DAI4D;AAC5D,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,eAAe,IAAI,CAAC,CACjE,KAAK,EAAE,MAAM,KACV,OAAO,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC,GAC9C,WAAW,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC;AAUjD,wBAAgB,UAAU,CACxB,OAAO,EAAE,iBAAiB,GACzB,CAAC,MAAM,SAAS,eAAe,EAChC,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,KAChC,iBAAiB,CAAC,MAAM,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAyR3D;AASD,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,MAAM,GACd,IAAI,CASN"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animus-ui/next-plugin",
3
- "version": "0.1.31",
3
+ "version": "0.1.32",
4
4
  "description": "Animus static CSS extraction for Next.js (webpack)",
5
5
  "keywords": [
6
6
  "animus",
@@ -40,10 +40,10 @@
40
40
  "compile": "bun check"
41
41
  },
42
42
  "dependencies": {
43
- "@animus-ui/extract": "0.1.31"
43
+ "@animus-ui/extract": "0.1.32"
44
44
  },
45
45
  "devDependencies": {
46
- "@animus-ui/assertions": "0.1.31"
46
+ "@animus-ui/assertions": "0.1.32"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "next": ">=15 <17",