@animus-ui/vite-plugin 0.1.16 → 0.1.17

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.
@@ -1 +1 @@
1
- {"version":3,"file":"build-start.d.ts","sourceRoot":"","sources":["../src/build-start.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,aAAa,EAClB,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAC/D,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,MAAM,GAC3D,OAAO,CAAC,IAAI,CAAC,CAkNf"}
1
+ {"version":3,"file":"build-start.d.ts","sourceRoot":"","sources":["../src/build-start.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,aAAa,EAClB,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAC/D,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,MAAM,GAC3D,OAAO,CAAC,IAAI,CAAC,CAmNf"}
package/dist/context.d.ts CHANGED
@@ -18,6 +18,8 @@ export declare function pruneFileCache(cache: Map<string, {
18
18
  export declare class PluginContext {
19
19
  readonly options: AnimusExtractOptions;
20
20
  readonly verbose: boolean;
21
+ /** The higher tier: `verbose: 'trace'` or `ANIMUS_DEBUG=trace`. */
22
+ readonly tracing: boolean;
21
23
  readonly staticCssJson: string | null;
22
24
  isProd: boolean;
23
25
  /** Emission mode (the explicit `mode` option wins over the command); feeds
@@ -44,7 +46,8 @@ export declare class PluginContext {
44
46
  reverseProvenance: Record<string, string[]>;
45
47
  storedSystemPropMapJson: string;
46
48
  storedDynamicPropsJson: string;
47
- storedTransformsSource: string;
49
+ storedAdmittedTransformsJson: string;
50
+ storedTypedSystemPropsJson: string;
48
51
  readonly fileCache: ReadonlyMap<string, {
49
52
  hash: string;
50
53
  source: string;
@@ -62,8 +65,18 @@ export declare class PluginContext {
62
65
  * this corpus's published projection. */
63
66
  readonly corpus: SourceCorpus;
64
67
  rawExtensionFallbacks: Set<string>;
68
+ /** Original path → hash of bytes whose parse aborted in a rejected attempt;
69
+ * non-empty while that rejection holds publication. Those bytes are served
70
+ * raw so the host reports its own syntax error instead of receiving the
71
+ * previous module from the retained engine. */
72
+ readonly abortedParseHashes: Map<string, string>;
73
+ /** A system reload is pending: the next analysis attempt loads the latest
74
+ * system. A parse hold keeps it pending and the published system served;
75
+ * new dependency watch keys stay registered meanwhile. */
76
+ systemReloadOwed: boolean;
65
77
  /** The one mutator of a file's fallback state — every raw-serve exit of the
66
- * transform hook reports here. Production keeps the set empty. The
78
+ * transform hook reports here, except aborted bytes, which never execute.
79
+ * Production keeps the set empty. The
67
80
  * barrier's one-shot withhold release must not route through here: it
68
81
  * retires other files' records, no claim about their current serve. */
69
82
  recordFallbackState(relativePath: string, isFallback: boolean): void;
@@ -90,6 +103,9 @@ export declare class PluginContext {
90
103
  readonly engineApi: () => any;
91
104
  constructor(options: AnimusExtractOptions, engineApiOverride?: () => any);
92
105
  log(msg: string): void;
106
+ /** One line per item — a pruned option, a transformed file, an HMR
107
+ * decision — printed only at the trace tier. */
108
+ trace(msg: string): void;
93
109
  /** Logs whether or not `verbose` is on — for events a developer must see
94
110
  * without opting in. */
95
111
  info(msg: string): void;
@@ -107,13 +123,31 @@ export declare class PluginContext {
107
123
  }>): boolean;
108
124
  private assertRuntimeImportSuppliesTerminals;
109
125
  /** The one ingest → quarantine → analyze → publish transaction. The corpus
110
- * publishes only on success; `beforeAnalysis` runs after quarantine. */
126
+ * publishes only on success. `afterIngestion` runs after quarantine even
127
+ * when an aborted parse rejects the attempt; `beforeAnalysis` runs only
128
+ * once the attempt will analyze. A rejection names its aborted originals
129
+ * and holds publication: development callers keep their cache's latest
130
+ * sources, valid edits included, for the repair to publish together. In
131
+ * every strictness mode it fails a production build, which has no
132
+ * generation to keep, and only warns in development: the host reports the
133
+ * syntax error itself, and a throw would leave its client on the failed
134
+ * module. The publication that ends a hold invalidates the modules of
135
+ * every original whose admitted bytes changed meanwhile and returns them
136
+ * as `redeliver`, for a hot update to push to the client. An owed system
137
+ * reload loads the latest system for the attempt: a hold restores the
138
+ * published one and keeps the reload owed, any other outcome completes
139
+ * the reload's invalidation. */
111
140
  analyzeIngested(options?: {
112
141
  rawEntries?: readonly RawSourceEntry[];
142
+ afterIngestion?: (ingested: SourceIngestionResult) => void;
113
143
  beforeAnalysis?: (accepted: SourceIngestionResult) => void;
114
144
  }): Promise<{
115
145
  ok: boolean;
116
146
  accepted: SourceIngestionResult;
147
+ /** Original path → hash of the bytes whose parse aborted. */
148
+ abortedOriginals?: ReadonlyMap<string, string>;
149
+ endedHold: boolean;
150
+ redeliver: string[];
117
151
  }>;
118
152
  publishSourceIngestion(result: SourceIngestionResult): void;
119
153
  devFsUrl(absPath: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -75,7 +75,7 @@ async function runBuildStart(ctx, resolveSpecifier, emitAsset) {
75
75
  t0 = performance.now();
76
76
  await ctx.analyzeIngested({
77
77
  rawEntries,
78
- beforeAnalysis: (accepted) => {
78
+ afterIngestion: (accepted) => {
79
79
  if (!ctx.isProd) ctx.mutateFileCache((cache) => {
80
80
  cache.clear();
81
81
  for (const entry of accepted.originalEntries) cache.set(entry.path, {
@@ -109,8 +109,8 @@ async function runBuildStart(ctx, resolveSpecifier, emitAsset) {
109
109
  ctx.log(`Reconciliation: ${report.components_extracted} kept, ${report.variants_eliminated} variants pruned, ${report.states_eliminated} states pruned`);
110
110
  for (const d of report.eliminated_details) if (d.kind === "component") ctx.warn(`⚠ ${d.component} eliminated: ${d.reason}`);
111
111
  else if (d.kind === "prospective_component") ctx.warn(`⚠ ${d.component} would be eliminated in production: ${d.reason}`);
112
- else if (d.kind === "variant") ctx.warn(`⚠ ${d.component} variant '${d.name}' pruned: ${d.reason}`);
113
- else if (d.kind === "state") ctx.warn(`⚠ ${d.component} state '${d.name}' pruned: ${d.reason}`);
112
+ else if (d.kind === "variant") ctx.trace(`${d.component} variant '${d.name}' pruned: ${d.reason}`);
113
+ else if (d.kind === "state") ctx.trace(`${d.component} state '${d.name}' pruned: ${d.reason}`);
114
114
  ctx.log(`CSS: ${ctx.resolvedComponentCss.length} bytes (${Object.keys(ctx.storedManifest.components).length} components)`);
115
115
  if (!ctx.isProd && ctx.storedSheets) {
116
116
  const staticSize = (0, _animus_ui_extract_pipeline.assembleStylesheet)({
@@ -238,8 +238,9 @@ function eventKey(file, timestamp) {
238
238
  //#endregion
239
239
  //#region src/module-invalidation.ts
240
240
  /**
241
- * Completeness is load-bearing: the file-plan diff is the only invalidation
242
- * candidate source, so a node shape missed here stays stale for the session.
241
+ * Completeness is load-bearing: the file-plan diff and the sources re-delivered
242
+ * when a held publication ends are the only invalidation candidate sources, so
243
+ * a node shape missed here stays stale for the session.
243
244
  */
244
245
  function invalidateFileModules(ctx, relPaths) {
245
246
  const server = ctx.devServer;
@@ -260,7 +261,7 @@ function invalidateFileModules(ctx, relPaths) {
260
261
  fileCount++;
261
262
  }
262
263
  }
263
- if (fileCount > 0) ctx.log(`HMR invalidate: ${relPath} (plan changed, ${fileCount} nodes)`);
264
+ if (fileCount > 0) ctx.trace(`HMR invalidate: ${relPath} (plan changed, ${fileCount} nodes)`);
264
265
  total += fileCount;
265
266
  }
266
267
  return total;
@@ -336,7 +337,8 @@ function generateSystemPropsModule(ctx) {
336
337
  systemPropMapJson: ctx.storedSystemPropMapJson,
337
338
  groupRegistryJson: ctx.system.groupRegistryJson,
338
339
  dynamicProps: JSON.parse(ctx.storedDynamicPropsJson),
339
- transformsSource: ctx.storedTransformsSource
340
+ admittedTransforms: JSON.parse(ctx.storedAdmittedTransformsJson),
341
+ typedSystemProps: JSON.parse(ctx.storedTypedSystemPropsJson)
340
342
  });
341
343
  }
342
344
  /** Memoized on the inputs themselves, so no writer owes the memo a refresh
@@ -348,7 +350,8 @@ function systemPropsModuleKey(ctx) {
348
350
  ctx.storedSystemPropMapJson,
349
351
  ctx.system.groupRegistryJson,
350
352
  ctx.storedDynamicPropsJson,
351
- ctx.storedTransformsSource
353
+ ctx.storedAdmittedTransformsJson,
354
+ ctx.storedTypedSystemPropsJson
352
355
  ].join("\0");
353
356
  }
354
357
  /** The exact source `virtual:animus/system-props` serves now — one definition,
@@ -373,6 +376,8 @@ function pruneFileCache(cache, rootDir, absPath) {
373
376
  var PluginContext = class {
374
377
  options;
375
378
  verbose;
379
+ /** The higher tier: `verbose: 'trace'` or `ANIMUS_DEBUG=trace`. */
380
+ tracing;
376
381
  staticCssJson;
377
382
  isProd = false;
378
383
  /** Emission mode (the explicit `mode` option wins over the command); feeds
@@ -401,7 +406,8 @@ var PluginContext = class {
401
406
  reverseProvenance = {};
402
407
  storedSystemPropMapJson = "{}";
403
408
  storedDynamicPropsJson = "{}";
404
- storedTransformsSource = "{}";
409
+ storedAdmittedTransformsJson = "{}";
410
+ storedTypedSystemPropsJson = "[]";
405
411
  fileCache = /* @__PURE__ */ new Map();
406
412
  /** Mutation attempts against `fileCache`, for memos that must not key on
407
413
  * `size` — a delete plus an unrelated create leaves it unchanged. */
@@ -423,8 +429,18 @@ var PluginContext = class {
423
429
  warn: (message) => this.warn(message)
424
430
  });
425
431
  rawExtensionFallbacks = /* @__PURE__ */ new Set();
432
+ /** Original path → hash of bytes whose parse aborted in a rejected attempt;
433
+ * non-empty while that rejection holds publication. Those bytes are served
434
+ * raw so the host reports its own syntax error instead of receiving the
435
+ * previous module from the retained engine. */
436
+ abortedParseHashes = /* @__PURE__ */ new Map();
437
+ /** A system reload is pending: the next analysis attempt loads the latest
438
+ * system. A parse hold keeps it pending and the published system served;
439
+ * new dependency watch keys stay registered meanwhile. */
440
+ systemReloadOwed = false;
426
441
  /** The one mutator of a file's fallback state — every raw-serve exit of the
427
- * transform hook reports here. Production keeps the set empty. The
442
+ * transform hook reports here, except aborted bytes, which never execute.
443
+ * Production keeps the set empty. The
428
444
  * barrier's one-shot withhold release must not route through here: it
429
445
  * retires other files' records, no claim about their current serve. */
430
446
  recordFallbackState(relativePath, isFallback) {
@@ -456,7 +472,9 @@ var PluginContext = class {
456
472
  constructor(options, engineApiOverride) {
457
473
  this.options = options;
458
474
  this.staticCssJson = (0, _animus_ui_extract_pipeline.serializeStaticCss)(options.staticCss);
459
- this.verbose = options.verbose || process.env.ANIMUS_DEBUG === "1" || process.env.ANIMUS_DEBUG === "true";
475
+ const verbosity = (0, _animus_ui_extract_pipeline.resolveVerbosity)(options.verbose, process.env.ANIMUS_DEBUG);
476
+ this.verbose = verbosity !== "quiet";
477
+ this.tracing = verbosity === "trace";
460
478
  this.extensionsSet = new Set(options.extensions ?? _animus_ui_extract_pipeline.DEFAULT_EXTENSIONS);
461
479
  this.excludeMatcher = (0, _animus_ui_extract_pipeline.createExcludeMatcher)(options.exclude);
462
480
  if (engineApiOverride) {
@@ -494,6 +512,11 @@ var PluginContext = class {
494
512
  log(msg) {
495
513
  if (this.verbose) (this.logger ?? console).info(`[animus] ${msg}`);
496
514
  }
515
+ /** One line per item — a pruned option, a transformed file, an HMR
516
+ * decision — printed only at the trace tier. */
517
+ trace(msg) {
518
+ if (this.tracing) (this.logger ?? console).info(`[animus] ${msg}`);
519
+ }
497
520
  /** Logs whether or not `verbose` is on — for events a developer must see
498
521
  * without opting in. */
499
522
  info(msg) {
@@ -565,6 +588,8 @@ var PluginContext = class {
565
588
  this.storedManifestJson = result.manifestJson;
566
589
  this.storedSystemPropMapJson = JSON.stringify(result.manifest.system_prop_map);
567
590
  this.storedDynamicPropsJson = JSON.stringify(result.manifest.dynamic_props);
591
+ this.storedAdmittedTransformsJson = JSON.stringify(result.manifest.admitted_transforms);
592
+ this.storedTypedSystemPropsJson = JSON.stringify(result.manifest.typed_system_props);
568
593
  this.reverseProvenance = result.manifest.reverse_provenance;
569
594
  this.storedSheets = result.manifest.sheets;
570
595
  this.globalCss = result.globalCss;
@@ -582,19 +607,85 @@ var PluginContext = class {
582
607
  throw new Error(`[animus-extract] runtimeImport '${override}' is valid only when every extracted terminal is .asClass(), but ${offenders.length} component(s) need createComponent/createComposedFamily from the default '@animus-ui/system' runtime: ${shown}` + (offenders.length > 5 ? ", …" : "") + `. Remove the override or convert these terminals to .asClass().`);
583
608
  }
584
609
  /** The one ingest → quarantine → analyze → publish transaction. The corpus
585
- * publishes only on success; `beforeAnalysis` runs after quarantine. */
610
+ * publishes only on success. `afterIngestion` runs after quarantine even
611
+ * when an aborted parse rejects the attempt; `beforeAnalysis` runs only
612
+ * once the attempt will analyze. A rejection names its aborted originals
613
+ * and holds publication: development callers keep their cache's latest
614
+ * sources, valid edits included, for the repair to publish together. In
615
+ * every strictness mode it fails a production build, which has no
616
+ * generation to keep, and only warns in development: the host reports the
617
+ * syntax error itself, and a throw would leave its client on the failed
618
+ * module. The publication that ends a hold invalidates the modules of
619
+ * every original whose admitted bytes changed meanwhile and returns them
620
+ * as `redeliver`, for a hot update to push to the client. An owed system
621
+ * reload loads the latest system for the attempt: a hold restores the
622
+ * published one and keeps the reload owed, any other outcome completes
623
+ * the reload's invalidation. */
586
624
  async analyzeIngested(options) {
587
- const accepted = await this.corpus.prepare(options?.rawEntries ?? {
588
- fileCache: this.fileCache,
589
- externalFileOwners: this.externalFileOwners
590
- });
591
- options?.beforeAnalysis?.(accepted);
592
- const ok = this.runAnalysis(accepted.analysisEntries) !== false;
593
- if (ok) this.publishSourceIngestion(accepted);
594
- return {
595
- ok,
596
- accepted
597
- };
625
+ const holding = this.abortedParseHashes.size > 0;
626
+ const previous = this.corpus.published.ownership;
627
+ const reloadingSystem = this.systemReloadOwed;
628
+ const prevPlans = reloadingSystem ? (0, _animus_ui_extract_pipeline.snapshotFilePlans)(this.storedManifest) : null;
629
+ const publishedSystem = this.system;
630
+ const publishedVocabulary = this.systemVocabularyDiagnostics;
631
+ let published = false;
632
+ try {
633
+ if (reloadingSystem) this.loadSystem();
634
+ const accepted = await this.corpus.prepare(options?.rawEntries ?? {
635
+ fileCache: this.fileCache,
636
+ externalFileOwners: this.externalFileOwners
637
+ });
638
+ options?.afterIngestion?.(accepted);
639
+ const rejection = this.corpus.rejection(accepted);
640
+ if (rejection) {
641
+ for (const [path$3, hash] of rejection.originals) this.abortedParseHashes.set(path$3, hash);
642
+ if (this.isProd) throw new Error(rejection.message);
643
+ this.warn(rejection.message);
644
+ return {
645
+ ok: false,
646
+ accepted,
647
+ abortedOriginals: rejection.originals,
648
+ endedHold: false,
649
+ redeliver: []
650
+ };
651
+ }
652
+ if (reloadingSystem) (0, _animus_ui_extract_pipeline.clearEngineCache)(this.engineApi);
653
+ options?.beforeAnalysis?.(accepted);
654
+ const ok = this.runAnalysis(accepted.analysisEntries) !== false;
655
+ if (!ok) return {
656
+ ok,
657
+ accepted,
658
+ endedHold: false,
659
+ redeliver: []
660
+ };
661
+ this.publishSourceIngestion(accepted);
662
+ published = true;
663
+ this.abortedParseHashes.clear();
664
+ if (!holding) return {
665
+ ok,
666
+ accepted,
667
+ endedHold: false,
668
+ redeliver: []
669
+ };
670
+ const redeliver = Object.values(accepted.ownership).filter((owner) => previous[owner.originalPath]?.originalHash !== owner.originalHash).map((owner) => owner.originalPath);
671
+ invalidateFileModules(this, redeliver);
672
+ return {
673
+ ok,
674
+ accepted,
675
+ endedHold: true,
676
+ redeliver
677
+ };
678
+ } finally {
679
+ const systemHeld = reloadingSystem && this.abortedParseHashes.size > 0;
680
+ if (systemHeld) {
681
+ this.system = publishedSystem;
682
+ this.systemVocabularyDiagnostics = publishedVocabulary;
683
+ } else if (reloadingSystem) {
684
+ this.systemReloadOwed = false;
685
+ if (published && prevPlans) invalidateFileModules(this, (0, _animus_ui_extract_pipeline.diffFilePlans)(prevPlans, (0, _animus_ui_extract_pipeline.snapshotFilePlans)(this.storedManifest)));
686
+ }
687
+ if (reloadingSystem) this.invalidateSystemReloadModules(!systemHeld);
688
+ }
598
689
  }
599
690
  publishSourceIngestion(result) {
600
691
  this.corpus.publish(result);
@@ -651,18 +742,12 @@ var PluginContext = class {
651
742
  }
652
743
  async performSystemReloadExclusive() {
653
744
  const resetStart = performance.now();
654
- const prevPlans = (0, _animus_ui_extract_pipeline.snapshotFilePlans)(this.storedManifest);
655
- try {
656
- this.loadSystem();
657
- const { ok } = await this.analyzeIngested({ beforeAnalysis: () => (0, _animus_ui_extract_pipeline.clearEngineCache)(this.engineApi) });
658
- if (!ok) return;
659
- invalidateFileModules(this, (0, _animus_ui_extract_pipeline.diffFilePlans)(prevPlans, (0, _animus_ui_extract_pipeline.snapshotFilePlans)(this.storedManifest)));
660
- this.log(`HMR system reload complete: ${Math.round(performance.now() - resetStart)}ms`);
661
- } finally {
662
- this.invalidateSystemReloadModules();
663
- }
745
+ this.systemReloadOwed = true;
746
+ const { ok } = await this.analyzeIngested();
747
+ if (!ok) return;
748
+ this.log(`HMR system reload complete: ${Math.round(performance.now() - resetStart)}ms`);
664
749
  }
665
- invalidateSystemReloadModules() {
750
+ invalidateSystemReloadModules(reloadClient) {
666
751
  const server = this.devServer;
667
752
  if (!server) return;
668
753
  for (const moduleId of [
@@ -673,7 +758,7 @@ var PluginContext = class {
673
758
  const mod = server.moduleGraph.getModuleById(moduleId);
674
759
  if (mod) server.moduleGraph.invalidateModule(mod);
675
760
  }
676
- server.hot?.send({ type: "full-reload" });
761
+ if (reloadClient) server.hot?.send({ type: "full-reload" });
677
762
  }
678
763
  isSystemDependency(absFile) {
679
764
  return (0, _animus_ui_extract_pipeline.toWatchKeys)(absFile).some((key) => this.systemDependencyKeys.has(key));
@@ -802,10 +887,13 @@ async function reconcileSourceCorpus(ctx) {
802
887
  ctx.log(`rediscovery: folded ${folded.length} on-disk file(s) after unresolved-parent drop`);
803
888
  reanalyzed = true;
804
889
  let published = false;
890
+ let held = false;
805
891
  try {
806
- published = (await ctx.analyzeIngested()).ok;
892
+ const analysis = await ctx.analyzeIngested();
893
+ published = analysis.ok;
894
+ held = analysis.abortedOriginals !== void 0;
807
895
  } finally {
808
- if (!published) ctx.mutateFileCache((cache) => {
896
+ if (!published && !held) ctx.mutateFileCache((cache) => {
809
897
  for (const key of folded) cache.delete(key);
810
898
  });
811
899
  }
@@ -903,10 +991,12 @@ function applyDevBridgeImport(code) {
903
991
  const prologue = /^(?:(['"])use [a-z -]+\1;?\r?\n)*/.exec(code)?.[0] ?? "";
904
992
  return prologue + `import '${VIRTUAL_BRIDGE_ID}';\n` + code.slice(prologue.length);
905
993
  }
906
- function rawFallbackDescendants(ctx, relPath) {
994
+ /** The files defining a transitive extension of a component the given
995
+ * analysis paths define, from the published provenance. */
996
+ function extendingFiles(ctx, analysisPaths) {
907
997
  const manifest = ctx.storedManifest;
908
- const conflicted = /* @__PURE__ */ new Set();
909
- const queue = [...manifest?.files[relPath] ?? []];
998
+ const files = /* @__PURE__ */ new Set();
999
+ const queue = analysisPaths.flatMap((path$2) => manifest?.files[path$2] ?? []);
910
1000
  const seen = new Set(queue);
911
1001
  while (queue.length > 0) {
912
1002
  const id = queue.shift();
@@ -915,10 +1005,13 @@ function rawFallbackDescendants(ctx, relPath) {
915
1005
  seen.add(childId);
916
1006
  queue.push(childId);
917
1007
  const childFile = manifest?.components[childId]?.file;
918
- if (childFile && childFile !== relPath && ctx.rawExtensionFallbacks.has(childFile)) conflicted.add(childFile);
1008
+ if (childFile) files.add(childFile);
919
1009
  }
920
1010
  }
921
- return [...conflicted].sort();
1011
+ return files;
1012
+ }
1013
+ function rawFallbackDescendants(ctx, relPath) {
1014
+ return [...extendingFiles(ctx, [relPath])].filter((file) => file !== relPath && ctx.rawExtensionFallbacks.has(file)).sort();
922
1015
  }
923
1016
  async function transformSource(ctx, code, id) {
924
1017
  if (!ctx.storedManifest) return null;
@@ -930,6 +1023,8 @@ async function transformSource(ctx, code, id) {
930
1023
  if (id.includes("node_modules")) return null;
931
1024
  if (!(0, _animus_ui_extract_pipeline.isPathWithinRoot)(ctx.rootDir, id)) return null;
932
1025
  }
1026
+ const abortedHash = ctx.abortedParseHashes.get(relativePath);
1027
+ if (abortedHash !== void 0 && abortedHash === (0, _animus_ui_extract_pipeline.contentHash)(code)) return null;
933
1028
  if (!ctx.storedManifest.files[relativePath]?.length) {
934
1029
  if (!ctx.isProd && !ctx.fileCache.has(relativePath)) await runExclusiveAnalysis(ctx, async () => {
935
1030
  if (ctx.fileCache.has(relativePath)) return;
@@ -944,10 +1039,13 @@ async function transformSource(ctx, code, id) {
944
1039
  }));
945
1040
  const prevPlans = (0, _animus_ui_extract_pipeline.snapshotFilePlans)(ctx.storedManifest);
946
1041
  let analysisOk = false;
1042
+ let held = false;
947
1043
  try {
948
- analysisOk = (await ctx.analyzeIngested()).ok;
1044
+ const analysis = await ctx.analyzeIngested();
1045
+ analysisOk = analysis.ok;
1046
+ held = analysis.abortedOriginals !== void 0;
949
1047
  } finally {
950
- if (!analysisOk) ctx.mutateFileCache((cache) => cache.delete(relativePath));
1048
+ if (!analysisOk && !held) ctx.mutateFileCache((cache) => cache.delete(relativePath));
951
1049
  }
952
1050
  if (analysisOk) {
953
1051
  await reconcileSourceCorpus(ctx);
@@ -978,9 +1076,9 @@ async function transformSource(ctx, code, id) {
978
1076
  ctx.recordFallbackState(relativePath, true);
979
1077
  return null;
980
1078
  }
981
- if (ctx.verbose) {
1079
+ if (ctx.tracing) {
982
1080
  const compCount = ctx.storedManifest.files[relativePath]?.length ?? 0;
983
- ctx.log(`transform ${relativePath}: ${compCount} components`);
1081
+ ctx.trace(`transform ${relativePath}: ${compCount} components`);
984
1082
  }
985
1083
  let outputCode = result.code;
986
1084
  if (!ctx.isProd) {
@@ -1010,7 +1108,7 @@ async function handleHotUpdate(ctx, environment, options) {
1010
1108
  async function handleHotUpdateExclusive(ctx, environment, { type, file, timestamp, modules, read }) {
1011
1109
  const ownsEvent = ctx.hotUpdateEvents.claim(environment.name, file, timestamp);
1012
1110
  const absFile = (0, path.resolve)(file);
1013
- ctx.log(`hotUpdate ${type} ${(0, path.relative)(ctx.rootDir, absFile)} env=${environment.name} owns=${ownsEvent}`);
1111
+ ctx.trace(`hotUpdate ${type} ${(0, path.relative)(ctx.rootDir, absFile)} env=${environment.name} owns=${ownsEvent}`);
1014
1112
  if (ctx.isSystemDependency(absFile)) {
1015
1113
  if (ownsEvent) {
1016
1114
  await reconcileSourceEntry(ctx, absFile, type, read);
@@ -1083,7 +1181,7 @@ async function analyzeChangedFile(ctx, file, absFile, read) {
1083
1181
  const hash = (0, _animus_ui_extract_pipeline.contentHash)(source);
1084
1182
  const cached = ctx.fileCache.get(relPath);
1085
1183
  if (cached && cached.hash === hash) {
1086
- ctx.log(`HMR skip: ${relPath} (unchanged)`);
1184
+ ctx.trace(`HMR skip: ${relPath} (unchanged)`);
1087
1185
  return { kind: "unchanged" };
1088
1186
  }
1089
1187
  const priorExternalOwner = ctx.externalFileOwners[relPath];
@@ -1105,30 +1203,17 @@ async function analyzeChangedFile(ctx, file, absFile, read) {
1105
1203
  };
1106
1204
  const hmrStart = performance.now();
1107
1205
  const prevPlans = (0, _animus_ui_extract_pipeline.snapshotFilePlans)(ctx.storedManifest);
1108
- const directComponentIds = (ctx.corpus.published.ownership[relPath]?.analysisPaths ?? [relPath]).flatMap((analysisPath) => ctx.storedManifest?.files[analysisPath] ?? []);
1109
- const invalidatedIds = new Set(directComponentIds);
1110
- const queue = [...directComponentIds];
1111
- while (queue.length > 0) {
1112
- const parentId = queue.shift();
1113
- const children = ctx.reverseProvenance[parentId];
1114
- if (children) {
1115
- for (const childId of children) if (!invalidatedIds.has(childId)) {
1116
- invalidatedIds.add(childId);
1117
- queue.push(childId);
1118
- }
1119
- }
1120
- }
1121
- if (ctx.verbose && invalidatedIds.size > directComponentIds.length) ctx.log(`HMR: ${directComponentIds.length} direct + ${invalidatedIds.size - directComponentIds.length} transitive components invalidated`);
1122
1206
  const analysisStart = performance.now();
1123
1207
  const systemPropsBefore = systemPropsModuleSource(ctx);
1124
- let analysisOk;
1208
+ let analysis;
1125
1209
  try {
1126
- analysisOk = (await ctx.analyzeIngested()).ok;
1210
+ analysis = await ctx.analyzeIngested();
1127
1211
  } catch (e) {
1128
1212
  restoreEntry();
1129
1213
  throw e;
1130
1214
  }
1131
- if (!analysisOk) {
1215
+ if (!analysis.ok) {
1216
+ if (analysis.abortedOriginals) return analysis.abortedOriginals.has(relPath) ? { kind: "ignored" } : { kind: "unchanged" };
1132
1217
  restoreEntry();
1133
1218
  return { kind: "ignored" };
1134
1219
  }
@@ -1140,9 +1225,14 @@ async function analyzeChangedFile(ctx, file, absFile, read) {
1140
1225
  }
1141
1226
  const systemPropsChanged = systemPropsModuleSource(ctx) !== systemPropsBefore;
1142
1227
  const analysisMs = Math.round(performance.now() - analysisStart);
1143
- const staleDefinitionFiles = (0, _animus_ui_extract_pipeline.diffFilePlans)(prevPlans, (0, _animus_ui_extract_pipeline.snapshotFilePlans)(ctx.storedManifest)).filter((defFile) => (0, path.resolve)(ctx.rootDir, defFile) !== absFile);
1144
1228
  const nativeEntry = ctx.corpus.published.analysisEntries.get(relPath);
1145
- const presentationOnly = nativeEntry ? isPresentationOnlyEdit(ctx, relPath, nativeEntry.source) : false;
1229
+ const presentationOnly = nativeEntry && !analysis.endedHold ? isPresentationOnlyEdit(ctx, relPath, nativeEntry.source) : false;
1230
+ const redelivered = presentationOnly ? [] : [relPath, ...analysis.redeliver];
1231
+ const staleDefinitionFiles = [.../* @__PURE__ */ new Set([
1232
+ ...(0, _animus_ui_extract_pipeline.diffFilePlans)(prevPlans, (0, _animus_ui_extract_pipeline.snapshotFilePlans)(ctx.storedManifest)),
1233
+ ...analysis.redeliver,
1234
+ ...extendingFiles(ctx, redelivered.flatMap((path$1) => ctx.corpus.published.ownership[path$1]?.analysisPaths ?? [path$1]))
1235
+ ])].filter((defFile) => (0, path.resolve)(ctx.rootDir, defFile) !== absFile);
1146
1236
  const hmrMs = Math.round(performance.now() - hmrStart);
1147
1237
  ctx.log(`HMR update: ${relPath} — analysis ${analysisMs}ms, total ${hmrMs}ms${presentationOnly ? " (presentation-only)" : ""}`);
1148
1238
  ctx.logTimingWaterfall(ctx.storedManifest?.timing ?? {});
@@ -1177,7 +1267,7 @@ async function pruneDeletedFile(ctx, absFile) {
1177
1267
  const prevPlans = (0, _animus_ui_extract_pipeline.snapshotFilePlans)(ctx.storedManifest);
1178
1268
  const { ok } = await ctx.analyzeIngested();
1179
1269
  if (!ok) return;
1180
- ctx.log(`Deleted file pruned: ${(0, path.relative)(ctx.rootDir, absFile)}`);
1270
+ ctx.trace(`Deleted file pruned: ${(0, path.relative)(ctx.rootDir, absFile)}`);
1181
1271
  invalidateFileModules(ctx, (0, _animus_ui_extract_pipeline.diffFilePlans)(prevPlans, (0, _animus_ui_extract_pipeline.snapshotFilePlans)(ctx.storedManifest)));
1182
1272
  ctx.invalidateExtractedModules();
1183
1273
  }
@@ -1199,7 +1289,7 @@ function invalidateStaleModules(ctx, environment, modules, analyzed) {
1199
1289
  const absDefPath = (0, path.resolve)(ctx.rootDir, defFile);
1200
1290
  const defModule = graph.getModuleById(absDefPath) ?? graph.getModulesByFile(absDefPath)?.values().next().value;
1201
1291
  if (defModule) {
1202
- ctx.log(`HMR invalidate: ${defFile} (replacement changed)`);
1292
+ ctx.trace(`HMR invalidate: ${defFile} (re-delivered)`);
1203
1293
  graph.invalidateModule(defModule);
1204
1294
  modulesToUpdate.push(defModule);
1205
1295
  }
package/dist/index.d.ts CHANGED
@@ -19,15 +19,21 @@ export interface AnimusExtractOptions {
19
19
  * `@mdx-js/mdx` peer, or those files warn once and are skipped.
20
20
  */
21
21
  extensions?: string[];
22
- /** Extraction failures throw instead of warning. */
22
+ /**
23
+ * Error-severity diagnostics — lost configured inputs and classified
24
+ * unsupported Animus declarations — fail the build instead of warning.
25
+ * Omitted or `false` warns.
26
+ */
23
27
  strict?: boolean;
24
28
  /**
25
29
  * Run a structural self-check at the end of `buildStart`; failures throw
26
30
  * under `strict`, otherwise warn.
27
31
  */
28
32
  verify?: boolean;
29
- /** Verbose logging; also enabled by `ANIMUS_DEBUG=1`. */
30
- verbose?: boolean;
33
+ /** `true` logs phase checkpoints, summaries and timing (`ANIMUS_DEBUG=1`);
34
+ * `'trace'` also logs one line per pruned option, transformed file and
35
+ * HMR decision (`ANIMUS_DEBUG=trace`). */
36
+ verbose?: boolean | 'trace';
31
37
  /**
32
38
  * Browserslist queries for autoprefixing and syntax lowering; falls back
33
39
  * to the project's browserslist config, then to `defaults`.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAMD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAsFnE;eAEc,aAAa"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;+CAE2C;IAC3C,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,aAAa,GAAG,YAAY,CAAC;IACpC,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;;;OAGG;IACH,mBAAmB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAMD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAsFnE;eAEc,aAAa"}
@@ -1,7 +1,8 @@
1
1
  import type { PluginContext } from './context';
2
2
  /**
3
- * Completeness is load-bearing: the file-plan diff is the only invalidation
4
- * candidate source, so a node shape missed here stays stale for the session.
3
+ * Completeness is load-bearing: the file-plan diff and the sources re-delivered
4
+ * when a held publication ends are the only invalidation candidate sources, so
5
+ * a node shape missed here stays stale for the session.
5
6
  */
6
7
  export declare function invalidateFileModules(ctx: PluginContext, relPaths: string[]): number;
7
8
  //# sourceMappingURL=module-invalidation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"module-invalidation.d.ts","sourceRoot":"","sources":["../src/module-invalidation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,CAmCR"}
1
+ {"version":3,"file":"module-invalidation.d.ts","sourceRoot":"","sources":["../src/module-invalidation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,CAqCR"}
@@ -1 +1 @@
1
- {"version":3,"file":"rediscovery.d.ts","sourceRoot":"","sources":["../src/rediscovery.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,GACjB,oBAAoB,EAAE,CAWxB;AAOD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAa3E;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,OAAO,CAAC,CAqElB"}
1
+ {"version":3,"file":"rediscovery.d.ts","sourceRoot":"","sources":["../src/rediscovery.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,GACjB,oBAAoB,EAAE,CAWxB;AAOD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,WAAW,CAAC,MAAM,CAAC,CAa3E;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,OAAO,CAAC,CAyElB"}
@@ -4,6 +4,9 @@ import type { PluginContext } from './context';
4
4
  * becomes an ordinary expression and the module loses its client marking.
5
5
  */
6
6
  export declare function applyDevBridgeImport(code: string): string;
7
+ /** The files defining a transitive extension of a component the given
8
+ * analysis paths define, from the published provenance. */
9
+ export declare function extendingFiles(ctx: PluginContext, analysisPaths: readonly string[]): Set<string>;
7
10
  export declare function transformSource(ctx: PluginContext, code: string, id: string): Promise<{
8
11
  code: string;
9
12
  map: null;
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AA4BD,wBAAsB,eAAe,CACnC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC,CA2J7C"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;4DAC4D;AAC5D,wBAAgB,cAAc,CAC5B,GAAG,EAAE,aAAa,EAClB,aAAa,EAAE,SAAS,MAAM,EAAE,GAC/B,GAAG,CAAC,MAAM,CAAC,CAkBb;AAQD,wBAAsB,eAAe,CACnC,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC,CAuK7C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@animus-ui/vite-plugin",
3
- "version": "0.1.16",
3
+ "version": "0.1.17",
4
4
  "description": "Animus static CSS extraction Vite plugin",
5
5
  "keywords": [
6
6
  "animus",
@@ -39,12 +39,12 @@
39
39
  "compile": "tsc --noEmit"
40
40
  },
41
41
  "dependencies": {
42
- "@animus-ui/extract": "0.1.16",
42
+ "@animus-ui/extract": "0.1.17",
43
43
  "browserslist": "^4.28.8",
44
44
  "lightningcss": "^1.33.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@animus-ui/assertions": "0.1.16"
47
+ "@animus-ui/assertions": "0.1.17"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "@mdx-js/mdx": "^3.0.0",