@prisma/composer-cli 0.25.0-dev.3 → 0.25.0-dev.5

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.
Files changed (58) hide show
  1. package/dist/bin.mjs +55 -108
  2. package/dist/bin.mjs.map +1 -1
  3. package/dist/{execute-deploy-destroy-Bdi-RiN5-T3tv5DHr.mjs → execute-deploy-destroy-CF6DR7sA-DGs5poBA.mjs} +23 -19
  4. package/dist/execute-deploy-destroy-CF6DR7sA-DGs5poBA.mjs.map +1 -0
  5. package/dist/{execute-deploy-destroy-Bdi-RiN5-BBrZ9a8c.mjs → execute-deploy-destroy-CF6DR7sA-jdelm-y5.mjs} +22 -18
  6. package/dist/execute-deploy-destroy-CF6DR7sA-jdelm-y5.mjs.map +1 -0
  7. package/dist/{execute-dev-BLCK5wF7-B-fG_E31.mjs → execute-dev-DAIUT0es-CVW9TfgX.mjs} +179 -130
  8. package/dist/execute-dev-DAIUT0es-CVW9TfgX.mjs.map +1 -0
  9. package/dist/{execute-dev-BLCK5wF7-CuzMSK7T.mjs → execute-dev-DAIUT0es-DTdnJdOi.mjs} +100 -131
  10. package/dist/{execute-dev-BLCK5wF7-B-fG_E31.mjs.map → execute-dev-DAIUT0es-DTdnJdOi.mjs.map} +1 -1
  11. package/dist/{execute-log-B_zCJ17b-C4a0uxJj.mjs → execute-log-PLs9-Qn3-BUBx5KmY.mjs} +7 -10
  12. package/dist/execute-log-PLs9-Qn3-BUBx5KmY.mjs.map +1 -0
  13. package/dist/{execute-log-B_zCJ17b-BrLUt7vo.mjs → execute-log-PLs9-Qn3-D8DRuvDr.mjs} +6 -9
  14. package/dist/execute-log-PLs9-Qn3-D8DRuvDr.mjs.map +1 -0
  15. package/dist/{family-DEJvITUc-DHsvEGPB.d.mts → family-DB2Uf88c-DWEm0USb.d.mts} +71 -14
  16. package/dist/{family-DEJvITUc-DHsvEGPB.d.mts.map → family-DB2Uf88c-DWEm0USb.d.mts.map} +1 -1
  17. package/dist/family.d.mts +3 -13
  18. package/dist/family.d.mts.map +1 -1
  19. package/dist/family.mjs +55 -108
  20. package/dist/family.mjs.map +1 -1
  21. package/dist/generate-dev-stack-CPpjJdTG-W0N0YgsI.mjs +87 -0
  22. package/dist/generate-dev-stack-CPpjJdTG-W0N0YgsI.mjs.map +1 -0
  23. package/dist/{local-target-hoEGqgVA.mjs → local-target-B9cBl_6r.mjs} +3 -3
  24. package/dist/local-target-B9cBl_6r.mjs.map +1 -0
  25. package/dist/{local-target-BOGjATc2.mjs → local-target-P4-n1Ovh.mjs} +3 -3
  26. package/dist/local-target-P4-n1Ovh.mjs.map +1 -0
  27. package/dist/{pipeline-C7gNjMzJ-CMqZQxqM.mjs → pipeline-DAYhea3J-BEnHHWp8.mjs} +36 -261
  28. package/dist/{pipeline-C7gNjMzJ-CMqZQxqM.mjs.map → pipeline-DAYhea3J-BEnHHWp8.mjs.map} +1 -1
  29. package/dist/{pipeline-C7gNjMzJ-CixaMvnR.mjs → pipeline-DAYhea3J-uuBciVDS.mjs} +36 -262
  30. package/dist/{pipeline-C7gNjMzJ-CixaMvnR.mjs.map → pipeline-DAYhea3J-uuBciVDS.mjs.map} +1 -1
  31. package/dist/result-D9vIrN7i.mjs +432 -0
  32. package/dist/result-D9vIrN7i.mjs.map +1 -0
  33. package/dist/{result-B874OKwb.mjs → result-SF9LFOuR.mjs} +207 -129
  34. package/dist/result-SF9LFOuR.mjs.map +1 -0
  35. package/dist/{run-alchemy-pANK8XNX-BH1wC0r6.mjs → run-alchemy-pANK8XNX-CqXC1tbs.mjs} +2 -2
  36. package/dist/{run-alchemy-pANK8XNX-BH1wC0r6.mjs.map → run-alchemy-pANK8XNX-CqXC1tbs.mjs.map} +1 -1
  37. package/dist/{run-alchemy-pANK8XNX-XcCQncKN.mjs → run-alchemy-pANK8XNX-T_pHNDBo.mjs} +2 -2
  38. package/dist/{run-alchemy-pANK8XNX-XcCQncKN.mjs.map → run-alchemy-pANK8XNX-T_pHNDBo.mjs.map} +1 -1
  39. package/dist/shared-BAIiDgXa-DYP7EOSk.mjs +33 -0
  40. package/dist/shared-BAIiDgXa-DYP7EOSk.mjs.map +1 -0
  41. package/dist/testing.d.mts +16 -2
  42. package/dist/testing.d.mts.map +1 -1
  43. package/dist/testing.mjs +3 -2
  44. package/dist/testing.mjs.map +1 -1
  45. package/package.json +4 -5
  46. package/src/exports/testing.ts +3 -1
  47. package/dist/execute-deploy-destroy-Bdi-RiN5-BBrZ9a8c.mjs.map +0 -1
  48. package/dist/execute-deploy-destroy-Bdi-RiN5-T3tv5DHr.mjs.map +0 -1
  49. package/dist/execute-dev-BLCK5wF7-CuzMSK7T.mjs.map +0 -1
  50. package/dist/execute-log-B_zCJ17b-BrLUt7vo.mjs.map +0 -1
  51. package/dist/execute-log-B_zCJ17b-C4a0uxJj.mjs.map +0 -1
  52. package/dist/local-target-BOGjATc2.mjs.map +0 -1
  53. package/dist/local-target-hoEGqgVA.mjs.map +0 -1
  54. package/dist/result-B874OKwb.mjs.map +0 -1
  55. package/dist/result-sR7PBi61.mjs +0 -229
  56. package/dist/result-sR7PBi61.mjs.map +0 -1
  57. package/dist/shared-BTnATsqm-BH4axbJg.mjs +0 -158
  58. package/dist/shared-BTnATsqm-BH4axbJg.mjs.map +0 -1
@@ -1,11 +1,12 @@
1
- import { c as CliStructuredError, n as ok, s as toStructured, t as notOk } from "./result-B874OKwb.mjs";
2
- import { n as alchemyInvocation, r as spawnAlchemy } from "./run-alchemy-pANK8XNX-BH1wC0r6.mjs";
3
- import { n as runPipeline } from "./pipeline-C7gNjMzJ-CMqZQxqM.mjs";
1
+ import { d as CliStructuredError, n as ok, o as noComposerExportMessage, t as notOk, u as toStructured } from "./result-SF9LFOuR.mjs";
2
+ import { n as alchemyInvocation, r as spawnAlchemy } from "./run-alchemy-pANK8XNX-CqXC1tbs.mjs";
3
+ import { n as runPipeline } from "./pipeline-DAYhea3J-uuBciVDS.mjs";
4
4
  import { t as containerEnv } from "./container-transport-HcvNOGZL-CIoZc7Rs.mjs";
5
- import { n as withEmulatorRetry, r as DEV_DIR, t as resolveLocalTargets } from "./local-target-hoEGqgVA.mjs";
5
+ import { n as withEmulatorRetry, r as DEV_DIR, t as resolveLocalTargets } from "./local-target-P4-n1Ovh.mjs";
6
6
  import * as fs from "node:fs";
7
7
  import * as path from "node:path";
8
8
  import { join, relative, resolve, sep } from "node:path";
9
+ import { createHash } from "node:crypto";
9
10
  import { stat, unwatchFile, watch, watchFile } from "fs";
10
11
  import { lstat, open, readdir, realpath, stat as stat$1 } from "fs/promises";
11
12
  import { EventEmitter } from "events";
@@ -13,6 +14,87 @@ import * as sysPath from "path";
13
14
  import { lstat as lstat$1, readdir as readdir$1, realpath as realpath$1, stat as stat$2 } from "node:fs/promises";
14
15
  import { Readable } from "node:stream";
15
16
  import { type } from "os";
17
+ //#region ../../0-framework/3-tooling/cli/dist/generate-dev-stack-CPpjJdTG.mjs
18
+ /**
19
+ * Local-dev spec § 6 `generate-dev-stack.ts`: like generate-stack.ts but at
20
+ * `.prisma-composer/dev/alchemy.run.ts`, always Alchemy stage `dev`, using
21
+ * Alchemy's own `localState()` and no `report` — dev prints its own front
22
+ * door (run-dev.ts), so core's presentation-free lower() gets nothing to
23
+ * call back into. The generated module IS the one orchestration point where
24
+ * dev provenance is resolved (spec § 3 REVISED): it deserializes the
25
+ * containers, top-level-awaits `resolveLocalTargets(config)` (the lazy
26
+ * `localTarget` thunks, ADR-0041), and passes
27
+ * `providers: localTargetProviders(...)` + `state: localState()` explicitly
28
+ * — `lower()` learns nothing about dev.
29
+ */
30
+ const DEV_GENERATED_DIR = ".prisma-composer/dev";
31
+ const DEV_GENERATED_FILE = "alchemy.run.ts";
32
+ /** A relative import specifier from `.prisma-composer/dev/alchemy.run.ts` to `target` (posix separators). */
33
+ function relativeImportSpecifier(generatedDir, target) {
34
+ const rel = path.relative(generatedDir, target).split(path.sep).join("/");
35
+ return rel.startsWith(".") ? rel : `./${rel}`;
36
+ }
37
+ function quote(value) {
38
+ return JSON.stringify(value);
39
+ }
40
+ function renderBundle(bundle) {
41
+ return `{ dir: ${quote(bundle.dir)}, entry: ${quote(bundle.entry)} }`;
42
+ }
43
+ function renderOptions(input) {
44
+ const lines = [];
45
+ lines.push(` name: ${quote(input.name)},`);
46
+ lines.push(" bundles: {");
47
+ for (const [id, bundle] of Object.entries(input.assembled.bundles)) lines.push(` ${quote(id)}: ${renderBundle(bundle)},`);
48
+ lines.push(" },");
49
+ lines.push(" providers: localTargetProviders(resolved, containers, devDir),");
50
+ lines.push(" state: localState(),");
51
+ return lines.join("\n");
52
+ }
53
+ /** Renders the dev stack module's source (tests assert on it without touching disk). */
54
+ function renderDevStackFile(input) {
55
+ const generatedDir = path.join(input.cwd, DEV_GENERATED_DIR);
56
+ const appImport = relativeImportSpecifier(generatedDir, input.entryPath);
57
+ const imports = [
58
+ "import * as path from 'node:path';",
59
+ "import { deserializeContainers } from '@prisma/composer/config';",
60
+ "import { lower } from '@prisma/composer/deploy';",
61
+ "import { DEV_DIR, localTargetProviders, resolveLocalTargets } from '@prisma/composer/local-target';",
62
+ "import { localState } from 'alchemy/State/LocalState';",
63
+ `import prismaConfig from ${quote(relativeImportSpecifier(generatedDir, input.configFile))};`,
64
+ `import app from ${quote(appImport)};`
65
+ ].join("\n");
66
+ return `// Generated by \`prisma-composer dev\` — overwritten on every run; do not
67
+ // edit by hand. Independently runnable from ${quote(input.cwd)}:
68
+ //
69
+ // alchemy deploy ${DEV_GENERATED_DIR}/${DEV_GENERATED_FILE} --stage dev
70
+ //
71
+ // bisects a CLI bug from an Alchemy bug (deploy-cli.md § Implementation decisions).
72
+ ${imports}
73
+
74
+ const config = prismaConfig.composer;
75
+ if (config === undefined) {
76
+ throw new Error(${quote(noComposerExportMessage(input.configFile))});
77
+ }
78
+
79
+ const containers = deserializeContainers(config.extensions, process.env);
80
+ const resolved = await resolveLocalTargets(config);
81
+ const devDir = path.join(process.cwd(), DEV_DIR);
82
+
83
+ export default lower(app, config, {
84
+ ${renderOptions(input)}
85
+ });
86
+ `;
87
+ }
88
+ /** Writes the dev stack file, returning its absolute path. */
89
+ function writeDevStackFile(input) {
90
+ const generatedDir = path.join(input.cwd, DEV_GENERATED_DIR);
91
+ fs.mkdirSync(generatedDir, { recursive: true });
92
+ const filePath = path.join(generatedDir, DEV_GENERATED_FILE);
93
+ fs.writeFileSync(filePath, renderDevStackFile(input));
94
+ return filePath;
95
+ }
96
+ const DEV_STACK_RELATIVE_PATH = path.join(DEV_GENERATED_DIR, DEV_GENERATED_FILE);
97
+ //#endregion
16
98
  //#region ../../0-framework/3-tooling/cli/node_modules/readdirp/esm/index.js
17
99
  const EntryTypes = {
18
100
  FILE_TYPE: "files",
@@ -1561,79 +1643,7 @@ var esm_default = {
1561
1643
  FSWatcher
1562
1644
  };
1563
1645
  //#endregion
1564
- //#region ../../0-framework/3-tooling/cli/dist/execute-dev-BLCK5wF7.mjs
1565
- /**
1566
- * Local-dev spec § 6 `generate-dev-stack.ts`: like generate-stack.ts but at
1567
- * `.prisma-composer/dev/alchemy.run.ts`, always Alchemy stage `dev`, using
1568
- * Alchemy's own `localState()` and no `report` — dev prints its own front
1569
- * door (run-dev.ts), so core's presentation-free lower() gets nothing to
1570
- * call back into. The generated module IS the one orchestration point where
1571
- * dev provenance is resolved (spec § 3 REVISED): it deserializes the
1572
- * containers, top-level-awaits `resolveLocalTargets(config)` (the lazy
1573
- * `localTarget` thunks, ADR-0041), and passes
1574
- * `providers: localTargetProviders(...)` + `state: localState()` explicitly
1575
- * — `lower()` learns nothing about dev.
1576
- */
1577
- const DEV_GENERATED_DIR = ".prisma-composer/dev";
1578
- const DEV_GENERATED_FILE = "alchemy.run.ts";
1579
- /** A relative import specifier from `.prisma-composer/dev/alchemy.run.ts` to `target` (posix separators). */
1580
- function relativeImportSpecifier(generatedDir, target) {
1581
- const rel = path.relative(generatedDir, target).split(path.sep).join("/");
1582
- return rel.startsWith(".") ? rel : `./${rel}`;
1583
- }
1584
- function quote(value) {
1585
- return JSON.stringify(value);
1586
- }
1587
- function renderBundle(bundle) {
1588
- return `{ dir: ${quote(bundle.dir)}, entry: ${quote(bundle.entry)} }`;
1589
- }
1590
- function renderOptions(input) {
1591
- const lines = [];
1592
- lines.push(` name: ${quote(input.name)},`);
1593
- lines.push(" bundles: {");
1594
- for (const [id, bundle] of Object.entries(input.assembled.bundles)) lines.push(` ${quote(id)}: ${renderBundle(bundle)},`);
1595
- lines.push(" },");
1596
- lines.push(" providers: localTargetProviders(resolved, containers, devDir),");
1597
- lines.push(" state: localState(),");
1598
- return lines.join("\n");
1599
- }
1600
- /** Renders the dev stack module's source (tests assert on it without touching disk). */
1601
- function renderDevStackFile(input) {
1602
- const generatedDir = path.join(input.cwd, DEV_GENERATED_DIR);
1603
- const appImport = relativeImportSpecifier(generatedDir, input.entryPath);
1604
- const configImport = relativeImportSpecifier(generatedDir, input.configPath);
1605
- return `// Generated by \`prisma-composer dev\` — overwritten on every run; do not
1606
- // edit by hand. Independently runnable from ${quote(input.cwd)}:
1607
- //
1608
- // alchemy deploy ${DEV_GENERATED_DIR}/${DEV_GENERATED_FILE} --stage dev
1609
- //
1610
- // bisects a CLI bug from an Alchemy bug (deploy-cli.md § Implementation decisions).
1611
- import * as path from 'node:path';
1612
- import { deserializeContainers } from '@prisma/composer/config';
1613
- import { lower } from '@prisma/composer/deploy';
1614
- import { DEV_DIR, localTargetProviders, resolveLocalTargets } from '@prisma/composer/local-target';
1615
- import { localState } from 'alchemy/State/LocalState';
1616
- import config from ${quote(configImport)};
1617
- import app from ${quote(appImport)};
1618
-
1619
- const containers = deserializeContainers(config.extensions, process.env);
1620
- const resolved = await resolveLocalTargets(config);
1621
- const devDir = path.join(process.cwd(), DEV_DIR);
1622
-
1623
- export default lower(app, config, {
1624
- ${renderOptions(input)}
1625
- });
1626
- `;
1627
- }
1628
- /** Writes the dev stack file, returning its absolute path. */
1629
- function writeDevStackFile(input) {
1630
- const generatedDir = path.join(input.cwd, DEV_GENERATED_DIR);
1631
- fs.mkdirSync(generatedDir, { recursive: true });
1632
- const filePath = path.join(generatedDir, DEV_GENERATED_FILE);
1633
- fs.writeFileSync(filePath, renderDevStackFile(input));
1634
- return filePath;
1635
- }
1636
- const DEV_STACK_RELATIVE_PATH = path.join(DEV_GENERATED_DIR, DEV_GENERATED_FILE);
1646
+ //#region ../../0-framework/3-tooling/cli/dist/execute-dev-DAIUT0es.mjs
1637
1647
  /**
1638
1648
  * Local-dev spec § 6 `watch.ts`: watches each assembled bundle's declared
1639
1649
  * `watch` paths (a directory watched recursively, a file watched through
@@ -1758,6 +1768,14 @@ async function mergedEndpoints(attachments) {
1758
1768
  return (await Promise.all(attachments.map((a) => withEmulatorRetry(() => a.endpoints())))).flat();
1759
1769
  }
1760
1770
  /** Runs the full dev pipeline; resolves to a running session or a structured failure. */
1771
+ /** The file's content hash; undefined when it cannot be read, which counts as a change. */
1772
+ function contentHash(file) {
1773
+ try {
1774
+ return createHash("sha256").update(fs.readFileSync(file)).digest("hex");
1775
+ } catch {
1776
+ return;
1777
+ }
1778
+ }
1761
1779
  async function executeDev(input, deps, cwd) {
1762
1780
  if (process.platform === "win32") return notOk(new CliStructuredError("DEV.PLATFORM_UNSUPPORTED", "local dev is not supported on Windows yet."));
1763
1781
  const { onEvent } = input;
@@ -1766,13 +1784,10 @@ async function executeDev(input, deps, cwd) {
1766
1784
  let resolved;
1767
1785
  const containers = /* @__PURE__ */ new Map();
1768
1786
  try {
1769
- const pipelineDeps = {
1770
- runAssembler: deps.runAssembler,
1771
- config: deps.config,
1772
- configPath: deps.configPath
1773
- };
1774
- pipeline = await runPipeline(input.entry, input.name, cwd, pipelineDeps);
1775
- const { config, graph, name } = pipeline;
1787
+ const pipelineDeps = { runAssembler: deps.runAssembler };
1788
+ pipeline = await runPipeline(input.entry, input.name, cwd, input.config, pipelineDeps);
1789
+ const { graph, name } = pipeline;
1790
+ const config = pipeline.configSource.value;
1776
1791
  resolved = await resolveLocalTargets(config);
1777
1792
  for (const [id, dev] of resolved) try {
1778
1793
  containers.set(id, await dev.container.ensure({
@@ -1828,7 +1843,7 @@ async function executeDev(input, deps, cwd) {
1828
1843
  stackPath = writeDevStackFile({
1829
1844
  entryPath: pipeline.entryModule.path,
1830
1845
  cwd,
1831
- configPath: pipeline.configPath,
1846
+ configFile: pipeline.configSource.file,
1832
1847
  name: pipeline.name,
1833
1848
  assembled: pipeline.assembled
1834
1849
  });
@@ -1887,6 +1902,7 @@ async function executeDev(input, deps, cwd) {
1887
1902
  const attachments = [];
1888
1903
  const started = [];
1889
1904
  let watch;
1905
+ let configWatch;
1890
1906
  try {
1891
1907
  for (const [id, dev] of resolved) try {
1892
1908
  attachments.push(await dev.attach({
@@ -1919,55 +1935,86 @@ async function executeDev(input, deps, cwd) {
1919
1935
  kind: "unwatchable",
1920
1936
  address
1921
1937
  });
1922
- const watchDeps = {
1923
- runAssembler: deps.runAssembler,
1924
- config: deps.config,
1925
- configPath: deps.configPath
1938
+ const watchDeps = { runAssembler: deps.runAssembler };
1939
+ const watchFiles = deps.watch ?? startWatch;
1940
+ const onWatchError = (error) => emit({
1941
+ kind: "watch-error",
1942
+ message: failureMessage(error)
1943
+ });
1944
+ const configFile = pipeline.configSource.file;
1945
+ const startedConfig = contentHash(configFile);
1946
+ let configChanged = false;
1947
+ const pausedForConfig = () => {
1948
+ if (!configChanged && contentHash(configFile) === startedConfig) return false;
1949
+ configChanged = true;
1950
+ emit({
1951
+ kind: "config-changed",
1952
+ file: configFile
1953
+ });
1954
+ return true;
1926
1955
  };
1927
- watch = startWatch(targets, () => {
1928
- (async () => {
1929
- try {
1930
- const rePipeline = await runPipeline(input.entry, input.name, cwd, watchDeps);
1931
- const stackPath = writeDevStackFile({
1932
- entryPath: rePipeline.entryModule.path,
1933
- cwd,
1934
- configPath: rePipeline.configPath,
1935
- name: rePipeline.name,
1936
- assembled: rePipeline.assembled
1937
- });
1938
- const outcome = await (deps.alchemy ?? spawnAlchemy)(alchemyInvocation({
1939
- command: "deploy",
1940
- stackFileRelativePath: DEV_STACK_RELATIVE_PATH,
1941
- cwd,
1942
- stage: "dev",
1943
- containerEnv: containerEnv(containers)
1944
- }));
1945
- if (outcome.signal !== null || outcome.exitCode !== 0) {
1946
- emit({
1947
- kind: "converge-failed",
1948
- stackFilePath: stackPath,
1949
- reproduceCommand,
1950
- cwd
1951
- });
1952
- return;
1953
- }
1954
- emit({
1955
- kind: "ready",
1956
- endpoints: await mergedEndpoints(attachments)
1957
- });
1958
- } catch (error) {
1956
+ configWatch = watchFiles([{
1957
+ address: configFile,
1958
+ paths: [configFile]
1959
+ }], () => void pausedForConfig(), onWatchError);
1960
+ const rebuild = async () => {
1961
+ try {
1962
+ const rePipeline = await runPipeline(input.entry, input.name, cwd, input.config, watchDeps);
1963
+ const stackPath = writeDevStackFile({
1964
+ entryPath: rePipeline.entryModule.path,
1965
+ cwd,
1966
+ configFile: rePipeline.configSource.file,
1967
+ name: rePipeline.name,
1968
+ assembled: rePipeline.assembled
1969
+ });
1970
+ const outcome = await (deps.alchemy ?? spawnAlchemy)(alchemyInvocation({
1971
+ command: "deploy",
1972
+ stackFileRelativePath: DEV_STACK_RELATIVE_PATH,
1973
+ cwd,
1974
+ stage: "dev",
1975
+ containerEnv: containerEnv(containers)
1976
+ }));
1977
+ if (outcome.signal !== null || outcome.exitCode !== 0) {
1959
1978
  emit({
1960
- kind: "rebuild-failed",
1961
- message: failureMessage(error)
1979
+ kind: "converge-failed",
1980
+ stackFilePath: stackPath,
1981
+ reproduceCommand,
1982
+ cwd
1962
1983
  });
1984
+ return;
1963
1985
  }
1964
- })();
1965
- }, (error) => emit({
1966
- kind: "watch-error",
1967
- message: failureMessage(error)
1968
- }));
1986
+ emit({
1987
+ kind: "ready",
1988
+ endpoints: await mergedEndpoints(attachments)
1989
+ });
1990
+ } catch (error) {
1991
+ emit({
1992
+ kind: "rebuild-failed",
1993
+ message: failureMessage(error)
1994
+ });
1995
+ }
1996
+ };
1997
+ let rebuilding = false;
1998
+ let changedDuringRebuild = false;
1999
+ const rebuildUntilSettled = async () => {
2000
+ rebuilding = true;
2001
+ do {
2002
+ changedDuringRebuild = false;
2003
+ await rebuild();
2004
+ } while (changedDuringRebuild && !pausedForConfig());
2005
+ rebuilding = false;
2006
+ };
2007
+ watch = watchFiles(targets, () => {
2008
+ if (pausedForConfig()) return;
2009
+ if (rebuilding) {
2010
+ changedDuringRebuild = true;
2011
+ return;
2012
+ }
2013
+ rebuildUntilSettled();
2014
+ }, onWatchError);
1969
2015
  const startedWatch = watch;
1970
- await watch.ready;
2016
+ const startedConfigWatch = configWatch;
2017
+ await Promise.all([watch.ready, configWatch.ready]);
1971
2018
  let stopping = false;
1972
2019
  let resolveClosed = () => void 0;
1973
2020
  const closed = new Promise((resolve) => {
@@ -1978,6 +2025,7 @@ async function executeDev(input, deps, cwd) {
1978
2025
  stopping = true;
1979
2026
  emit({ kind: "stopping" });
1980
2027
  startedWatch.stop();
2028
+ startedConfigWatch.stop();
1981
2029
  (async () => {
1982
2030
  for (const attachment of attachments) try {
1983
2031
  await attachment.stopServices();
@@ -2000,6 +2048,7 @@ async function executeDev(input, deps, cwd) {
2000
2048
  });
2001
2049
  } catch (error) {
2002
2050
  watch?.stop();
2051
+ configWatch?.stop();
2003
2052
  await Promise.all(started.map((a) => a.stopServices().catch(() => void 0)));
2004
2053
  if (CliStructuredError.is(error)) return notOk(error);
2005
2054
  throw error;
@@ -2008,4 +2057,4 @@ async function executeDev(input, deps, cwd) {
2008
2057
  //#endregion
2009
2058
  export { executeDev };
2010
2059
 
2011
- //# sourceMappingURL=execute-dev-BLCK5wF7-B-fG_E31.mjs.map
2060
+ //# sourceMappingURL=execute-dev-DAIUT0es-CVW9TfgX.mjs.map