@animus-ui/next-plugin 0.1.6 → 0.1.8

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.
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Session-scoped artifact names, path derivations, and the analysis-status
3
+ * shape (openspec: next-turbopack-served-transform-coherence, design D1–D3)
4
+ * — shared by the session writer (extraction-session), the webpack
5
+ * plugin/loader, and the Turbopack loader.
6
+ *
7
+ * Deliberately free of singleton/session imports: the Turbopack loader
8
+ * executes in isolated worker processes and its module graph must stay
9
+ * worker-local (guardrail G1) — this module is pure path/shape vocabulary.
10
+ */
11
+ /** Session-dir-relative name of the replacement-epoch disk witness
12
+ * (openspec: next-webpack-served-transform-coherence, design D2;
13
+ * session-scoped by next-turbopack-served-transform-coherence D2). */
14
+ export declare const REPLACEMENT_EPOCH_ARTIFACT = "replacements-epoch";
15
+ /** Session-dir-relative name of the analysis-commit transaction artifact
16
+ * (design D1). */
17
+ export declare const ANALYSIS_COMMIT_ARTIFACT = "analysis-commit";
18
+ /** Session-dir-relative name of the analysis-status artifact (design D3). */
19
+ export declare const ANALYSIS_STATUS_ARTIFACT = "analysis-status.json";
20
+ /** Session-dir-relative name of the manifest payload artifact. */
21
+ export declare const MANIFEST_ARTIFACT = "manifest.json";
22
+ /** Session-dir-relative name of the analysis-inputs payload artifact
23
+ * (Turbopack loader-worker hydration corpus). */
24
+ export declare const ANALYSIS_INPUTS_ARTIFACT = "analysis-inputs.json";
25
+ /** Session-dir-relative name of the emitted stylesheet artifact. */
26
+ export declare const STYLES_ARTIFACT = "styles.css";
27
+ /** Session-dir-relative name of the emitted system-props module. */
28
+ export declare const SYSTEM_PROPS_ARTIFACT = "system-props.js";
29
+ /** Session-dir-relative directory holding copied asset() files. */
30
+ export declare const SESSION_ASSETS_DIR = "assets";
31
+ /** Root of every session-scoped artifact tree for a project. */
32
+ export declare function sessionsRootDir(rootDir: string): string;
33
+ /** One session's artifact directory (design D2: session-scoped trees,
34
+ * no global pointer). */
35
+ export declare function sessionArtifactDir(rootDir: string, sessionId: string): string;
36
+ /** Absolute path of a session's replacement-epoch artifact — the single
37
+ * derivation shared by the session writer, the webpack plugin's
38
+ * watch-ignore entry, and both loaders' file dependencies. Takes the
39
+ * SESSION directory (not the project root) since the artifact was
40
+ * relocated into the session tree. */
41
+ export declare function replacementEpochPath(sessionDir: string): string;
42
+ /** Absolute path of a session's analysis-commit artifact. */
43
+ export declare function analysisCommitPath(sessionDir: string): string;
44
+ /** Absolute path of a session's analysis-status artifact. */
45
+ export declare function analysisStatusPath(sessionDir: string): string;
46
+ /** Absolute path of a session's manifest artifact. */
47
+ export declare function manifestPath(sessionDir: string): string;
48
+ /** Absolute path of a session's analysis-inputs artifact. */
49
+ export declare function analysisInputsPath(sessionDir: string): string;
50
+ /** Absolute path of a session's stylesheet artifact. */
51
+ export declare function stylesPath(sessionDir: string): string;
52
+ /** Absolute path of a session's system-props module artifact. */
53
+ export declare function systemPropsPath(sessionDir: string): string;
54
+ /** Session-scoped analysis-status shape (design D3). Successful loader
55
+ * invocations never depend on it; it exists so a loader observing a
56
+ * source/commit mismatch can decide — on evidence — whether to wait. */
57
+ export interface AnalysisStatus {
58
+ schema: 1;
59
+ sessionId: string;
60
+ attemptId: number;
61
+ state: 'starting' | 'debouncing' | 'analyzing' | 'committing' | 'idle' | 'failed';
62
+ /** [(rootDir-relative sourceKey, observed content hash)] of the batch. */
63
+ pending: Array<[string, string]>;
64
+ /** Epoch-ms deadline for the active attempt (debounce ceiling + 2s). */
65
+ deadlineAt: number;
66
+ diagnostic?: string;
67
+ }
68
+ /** analysis-commit artifact shape (design D1: the transaction identity —
69
+ * hashes are of the DISK payload bytes, envelope included). `inputsHash`
70
+ * is present only when the hydration corpus is persisted (Turbopack
71
+ * orchestration); webpack-mode commits omit it (spec:
72
+ * next-turbopack-integration, "Webpack mode skips the hydration corpus"). */
73
+ export interface AnalysisCommit {
74
+ schema: 1;
75
+ sessionId: string;
76
+ generation: number;
77
+ replacementEpoch: string;
78
+ manifestHash: string;
79
+ inputsHash?: string;
80
+ stylesHash: string;
81
+ }
82
+ /** Envelope embedded in every payload artifact (design D2: sessionId in
83
+ * every artifact; payloadHash lets a same-session restart seed its write
84
+ * guards without byte-reconstructing the payload). */
85
+ export interface SessionEnvelope {
86
+ sessionId: string;
87
+ generation: number;
88
+ replacementEpoch: string;
89
+ payloadHash: string;
90
+ }
91
+ /** Splice the session envelope into a JSON-object payload as a leading
92
+ * `__animusSession` field, byte-preserving the payload's own content
93
+ * (parse/re-stringify could reformat engine-emitted JSON). */
94
+ export declare function envelopeJsonArtifact(payload: string, envelopeJson: string): string;
95
+ /** Trailing-comment side-band for the CSS artifact (a leading comment
96
+ * would displace the @layer declaration consumers pin at offset 0). */
97
+ export declare function envelopeCssArtifact(payload: string, envelopeJson: string): string;
98
+ /** Matches the CSS artifact's envelope side-band. */
99
+ export declare const ENVELOPE_CSS_COMMENT_RE: RegExp;
100
+ /** Envelope of a JSON artifact's bytes, or undefined when the artifact
101
+ * carries none. THROWS on unparseable bytes — callers decide whether a
102
+ * torn artifact fails closed or degrades. */
103
+ export declare function readJsonEnvelope(bytes: string): SessionEnvelope | undefined;
104
+ /** Envelope of the CSS artifact's side-band comment, or undefined when the
105
+ * side-band is absent. THROWS on an unparseable envelope body. */
106
+ export declare function readCssEnvelope(bytes: string): SessionEnvelope | undefined;
107
+ //# sourceMappingURL=session-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-paths.d.ts","sourceRoot":"","sources":["../src/session-paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
1
+ import { S as __require } from "./session-paths-DfYIPDcM.mjs";
2
+ import { createV2EngineApi } from "@animus-ui/extract/pipeline";
3
+ import { randomUUID } from "crypto";
4
+ //#region src/singleton.ts
5
+ /**
6
+ * Module-scope singleton for sharing analysis state between the webpack plugin and loader.
7
+ *
8
+ * Uses globalThis to survive the ESM/CJS module boundary: the plugin is loaded via ESM
9
+ * (next.config.ts import) while the loader is loaded by webpack via require(). Without
10
+ * globalThis, each module system gets its own singleton instance.
11
+ */
12
+ const MANIFEST_KEY = "__animus_manifest_json__";
13
+ const PROMISE_KEY = "__animus_analysis_promise__";
14
+ const SHARED_CSS_KEY = "__animus_shared_css__";
15
+ const SHARED_SYSTEM_PROPS_KEY = "__animus_shared_system_props__";
16
+ const SHARED_EXTERNAL_DIRS_KEY = "__animus_external_pkg_dirs__";
17
+ const SHARED_EXTERNAL_ENTRIES_KEY = "__animus_external_source_entries__";
18
+ function getManifestJson() {
19
+ return globalThis[MANIFEST_KEY];
20
+ }
21
+ function setManifestJson(json) {
22
+ globalThis[MANIFEST_KEY] = json;
23
+ }
24
+ function getAnalysisPromise() {
25
+ return globalThis[PROMISE_KEY];
26
+ }
27
+ function setAnalysisPromise(promise) {
28
+ globalThis[PROMISE_KEY] = promise;
29
+ }
30
+ function resetAnalysisPromise() {
31
+ globalThis[PROMISE_KEY] = null;
32
+ }
33
+ function getSharedCss() {
34
+ return globalThis[SHARED_CSS_KEY] || "";
35
+ }
36
+ function setSharedCss(css) {
37
+ globalThis[SHARED_CSS_KEY] = css;
38
+ }
39
+ function setSharedSystemProps(content) {
40
+ globalThis[SHARED_SYSTEM_PROPS_KEY] = content;
41
+ }
42
+ function getSharedExternalDirs() {
43
+ return globalThis[SHARED_EXTERNAL_DIRS_KEY] || [];
44
+ }
45
+ function setSharedExternalDirs(dirs) {
46
+ globalThis[SHARED_EXTERNAL_DIRS_KEY] = dirs;
47
+ }
48
+ function getSharedExternalEntries() {
49
+ return globalThis[SHARED_EXTERNAL_ENTRIES_KEY] || /* @__PURE__ */ new Map();
50
+ }
51
+ function setSharedExternalEntries(entries) {
52
+ globalThis[SHARED_EXTERNAL_ENTRIES_KEY] = entries;
53
+ }
54
+ /** One typed globalThis slot — the single accessor shape every
55
+ * singleton-published value shares (null when unset). */
56
+ function globalSlot(key) {
57
+ const store = globalThis;
58
+ return {
59
+ get: () => store[key] ?? null,
60
+ set: (value) => {
61
+ store[key] = value;
62
+ }
63
+ };
64
+ }
65
+ const ANALYZED_HASHES_KEY = "__animus_analyzed_hashes__";
66
+ const REPLACEMENT_EPOCH_KEY = "__animus_replacement_epoch__";
67
+ const WATCH_TRANSACTION_KEY = "__animus_watch_transaction__";
68
+ const PROCESS_SESSION_ID_KEY = "__animus_process_session_id__";
69
+ const SESSION_ARTIFACT_DIR_KEY = "__animus_session_artifact_dir__";
70
+ const analyzedHashesSlot = globalSlot(ANALYZED_HASHES_KEY);
71
+ const replacementEpochSlot = globalSlot(REPLACEMENT_EPOCH_KEY);
72
+ const watchTransactionSlot = globalSlot(WATCH_TRANSACTION_KEY);
73
+ const sessionArtifactDirSlot = globalSlot(SESSION_ARTIFACT_DIR_KEY);
74
+ /**
75
+ * Per-file analyzed content hashes of the last published analysis (relPath →
76
+ * contentHash of the exact bytes analyzed) — the loader's witness for the
77
+ * unconditional catching-up guard (openspec:
78
+ * next-webpack-served-transform-coherence, design D4). Includes files
79
+ * analyzed with ZERO animus entries: analyzed identity is membership in the
80
+ * analysis input set, not manifest entry count.
81
+ */
82
+ function getAnalyzedHashes() {
83
+ return analyzedHashesSlot.get();
84
+ }
85
+ function setAnalyzedHashes(hashes) {
86
+ analyzedHashesSlot.set(hashes);
87
+ }
88
+ /**
89
+ * Session identity is per Next INVOCATION — one process, however many
90
+ * compiler instances it holds (openspec:
91
+ * next-turbopack-served-transform-coherence, design D2). The first
92
+ * ExtractionSession constructed in a process claims a fresh randomUUID;
93
+ * every later instance (client/server/RSC compilers each construct one)
94
+ * adopts it, so all compilers alias, watch-ignore, and publish ONE
95
+ * session-scoped artifact tree. Separate invocations (`next dev` +
96
+ * `next build` co-writing) are separate processes and therefore separate
97
+ * sessions by construction.
98
+ */
99
+ function claimProcessSessionId() {
100
+ const store = globalThis;
101
+ const existing = store[PROCESS_SESSION_ID_KEY];
102
+ if (typeof existing === "string" && existing.length > 0) return existing;
103
+ const fresh = randomUUID();
104
+ store[PROCESS_SESSION_ID_KEY] = fresh;
105
+ return fresh;
106
+ }
107
+ /**
108
+ * Absolute session artifact directory of the OWNING session's last
109
+ * publication — the webpack loader's source for the session-scoped epoch
110
+ * dependency path (the loader shares the process with the pipeline; the
111
+ * Turbopack loader instead receives the directory via its options).
112
+ */
113
+ function getSessionArtifactDir() {
114
+ return sessionArtifactDirSlot.get();
115
+ }
116
+ function setSessionArtifactDir(dir) {
117
+ sessionArtifactDirSlot.set(dir);
118
+ }
119
+ /**
120
+ * Canonical replacement epoch of the last published analysis
121
+ * (`hashReplacementPlans(snapshotFilePlans(manifest), systemPropsContent)`
122
+ * — openspec: next-webpack-served-transform-coherence, design D5; the
123
+ * served system-props module rides as the served-dependency witness so
124
+ * offline system-props changes move the epoch). Published by the
125
+ * owning session AFTER the manifest so a reader that observes the epoch
126
+ * always observes at least that generation's manifest. (Session
127
+ * attribution lives on the DISK epoch artifact — no in-process mirror.)
128
+ */
129
+ function getReplacementEpoch() {
130
+ return replacementEpochSlot.get();
131
+ }
132
+ function setReplacementEpoch(epoch) {
133
+ replacementEpochSlot.set(epoch);
134
+ }
135
+ /**
136
+ * The one in-flight watch-analysis transaction (design D3): the first
137
+ * compiler entering a watch batch runs analysis + publication; every other
138
+ * compiler (client/server/RSC — each holds its own session instance) joins
139
+ * this promise instead of proceeding against a pre-transaction generation.
140
+ */
141
+ function getWatchTransaction() {
142
+ return watchTransactionSlot.get();
143
+ }
144
+ function setWatchTransaction(transaction) {
145
+ watchTransactionSlot.set(transaction);
146
+ }
147
+ const ENGINE_KEY = "__animus_engine__";
148
+ /** Engine selection travels through the singleton so non-owning compiler
149
+ * instances and the webpack loader honor the same choice as the owner. */
150
+ function setSharedEngine(engine) {
151
+ globalThis[ENGINE_KEY] = engine;
152
+ }
153
+ function getSharedEngine() {
154
+ return globalThis[ENGINE_KEY] || "v2";
155
+ }
156
+ /** Single engine choke-point for every native extraction call. Return type
157
+ * mirrors the untyped `require` the call sites previously used — the NAPI
158
+ * module's own .d.ts is the authoritative surface. */
159
+ function requireEngine() {
160
+ return __require("@animus-ui/extract");
161
+ }
162
+ const V2_ENGINE_KEY = "__animus_v2_engine__";
163
+ /**
164
+ * Engine-agnostic API over both engines (extract-v2-spine row 13). The
165
+ * v2 leg adapts the v1 function surface onto a stateful ExtractEngine
166
+ * (hoisted to `createV2EngineApi` in @animus-ui/extract/pipeline — the
167
+ * single authoritative copy shared with vite-plugin). The engine INSTANCE,
168
+ * its analyze-time sources, and the one-shot drift flag all live on
169
+ * globalThis for the same reason the manifest does — the ESM plugin and the
170
+ * CJS webpack loader must see one engine (and one drift warning) across the
171
+ * double-load. (The next-plugin is already process-singleton by design:
172
+ * manifest, css, and system props share the same globalThis keys.)
173
+ * loadSystemModule is exported by both bindings from one engine-neutral
174
+ * Rust crate, so the default path no longer loads the v1 binary.
175
+ */
176
+ const V2_SENT_SOURCES_KEY = "__animus_v2_sent_sources__";
177
+ const V2_DRIFT_WARNED_KEY = "__animus_v2_drift_warned__";
178
+ const v2EngineApi = createV2EngineApi({
179
+ label: "animus-next",
180
+ isV2: () => getSharedEngine() === "v2",
181
+ loadNativeEngine: requireEngine,
182
+ passThroughUnknownPaths: true,
183
+ store: {
184
+ getEngine: () => globalThis[V2_ENGINE_KEY],
185
+ setEngine: (engine) => {
186
+ globalThis[V2_ENGINE_KEY] = engine;
187
+ },
188
+ getSentSources: () => globalThis[V2_SENT_SOURCES_KEY] ?? null,
189
+ setSentSources: (sources) => {
190
+ globalThis[V2_SENT_SOURCES_KEY] = sources;
191
+ },
192
+ getDriftWarned: () => Boolean(globalThis[V2_DRIFT_WARNED_KEY]),
193
+ setDriftWarned: (value) => {
194
+ globalThis[V2_DRIFT_WARNED_KEY] = value;
195
+ }
196
+ }
197
+ });
198
+ function engineApi() {
199
+ return v2EngineApi();
200
+ }
201
+ //#endregion
202
+ export { setWatchTransaction as C, setSharedSystemProps as S, setSessionArtifactDir as _, getManifestJson as a, setSharedExternalDirs as b, getSharedCss as c, getWatchTransaction as d, resetAnalysisPromise as f, setReplacementEpoch as g, setManifestJson as h, getAnalyzedHashes as i, getSharedExternalDirs as l, setAnalyzedHashes as m, engineApi as n, getReplacementEpoch as o, setAnalysisPromise as p, getAnalysisPromise as r, getSessionArtifactDir as s, claimProcessSessionId as t, getSharedExternalEntries as u, setSharedCss as v, setSharedExternalEntries as x, setSharedEngine as y };
@@ -1,4 +1,6 @@
1
+ require("./turbopack-loader.cjs");
1
2
  let _animus_ui_extract_pipeline = require("@animus-ui/extract/pipeline");
3
+ let crypto = require("crypto");
2
4
  //#region src/singleton.ts
3
5
  /**
4
6
  * Module-scope singleton for sharing analysis state between the webpack plugin and loader.
@@ -49,6 +51,99 @@ function getSharedExternalEntries() {
49
51
  function setSharedExternalEntries(entries) {
50
52
  globalThis[SHARED_EXTERNAL_ENTRIES_KEY] = entries;
51
53
  }
54
+ /** One typed globalThis slot — the single accessor shape every
55
+ * singleton-published value shares (null when unset). */
56
+ function globalSlot(key) {
57
+ const store = globalThis;
58
+ return {
59
+ get: () => store[key] ?? null,
60
+ set: (value) => {
61
+ store[key] = value;
62
+ }
63
+ };
64
+ }
65
+ const ANALYZED_HASHES_KEY = "__animus_analyzed_hashes__";
66
+ const REPLACEMENT_EPOCH_KEY = "__animus_replacement_epoch__";
67
+ const WATCH_TRANSACTION_KEY = "__animus_watch_transaction__";
68
+ const PROCESS_SESSION_ID_KEY = "__animus_process_session_id__";
69
+ const SESSION_ARTIFACT_DIR_KEY = "__animus_session_artifact_dir__";
70
+ const analyzedHashesSlot = globalSlot(ANALYZED_HASHES_KEY);
71
+ const replacementEpochSlot = globalSlot(REPLACEMENT_EPOCH_KEY);
72
+ const watchTransactionSlot = globalSlot(WATCH_TRANSACTION_KEY);
73
+ const sessionArtifactDirSlot = globalSlot(SESSION_ARTIFACT_DIR_KEY);
74
+ /**
75
+ * Per-file analyzed content hashes of the last published analysis (relPath →
76
+ * contentHash of the exact bytes analyzed) — the loader's witness for the
77
+ * unconditional catching-up guard (openspec:
78
+ * next-webpack-served-transform-coherence, design D4). Includes files
79
+ * analyzed with ZERO animus entries: analyzed identity is membership in the
80
+ * analysis input set, not manifest entry count.
81
+ */
82
+ function getAnalyzedHashes() {
83
+ return analyzedHashesSlot.get();
84
+ }
85
+ function setAnalyzedHashes(hashes) {
86
+ analyzedHashesSlot.set(hashes);
87
+ }
88
+ /**
89
+ * Session identity is per Next INVOCATION — one process, however many
90
+ * compiler instances it holds (openspec:
91
+ * next-turbopack-served-transform-coherence, design D2). The first
92
+ * ExtractionSession constructed in a process claims a fresh randomUUID;
93
+ * every later instance (client/server/RSC compilers each construct one)
94
+ * adopts it, so all compilers alias, watch-ignore, and publish ONE
95
+ * session-scoped artifact tree. Separate invocations (`next dev` +
96
+ * `next build` co-writing) are separate processes and therefore separate
97
+ * sessions by construction.
98
+ */
99
+ function claimProcessSessionId() {
100
+ const store = globalThis;
101
+ const existing = store[PROCESS_SESSION_ID_KEY];
102
+ if (typeof existing === "string" && existing.length > 0) return existing;
103
+ const fresh = (0, crypto.randomUUID)();
104
+ store[PROCESS_SESSION_ID_KEY] = fresh;
105
+ return fresh;
106
+ }
107
+ /**
108
+ * Absolute session artifact directory of the OWNING session's last
109
+ * publication — the webpack loader's source for the session-scoped epoch
110
+ * dependency path (the loader shares the process with the pipeline; the
111
+ * Turbopack loader instead receives the directory via its options).
112
+ */
113
+ function getSessionArtifactDir() {
114
+ return sessionArtifactDirSlot.get();
115
+ }
116
+ function setSessionArtifactDir(dir) {
117
+ sessionArtifactDirSlot.set(dir);
118
+ }
119
+ /**
120
+ * Canonical replacement epoch of the last published analysis
121
+ * (`hashReplacementPlans(snapshotFilePlans(manifest), systemPropsContent)`
122
+ * — openspec: next-webpack-served-transform-coherence, design D5; the
123
+ * served system-props module rides as the served-dependency witness so
124
+ * offline system-props changes move the epoch). Published by the
125
+ * owning session AFTER the manifest so a reader that observes the epoch
126
+ * always observes at least that generation's manifest. (Session
127
+ * attribution lives on the DISK epoch artifact — no in-process mirror.)
128
+ */
129
+ function getReplacementEpoch() {
130
+ return replacementEpochSlot.get();
131
+ }
132
+ function setReplacementEpoch(epoch) {
133
+ replacementEpochSlot.set(epoch);
134
+ }
135
+ /**
136
+ * The one in-flight watch-analysis transaction (design D3): the first
137
+ * compiler entering a watch batch runs analysis + publication; every other
138
+ * compiler (client/server/RSC — each holds its own session instance) joins
139
+ * this promise instead of proceeding against a pre-transaction generation.
140
+ */
141
+ function getWatchTransaction() {
142
+ return watchTransactionSlot.get();
143
+ }
144
+ function setWatchTransaction(transaction) {
145
+ watchTransactionSlot.set(transaction);
146
+ }
52
147
  const ENGINE_KEY = "__animus_engine__";
53
148
  /** Engine selection travels through the singleton so non-owning compiler
54
149
  * instances and the webpack loader honor the same choice as the owner. */
@@ -104,6 +199,12 @@ function engineApi() {
104
199
  return v2EngineApi();
105
200
  }
106
201
  //#endregion
202
+ Object.defineProperty(exports, "claimProcessSessionId", {
203
+ enumerable: true,
204
+ get: function() {
205
+ return claimProcessSessionId;
206
+ }
207
+ });
107
208
  Object.defineProperty(exports, "engineApi", {
108
209
  enumerable: true,
109
210
  get: function() {
@@ -116,12 +217,30 @@ Object.defineProperty(exports, "getAnalysisPromise", {
116
217
  return getAnalysisPromise;
117
218
  }
118
219
  });
220
+ Object.defineProperty(exports, "getAnalyzedHashes", {
221
+ enumerable: true,
222
+ get: function() {
223
+ return getAnalyzedHashes;
224
+ }
225
+ });
119
226
  Object.defineProperty(exports, "getManifestJson", {
120
227
  enumerable: true,
121
228
  get: function() {
122
229
  return getManifestJson;
123
230
  }
124
231
  });
232
+ Object.defineProperty(exports, "getReplacementEpoch", {
233
+ enumerable: true,
234
+ get: function() {
235
+ return getReplacementEpoch;
236
+ }
237
+ });
238
+ Object.defineProperty(exports, "getSessionArtifactDir", {
239
+ enumerable: true,
240
+ get: function() {
241
+ return getSessionArtifactDir;
242
+ }
243
+ });
125
244
  Object.defineProperty(exports, "getSharedCss", {
126
245
  enumerable: true,
127
246
  get: function() {
@@ -140,6 +259,12 @@ Object.defineProperty(exports, "getSharedExternalEntries", {
140
259
  return getSharedExternalEntries;
141
260
  }
142
261
  });
262
+ Object.defineProperty(exports, "getWatchTransaction", {
263
+ enumerable: true,
264
+ get: function() {
265
+ return getWatchTransaction;
266
+ }
267
+ });
143
268
  Object.defineProperty(exports, "resetAnalysisPromise", {
144
269
  enumerable: true,
145
270
  get: function() {
@@ -152,12 +277,30 @@ Object.defineProperty(exports, "setAnalysisPromise", {
152
277
  return setAnalysisPromise;
153
278
  }
154
279
  });
280
+ Object.defineProperty(exports, "setAnalyzedHashes", {
281
+ enumerable: true,
282
+ get: function() {
283
+ return setAnalyzedHashes;
284
+ }
285
+ });
155
286
  Object.defineProperty(exports, "setManifestJson", {
156
287
  enumerable: true,
157
288
  get: function() {
158
289
  return setManifestJson;
159
290
  }
160
291
  });
292
+ Object.defineProperty(exports, "setReplacementEpoch", {
293
+ enumerable: true,
294
+ get: function() {
295
+ return setReplacementEpoch;
296
+ }
297
+ });
298
+ Object.defineProperty(exports, "setSessionArtifactDir", {
299
+ enumerable: true,
300
+ get: function() {
301
+ return setSessionArtifactDir;
302
+ }
303
+ });
161
304
  Object.defineProperty(exports, "setSharedCss", {
162
305
  enumerable: true,
163
306
  get: function() {
@@ -188,3 +331,9 @@ Object.defineProperty(exports, "setSharedSystemProps", {
188
331
  return setSharedSystemProps;
189
332
  }
190
333
  });
334
+ Object.defineProperty(exports, "setWatchTransaction", {
335
+ enumerable: true,
336
+ get: function() {
337
+ return setWatchTransaction;
338
+ }
339
+ });
@@ -10,6 +10,56 @@ export declare function getSharedExternalDirs(): string[];
10
10
  export declare function setSharedExternalDirs(dirs: string[]): void;
11
11
  export declare function getSharedExternalEntries(): Map<string, string>;
12
12
  export declare function setSharedExternalEntries(entries: Map<string, string>): void;
13
+ /**
14
+ * Per-file analyzed content hashes of the last published analysis (relPath →
15
+ * contentHash of the exact bytes analyzed) — the loader's witness for the
16
+ * unconditional catching-up guard (openspec:
17
+ * next-webpack-served-transform-coherence, design D4). Includes files
18
+ * analyzed with ZERO animus entries: analyzed identity is membership in the
19
+ * analysis input set, not manifest entry count.
20
+ */
21
+ export declare function getAnalyzedHashes(): ReadonlyMap<string, string> | null;
22
+ export declare function setAnalyzedHashes(hashes: Map<string, string>): void;
23
+ /**
24
+ * Session identity is per Next INVOCATION — one process, however many
25
+ * compiler instances it holds (openspec:
26
+ * next-turbopack-served-transform-coherence, design D2). The first
27
+ * ExtractionSession constructed in a process claims a fresh randomUUID;
28
+ * every later instance (client/server/RSC compilers each construct one)
29
+ * adopts it, so all compilers alias, watch-ignore, and publish ONE
30
+ * session-scoped artifact tree. Separate invocations (`next dev` +
31
+ * `next build` co-writing) are separate processes and therefore separate
32
+ * sessions by construction.
33
+ */
34
+ export declare function claimProcessSessionId(): string;
35
+ /**
36
+ * Absolute session artifact directory of the OWNING session's last
37
+ * publication — the webpack loader's source for the session-scoped epoch
38
+ * dependency path (the loader shares the process with the pipeline; the
39
+ * Turbopack loader instead receives the directory via its options).
40
+ */
41
+ export declare function getSessionArtifactDir(): string | null;
42
+ export declare function setSessionArtifactDir(dir: string): void;
43
+ /**
44
+ * Canonical replacement epoch of the last published analysis
45
+ * (`hashReplacementPlans(snapshotFilePlans(manifest), systemPropsContent)`
46
+ * — openspec: next-webpack-served-transform-coherence, design D5; the
47
+ * served system-props module rides as the served-dependency witness so
48
+ * offline system-props changes move the epoch). Published by the
49
+ * owning session AFTER the manifest so a reader that observes the epoch
50
+ * always observes at least that generation's manifest. (Session
51
+ * attribution lives on the DISK epoch artifact — no in-process mirror.)
52
+ */
53
+ export declare function getReplacementEpoch(): string | null;
54
+ export declare function setReplacementEpoch(epoch: string): void;
55
+ /**
56
+ * The one in-flight watch-analysis transaction (design D3): the first
57
+ * compiler entering a watch batch runs analysis + publication; every other
58
+ * compiler (client/server/RSC — each holds its own session instance) joins
59
+ * this promise instead of proceeding against a pre-transaction generation.
60
+ */
61
+ export declare function getWatchTransaction(): Promise<void> | null;
62
+ export declare function setWatchTransaction(transaction: Promise<void> | null): void;
13
63
  export type AnimusEngine = 'v2';
14
64
  /** Engine selection travels through the singleton so non-owning compiler
15
65
  * instances and the webpack loader honor the same choice as the owner. */
@@ -20,4 +70,9 @@ export declare function getSharedEngine(): AnimusEngine;
20
70
  * module's own .d.ts is the authoritative surface. */
21
71
  export declare function requireEngine(): any;
22
72
  export declare function engineApi(): any;
73
+ /**
74
+ * Every globalThis key this module owns — the single authority test
75
+ * harnesses snapshot/clear per test (never re-declare this list).
76
+ */
77
+ export declare const SINGLETON_GLOBAL_KEYS: readonly ["__animus_manifest_json__", "__animus_analysis_promise__", "__animus_shared_css__", "__animus_shared_system_props__", "__animus_external_pkg_dirs__", "__animus_external_source_entries__", "__animus_analyzed_hashes__", "__animus_replacement_epoch__", "__animus_watch_transaction__", "__animus_process_session_id__", "__animus_session_artifact_dir__", "__animus_engine__", "__animus_v2_engine__", "__animus_v2_sent_sources__", "__animus_v2_drift_warned__"];
23
78
  //# sourceMappingURL=singleton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../src/singleton.ts"],"names":[],"mappings":"AAkBA,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAIzD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE/D;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAIrC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAMhD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAE1D;AAED,wBAAgB,wBAAwB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAM9D;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAG3E;AAID,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC;AAEhC;2EAC2E;AAC3E,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE1D;AAED,wBAAgB,eAAe,IAAI,YAAY,CAQ9C;AAED;;uDAEuD;AAEvD,wBAAgB,aAAa,IAAI,GAAG,CAInC;AAoDD,wBAAgB,SAAS,IAAI,GAAG,CAE/B"}
1
+ {"version":3,"file":"singleton.d.ts","sourceRoot":"","sources":["../src/singleton.ts"],"names":[],"mappings":"AAmBA,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAIzD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE/D;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAIrC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAMhD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAE1D;AAED,wBAAgB,wBAAwB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAM9D;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAG3E;AA4BD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEtE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAO9C;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAErD;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEnD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAE3E;AAID,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC;AAEhC;2EAC2E;AAC3E,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE1D;AAED,wBAAgB,eAAe,IAAI,YAAY,CAQ9C;AAED;;uDAEuD;AAEvD,wBAAgB,aAAa,IAAI,GAAG,CAInC;AAoDD,wBAAgB,SAAS,IAAI,GAAG,CAE/B;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,kdAgBxB,CAAC"}
@@ -36,13 +36,18 @@ export declare function resolveTurbopackMode(options: AnimusNextOptions, env?: R
36
36
  * (file-level allowlisting lives in the loader via manifest lookup — Next 15
37
37
  * rules have no condition algebra) plus resolve aliases for the virtual
38
38
  * system-props id, the emitter's stylesheet id, and each collected external
39
- * package specifier redirected to its source entry.
39
+ * package specifier redirected to its source entry. Loader options carry
40
+ * the session identity (design D2: an options-borne, JSON-serializable
41
+ * Turbopack task input — restart-cold by construction), and the artifact
42
+ * aliases point into the session-scoped tree.
40
43
  */
41
44
  export declare function buildTurbopackConfig(args: {
42
45
  rootDir: string;
43
46
  loaderPath: string;
44
47
  options: AnimusNextOptions;
45
48
  externalSourceEntries: ReadonlyMap<string, string>;
49
+ sessionId: string;
50
+ sessionDir: string;
46
51
  }): TurbopackConfigFragment;
47
52
  /**
48
53
  * Locate the Turbopack loader module: built dist first, source fallback for
@@ -1 +1 @@
1
- {"version":3,"file":"turbopack-config.d.ts","sourceRoot":"","sources":["../src/turbopack-config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;GAIG;AAEH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;gEAGgE;AAChE,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAElE;;wBAEwB;AACxB,eAAO,MAAM,yBAAyB,gCAAgC,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,OAAO,CAMT;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,qBAAqB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD,GAAG,uBAAuB,CA8B1B;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMpE"}
1
+ {"version":3,"file":"turbopack-config.d.ts","sourceRoot":"","sources":["../src/turbopack-config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;GAIG;AAEH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED;;;gEAGgE;AAChE,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAElE;;wBAEwB;AACxB,eAAO,MAAM,yBAAyB,gCAAgC,CAAC;AAEvE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,iBAAiB,EAC1B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,OAAO,CAMT;AAQD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,qBAAqB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,uBAAuB,CA0C1B;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMpE"}