@animus-ui/extract 0.1.26 → 0.1.27

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/session.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_pipeline = require("./pipeline-DyUf-eKZ.cjs");
2
+ const require_pipeline = require("./pipeline-CPSPw522.cjs");
3
3
  let crypto = require("crypto");
4
4
  let fs = require("fs");
5
5
  let path = require("path");
@@ -51,6 +51,50 @@ var CoalescingWindow = class {
51
51
  }
52
52
  };
53
53
  //#endregion
54
+ //#region session/environment-builds.ts
55
+ /**
56
+ * Each environment build that started and has not ended, by name. A host
57
+ * that builds a shared plugin's environments in parallel (a Vite `buildApp`)
58
+ * shares one build among them, retired by the last to end. A build under a
59
+ * name whose build is open (a reused builder, or a second environment under
60
+ * one name) waits for that build's end, so each build ends only its own
61
+ * generation, once.
62
+ */
63
+ var EnvironmentBuilds = class {
64
+ /** What a host without environments builds as. */
65
+ single = { name: "build" };
66
+ builds = /* @__PURE__ */ new Map();
67
+ /** Opens `environment`'s build once no build under its name is open;
68
+ * whether another environment's build is open beside it. */
69
+ async open(environment) {
70
+ for (;;) {
71
+ const open = this.builds.get(environment.name);
72
+ if (open === void 0) break;
73
+ await open.ended;
74
+ }
75
+ let end = () => {};
76
+ const ended = new Promise((settle) => {
77
+ end = settle;
78
+ });
79
+ this.builds.set(environment.name, {
80
+ environment,
81
+ ended,
82
+ end
83
+ });
84
+ return this.builds.size > 1;
85
+ }
86
+ /** Ends `environment`'s build if this environment opened it; whether that
87
+ * left none open. A host can end an environment it never opened (a dev
88
+ * server ends every environment, started or not), which ends nothing. */
89
+ end(environment) {
90
+ const open = this.builds.get(environment.name);
91
+ if (open === void 0 || open.environment !== environment) return false;
92
+ this.builds.delete(environment.name);
93
+ open.end();
94
+ return this.builds.size === 0;
95
+ }
96
+ };
97
+ //#endregion
54
98
  //#region pipeline/system-instances.ts
55
99
  /**
56
100
  * The system and the analysis read one instance of each kit (spec §2.2
@@ -60,11 +104,11 @@ var CoalescingWindow = class {
60
104
  * one the system evaluated is refused: its components would be extracted
61
105
  * against another instance's vocabulary.
62
106
  */
63
- function realPath(path$38) {
107
+ function realPath(path$39) {
64
108
  try {
65
- return (0, fs.realpathSync)(path$38);
109
+ return (0, fs.realpathSync)(path$39);
66
110
  } catch {
67
- return path$38;
111
+ return path$39;
68
112
  }
69
113
  }
70
114
  /**
@@ -75,7 +119,7 @@ function realPath(path$38) {
75
119
  */
76
120
  function systemInstanceMismatches(input) {
77
121
  const evaluated = new Set(input.evaluated.map(realPath));
78
- const shown = (path$39) => (0, path.relative)(input.rootDir, path$39).split(path.sep).join("/");
122
+ const shown = (path$40) => (0, path.relative)(input.rootDir, path$40).split(path.sep).join("/");
79
123
  const diagnostics = [];
80
124
  for (const specifier of input.specifiers) {
81
125
  if (!require_pipeline.isPackageSpecifier(specifier)) continue;
@@ -315,7 +359,7 @@ function lockRecordBytes(startedAt, build) {
315
359
  const HEARTBEAT_TEMP_PREFIX = ".lock-heartbeat-";
316
360
  function holdDirectoryClaim(dir, options = {}) {
317
361
  const startedAt = options.startedAt ?? (/* @__PURE__ */ new Date()).toISOString();
318
- const path$37 = (0, path.join)(dir, CLI_LOCK_ARTIFACT);
362
+ const path$38 = (0, path.join)(dir, CLI_LOCK_ARTIFACT);
319
363
  const tempPath = (0, path.join)(dir, `${HEARTBEAT_TEMP_PREFIX}${process.pid}`);
320
364
  const rename = options.write === "rename";
321
365
  let refresh = null;
@@ -329,12 +373,12 @@ function holdDirectoryClaim(dir, options = {}) {
329
373
  try {
330
374
  if (rename) {
331
375
  (0, fs.writeFileSync)(tempPath, lockRecordBytes(startedAt, options.build));
332
- (0, fs.renameSync)(tempPath, path$37);
333
- } else (0, fs.writeFileSync)(path$37, lockRecordBytes(startedAt, options.build));
376
+ (0, fs.renameSync)(tempPath, path$38);
377
+ } else (0, fs.writeFileSync)(path$38, lockRecordBytes(startedAt, options.build));
334
378
  } catch (error) {
335
379
  stop();
336
380
  if (isMissingFile(error)) return;
337
- console.error(`[animus] Could not write the directory claim ${path$37}: ${String(error)}`);
381
+ console.error(`[animus] Could not write the directory claim ${path$38}: ${String(error)}`);
338
382
  }
339
383
  };
340
384
  stamp();
@@ -345,7 +389,7 @@ function holdDirectoryClaim(dir, options = {}) {
345
389
  return () => {
346
390
  stop();
347
391
  if (rename) (0, fs.rmSync)(tempPath, { force: true });
348
- (0, fs.rmSync)(path$37, { force: true });
392
+ (0, fs.rmSync)(path$38, { force: true });
349
393
  };
350
394
  }
351
395
  /** Snapshot the session's copied asset() files, sorted, BEFORE the session
@@ -373,11 +417,15 @@ function joined(key) {
373
417
  if (state === void 0) throw new Error(`[animus] no participant has joined build ${key.build} of ${key.root}`);
374
418
  return state;
375
419
  }
376
- function getManifestJson(key) {
377
- return findSession(key)?.manifestJson ?? null;
420
+ /** Commits the build's publication, the one write of everything below. */
421
+ function setPublication(key, publication) {
422
+ joined(key).publication = publication;
378
423
  }
379
- function setManifestJson(key, json) {
380
- joined(key).manifestJson = json;
424
+ function publicationOf(key) {
425
+ return findSession(key)?.publication ?? null;
426
+ }
427
+ function getManifestJson(key) {
428
+ return publicationOf(key)?.manifestJson ?? null;
381
429
  }
382
430
  /**
383
431
  * A latch over the most recently STARTED analysis, never cleared on settle:
@@ -402,36 +450,21 @@ function claimUnmatchedExcludeReport(key) {
402
450
  return true;
403
451
  }
404
452
  function getSharedCss(key) {
405
- return findSession(key)?.sharedCss ?? "";
406
- }
407
- function setSharedCss(key, css) {
408
- joined(key).sharedCss = css;
453
+ return publicationOf(key)?.styles ?? "";
409
454
  }
410
455
  function getSharedSystemProps(key) {
411
- return findSession(key)?.sharedSystemProps ?? "";
412
- }
413
- function setSharedSystemProps(key, content) {
414
- joined(key).sharedSystemProps = content;
456
+ return publicationOf(key)?.systemPropsModule ?? "";
415
457
  }
416
458
  function getSharedExternalDirs(key) {
417
- return findSession(key)?.externalDirs ?? [];
418
- }
419
- function setSharedExternalDirs(key, dirs) {
420
- joined(key).externalDirs = dirs;
459
+ return publicationOf(key)?.externalPackageDirs ?? [];
421
460
  }
422
461
  function getSharedExternalEntries(key) {
423
- return findSession(key)?.externalEntries ?? /* @__PURE__ */ new Map();
424
- }
425
- function setSharedExternalEntries(key, entries) {
426
- joined(key).externalEntries = entries;
462
+ return publicationOf(key)?.externalSourceEntries ?? /* @__PURE__ */ new Map();
427
463
  }
428
464
  /** Specifier → its source entry's side effects, published with the shared
429
465
  * entries; absent leaves the bundler's own classification. */
430
466
  function getSharedExternalSideEffects(key) {
431
- return findSession(key)?.externalSideEffects ?? /* @__PURE__ */ new Map();
432
- }
433
- function setSharedExternalSideEffects(key, sideEffects) {
434
- joined(key).externalSideEffects = sideEffects;
467
+ return publicationOf(key)?.externalSourceSideEffects ?? /* @__PURE__ */ new Map();
435
468
  }
436
469
  /**
437
470
  * The only session of a build that can run watch analysis. A non-owning
@@ -449,18 +482,12 @@ function setOwningWatchSession(key, session) {
449
482
  * the exact bytes analyzed), including files that produced zero entries.
450
483
  */
451
484
  function getAnalyzedHashes(key) {
452
- return findSession(key)?.analyzedHashes ?? null;
453
- }
454
- function setAnalyzedHashes(key, hashes) {
455
- joined(key).analyzedHashes = hashes;
485
+ return publicationOf(key)?.analyzedHashes ?? null;
456
486
  }
457
487
  /** What the build's last published analysis read of the discovered
458
488
  * packages (spec §2.2 A4); null before one publishes. */
459
489
  function getSharedPackageReadRecord(key) {
460
- return findSession(key)?.packageReadRecord ?? null;
461
- }
462
- function setSharedPackageReadRecord(key, record) {
463
- joined(key).packageReadRecord = record;
490
+ return publicationOf(key)?.packageReadRecord ?? null;
464
491
  }
465
492
  /**
466
493
  * One participant publishes a build's analysis, holding this claim until it
@@ -486,15 +513,10 @@ function getSessionArtifactDir(key) {
486
513
  function setSessionArtifactDir(key, dir) {
487
514
  joined(key).artifactDir = dir;
488
515
  }
489
- /**
490
- * Replacement epoch of the last published analysis, written AFTER the
491
- * manifest so an epoch reader always sees at least that generation's manifest.
492
- */
516
+ /** Replacement epoch of the last published analysis: committed in the same
517
+ * record as its manifest, so an epoch reader sees that generation's. */
493
518
  function getReplacementEpoch(key) {
494
- return findSession(key)?.replacementEpoch ?? null;
495
- }
496
- function setReplacementEpoch(key, epoch) {
497
- joined(key).replacementEpoch = epoch;
519
+ return publicationOf(key)?.replacementEpoch ?? null;
498
520
  }
499
521
  /**
500
522
  * The build's one in-flight watch-analysis transaction: a participant that
@@ -672,6 +694,7 @@ const OPTION_CLASSES = {
672
694
  layers: digestOf("layers"),
673
695
  engine: digestOf("engine"),
674
696
  mode: digestOf("mode"),
697
+ runtimeImport: digestOf("runtimeImport"),
675
698
  root: "excluded"
676
699
  };
677
700
  /** The options a build's analysis depends on, each as stable text; each is
@@ -724,15 +747,7 @@ function joinSession(key, participant, options) {
724
747
  },
725
748
  systemAuthority: null,
726
749
  claimRecord: null,
727
- manifestJson: null,
728
- sharedCss: "",
729
- sharedSystemProps: "",
730
- externalDirs: [],
731
- externalEntries: /* @__PURE__ */ new Map(),
732
- externalSideEffects: /* @__PURE__ */ new Map(),
733
- analyzedHashes: null,
734
- packageReadRecord: null,
735
- replacementEpoch: null,
750
+ publication: null,
736
751
  artifactDir: null,
737
752
  unmatchedExcludesReported: false
738
753
  };
@@ -887,6 +902,9 @@ function misspelledHostSources(hostSources, readPaths) {
887
902
  function isDiskNumber(value) {
888
903
  return Object(value) !== value && Object.prototype.toString.call(value) === "[object Number]";
889
904
  }
905
+ /** The session's own system-props file, imported by absolute path: what a
906
+ * host that serves no system-props module (the CLI) delivers. */
907
+ const SESSION_ARTIFACT = Symbol("animus.session-artifact");
890
908
  /** A file's content hash, or '' when it cannot be read. */
891
909
  function fileHashOrEmpty(path$7) {
892
910
  try {
@@ -906,9 +924,6 @@ var ExtractionSession = class {
906
924
  host;
907
925
  /** Set by the adapter before any pipeline run. */
908
926
  rootDir = null;
909
- /** The module extracted terminals import their factories from; an
910
- * override must supply every terminal the analysis extracts. */
911
- runtimeImport = require_pipeline.DEFAULT_RUNTIME_IMPORT;
912
927
  /** A host that resolves imports itself (Vite's `this.resolve`): package
913
928
  * discovery asks it first, the loader only for a declared workspace it
914
929
  * cannot resolve. Null resolves through the loader alone. */
@@ -942,12 +957,12 @@ var ExtractionSession = class {
942
957
  /** Physical asset files registered with the host watcher. */
943
958
  assetDependencyPaths = /* @__PURE__ */ new Set();
944
959
  assetDependencyKeys = /* @__PURE__ */ new Set();
945
- /** System-props module id override. Turbopack rejects absolute-path
946
- * imports, so its driver sets a virtual id; null injects the abs path. */
947
- systemPropsModuleId = null;
948
- /** The stylesheet module generated code imports; a host that serves the
949
- * stylesheet itself names its own. */
950
- cssModuleId = ANIMUS_CSS_MODULE_ID;
960
+ /** What generated code imports; a host that serves its own modules
961
+ * declares them before planning. */
962
+ delivery = {
963
+ cssModuleId: ANIMUS_CSS_MODULE_ID,
964
+ systemPropsModuleId: SESSION_ARTIFACT
965
+ };
951
966
  /** Whether the analysis-inputs hydration corpus is written to disk. Only
952
967
  * isolated loader workers replay it; an in-process loader reads memory. */
953
968
  persistAnalysisInputs = false;
@@ -1019,8 +1034,8 @@ var ExtractionSession = class {
1019
1034
  get heldSources() {
1020
1035
  return this.fileCache;
1021
1036
  }
1022
- /** The generation an emit produced, current once its ingestion
1023
- * publishes. */
1037
+ /** The generation an emit produced, until it commits with the
1038
+ * ingestion's ownership and the external package state it analysed. */
1024
1039
  stagedPublication = null;
1025
1040
  options;
1026
1041
  staticCssJson;
@@ -1062,10 +1077,31 @@ var ExtractionSession = class {
1062
1077
  };
1063
1078
  }
1064
1079
  systemDependencyKeys = /* @__PURE__ */ new Set();
1080
+ /** What a host watches for this Session, one list for every host: the
1081
+ * files whose change it acts on (the system module and the modules it
1082
+ * read, asset() sources, the configuration inputs), the paths the system
1083
+ * load found absent, whose creation reloads it, and the external package
1084
+ * roots, watched recursively. An absent path inside `covered` (roots the
1085
+ * host already watches recursively) is left out: a host's recursive
1086
+ * watch reports its creation, and watching an absent file inside a
1087
+ * watched directory can stop that directory's events (inotify). */
1088
+ watchPlan(covered = []) {
1089
+ const system = this.rootDir === null ? [] : [(0, path.resolve)(this.rootDir, this.options.system)];
1090
+ return {
1091
+ files: [.../* @__PURE__ */ new Set([
1092
+ ...system,
1093
+ ...this.systemDependencyPaths,
1094
+ ...this.assetDependencyPaths,
1095
+ ...this.configInputPaths
1096
+ ])],
1097
+ missing: this.systemMissingPaths.filter((path$9) => !covered.some((root) => require_pipeline.isPathWithinRoot(root, path$9))),
1098
+ directories: [...this.externalWatchRoots]
1099
+ };
1100
+ }
1065
1101
  /** Whether `path` is the system module, one of its dependencies, or a
1066
1102
  * path its load found absent: a change to it reloads the system. */
1067
- isSystemDependency(path$9) {
1068
- return require_pipeline.toWatchKeys(path$9).some((key) => this.systemDependencyKeys.has(key));
1103
+ isSystemDependency(path$10) {
1104
+ return require_pipeline.toWatchKeys(path$10).some((key) => this.systemDependencyKeys.has(key));
1069
1105
  }
1070
1106
  /** Loader-reported dependency paths for bundler watch registration. */
1071
1107
  systemDependencyPaths = [];
@@ -1153,6 +1189,10 @@ var ExtractionSession = class {
1153
1189
  this.ingestionFailureDiagnostics = this.ingestionFailureDiagnostics.filter((diagnostic) => diagnostic.file !== relPath);
1154
1190
  return this.ingestionFailureDiagnostics.length !== before;
1155
1191
  }
1192
+ /** The module extracted terminals import their factories from. */
1193
+ get runtimeImport() {
1194
+ return this.options.runtimeImport ?? "@animus-ui/system/runtime";
1195
+ }
1156
1196
  get sessionDir() {
1157
1197
  return sessionArtifactDir(this.rootDir, this.sessionId);
1158
1198
  }
@@ -1276,27 +1316,27 @@ var ExtractionSession = class {
1276
1316
  recordObservation(changes) {
1277
1317
  const queue = observationQueue(this.key);
1278
1318
  const observed = /* @__PURE__ */ new Map();
1279
- for (const path$10 of changes.modifiedFiles ?? []) {
1319
+ for (const path$11 of changes.modifiedFiles ?? []) {
1280
1320
  let state;
1281
1321
  try {
1282
- state = require_pipeline.contentHash(changes.sources?.get(path$10) ?? (0, fs.readFileSync)(path$10, "utf-8"));
1322
+ state = require_pipeline.contentHash(changes.sources?.get(path$11) ?? (0, fs.readFileSync)(path$11, "utf-8"));
1283
1323
  } catch {
1284
1324
  state = UNREADABLE_OBSERVATION;
1285
1325
  }
1286
- observed.set(path$10, state);
1326
+ observed.set(path$11, state);
1287
1327
  }
1288
- for (const path$11 of changes.removedFiles ?? []) observed.set(path$11, REMOVED_OBSERVATION);
1328
+ for (const path$12 of changes.removedFiles ?? []) observed.set(path$12, REMOVED_OBSERVATION);
1289
1329
  const revision = ++queue.revision;
1290
1330
  const active = queue.active;
1291
- if (active !== null && [...observed].every(([path$12, state]) => !queue.untaken.has(path$12) && active.taken.get(path$12) === state)) {
1331
+ if (active !== null && [...observed].every(([path$13, state]) => !queue.untaken.has(path$13) && active.taken.get(path$13) === state)) {
1292
1332
  queue.revisions.set(revision, active.transaction);
1293
1333
  return revision;
1294
1334
  }
1295
- for (const [path$13, state] of observed) {
1296
- queue.untaken.set(path$13, state);
1297
- const supplied = changes.sources?.get(path$13);
1298
- if (supplied === void 0) queue.suppliedSources.delete(path$13);
1299
- else queue.suppliedSources.set(path$13, supplied);
1335
+ for (const [path$14, state] of observed) {
1336
+ queue.untaken.set(path$14, state);
1337
+ const supplied = changes.sources?.get(path$14);
1338
+ if (supplied === void 0) queue.suppliedSources.delete(path$14);
1339
+ else queue.suppliedSources.set(path$14, supplied);
1300
1340
  }
1301
1341
  queue.revisions.set(revision, null);
1302
1342
  return revision;
@@ -1334,7 +1374,7 @@ var ExtractionSession = class {
1334
1374
  const { taken, rescan, sources } = this.takeObservations();
1335
1375
  const modifiedFiles = /* @__PURE__ */ new Set();
1336
1376
  const removedFiles = /* @__PURE__ */ new Set();
1337
- for (const [path$14, state] of taken) (state === REMOVED_OBSERVATION ? removedFiles : modifiedFiles).add(path$14);
1377
+ for (const [path$15, state] of taken) (state === REMOVED_OBSERVATION ? removedFiles : modifiedFiles).add(path$15);
1338
1378
  this.settleTaken(taken, this.runWatchAttempt({
1339
1379
  modifiedFiles,
1340
1380
  removedFiles,
@@ -1399,11 +1439,11 @@ var ExtractionSession = class {
1399
1439
  if (changed.length === 0) {
1400
1440
  systemHit = firstChangedFile(this.systemDependencyHashes);
1401
1441
  if (systemHit === void 0) configHit = firstChangedFile(this.configInputHashes);
1402
- } else systemHit = changed.find((path$15) => this.isSystemDependency(path$15));
1442
+ } else systemHit = changed.find((path$16) => this.isSystemDependency(path$16));
1403
1443
  } catch (err) {
1404
1444
  this.warn(`HMR system-reload check failed: ${String(err)}`);
1405
1445
  }
1406
- configHit ??= changed.find((path$16) => require_pipeline.toWatchKeys(path$16).some((key) => this.configInputKeys.has(key)));
1446
+ configHit ??= changed.find((path$17) => require_pipeline.toWatchKeys(path$17).some((key) => this.configInputKeys.has(key)));
1407
1447
  const debtRetry = this.systemReloadOwed && this.heldRejection === null;
1408
1448
  if (systemHit || configHit || debtRetry) {
1409
1449
  this.log(systemHit ? `system reload: system dependency changed (${(0, path.relative)(rootDir, systemHit)})` : configHit ? `system reload: configuration changed (${(0, path.relative)(rootDir, configHit)})` : "system reload: retrying the reload a failure left owed");
@@ -1423,13 +1463,14 @@ var ExtractionSession = class {
1423
1463
  }
1424
1464
  return;
1425
1465
  }
1426
- if (changed.some((path$17) => require_pipeline.toWatchKeys(path$17).some((key) => this.assetDependencyKeys.has(key)))) {
1466
+ if (changed.some((path$18) => require_pipeline.toWatchKeys(path$18).some((key) => this.assetDependencyKeys.has(key)))) {
1427
1467
  this.assetCopyCache.clear();
1428
1468
  assetChanged = true;
1429
1469
  }
1430
1470
  const { excludeMatcher, extensionsSet } = this.scanConfig;
1431
1471
  const priorCacheEntries = /* @__PURE__ */ new Map();
1432
1472
  const priorExternalFileOwners = { ...this.externalFileOwners };
1473
+ const priorHostSuppliedKeys = new Set(this.hostSuppliedKeys);
1433
1474
  const recordPrior = (key) => {
1434
1475
  if (!priorCacheEntries.has(key)) priorCacheEntries.set(key, this.fileCache.get(key) ?? null);
1435
1476
  };
@@ -1579,6 +1620,7 @@ var ExtractionSession = class {
1579
1620
  else this.fileCache.set(key, prior);
1580
1621
  }
1581
1622
  this.externalFileOwners = priorExternalFileOwners;
1623
+ this.hostSuppliedKeys = priorHostSuppliedKeys;
1582
1624
  }
1583
1625
  if (this.statusAttemptOpen) {
1584
1626
  this.debouncePending.clear();
@@ -1586,7 +1628,7 @@ var ExtractionSession = class {
1586
1628
  }
1587
1629
  throw err;
1588
1630
  }
1589
- this.publishSourceIngestion(ingested, "incremental", (path$18) => this.fileCache.get(path$18));
1631
+ this.publishSourceIngestion(ingested, "incremental", (path$19) => this.fileCache.get(path$19));
1590
1632
  commitObservedBatch();
1591
1633
  } else if (this.statusAttemptOpen) {
1592
1634
  this.debouncePending.clear();
@@ -1607,6 +1649,20 @@ var ExtractionSession = class {
1607
1649
  });
1608
1650
  throw new AbortedParseRejection(rejection.message);
1609
1651
  }
1652
+ /** Holds a held full read's entries: what it read stays the held bytes,
1653
+ * never overwriting held host bytes with the disk's (a key the host
1654
+ * supplied before that this read took from disk keeps its bytes). */
1655
+ holdObservedEntries(entries, supplied) {
1656
+ for (const entry of entries) {
1657
+ const fromHost = supplied.has(entry.path);
1658
+ if (this.hostSuppliedKeys.has(entry.path) && !fromHost) continue;
1659
+ this.fileCache.set(entry.path, {
1660
+ hash: entry.hash,
1661
+ source: entry.source
1662
+ });
1663
+ if (fromHost) this.hostSuppliedKeys.add(entry.path);
1664
+ }
1665
+ }
1610
1666
  /** Held sources whose bytes the host supplied and which the disk no
1611
1667
  * longer matches: a full read not carrying them (`carried`) would
1612
1668
  * publish the disk's bytes in their place. */
@@ -1638,9 +1694,9 @@ var ExtractionSession = class {
1638
1694
  hash: entry.hash,
1639
1695
  source: entry.source
1640
1696
  }]));
1641
- for (const path$19 of result.skippedOriginals ?? []) {
1642
- const entry = raw(path$19);
1643
- if (entry) held.set(path$19, {
1697
+ for (const path$20 of result.skippedOriginals ?? []) {
1698
+ const entry = raw(path$20);
1699
+ if (entry) held.set(path$20, {
1644
1700
  hash: entry.hash ?? require_pipeline.contentHash(entry.source),
1645
1701
  source: entry.source
1646
1702
  });
@@ -1653,9 +1709,13 @@ var ExtractionSession = class {
1653
1709
  const previous = this.publication;
1654
1710
  const publication = {
1655
1711
  ...staged,
1656
- ownership: result.ownership
1712
+ ownership: result.ownership,
1713
+ externalPackageDirs: this.externalPackageDirs,
1714
+ externalSourceEntries: this.externalSourceEntries,
1715
+ externalSourceSideEffects: this.externalSourceSideEffects
1657
1716
  };
1658
1717
  this.publication = publication;
1718
+ setPublication(this.key, publication);
1659
1719
  this.onOutcome?.({
1660
1720
  kind: "published",
1661
1721
  publication,
@@ -1713,18 +1773,18 @@ var ExtractionSession = class {
1713
1773
  * paths it found absent, whose creation is a system change. */
1714
1774
  recordSystemDependencies(systemPath, dependencies, missing) {
1715
1775
  const keys = /* @__PURE__ */ new Set();
1716
- for (const path$20 of [
1776
+ for (const path$21 of [
1717
1777
  systemPath,
1718
1778
  ...dependencies,
1719
1779
  ...missing
1720
- ]) for (const key of require_pipeline.toWatchKeys(path$20)) keys.add(key);
1780
+ ]) for (const key of require_pipeline.toWatchKeys(path$21)) keys.add(key);
1721
1781
  const hashes = /* @__PURE__ */ new Map();
1722
1782
  for (const dep of dependencies.length > 0 ? dependencies : [systemPath]) try {
1723
1783
  hashes.set(dep, require_pipeline.contentHash((0, fs.readFileSync)(dep, "utf-8")));
1724
1784
  } catch {
1725
1785
  hashes.set(dep, "");
1726
1786
  }
1727
- for (const path$21 of missing) hashes.set(path$21, "");
1787
+ for (const path$22 of missing) hashes.set(path$22, "");
1728
1788
  this.systemDependencyKeys = keys;
1729
1789
  this.systemDependencyPaths = dependencies;
1730
1790
  this.systemMissingPaths = missing;
@@ -1735,8 +1795,8 @@ var ExtractionSession = class {
1735
1795
  * re-reads its aliases. */
1736
1796
  readConfigInputs(rootDir) {
1737
1797
  this.configInputPaths = [(0, path.join)(rootDir, "package.json"), ...require_pipeline.tsconfigChainPaths(rootDir)];
1738
- this.configInputKeys = new Set(this.configInputPaths.flatMap((path$22) => require_pipeline.toWatchKeys(path$22)));
1739
- this.configInputHashes = new Map(this.configInputPaths.map((path$23) => [path$23, fileHashOrEmpty(path$23)]));
1798
+ this.configInputKeys = new Set(this.configInputPaths.flatMap((path$23) => require_pipeline.toWatchKeys(path$23)));
1799
+ this.configInputHashes = new Map(this.configInputPaths.map((path$24) => [path$24, fileHashOrEmpty(path$24)]));
1740
1800
  if (this.aliasesFromTsconfig) this.pathAliasesJson = require_pipeline.buildPathAliasesJson(require_pipeline.readTsconfigAliasPairs(rootDir), rootDir)?.json ?? null;
1741
1801
  }
1742
1802
  /** What hosts watch for assets, and what the last-good generation
@@ -1819,15 +1879,15 @@ var ExtractionSession = class {
1819
1879
  const rawEntries = [];
1820
1880
  const ingestionFailures = [];
1821
1881
  const readPaths = /* @__PURE__ */ new Set();
1882
+ const supplied = /* @__PURE__ */ new Set();
1822
1883
  for (const filePath of files) {
1823
1884
  const relPath = (0, path.relative)(rootDir, filePath);
1824
1885
  readPaths.add(filePath);
1825
1886
  let source;
1826
1887
  try {
1827
- const supplied = hostSources.get(filePath);
1828
- source = supplied ?? (0, fs.readFileSync)(filePath, "utf-8");
1829
- if (supplied === void 0) this.hostSuppliedKeys.delete(relPath);
1830
- else this.hostSuppliedKeys.add(relPath);
1888
+ const hostSource = hostSources.get(filePath);
1889
+ source = hostSource ?? (0, fs.readFileSync)(filePath, "utf-8");
1890
+ if (hostSource !== void 0) supplied.add(relPath);
1831
1891
  } catch (err) {
1832
1892
  if (!require_pipeline.isDeletedSource(err)) ingestionFailures.push(require_pipeline.unreadableSourceDiagnostic(relPath, err));
1833
1893
  continue;
@@ -1957,7 +2017,9 @@ var ExtractionSession = class {
1957
2017
  for (const entry of admitted.entries) {
1958
2018
  const entryPath = (0, path.resolve)(rootDir, entry.path);
1959
2019
  readPaths.add(entryPath);
1960
- const source = hostSources.get(entryPath) ?? entry.source;
2020
+ const hostSource = hostSources.get(entryPath);
2021
+ if (hostSource !== void 0) supplied.add(entry.path);
2022
+ const source = hostSource ?? entry.source;
1961
2023
  rawEntries.push({
1962
2024
  path: entry.path,
1963
2025
  source,
@@ -1968,17 +2030,19 @@ var ExtractionSession = class {
1968
2030
  this.externalLinkedDirs = admitted.linkedDirs;
1969
2031
  this.externalOutputDirs = admitted.outputDirs;
1970
2032
  bt.packageResolve = this.elapsed(t);
1971
- const misspelled = misspelledHostSources(hostSources, readPaths).map(({ path: path$24, read }) => `${(0, path.relative)(rootDir, path$24)} (read as ${read.map((readPath) => (0, path.relative)(rootDir, readPath)).join(", ")})`);
2033
+ const misspelled = misspelledHostSources(hostSources, readPaths).map(({ path: path$25, read }) => `${(0, path.relative)(rootDir, path$25)} (read as ${read.map((readPath) => (0, path.relative)(rootDir, readPath)).join(", ")})`);
1972
2034
  if (misspelled.length > 0) throw new DeferredReloadRefusal(`[${this.driverLabel}] reload not published: the host supplied bytes for ${misspelled.join(", ")}, which the full read reaches only under another spelling; the last generation stays served`);
1973
2035
  this.beginStatusAttempt();
1974
2036
  let accepted;
2037
+ const readEntries = this.withoutOutputSources(rawEntries);
1975
2038
  try {
1976
- accepted = await this.corpus.prepare(this.withoutOutputSources(rawEntries));
2039
+ accepted = await this.corpus.prepare(readEntries);
1977
2040
  this.throwOnAbortedParse(accepted);
1978
2041
  this.skippedSources = accepted.skippedOriginals ?? [];
1979
2042
  this.ingestionOpenings = accepted.openings ?? [];
1980
2043
  this.ingestionAdapted = require_pipeline.adaptedOriginals(accepted.ownership);
1981
2044
  } catch (err) {
2045
+ if (err instanceof AbortedParseRejection) this.holdObservedEntries(readEntries, supplied);
1982
2046
  this.debouncePending.clear();
1983
2047
  this.writeAnalysisStatus("failed", pending, String(err));
1984
2048
  throw err;
@@ -1987,10 +2051,8 @@ var ExtractionSession = class {
1987
2051
  bt.fileCount = accepted.analysisEntries.length;
1988
2052
  require_pipeline.clearEngineCache(() => this.engine());
1989
2053
  await this.analyzeAndEmit(accepted.analysisEntries, packageMap, false, bt, pipelineStart, pending);
1990
- this.publishSourceIngestion(accepted, "full", (path$25) => rawEntries.find((entry) => entry.path === path$25));
1991
- setSharedExternalDirs(this.key, admitted.packageDirs);
1992
- setSharedExternalEntries(this.key, admitted.sourceEntries);
1993
- setSharedExternalSideEffects(this.key, admitted.sourceEntrySideEffects);
2054
+ this.publishSourceIngestion(accepted, "full", (path$26) => rawEntries.find((entry) => entry.path === path$26));
2055
+ this.hostSuppliedKeys = supplied;
1994
2056
  this.onExternalRootsCommitted?.(this.externalWatchRoots);
1995
2057
  setOwningWatchSession(this.key, this);
1996
2058
  } catch (err) {
@@ -2072,7 +2134,7 @@ var ExtractionSession = class {
2072
2134
  if (own.identity === authority.identity) return;
2073
2135
  const shared = new Set(authority.dependencies);
2074
2136
  const mine = new Set(own.dependencies);
2075
- const differing = [...authority.dependencies.filter((path$26) => !mine.has(path$26)), ...own.dependencies.filter((path$27) => !shared.has(path$27))].map((path$28) => (0, path.relative)(this.rootDir, path$28));
2137
+ const differing = [...authority.dependencies.filter((path$27) => !mine.has(path$27)), ...own.dependencies.filter((path$28) => !shared.has(path$28))].map((path$29) => (0, path.relative)(this.rootDir, path$29));
2076
2138
  throw new SessionConfigurationConflict(this.key, authority.label, this.resolutionContextLabel(), differing.length > 0 ? [`system modules ${differing.join(", ")}`] : ["the evaluated system"], "Every participant of one build must evaluate the same system: give each compiler conditions that select the same system modules.");
2077
2139
  }
2078
2140
  /** Release this session's publication claim so a successor may publish,
@@ -2081,6 +2143,7 @@ var ExtractionSession = class {
2081
2143
  close() {
2082
2144
  this.releasePublicationClaim?.();
2083
2145
  this.releasePublicationClaim = null;
2146
+ this.hostSuppliedKeys.clear();
2084
2147
  if (this.joinedKey === null || this.participant === null) return;
2085
2148
  if (getOwningWatchSession(this.joinedKey) === this) setOwningWatchSession(this.joinedKey, null);
2086
2149
  leaveSession(this.joinedKey, this.participant);
@@ -2128,14 +2191,14 @@ var ExtractionSession = class {
2128
2191
  pendingFromBatch(changes) {
2129
2192
  const { excludeMatcher, extensionsSet } = this.scanConfig;
2130
2193
  const pending = [];
2131
- for (const path$29 of changes.modifiedFiles ?? []) {
2132
- const classified = this.classifyWatchPath(path$29, {
2194
+ for (const path$30 of changes.modifiedFiles ?? []) {
2195
+ const classified = this.classifyWatchPath(path$30, {
2133
2196
  excludeMatcher,
2134
2197
  extensionsSet
2135
2198
  });
2136
2199
  if (!classified) continue;
2137
2200
  try {
2138
- pending.push([classified.key, require_pipeline.contentHash(changes.sources?.get(path$29) ?? (0, fs.readFileSync)(path$29, "utf-8"))]);
2201
+ pending.push([classified.key, require_pipeline.contentHash(changes.sources?.get(path$30) ?? (0, fs.readFileSync)(path$30, "utf-8"))]);
2139
2202
  } catch {}
2140
2203
  }
2141
2204
  return pending;
@@ -2151,24 +2214,24 @@ var ExtractionSession = class {
2151
2214
  const dirtyRoots = /* @__PURE__ */ new Set();
2152
2215
  const modified = /* @__PURE__ */ new Set();
2153
2216
  const removed = /* @__PURE__ */ new Set();
2154
- const rootHitFor = (path$30) => {
2155
- const containing = identity.containingExternalRoot(path$30);
2217
+ const rootHitFor = (path$31) => {
2218
+ const containing = identity.containingExternalRoot(path$31);
2156
2219
  if (!containing) return null;
2157
2220
  try {
2158
- return (0, fs.statSync)(path$30).isDirectory() ? containing : null;
2221
+ return (0, fs.statSync)(path$31).isDirectory() ? containing : null;
2159
2222
  } catch {
2160
- return identity.resolveDeletedSourceId(path$30) ? null : containing;
2223
+ return identity.resolveDeletedSourceId(path$31) ? null : containing;
2161
2224
  }
2162
2225
  };
2163
- for (const path$31 of changes.modifiedFiles ?? []) {
2164
- const root = rootHitFor(path$31);
2226
+ for (const path$32 of changes.modifiedFiles ?? []) {
2227
+ const root = rootHitFor(path$32);
2165
2228
  if (root) dirtyRoots.add(root);
2166
- else modified.add(path$31);
2229
+ else modified.add(path$32);
2167
2230
  }
2168
- for (const path$32 of changes.removedFiles ?? []) {
2169
- const root = rootHitFor(path$32);
2231
+ for (const path$33 of changes.removedFiles ?? []) {
2232
+ const root = rootHitFor(path$33);
2170
2233
  if (root) dirtyRoots.add(root);
2171
- else removed.add(path$32);
2234
+ else removed.add(path$33);
2172
2235
  }
2173
2236
  for (const root of dirtyRoots) {
2174
2237
  const previous = this.externalInventory.get(root) ?? /* @__PURE__ */ new Map();
@@ -2260,8 +2323,8 @@ var ExtractionSession = class {
2260
2323
  system,
2261
2324
  emitter: {
2262
2325
  runtimeImport: this.runtimeImport,
2263
- cssModuleId: this.cssModuleId,
2264
- systemPropsModuleId: this.systemPropsModuleId ?? systemPropsPath(this.sessionDir)
2326
+ cssModuleId: this.delivery.cssModuleId,
2327
+ systemPropsModuleId: this.delivery.systemPropsModuleId === SESSION_ARTIFACT ? systemPropsPath(this.sessionDir) : this.delivery.systemPropsModuleId
2265
2328
  },
2266
2329
  pathAliasesJson: this.pathAliasesJson,
2267
2330
  staticCssJson: this.staticCssJson,
@@ -2345,7 +2408,6 @@ var ExtractionSession = class {
2345
2408
  prefix: `[${this.driverLabel}]`,
2346
2409
  surface: "generated runtime modules"
2347
2410
  });
2348
- setSharedCss(this.key, fullCss);
2349
2411
  const systemPropsContent = require_pipeline.buildSystemPropsModule({
2350
2412
  systemPropMapJson: JSON.stringify(manifest?.system_prop_map ?? {}),
2351
2413
  groupRegistryJson: system.groupRegistryJson,
@@ -2353,20 +2415,6 @@ var ExtractionSession = class {
2353
2415
  admittedTransforms: manifest?.admitted_transforms ?? {},
2354
2416
  typedSystemProps: manifest?.typed_system_props ?? []
2355
2417
  });
2356
- setSharedSystemProps(this.key, systemPropsContent);
2357
- setManifestJson(this.key, result.manifestJson);
2358
- if (manifest) this.stagedPublication = {
2359
- manifest,
2360
- manifestJson: result.manifestJson,
2361
- analysisGlobalCss: sheets.globalCss,
2362
- analysisComponentCss: sheets.componentCss,
2363
- styles: fullCss,
2364
- systemPropsModule: systemPropsContent,
2365
- system,
2366
- packageMap
2367
- };
2368
- setAnalyzedHashes(this.key, new Map(fileEntries.map((entry) => [entry.path, entry.hash])));
2369
- if (this.packageReadRecord !== null) setSharedPackageReadRecord(this.key, this.packageReadRecord);
2370
2418
  this.writeAnalysisStatus("committing", pending);
2371
2419
  const epoch = require_pipeline.hashReplacementPlans(require_pipeline.snapshotFilePlans(manifest), systemPropsContent);
2372
2420
  if (this.lastCommit === null) this.lastCommit = this.seedCommitFromDisk();
@@ -2386,6 +2434,19 @@ var ExtractionSession = class {
2386
2434
  } else this.writeSessionArtifact(SYSTEM_PROPS_ARTIFACT, systemPropsContent);
2387
2435
  this.publishAnalysisCommit(epoch, generation);
2388
2436
  this.publishReplacementEpoch(epoch);
2437
+ this.stagedPublication = {
2438
+ manifest,
2439
+ manifestJson: result.manifestJson,
2440
+ analysisGlobalCss: sheets.globalCss,
2441
+ analysisComponentCss: sheets.componentCss,
2442
+ styles: fullCss,
2443
+ systemPropsModule: systemPropsContent,
2444
+ system,
2445
+ packageMap,
2446
+ analyzedHashes: new Map(fileEntries.map((entry) => [entry.path, entry.hash])),
2447
+ packageReadRecord: this.packageReadRecord,
2448
+ replacementEpoch: epoch
2449
+ };
2389
2450
  bt.total = this.elapsed(pipelineStart);
2390
2451
  logBuildTimings(bt, manifest?.timing, (msg) => this.log(msg), this.verbose);
2391
2452
  }
@@ -2446,12 +2507,12 @@ var ExtractionSession = class {
2446
2507
  if (!require_pipeline.isEngineTransformExtension(file)) return false;
2447
2508
  const { extractFacts } = this.engine();
2448
2509
  if (extractFacts === void 0) return true;
2449
- const path$33 = (0, path.relative)(this.rootDir, file);
2510
+ const path$34 = (0, path.relative)(this.rootDir, file);
2450
2511
  try {
2451
2512
  const facts = require_pipeline.parseInternalWire(extractFacts(JSON.stringify([{
2452
- path: path$33,
2513
+ path: path$34,
2453
2514
  source: (0, fs.readFileSync)(file, "utf-8")
2454
- }])), "extractFacts").files[path$33];
2515
+ }])), "extractFacts").files[path$34];
2455
2516
  return facts === void 0 || facts.parsePanicked || facts.chains.length > 0;
2456
2517
  } catch {
2457
2518
  return true;
@@ -2590,7 +2651,6 @@ var ExtractionSession = class {
2590
2651
  publishReplacementEpoch(epoch) {
2591
2652
  if (!this.persistArtifacts) {
2592
2653
  this.lastEpochValue = epoch;
2593
- setReplacementEpoch(this.key, epoch);
2594
2654
  return;
2595
2655
  }
2596
2656
  const onDisk = this.diskEpochValue();
@@ -2604,7 +2664,6 @@ var ExtractionSession = class {
2604
2664
  this.lastEpochValue = epoch;
2605
2665
  this.reconcileSiblingEpochs(epoch);
2606
2666
  }
2607
- setReplacementEpoch(this.key, epoch);
2608
2667
  }
2609
2668
  /** sessions-root listing memo, keyed by the root dir's mtime — a new or
2610
2669
  * pruned sibling DIRECTORY moves it; agreeing siblings stay listed. */
@@ -2743,11 +2802,11 @@ var ExtractionSession = class {
2743
2802
  assetFingerprints() {
2744
2803
  const { fingerprintFile, fingerprintBytes } = this.engine();
2745
2804
  if (fingerprintFile && fingerprintBytes) return {
2746
- ofFile: (path$34) => fingerprintFile(path$34) ?? require_pipeline.contentHash((0, fs.readFileSync)(path$34)),
2805
+ ofFile: (path$35) => fingerprintFile(path$35) ?? require_pipeline.contentHash((0, fs.readFileSync)(path$35)),
2747
2806
  ofBytes: fingerprintBytes
2748
2807
  };
2749
2808
  return {
2750
- ofFile: (path$35) => require_pipeline.contentHash((0, fs.readFileSync)(path$35)),
2809
+ ofFile: (path$36) => require_pipeline.contentHash((0, fs.readFileSync)(path$36)),
2751
2810
  ofBytes: require_pipeline.contentHash
2752
2811
  };
2753
2812
  }
@@ -2797,9 +2856,9 @@ var ExtractionSession = class {
2797
2856
  const message = `unresolvable asset() specifier: ${specifier}`;
2798
2857
  this.strictOrWarn(message, `[${this.driverLabel}] ${message}`);
2799
2858
  }
2800
- trackAssetDependency(path$36) {
2801
- this.assetDependencyPaths.add(path$36);
2802
- for (const key of require_pipeline.toWatchKeys(path$36)) this.assetDependencyKeys.add(key);
2859
+ trackAssetDependency(path$37) {
2860
+ this.assetDependencyPaths.add(path$37);
2861
+ for (const key of require_pipeline.toWatchKeys(path$37)) this.assetDependencyKeys.add(key);
2803
2862
  }
2804
2863
  /** Resolve an asset specifier through the shared resolver, with one
2805
2864
  * last resort: a discovered source entry's package root. */
@@ -2821,7 +2880,10 @@ var ExtractionSession = class {
2821
2880
  //#endregion
2822
2881
  //#region session/turbopack-orchestrator.ts
2823
2882
  async function runSessionPipeline(session) {
2824
- session.systemPropsModuleId = TURBOPACK_SYSTEM_PROPS_ID;
2883
+ session.delivery = {
2884
+ ...session.delivery,
2885
+ systemPropsModuleId: TURBOPACK_SYSTEM_PROPS_ID
2886
+ };
2825
2887
  session.persistAnalysisInputs = true;
2826
2888
  await session.runFullPipeline();
2827
2889
  }
@@ -2987,16 +3049,14 @@ function startTurbopackWatcher(session, rootDir, options = {}) {
2987
3049
  if (require_pipeline.isPathWithinRoot(rootDir, path$2) && !(0, path.relative)(rootDir, path$2).split(/[\\/]/).some((segment) => IGNORED_SEGMENTS.has(segment))) return true;
2988
3050
  return [...externalWatchers.keys()].some((root) => require_pipeline.isPathWithinRoot(root, path$2));
2989
3051
  };
2990
- /** Watches the system, asset and configuration dependencies no root
2991
- * watcher reports, by their directories, for those files only. */
3052
+ /** Watches the Session's plan (its files, and the absent paths whose
3053
+ * creation reloads the system) where no root watcher reports them, by
3054
+ * their directories, for those paths only. */
2992
3055
  const syncDependencyWatchers = () => {
2993
3056
  if (closed) return;
2994
3057
  const wanted = /* @__PURE__ */ new Map();
2995
- for (const path$3 of [
2996
- ...session.systemDependencyPaths,
2997
- ...session.assetDependencyPaths,
2998
- ...session.configInputPaths
2999
- ]) {
3058
+ const plan = session.watchPlan();
3059
+ for (const path$3 of [...plan.files, ...plan.missing]) {
3000
3060
  if (watchedByRoot(path$3)) continue;
3001
3061
  const files = wanted.get((0, path.dirname)(path$3)) ?? /* @__PURE__ */ new Set();
3002
3062
  files.add(path$3);
@@ -3098,9 +3158,11 @@ exports.CLI_LOCK_HEARTBEAT_INTERVAL_MS = CLI_LOCK_HEARTBEAT_INTERVAL_MS;
3098
3158
  exports.CLI_LOCK_STALE_AFTER_MS = CLI_LOCK_STALE_AFTER_MS;
3099
3159
  exports.COALESCING_WINDOW_MS = COALESCING_WINDOW_MS;
3100
3160
  exports.CoalescingWindow = CoalescingWindow;
3161
+ exports.EnvironmentBuilds = EnvironmentBuilds;
3101
3162
  exports.EnvironmentFailure = EnvironmentFailure;
3102
3163
  exports.ExtractionSession = ExtractionSession;
3103
3164
  exports.MANIFEST_ARTIFACT = MANIFEST_ARTIFACT;
3165
+ exports.SESSION_ARTIFACT = SESSION_ARTIFACT;
3104
3166
  exports.SESSION_ASSETS_DIR = SESSION_ASSETS_DIR;
3105
3167
  exports.STYLES_ARTIFACT = STYLES_ARTIFACT;
3106
3168
  exports.SYSTEM_PROPS_ARTIFACT = SYSTEM_PROPS_ARTIFACT;