@animus-ui/next-plugin 0.1.1-beta.2 → 0.1.2
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/README.md +83 -4
- package/dist/chunk-y_GBKt04.mjs +5 -0
- package/dist/extraction-session.d.ts +138 -0
- package/dist/extraction-session.d.ts.map +1 -0
- package/dist/index.cjs +762 -541
- package/dist/index.mjs +762 -540
- package/dist/loader-core-CbaYNhBu.cjs +71 -0
- package/dist/loader-core-D6Tm_b8F.mjs +66 -0
- package/dist/loader-core.d.ts +26 -0
- package/dist/loader-core.d.ts.map +1 -0
- package/dist/loader.cjs +12 -43
- package/dist/loader.d.ts +5 -9
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.mjs +12 -43
- package/dist/plugin.d.ts +24 -42
- package/dist/plugin.d.ts.map +1 -1
- package/dist/resolve-packages.d.ts +8 -0
- package/dist/resolve-packages.d.ts.map +1 -0
- package/dist/singleton-BKALu7Mk.mjs +108 -0
- package/dist/{singleton-CttvA4Rg.cjs → singleton-DH7yeWZa.cjs} +29 -60
- package/dist/singleton.d.ts +1 -8
- package/dist/singleton.d.ts.map +1 -1
- package/dist/timing.d.ts +7 -0
- package/dist/timing.d.ts.map +1 -0
- package/dist/turbopack-config.d.ts +55 -0
- package/dist/turbopack-config.d.ts.map +1 -0
- package/dist/turbopack-loader.cjs +90 -0
- package/dist/turbopack-loader.d.ts +16 -0
- package/dist/turbopack-loader.d.ts.map +1 -0
- package/dist/turbopack-loader.mjs +91 -0
- package/dist/turbopack-orchestrator.d.ts +31 -0
- package/dist/turbopack-orchestrator.d.ts.map +1 -0
- package/dist/types.d.ts +67 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/with-animus.d.ts +1 -1
- package/dist/with-animus.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/analyze-project-args.d.ts +0 -33
- package/dist/analyze-project-args.d.ts.map +0 -1
- package/dist/manifest-diagnostics.d.ts +0 -10
- package/dist/manifest-diagnostics.d.ts.map +0 -1
- package/dist/singleton-CmwFBCJ5.mjs +0 -136
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @animus-ui/next-plugin
|
|
2
2
|
|
|
3
|
-
Static CSS extraction for Next.js. Wraps `next.config` to integrate the Animus extraction pipeline
|
|
3
|
+
Static CSS extraction for Next.js (15 and 16). Wraps `next.config` to integrate the Animus extraction pipeline — webpack and Turbopack.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -18,15 +18,94 @@ const nextConfig = {
|
|
|
18
18
|
// your existing Next.js config
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
export default withAnimus(
|
|
21
|
+
export default withAnimus({
|
|
22
22
|
system: './src/ds.ts',
|
|
23
|
-
});
|
|
23
|
+
})(nextConfig);
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
## Turbopack
|
|
27
|
+
|
|
28
|
+
Turbopack support activates automatically whenever the process runs under
|
|
29
|
+
Turbopack (`next dev --turbopack`, or Next 16 where Turbopack is the
|
|
30
|
+
default) — no config change needed. Extraction runs while `next.config`
|
|
31
|
+
resolves, a watcher re-analyzes on source changes in dev, and per-file
|
|
32
|
+
transforms run in a stateless loader fed by generated `.animus/` artifacts.
|
|
33
|
+
tsconfig `paths` aliases are honored.
|
|
34
|
+
|
|
35
|
+
Control it explicitly with the `turbopack` option:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
export default withAnimus({
|
|
39
|
+
system: './src/ds.ts',
|
|
40
|
+
turbopack: { mode: 'auto' }, // 'auto' (default) | 'on' | 'off'
|
|
41
|
+
})(nextConfig);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Under webpack (`next dev` / `next build` on 15, or `--webpack` on 16) the
|
|
45
|
+
plugin behaves exactly as before.
|
|
46
|
+
|
|
47
|
+
## Appearance bootstrap (no-FOUC color mode)
|
|
48
|
+
|
|
49
|
+
Optional. Restores a persisted color mode before first paint with zero runtime
|
|
50
|
+
— a generated, dependency-free inline snippet whose CSP hash is computed at
|
|
51
|
+
build time from the exact bytes generated.
|
|
52
|
+
|
|
53
|
+
The plugin deliberately injects nothing: CSP nonces need request-time control
|
|
54
|
+
the bundler does not have, so the **application** places the artifact. Generate
|
|
55
|
+
it in a server-only module and inline it as the first child of `<head>`.
|
|
56
|
+
|
|
57
|
+
**App Router:**
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
// appearance-bootstrap.ts — server-only; never import from a client component
|
|
61
|
+
import { createAppearanceBootstrap } from '@animus-ui/system/bootstrap';
|
|
62
|
+
|
|
63
|
+
import { tokens } from './src/ds';
|
|
64
|
+
|
|
65
|
+
export const appearanceBootstrap = createAppearanceBootstrap(tokens);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
// app/layout.tsx
|
|
70
|
+
import { appearanceBootstrap } from '../appearance-bootstrap';
|
|
71
|
+
|
|
72
|
+
export default function RootLayout({
|
|
73
|
+
children,
|
|
74
|
+
}: {
|
|
75
|
+
children: React.ReactNode;
|
|
76
|
+
}) {
|
|
77
|
+
return (
|
|
78
|
+
<html lang="en" suppressHydrationWarning>
|
|
79
|
+
<head>
|
|
80
|
+
<script
|
|
81
|
+
data-animus-bootstrap=""
|
|
82
|
+
dangerouslySetInnerHTML={{ __html: appearanceBootstrap.code }}
|
|
83
|
+
/>
|
|
84
|
+
</head>
|
|
85
|
+
<body>{children}</body>
|
|
86
|
+
</html>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Pages Router:** same artifact, placed as the first child of `<Head>` in
|
|
92
|
+
`pages/_document.tsx`, with `suppressHydrationWarning` on `<Html>`.
|
|
93
|
+
|
|
94
|
+
Two rules either way:
|
|
95
|
+
|
|
96
|
+
- `suppressHydrationWarning` on the root element is required, not cosmetic —
|
|
97
|
+
the snippet legitimately mutates `data-color-mode` between SSR and hydration.
|
|
98
|
+
- Serve a CSP that authorizes the script from the artifact itself: either
|
|
99
|
+
`script-src '<artifact.cspHash>'` (single-quoted, derived at build time —
|
|
100
|
+
never hand-copied; a renamed mode changes the hash) or a per-request nonce
|
|
101
|
+
you add to the script tag. The full CSP footguns are documented in the
|
|
102
|
+
[`@animus-ui/vite-plugin` README](https://github.com/codecaaron/animus/tree/main/packages/vite-plugin#content-security-policy).
|
|
103
|
+
|
|
26
104
|
## What It Does
|
|
27
105
|
|
|
28
|
-
-
|
|
106
|
+
- Transforms `@animus-ui/system` builder chains into static CSS (webpack loader or Turbopack loader rule)
|
|
29
107
|
- Emits extracted CSS as a separate asset with `@layer` ordering
|
|
108
|
+
- Post-processes the emitted sheet with Lightning CSS — autoprefixed for your `targets` (browserslist query; defaults to the project config), minified in production (`minify` overrides)
|
|
30
109
|
- Works with both App Router and Pages Router
|
|
31
110
|
- Supports RSC — no runtime style injection means server components work out of the box
|
|
32
111
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { AnimusNextOptions } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Module id the Rust emitter injects for the extracted stylesheet — also the
|
|
4
|
+
* exact resolve.alias key with-animus registers for it, which the adapter's
|
|
5
|
+
* alias harvesting must skip.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ANIMUS_CSS_MODULE_ID = ".animus/styles.css";
|
|
8
|
+
/** Watch-cycle change sets, as reported by the bundler's watcher. */
|
|
9
|
+
export interface WatchChanges {
|
|
10
|
+
modifiedFiles?: ReadonlySet<string>;
|
|
11
|
+
removedFiles?: ReadonlySet<string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Bundler-agnostic extraction pipeline: system loading, source discovery
|
|
15
|
+
* and ingestion, external-package collection, analysis, stylesheet and
|
|
16
|
+
* system-props emission, and watch-cycle diffing.
|
|
17
|
+
*
|
|
18
|
+
* The webpack adapter (plugin.ts) owns only bundler wiring: hook
|
|
19
|
+
* registration, alias harvesting from the compiler config, in-memory asset
|
|
20
|
+
* replacement, and translating watch events into `handleWatchUpdate`
|
|
21
|
+
* change sets. Keeping this class free of webpack types is deliberate — a
|
|
22
|
+
* future Turbopack integration must drive the same session from outside
|
|
23
|
+
* the bundler (Turbopack has no compiler-hook surface), reusing everything
|
|
24
|
+
* here unchanged.
|
|
25
|
+
*
|
|
26
|
+
* Outputs are published through the package singleton (shared CSS,
|
|
27
|
+
* manifest, system props) and written to `.animus/` on disk.
|
|
28
|
+
*/
|
|
29
|
+
export declare class ExtractionSession {
|
|
30
|
+
/** Set by the adapter before any pipeline run. */
|
|
31
|
+
rootDir: string | null;
|
|
32
|
+
/** Serialized path aliases, harvested by the adapter from bundler config. */
|
|
33
|
+
pathAliasesJson: string | null;
|
|
34
|
+
/** When set (Turbopack orchestration), every analysis also persists
|
|
35
|
+
* `.animus/analysis-inputs.json` so isolated loader workers can hydrate.
|
|
36
|
+
* Webpack mode leaves this off — its loader shares the process. */
|
|
37
|
+
persistAnalysisInputs: boolean;
|
|
38
|
+
/** Emitter identity override for the system-props module id. Webpack mode
|
|
39
|
+
* (null) injects the absolute `.animus/system-props.js` path, resolved by
|
|
40
|
+
* NormalModuleReplacement; Turbopack rejects absolute-path imports, so
|
|
41
|
+
* its driver sets the virtual id that `resolveAlias` maps to disk. */
|
|
42
|
+
systemPropsModuleId: string | null;
|
|
43
|
+
/** Absolute directory prefixes for external DS packages (loader allowlisting). */
|
|
44
|
+
externalPackageDirs: string[];
|
|
45
|
+
/** External package specifier → absolute source entry path. */
|
|
46
|
+
externalSourceEntries: Map<string, string>;
|
|
47
|
+
private readonly options;
|
|
48
|
+
private readonly staticCssJson;
|
|
49
|
+
private system;
|
|
50
|
+
/** Full package-resolution map from the last full pipeline — replayed by
|
|
51
|
+
* incremental passes (sourceEntries alone omits dist-resolved packages). */
|
|
52
|
+
private lastPackageMap;
|
|
53
|
+
private fileCache;
|
|
54
|
+
private systemDependencyKeys;
|
|
55
|
+
/** Loader-reported dependency paths for bundler watch registration. */
|
|
56
|
+
systemDependencyPaths: string[];
|
|
57
|
+
private systemDependencyHashes;
|
|
58
|
+
private lastCssHash;
|
|
59
|
+
private lastSystemPropsHash;
|
|
60
|
+
private lastManifestHash;
|
|
61
|
+
private lastAnalysisInputsHash;
|
|
62
|
+
private lcssTargets;
|
|
63
|
+
constructor(options: AnimusNextOptions);
|
|
64
|
+
get verbose(): boolean;
|
|
65
|
+
private log;
|
|
66
|
+
private warn;
|
|
67
|
+
private now;
|
|
68
|
+
private elapsed;
|
|
69
|
+
/** Resolve the scan configuration from options — the single source of the
|
|
70
|
+
* exclude/extension policy shared by the full and incremental pipelines. */
|
|
71
|
+
private resolveScanConfig;
|
|
72
|
+
/**
|
|
73
|
+
* Incremental watch pass: geological reset when the system file changed,
|
|
74
|
+
* otherwise content-hash diffing restricted to the watcher's change sets
|
|
75
|
+
* (falling back to a full discovery walk when no sets are provided).
|
|
76
|
+
*/
|
|
77
|
+
handleWatchUpdate(changes: WatchChanges): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Preprocess one `.mdx` entry into scanner-consumable tsx. Returns the
|
|
80
|
+
* rewritten source plus the `relPath + '.tsx'` path on success, or null
|
|
81
|
+
* when the file must be skipped.
|
|
82
|
+
*
|
|
83
|
+
* `warn: false` (incremental watch pass) skips silently — the full
|
|
84
|
+
* pipeline already surfaced the warning. `warn: true` (full pipeline)
|
|
85
|
+
* warns ONCE for a missing @mdx-js/mdx dependency via the shared
|
|
86
|
+
* `missingDepFlag` holder, and every time for a preprocessing error.
|
|
87
|
+
*/
|
|
88
|
+
private preprocessMdxEntry;
|
|
89
|
+
runFullPipeline(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Reset analysis state for HMR geological reset.
|
|
92
|
+
*/
|
|
93
|
+
resetForHmr(): void;
|
|
94
|
+
/**
|
|
95
|
+
* Build file entries from cache: every cached file rides with full source.
|
|
96
|
+
* The v2 engine has NO Rust-side cache (extract-v2-spine DEF-7: uncached
|
|
97
|
+
* re-analysis beats a cache-hit path), so it must always receive full sources
|
|
98
|
+
* (openspec: retire-extract-v1 removed the v1 empty-source cache contract).
|
|
99
|
+
*/
|
|
100
|
+
private buildFileEntriesFromCache;
|
|
101
|
+
/**
|
|
102
|
+
* Run incremental pipeline with cache-aware file entries.
|
|
103
|
+
* Reuses system config from the last full pipeline run.
|
|
104
|
+
*/
|
|
105
|
+
private runIncrementalPipeline;
|
|
106
|
+
/**
|
|
107
|
+
* Shared analysis + emit core for both pipelines — the single call site
|
|
108
|
+
* that routes every manifest through the shared `runProjectAnalysis`,
|
|
109
|
+
* reachable from both runFullPipeline (production) and
|
|
110
|
+
* runIncrementalPipeline (HMR).
|
|
111
|
+
*
|
|
112
|
+
* Owns diagnostic surfacing, CSS assembly + styles.css write guard,
|
|
113
|
+
* system-props module emit, and the timing log. The `devMode` flag is the
|
|
114
|
+
* ONLY behavioral fork:
|
|
115
|
+
*
|
|
116
|
+
* - `false` (production): computes bt.analysis + logs the extraction
|
|
117
|
+
* report, and writes system-props.js UNCONDITIONALLY (no
|
|
118
|
+
* lastSystemPropsHash guard).
|
|
119
|
+
* - `true` (HMR): skips the report log, and guards the system-props.js
|
|
120
|
+
* write by lastSystemPropsHash.
|
|
121
|
+
*
|
|
122
|
+
* The styles.css write guard (lastCssHash) is identical on both paths.
|
|
123
|
+
*/
|
|
124
|
+
private analyzeAndEmit;
|
|
125
|
+
/** Content hash of an existing `.animus/` artifact, or null when absent or
|
|
126
|
+
* unreadable. Seeds a null write guard so a FRESH session never rewrites a
|
|
127
|
+
* byte-identical artifact (spec: next-turbopack-integration — a rewrite
|
|
128
|
+
* changes mtime/inode and needlessly re-keys Turbopack loader-worker
|
|
129
|
+
* hydration). */
|
|
130
|
+
private diskArtifactHash;
|
|
131
|
+
/** Ensure `.animus/` exists and write one generated artifact into it.
|
|
132
|
+
* Write-then-rename so cross-process readers (Turbopack loader workers)
|
|
133
|
+
* can never observe a torn half-written file. The tmp name carries the
|
|
134
|
+
* pid — Next dev evaluates the config in more than one process, and two
|
|
135
|
+
* sessions writing the same artifact must not race on one tmp path. */
|
|
136
|
+
private writeAnimusFile;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=extraction-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extraction-session.d.ts","sourceRoot":"","sources":["../src/extraction-session.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAOjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAczD,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,iBAAiB;IAC5B,kDAAkD;IAClD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC9B,6EAA6E;IAC7E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtC;;wEAEoE;IACpE,qBAAqB,UAAS;IAC9B;;;2EAGuE;IACvE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1C,kFAAkF;IAClF,mBAAmB,EAAE,MAAM,EAAE,CAAM;IACnC,+DAA+D;IAC/D,qBAAqB,sBAA6B;IAElD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,OAAO,CAAC,MAAM,CAA6B;IAC3C;iFAC6E;IAC7E,OAAO,CAAC,cAAc,CAA8B;IAGpD,OAAO,CAAC,SAAS,CAAuD;IAMxE,OAAO,CAAC,oBAAoB,CAA0B;IAEtD,uEAAuE;IACvE,qBAAqB,EAAE,MAAM,EAAE,CAAM;IAKrC,OAAO,CAAC,sBAAsB,CAAkC;IAChE,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,sBAAsB,CAAuB;IAGrD,OAAO,CAAC,WAAW,CAAiC;IAEpD,YAAY,OAAO,EAAE,iBAAiB,EAKrC;IAED,IAAI,OAAO,IAAI,OAAO,CAMrB;IAED,OAAO,CAAC,GAAG;IAMX,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,GAAG;IAGX,OAAO,CAAC,OAAO;IAIf;iFAC6E;IAC7E,OAAO,CAAC,iBAAiB;IAezB;;;;OAIG;IACG,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0I5D;IAED;;;;;;;;;OASG;YACW,kBAAkB;IA2B1B,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAmJrC;IAED;;OAEG;IACH,WAAW,IAAI,IAAI,CAOlB;IAED;;;;;OAKG;IACH,OAAO,CAAC,yBAAyB;IAQjC;;;OAGG;YACW,sBAAsB;IAmBpC;;;;;;;;;;;;;;;;;OAiBG;YACW,cAAc;IAmJ5B;;;;sBAIkB;IAClB,OAAO,CAAC,gBAAgB;IAUxB;;;;4EAIwE;IACxE,OAAO,CAAC,eAAe;CASxB"}
|