@publish.os/nextjs 0.0.1-alpha.81 → 0.0.1-alpha.91

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 (265) hide show
  1. package/compiler-assets/nextjs/defaults/app/globals.css +1 -0
  2. package/compiler-assets/nextjs/defaults/group/index.tsx +50 -0
  3. package/compiler-assets/nextjs/defaults/group/layout.tsx +8 -8
  4. package/compiler-assets/nextjs/defaults/group/page.tsx +44 -43
  5. package/compiler-assets/nextjs/defaults/project/next.config.mjs +33 -13
  6. package/compiler-assets/nextjs/defaults/project/tsconfig.json.template +10 -3
  7. package/compiler-assets/nextjs/defaults/root/css/animation.css +131 -0
  8. package/compiler-assets/nextjs/defaults/root/css/components/code-block.css +18 -0
  9. package/compiler-assets/nextjs/defaults/root/css/components/dialog.css +4 -1
  10. package/compiler-assets/nextjs/defaults/root/css/components/menu.css +1 -1
  11. package/compiler-assets/nextjs/defaults/root/css/components/navigation-menu.css +1 -1
  12. package/compiler-assets/nextjs/defaults/root/css/components/popover.css +1 -1
  13. package/compiler-assets/nextjs/defaults/root/css/components/select.css +1 -1
  14. package/compiler-assets/nextjs/defaults/root/css/components/tooltip.css +1 -1
  15. package/compiler-assets/nextjs/defaults/root/css/shadow.css +6 -25
  16. package/compiler-assets/nextjs/defaults/root/css/typography.css +51 -68
  17. package/compiler-assets/nextjs/defaults/root/globals.css +25 -0
  18. package/compiler-assets/nextjs/defaults/root/{page.tsx → index.tsx} +6 -2
  19. package/compiler-assets/nextjs/defaults/root/layout.tsx +7 -1
  20. package/compiler-assets/nextjs/defaults/root/theme.css +22 -22
  21. package/compiler-assets/nextjs/shims/document.tsx +38 -0
  22. package/compiler-assets/nextjs/shims/generated-group-page.tsx +19 -2
  23. package/compiler-assets/nextjs/shims/generated-leaf-page.tsx +18 -2
  24. package/compiler-assets/nextjs/shims/global-layout.tsx +19 -85
  25. package/compiler-assets/nextjs/shims/global-not-found.tsx +69 -0
  26. package/compiler-assets/nextjs/shims/markdown-route.ts +2 -0
  27. package/compiler-assets/nextjs/shims/metadata-icons.tsx +39 -0
  28. package/compiler-assets/nextjs/shims/not-found-content.tsx +53 -0
  29. package/compiler-assets/nextjs/shims/not-found-navigation.tsx +60 -0
  30. package/compiler-assets/nextjs/shims/proxy.ts +143 -65
  31. package/compiler-assets/nextjs/shims/publish-os-theme-provider.tsx +76 -15
  32. package/compiler-assets/nextjs/shims/root-page.tsx +7 -1
  33. package/compiler-assets/nextjs/shims/site-fenced-code-block.tsx +30 -0
  34. package/compiler-assets/nextjs/shims/site-heading-level.tsx +14 -0
  35. package/compiler-assets/nextjs/shims/site-mdx-components.tsx +112 -0
  36. package/compiler-assets/nextjs/shims/site-mdx.tsx +17 -0
  37. package/compiler-assets/nextjs/shims/theme-defaults.css +41 -25
  38. package/dist/build-operation-5QMLXF7N.js +89 -0
  39. package/dist/{button-CFdx-ohV.d.ts → button-BdCScEKi.d.ts} +6 -6
  40. package/dist/capture-local-source-WGGDIUU2.js +258 -0
  41. package/dist/chunk-22RSSUNV.js +13 -0
  42. package/dist/chunk-4BC2L2KA.js +620 -0
  43. package/dist/chunk-5J3YUNRY.js +121 -0
  44. package/dist/chunk-5KAD7W53.js +248 -0
  45. package/dist/chunk-6C65KV7O.js +142 -0
  46. package/dist/chunk-6D2E6UMD.js +695 -0
  47. package/dist/chunk-7NY22B5U.js +161 -0
  48. package/dist/chunk-AI2UULNX.js +9 -0
  49. package/dist/chunk-EFO6AWXN.js +19 -0
  50. package/dist/chunk-F3AGNDF4.js +2377 -0
  51. package/dist/chunk-GBPLER5H.js +426 -0
  52. package/dist/chunk-IL4RJOKI.js +186 -0
  53. package/dist/chunk-NNBJZPFM.js +193 -0
  54. package/dist/chunk-ORIUWJBQ.js +58 -0
  55. package/dist/chunk-OXOFRXEI.js +7129 -0
  56. package/dist/chunk-UYGCOWRF.js +1709 -0
  57. package/dist/chunk-WL75GQ5M.js +80 -0
  58. package/dist/compiler.d.ts +54 -7
  59. package/dist/compiler.js +121 -13147
  60. package/dist/components/blocks/agent-actions.d.ts +81 -0
  61. package/dist/components/blocks/agent-actions.js +594 -0
  62. package/dist/components/blocks/toc.d.ts +43 -0
  63. package/dist/components/blocks/toc.js +136 -0
  64. package/dist/components/ui/button.d.ts +5 -0
  65. package/dist/components/ui/button.js +94 -0
  66. package/dist/compose-CVBJRAF6.js +16 -0
  67. package/dist/config/createNextConfig.js +27 -0
  68. package/dist/dev-operation-OSHHWRWK.js +1095 -0
  69. package/dist/framework-selection-ZVO323PK.js +11 -0
  70. package/dist/ide-support-CU6Z5PVR.js +16 -0
  71. package/dist/index.d.ts +55 -4
  72. package/dist/jsx-dev-runtime.d.ts +6 -0
  73. package/dist/jsx-dev-runtime.js +100 -0
  74. package/dist/jsx-runtime.d.ts +7 -0
  75. package/dist/jsx-runtime.js +97 -0
  76. package/dist/kernel/components/blocks/AgentActions.d.ts +35 -6
  77. package/dist/kernel/components/blocks/AgentActions.js +401 -150
  78. package/dist/kernel/components/blocks/agent-actions.d.ts +5 -0
  79. package/dist/kernel/components/blocks/agent-actions.js +594 -0
  80. package/dist/kernel/components/blocks/animated-icon-swap.js +1 -1
  81. package/dist/kernel/components/blocks/color-palette.js +4 -4
  82. package/dist/kernel/components/blocks/logo-block.js +3 -3
  83. package/dist/kernel/components/blocks/nav-breadcrumb.d.ts +10 -2
  84. package/dist/kernel/components/blocks/nav-breadcrumb.js +22 -7
  85. package/dist/kernel/components/blocks/navbar.d.ts +2 -2
  86. package/dist/kernel/components/blocks/navbar.js +406 -65
  87. package/dist/kernel/components/blocks/navigation-progress.js +6 -3
  88. package/dist/kernel/components/blocks/next-prev.d.ts +1 -1
  89. package/dist/kernel/components/blocks/next-prev.js +12 -24
  90. package/dist/kernel/components/blocks/page-list.d.ts +1 -1
  91. package/dist/kernel/components/blocks/page-list.js +7 -6
  92. package/dist/kernel/components/blocks/search.d.ts +83 -58
  93. package/dist/kernel/components/blocks/search.js +554 -428
  94. package/dist/kernel/components/blocks/sidebar-node.d.ts +2 -2
  95. package/dist/kernel/components/blocks/sidebar-node.js +12 -10
  96. package/dist/kernel/components/blocks/sidebar.d.ts +3 -3
  97. package/dist/kernel/components/blocks/sidebar.js +24 -14
  98. package/dist/kernel/components/blocks/theme-toggle.d.ts +2 -2
  99. package/dist/kernel/components/blocks/theme-toggle.js +47 -1
  100. package/dist/kernel/components/blocks/toc-client.d.ts +40 -0
  101. package/dist/kernel/components/blocks/toc-client.js +495 -0
  102. package/dist/kernel/components/blocks/toc.d.ts +19 -1
  103. package/dist/kernel/components/blocks/toc.js +122 -180
  104. package/dist/kernel/components/mdx/components/blockquote.js +2 -2
  105. package/dist/kernel/components/mdx/components/callout.d.ts +5 -7
  106. package/dist/kernel/components/mdx/components/callout.js +67 -36
  107. package/dist/kernel/components/mdx/components/code-block.d.ts +5 -2
  108. package/dist/kernel/components/mdx/components/code-block.js +106 -5
  109. package/dist/kernel/components/mdx/components/copy-code-button.d.ts +8 -0
  110. package/dist/kernel/components/mdx/components/copy-code-button.js +61 -0
  111. package/dist/kernel/components/mdx/components/figure-caption.d.ts +1 -1
  112. package/dist/kernel/components/mdx/components/figure-caption.js +4 -3
  113. package/dist/kernel/components/mdx/components/figure.d.ts +6 -2
  114. package/dist/kernel/components/mdx/components/figure.js +24 -14
  115. package/dist/kernel/components/mdx/components/footnotes.js +1 -1
  116. package/dist/kernel/components/mdx/components/heading-copy-link.js +4 -4
  117. package/dist/kernel/components/mdx/components/heading.js +6 -3
  118. package/dist/kernel/components/mdx/components/hr.js +2 -2
  119. package/dist/kernel/components/mdx/components/image-zoom.js +2 -2
  120. package/dist/kernel/components/mdx/components/image.d.ts +1 -1
  121. package/dist/kernel/components/mdx/components/image.js +94 -68
  122. package/dist/kernel/components/mdx/components/inline-code.js +2 -2
  123. package/dist/kernel/components/mdx/components/kbd.d.ts +2 -2
  124. package/dist/kernel/components/mdx/components/kbd.js +5 -4
  125. package/dist/kernel/components/mdx/components/link.d.ts +35 -4
  126. package/dist/kernel/components/mdx/components/link.js +3 -3
  127. package/dist/kernel/components/mdx/components/paragraph.js +2 -5
  128. package/dist/kernel/components/mdx/components/strikethrough.js +1 -1
  129. package/dist/kernel/components/mdx/components/table.js +2 -2
  130. package/dist/kernel/components/mdx/components/task-list.js +2 -2
  131. package/dist/kernel/components/mdx/components/video-player.d.ts +6 -2
  132. package/dist/kernel/components/mdx/components/video-player.js +8 -4
  133. package/dist/kernel/components/mdx/components/video.d.ts +5 -3
  134. package/dist/kernel/components/mdx/components/video.js +8 -6
  135. package/dist/kernel/components/mdx/error-boundary.js +2 -2
  136. package/dist/kernel/components/mdx/error-fallback.js +1 -1
  137. package/dist/kernel/components/mdx/mdx.d.ts +28 -14
  138. package/dist/kernel/components/mdx/mdx.js +336 -63
  139. package/dist/kernel/components/mdx/rehype-heading-ids.d.ts +1 -0
  140. package/dist/kernel/components/mdx/rehype-heading-ids.js +6 -4
  141. package/dist/kernel/components/next-image.d.ts +12 -0
  142. package/dist/kernel/components/next-image.js +61 -0
  143. package/dist/kernel/components/ui/accordion.js +1 -1
  144. package/dist/kernel/components/ui/breadcrumb-trail.d.ts +6 -23
  145. package/dist/kernel/components/ui/breadcrumb-trail.js +2 -2
  146. package/dist/kernel/components/ui/breadcrumb.d.ts +11 -3
  147. package/dist/kernel/components/ui/breadcrumb.js +10 -8
  148. package/dist/kernel/components/ui/button-group.js +8 -7
  149. package/dist/kernel/components/ui/button.d.ts +58 -6
  150. package/dist/kernel/components/ui/button.js +43 -39
  151. package/dist/kernel/components/ui/card.d.ts +2 -2
  152. package/dist/kernel/components/ui/card.js +1 -1
  153. package/dist/kernel/components/ui/dialog.js +1 -1
  154. package/dist/kernel/components/ui/drawer.d.ts +3 -1
  155. package/dist/kernel/components/ui/drawer.js +6 -2
  156. package/dist/kernel/components/ui/input.d.ts +2 -2
  157. package/dist/kernel/components/ui/input.js +1 -1
  158. package/dist/kernel/components/ui/kbd.js +10 -17
  159. package/dist/kernel/components/ui/link.d.ts +11 -3
  160. package/dist/kernel/components/ui/link.js +12 -11
  161. package/dist/kernel/components/ui/menu.js +6 -6
  162. package/dist/kernel/components/ui/mod-key.d.ts +10 -0
  163. package/dist/kernel/components/ui/mod-key.js +36 -0
  164. package/dist/kernel/components/ui/navigation-menu.js +3 -3
  165. package/dist/kernel/components/ui/popover.js +1 -1
  166. package/dist/kernel/components/ui/progress.js +2 -2
  167. package/dist/kernel/components/ui/scroll-area.js +5 -5
  168. package/dist/kernel/components/ui/select.js +8 -11
  169. package/dist/kernel/components/ui/separator.js +1 -1
  170. package/dist/kernel/components/ui/table.js +1 -1
  171. package/dist/kernel/components/ui/tabs.js +1 -1
  172. package/dist/kernel/components/ui/tag.js +1 -1
  173. package/dist/kernel/components/ui/text.d.ts +2 -2
  174. package/dist/kernel/components/ui/text.js +1 -1
  175. package/dist/kernel/components/ui/toast.js +1 -1
  176. package/dist/kernel/components/ui/tooltip.js +1 -1
  177. package/dist/kernel/defaults.registry.d.ts +11 -24
  178. package/dist/kernel/defaults.registry.js +11 -26
  179. package/dist/kernel/routes/agent/markdown.d.ts +3 -1
  180. package/dist/kernel/routes/agent/markdown.js +219 -48
  181. package/dist/kernel/routes/layouts/group.d.ts +1 -1
  182. package/dist/kernel/routes/layouts/group.js +5 -7
  183. package/dist/kernel/routes/metadata/feed.d.ts +1 -1
  184. package/dist/kernel/routes/metadata/feed.js +111 -81
  185. package/dist/kernel/routes/metadata/llms.d.ts +12 -3
  186. package/dist/kernel/routes/metadata/llms.js +156 -59
  187. package/dist/kernel/routes/metadata/og-image.js +1 -1
  188. package/dist/kernel/routes/metadata/robots.d.ts +1 -1
  189. package/dist/kernel/routes/metadata/robots.js +2 -2
  190. package/dist/kernel/routes/metadata/sitemap.d.ts +26 -4
  191. package/dist/kernel/routes/metadata/sitemap.js +206 -38
  192. package/dist/kernel/routes/not-found.d.ts +34 -0
  193. package/dist/kernel/routes/not-found.js +213 -0
  194. package/dist/kernel/routes/pages/group.d.ts +2 -2
  195. package/dist/kernel/routes/pages/group.js +21 -13
  196. package/dist/kernel/routes/pages/leaf.d.ts +28 -1
  197. package/dist/kernel/routes/pages/leaf.js +25 -16
  198. package/dist/kernel/routes/pages/root.js +19 -13
  199. package/dist/keyboard-shortcuts.js +1 -1
  200. package/dist/resolvers/manifest-resolver.js +29 -6
  201. package/dist/search.d.ts +6 -7
  202. package/dist/search.js +52 -29
  203. package/dist/{sidebar-types-Bgchdfd6.d.ts → sidebar-types-DKpR27II.d.ts} +1 -1
  204. package/dist/theme-scope.js +1 -1
  205. package/dist/{types-DHBm7-j6.d.ts → types-CJWRG05y.d.ts} +20 -1
  206. package/dist/{types-B_b3C0U6.d.ts → types-CUtrppxt.d.ts} +8 -2
  207. package/dist/{types-CIwwieNw.d.ts → types-J2w_puPF.d.ts} +11 -10
  208. package/dist/types.d.ts +15 -6
  209. package/dist/utils/heading-ids.js +30 -11
  210. package/dist/utils/toc-selection.d.ts +7 -0
  211. package/dist/utils/toc-selection.js +14 -0
  212. package/dist/validate-local-source-SV44DBQT.js +16 -0
  213. package/dist/validate-publish-os-source-NZJF3TB2.js +14 -0
  214. package/init/seed/minimal/.gitignore +1 -0
  215. package/init/seed/minimal/publish.os/assets/blog/hello-world.svg +13 -0
  216. package/init/seed/minimal/publish.os/assets/favicon.dark.svg +13 -0
  217. package/init/seed/minimal/publish.os/assets/favicon.svg +13 -0
  218. package/init/seed/minimal/publish.os/blog/content/hello-world.mdx +48 -0
  219. package/init/seed/minimal/publish.os/blog/content/series-a.mdx +11 -0
  220. package/init/seed/minimal/publish.os/blog/index.tsx +82 -0
  221. package/init/seed/minimal/publish.os/blog/layout.tsx +13 -0
  222. package/init/seed/minimal/publish.os/blog/page.tsx +76 -0
  223. package/init/seed/minimal/publish.os/components/blog/copy-link.tsx +64 -0
  224. package/init/seed/minimal/publish.os/docs/content/get-started.mdx +6 -11
  225. package/init/seed/minimal/publish.os/docs/content/groups.mdx +6 -7
  226. package/init/seed/minimal/publish.os/docs/content/{theme.mdx → themes.mdx} +14 -12
  227. package/init/seed/minimal/publish.os/publish.os.config.json +7 -7
  228. package/init/seed/minimal/publish.os/theme.css +52 -24
  229. package/init/seed/minimal/publish.os/tsconfig.json +3 -0
  230. package/init/seed/minimal/seed.json +12 -2
  231. package/init/seed/scratch/publish.os/docs/content/get-started.mdx +6 -0
  232. package/init/seed/scratch/publish.os/publish.os.config.json +4 -0
  233. package/init/seed/scratch/seed.json +5 -0
  234. package/package.json +55 -44
  235. package/release/app/phosphor/package.json +5 -5
  236. package/release/app/phosphor/pnpm-lock.yaml.template +553 -377
  237. package/release/app/phosphor/pnpm-workspace.yaml +3 -0
  238. package/release/compiler/package.json +5 -3
  239. package/release/compiler/pnpm-lock.yaml.template +500 -303
  240. package/release/compiler/pnpm-workspace.yaml +3 -0
  241. package/release/release.json +8 -37
  242. package/compiler-assets/nextjs/defaults/group/leaf.tsx +0 -48
  243. package/dist/icons.d.ts +0 -1
  244. package/dist/icons.js +0 -2
  245. package/dist/kernel/components/blocks/design-system-preview.d.ts +0 -61
  246. package/dist/kernel/components/blocks/design-system-preview.js +0 -648
  247. package/dist/kernel/components/blocks/link-playground.d.ts +0 -5
  248. package/dist/kernel/components/blocks/link-playground.js +0 -744
  249. package/dist/kernel/components/blocks/navigation-progress-playground.d.ts +0 -5
  250. package/dist/kernel/components/blocks/navigation-progress-playground.js +0 -629
  251. package/dist/kernel/components/mdx/components/pre.d.ts +0 -6
  252. package/dist/kernel/components/mdx/components/pre.js +0 -18
  253. package/dist/kernel/components/ui/meta-key.d.ts +0 -17
  254. package/dist/kernel/components/ui/meta-key.js +0 -9
  255. package/dist/kernel/components/ui/theme-toggle.d.ts +0 -24
  256. package/dist/kernel/components/ui/theme-toggle.js +0 -58
  257. package/dist/kernel/framework-icons.d.ts +0 -1
  258. package/dist/kernel/framework-icons.js +0 -39
  259. package/dist/link-CYaCRDb6.d.ts +0 -35
  260. package/release/app/lucide/package.json +0 -30
  261. package/release/app/lucide/pnpm-lock.yaml.template +0 -2905
  262. package/release/app/lucide/pnpm-workspace.yaml +0 -11
  263. package/release/app/tabler/package.json +0 -30
  264. package/release/app/tabler/pnpm-lock.yaml.template +0 -2911
  265. package/release/app/tabler/pnpm-workspace.yaml +0 -11
@@ -0,0 +1,1095 @@
1
+ import {
2
+ withCheckoutPreparation
3
+ } from "./chunk-6C65KV7O.js";
4
+ import {
5
+ LocalProcessError,
6
+ approveLocalComposition,
7
+ installLocalApp,
8
+ localProcessEnvironment,
9
+ startLocalProcess
10
+ } from "./chunk-4BC2L2KA.js";
11
+ import {
12
+ withLocalOperation
13
+ } from "./chunk-IL4RJOKI.js";
14
+ import {
15
+ assertGeneratedOutput,
16
+ assertLocalDirectory,
17
+ assertOperationOutput,
18
+ prepareGeneratedOutputUpdate
19
+ } from "./chunk-6D2E6UMD.js";
20
+ import {
21
+ assertFrameworkSelection
22
+ } from "./chunk-NNBJZPFM.js";
23
+ import "./chunk-7NY22B5U.js";
24
+ import {
25
+ PUBLIC_SEARCH_DIRECTORY
26
+ } from "./chunk-EFO6AWXN.js";
27
+ import {
28
+ isExcludedSourcePath,
29
+ isOsMetadataPath
30
+ } from "./chunk-WL75GQ5M.js";
31
+ import "./chunk-AI2UULNX.js";
32
+ import {
33
+ readInstalledFramework
34
+ } from "./chunk-5J3YUNRY.js";
35
+ import {
36
+ AppError
37
+ } from "./chunk-22RSSUNV.js";
38
+
39
+ // src/lib/compiler/lifecycle/dev-operation.ts
40
+ import { createHash as createHash4 } from "crypto";
41
+ import { mkdtemp as mkdtemp2, readFile as readFile5, realpath as realpath2, rm as rm3 } from "fs/promises";
42
+ import { createServer } from "net";
43
+ import { join as join5 } from "path";
44
+ import { setTimeout as delay } from "timers/promises";
45
+ import { stripVTControlCharacters } from "util";
46
+
47
+ // src/lib/compiler/lifecycle/change-scheduler.ts
48
+ function createChangeScheduler({
49
+ onChange,
50
+ onReady,
51
+ delayMs = 100
52
+ }) {
53
+ let timer;
54
+ return {
55
+ notify() {
56
+ onChange(), timer && clearTimeout(timer), timer = setTimeout(() => {
57
+ timer = void 0, onReady();
58
+ }, delayMs);
59
+ },
60
+ stop() {
61
+ timer && clearTimeout(timer), timer = void 0;
62
+ }
63
+ };
64
+ }
65
+
66
+ // src/lib/compiler/lifecycle/checkout-development.ts
67
+ import { createHash as createHash2 } from "crypto";
68
+ import { mkdtemp, readFile as readFile2, rm, stat, writeFile } from "fs/promises";
69
+ import { createRequire } from "module";
70
+ import { dirname, isAbsolute, join as join2 } from "path";
71
+ import { pathToFileURL } from "url";
72
+
73
+ // src/lib/compiler/lifecycle/source-watch.ts
74
+ import { createHash } from "crypto";
75
+ import { watch } from "fs";
76
+ import { lstat, readdir, readFile } from "fs/promises";
77
+ import { join, relative } from "path";
78
+ import { setImmediate } from "timers/promises";
79
+ function ignored(sourceRoot, path, include) {
80
+ let name = relative(sourceRoot, path).replace(/\\/g, "/");
81
+ return isOsMetadataPath(name) || (include ? !include(name) : isExcludedSourcePath(name)) || name.split("/").length === 1 && name.startsWith(".env") || name.split("/").some(
82
+ (segment) => ["node_modules", ".next", ".cache", ".turbo", ".git"].includes(segment)
83
+ );
84
+ }
85
+ function usesRecursiveSourceWatch(platform) {
86
+ return platform === "darwin";
87
+ }
88
+ function changesBetween(before, after) {
89
+ return [.../* @__PURE__ */ new Set([...before.keys(), ...after.keys()])].sort().flatMap((path) => {
90
+ let previous = before.get(path), current = after.get(path);
91
+ return previous === current ? [] : [
92
+ {
93
+ path,
94
+ action: previous === void 0 ? "added" : current === void 0 ? "deleted" : "edited"
95
+ }
96
+ ];
97
+ });
98
+ }
99
+ async function watchSource(options) {
100
+ let watchers = /* @__PURE__ */ new Map(), recursiveRootWatch = usesRecursiveSourceWatch(process.platform), closed = !1, scan = Promise.resolve(), rescanning = !1, baseline = /* @__PURE__ */ new Map(), closeWatchers = async () => {
101
+ let entries = [...watchers.values()];
102
+ watchers.clear();
103
+ for (let { watcher } of entries)
104
+ await setImmediate(), watcher.close();
105
+ }, scanNow = async () => {
106
+ let visited = /* @__PURE__ */ new Set(), identity = /* @__PURE__ */ new Map();
107
+ await visit(options.sourceRoot, visited, identity);
108
+ for (let [path, entry] of watchers)
109
+ visited.has(path) || (entry.watcher.close(), watchers.delete(path));
110
+ return identity;
111
+ }, rescan = () => (closed || rescanning || (rescanning = !0, scan = scan.then(async () => {
112
+ if (closed) return;
113
+ let identity = await scanNow();
114
+ !closed && changesBetween(baseline, identity).length > 0 && options.onChange();
115
+ }).catch(options.onError).finally(() => {
116
+ rescanning = !1;
117
+ })), scan), visit = async (directory, visited, identity) => {
118
+ if (closed || ignored(options.sourceRoot, directory, options.include))
119
+ return;
120
+ let entry = await lstat(directory, { bigint: !0 }).catch(
121
+ (error) => {
122
+ if (error.code !== "ENOENT") throw error;
123
+ }
124
+ );
125
+ if (closed) return;
126
+ if (entry && entry.isFile() && identity.set(
127
+ relative(options.sourceRoot, directory).replace(/\\/g, "/"),
128
+ [
129
+ entry.mode,
130
+ entry.dev,
131
+ entry.ino,
132
+ entry.size,
133
+ entry.mtimeNs,
134
+ entry.ctimeNs
135
+ ].map(String).join(":")
136
+ ), !entry?.isDirectory() || entry.isSymbolicLink()) {
137
+ watchers.get(directory)?.watcher.close(), watchers.delete(directory);
138
+ return;
139
+ }
140
+ visited.add(directory);
141
+ let watchDirectory = !recursiveRootWatch || directory === options.sourceRoot, previous = watchDirectory ? watchers.get(directory) : void 0;
142
+ if (previous && (previous.dev !== entry.dev || previous.ino !== entry.ino) && (previous.watcher.close(), watchers.delete(directory)), watchDirectory && !watchers.has(directory)) {
143
+ let onEvent = (_event, filename) => {
144
+ let relativeFilename = typeof filename == "string" ? filename : Buffer.isBuffer(filename) ? filename.toString("utf8") : void 0;
145
+ closed || relativeFilename && ignored(
146
+ options.sourceRoot,
147
+ join(directory, relativeFilename),
148
+ options.include
149
+ ) || rescan();
150
+ }, watcher = recursiveRootWatch ? watch(directory, { recursive: !0 }, onEvent) : watch(directory, onEvent);
151
+ watcher.on("error", (error) => {
152
+ closed || options.onError(error);
153
+ }), watchers.set(directory, { watcher, dev: entry.dev, ino: entry.ino });
154
+ }
155
+ let entries = await readdir(directory, { withFileTypes: !0 }).catch(
156
+ (error) => {
157
+ if (error.code !== "ENOENT" && error.code !== "ENOTDIR") throw error;
158
+ return [];
159
+ }
160
+ );
161
+ for (let child of entries)
162
+ await visit(join(directory, child.name), visited, identity);
163
+ };
164
+ try {
165
+ scan = scanNow().then((identity) => {
166
+ baseline = identity;
167
+ }), await scan;
168
+ } catch (error) {
169
+ throw closed = !0, await closeWatchers(), error;
170
+ }
171
+ let reconciliation = setInterval(() => {
172
+ rescan();
173
+ }, 2e3);
174
+ return reconciliation.unref(), {
175
+ reconcileStartup: rescan,
176
+ revision: async () => {
177
+ if (await scan, closed) return;
178
+ let before = await scanNow(), hash = createHash("sha256");
179
+ for (let path of [...before.keys()].sort()) {
180
+ let contents = await readFile(join(options.sourceRoot, path)).catch(
181
+ (error) => {
182
+ if (!(error.code === "ENOENT" || error.code === "ENOTDIR"))
183
+ throw error;
184
+ }
185
+ );
186
+ if (!contents) return;
187
+ hash.update(JSON.stringify([path, contents.byteLength])), hash.update("\0"), hash.update(contents);
188
+ }
189
+ let after = await scanNow();
190
+ return changesBetween(before, after).length === 0 ? `sha256:${hash.digest("hex")}` : void 0;
191
+ },
192
+ takeChanges: async () => {
193
+ if (await scan, closed) return [];
194
+ let current = await scanNow(), changes = changesBetween(baseline, current);
195
+ return baseline = current, changes;
196
+ },
197
+ stop: async () => {
198
+ closed = !0, clearInterval(reconciliation), await closeWatchers(), await scan;
199
+ }
200
+ };
201
+ }
202
+
203
+ // src/lib/compiler/lifecycle/checkout-development.ts
204
+ var compilerPaths = [
205
+ "src/compiler.ts",
206
+ "src/lib/compiler",
207
+ "compiler-assets/nextjs",
208
+ "release",
209
+ "package.json",
210
+ "tsconfig.json"
211
+ ], workspacePaths = [
212
+ "package.json",
213
+ "pnpm-lock.yaml",
214
+ "pnpm-workspace.yaml",
215
+ ".pnpmfile.mjs"
216
+ ], includesPath = (paths, path) => path === "" || paths.some(
217
+ (input) => input === path || input.startsWith(`${path}/`) || path.startsWith(`${input}/`)
218
+ );
219
+ async function watchCheckout(options) {
220
+ let workspaceRoot;
221
+ for (let directory = options.packageRoot; ; directory = dirname(directory)) {
222
+ if (await stat(join2(directory, "pnpm-workspace.yaml")).then((entry) => entry.isFile()).catch((error) => {
223
+ if (error.code !== "ENOENT") throw error;
224
+ return !1;
225
+ })) {
226
+ workspaceRoot = directory;
227
+ break;
228
+ }
229
+ if (directory === dirname(directory)) break;
230
+ }
231
+ let compiler = await watchSource({
232
+ ...options,
233
+ sourceRoot: options.packageRoot,
234
+ include: (path) => includesPath(
235
+ workspaceRoot === options.packageRoot ? [...compilerPaths, ...workspacePaths] : compilerPaths,
236
+ path
237
+ ) && path !== "compiler-assets/nextjs/defaults/root" && !path.startsWith("compiler-assets/nextjs/defaults/root/")
238
+ }), workspace;
239
+ try {
240
+ workspaceRoot && workspaceRoot !== options.packageRoot && (workspace = await watchSource({
241
+ ...options,
242
+ sourceRoot: workspaceRoot,
243
+ include: (path) => includesPath(workspacePaths, path)
244
+ }));
245
+ } catch (error) {
246
+ throw await compiler.stop(), error;
247
+ }
248
+ return {
249
+ workspaceRoot,
250
+ reconcileStartup: async () => {
251
+ await compiler.reconcileStartup(), await workspace?.reconcileStartup();
252
+ },
253
+ takeChanges: async () => [
254
+ ...(await compiler.takeChanges()).map((change) => ({
255
+ ...change,
256
+ path: `framework/${change.path}`,
257
+ dependency: workspacePaths.includes(change.path)
258
+ })),
259
+ ...(await workspace?.takeChanges() ?? []).map((change) => ({
260
+ ...change,
261
+ path: `workspace/${change.path}`,
262
+ dependency: !0
263
+ }))
264
+ ],
265
+ revision: async () => {
266
+ let revisions = [
267
+ await compiler.revision(),
268
+ await workspace?.revision()
269
+ ];
270
+ if (!(!revisions[0] || workspace && !revisions[1]))
271
+ return createHash2("sha256").update(JSON.stringify(revisions)).digest("hex");
272
+ },
273
+ dependencyRevision: async () => {
274
+ let hash = createHash2("sha256"), paths = /* @__PURE__ */ new Set([
275
+ join2(options.packageRoot, "package.json"),
276
+ ...workspacePaths.map(
277
+ (path) => join2(workspaceRoot ?? options.packageRoot, path)
278
+ )
279
+ ]);
280
+ for (let path of paths)
281
+ hash.update(path), hash.update(
282
+ await readFile2(path).catch((error) => {
283
+ if (error.code !== "ENOENT") throw error;
284
+ return "missing";
285
+ })
286
+ ), hash.update("\0");
287
+ return hash.digest("hex");
288
+ },
289
+ stop: async () => {
290
+ await Promise.all([compiler.stop(), workspace?.stop()]);
291
+ }
292
+ };
293
+ }
294
+ async function prepareCheckoutDependencies(options) {
295
+ if (!options.pnpmExecutable || !isAbsolute(options.pnpmExecutable))
296
+ throw new AppError({
297
+ code: "FRAMEWORK_PNPM_MISSING",
298
+ message: "Checkout development requires the caller's pnpm executable."
299
+ });
300
+ for (let root of /* @__PURE__ */ new Set([options.packageRoot, options.workspaceRoot])) {
301
+ if (!root) continue;
302
+ let manifest = JSON.parse(
303
+ await readFile2(join2(root, "package.json"), "utf8")
304
+ );
305
+ for (let kind of [
306
+ "dependencies",
307
+ "devDependencies",
308
+ "optionalDependencies"
309
+ ])
310
+ for (let [name, version] of Object.entries(manifest[kind] ?? {}))
311
+ if (["@publish.os/nextjs", "@publish.os/cli"].includes(name) && (typeof version != "string" || !/^(?:workspace:|link:|file:)/.test(version)))
312
+ throw new AppError({
313
+ code: "FRAMEWORK_SELECTION_INVALID",
314
+ message: "Checkout dependencies cannot acquire PublishOS packages from npm.",
315
+ fix: "Use the local workspace or artifact dependency, then save again."
316
+ });
317
+ }
318
+ try {
319
+ await withCheckoutPreparation({
320
+ packageRoot: options.packageRoot,
321
+ workspaceRoot: options.workspaceRoot,
322
+ signal: options.lifetime.signal,
323
+ prepare: async (confirmStopped) => {
324
+ try {
325
+ await startLocalProcess({
326
+ command: options.pnpmExecutable,
327
+ args: [
328
+ "--filter",
329
+ "@publish.os/nextjs...",
330
+ "install",
331
+ "--frozen-lockfile",
332
+ "--prefer-offline"
333
+ ],
334
+ cwd: options.workspaceRoot ?? options.packageRoot,
335
+ environment: {
336
+ ...localProcessEnvironment({ mode: "development" }),
337
+ CI: "true"
338
+ },
339
+ signal: AbortSignal.any([
340
+ options.lifetime.signal,
341
+ AbortSignal.timeout(3e5)
342
+ ]),
343
+ onShutdown: options.lifetime.onShutdown,
344
+ quiet: !0
345
+ }).completion, confirmStopped();
346
+ } catch (error) {
347
+ throw (!(error instanceof AppError) || error.code !== "FRAMEWORK_PROCESS_SHUTDOWN_FAILED") && confirmStopped(), error;
348
+ }
349
+ }
350
+ });
351
+ } catch (error) {
352
+ throw error instanceof LocalProcessError && error.output.trim() && process.stderr.write(error.output), error;
353
+ }
354
+ }
355
+ async function runCheckoutCompiler(options) {
356
+ let selection = options.request.context?.framework;
357
+ if (selection?.kind !== "checkout" || !options.request.paths.output)
358
+ throw new AppError({
359
+ code: "FRAMEWORK_SELECTION_INVALID",
360
+ message: "Compiler updates require the selected checkout and owned output."
361
+ });
362
+ let temporary = await mkdtemp(
363
+ join2(dirname(options.request.paths.output), "compiler-")
364
+ ), identity = await assertLocalDirectory(temporary), requestPath = join2(temporary, "request.json"), resultPath = join2(temporary, "result.json"), retain = !1;
365
+ try {
366
+ await writeFile(requestPath, JSON.stringify(options.request), {
367
+ flag: "wx",
368
+ mode: 384
369
+ }), await startLocalProcess({
370
+ command: process.execPath,
371
+ args: [
372
+ "--import",
373
+ pathToFileURL(
374
+ createRequire(join2(selection.packageRoot, "package.json")).resolve(
375
+ "tsx/esm"
376
+ )
377
+ ).href,
378
+ join2(
379
+ selection.packageRoot,
380
+ "src/lib/compiler/lifecycle/checkout-compiler-worker.ts"
381
+ ),
382
+ requestPath,
383
+ resultPath
384
+ ],
385
+ cwd: selection.packageRoot,
386
+ environment: {
387
+ ...localProcessEnvironment({ mode: "development" }),
388
+ TSX_TSCONFIG_PATH: join2(selection.packageRoot, "tsconfig.json")
389
+ },
390
+ signal: AbortSignal.any([
391
+ options.lifetime.signal,
392
+ AbortSignal.timeout(18e4)
393
+ ]),
394
+ onShutdown: options.lifetime.onShutdown
395
+ }).completion;
396
+ let response = JSON.parse(await readFile2(resultPath, "utf8"));
397
+ if (response?.result?.type !== "result" || !["success", "failure", "cancelled"].includes(response.result.status) || !Array.isArray(response.events))
398
+ throw new Error("Invalid compiler result");
399
+ return response;
400
+ } catch (error) {
401
+ throw options.lifetime.signal.throwIfAborted(), error instanceof AppError && error.code === "FRAMEWORK_PROCESS_SHUTDOWN_FAILED" ? (retain = !0, error) : new AppError({
402
+ code: "FRAMEWORK_CHECKOUT_COMPILE_FAILED",
403
+ message: "The checkout compiler could not apply this edit.",
404
+ fix: "Correct the compiler error and save again. The previous preview remains available.",
405
+ details: { cause: error }
406
+ });
407
+ } finally {
408
+ retain || (await assertLocalDirectory(temporary, identity), await rm(temporary, { recursive: !0, force: !0 }));
409
+ }
410
+ }
411
+
412
+ // src/lib/compiler/lifecycle/checkout-watch-shutdown.ts
413
+ async function startCheckoutWatchForOperation({
414
+ lifetime,
415
+ watch: watch2
416
+ }) {
417
+ let checkoutWatch = await watch2();
418
+ return lifetime.onShutdown(() => checkoutWatch.stop()), checkoutWatch;
419
+ }
420
+
421
+ // src/lib/compiler/lifecycle/preview-cache.ts
422
+ import { createHash as createHash3 } from "crypto";
423
+ import {
424
+ lstat as lstat2,
425
+ readdir as readdir2,
426
+ readFile as readFile3,
427
+ realpath,
428
+ writeFile as writeFile2
429
+ } from "fs/promises";
430
+ import { join as join3 } from "path";
431
+ var CACHE_FILE = ".preview-cache.json", GENERATED_FILES = [
432
+ "package.json",
433
+ "pnpm-lock.yaml",
434
+ "manifest.generated.ts",
435
+ "next.config.mjs",
436
+ "postcss.config.mjs",
437
+ "proxy.ts",
438
+ "tsconfig.json"
439
+ ], GENERATED_DIRECTORIES = [".meta", "app", "source", "public", "scripts"], INSTALLATION_FILES = [
440
+ "node_modules/.modules.yaml",
441
+ "node_modules/.package-map.json",
442
+ "node_modules/.pnpm/lock.yaml",
443
+ "node_modules/next/package.json",
444
+ "node_modules/next/dist/bin/next",
445
+ "node_modules/@publish.os/nextjs/package.json"
446
+ ];
447
+ async function hashEntry({
448
+ hash,
449
+ outputDir,
450
+ path
451
+ }) {
452
+ let absolute = join3(outputDir, path), entry = await lstat2(absolute);
453
+ if (entry.isFile()) {
454
+ hash.update(`file:${JSON.stringify(path)}\0`), hash.update(await readFile3(absolute)), hash.update("\0");
455
+ return;
456
+ }
457
+ if (!entry.isDirectory())
458
+ throw new Error(`Unexpected generated preview entry: ${path}`);
459
+ hash.update(`directory:${JSON.stringify(path)}\0`);
460
+ for (let name of (await readdir2(absolute)).sort())
461
+ await hashEntry({ hash, outputDir, path: join3(path, name) });
462
+ }
463
+ async function outputIntegrity({
464
+ outputDir,
465
+ inputKind
466
+ }) {
467
+ let hash = createHash3("sha256");
468
+ for (let path of [
469
+ ...GENERATED_FILES,
470
+ ...inputKind === "checkout" ? ["next.config.base.mjs"] : [],
471
+ ...GENERATED_DIRECTORIES,
472
+ ...INSTALLATION_FILES.filter(
473
+ (path2) => inputKind !== "checkout" || path2 !== "node_modules/@publish.os/nextjs/package.json"
474
+ )
475
+ ])
476
+ await hashEntry({ hash, outputDir, path });
477
+ return `sha256:${hash.digest("hex")}`;
478
+ }
479
+ async function reusablePreview(options) {
480
+ if (options.revision)
481
+ try {
482
+ let cache = JSON.parse(
483
+ await readFile3(join3(options.outputDir, CACHE_FILE), "utf8")
484
+ );
485
+ if (cache.version !== 5 || cache.inputKind !== (options.inputKind ?? "customer") || cache.runtimeGraph !== (options.inputKind === "checkout" ? "checkout-source" : void 0) || cache.runtime !== options.runtime || cache.sourcePath !== options.sourcePath || typeof cache.integrity != "string")
486
+ return;
487
+ let current = cache.revision === options.revision && cache.frameworkIdentity === options.frameworkIdentity && cache.compilerRevision === options.compilerRevision && cache.checkoutDependencyRevision === options.checkoutDependencyRevision && cache.url === options.url;
488
+ return !current && options.inputKind !== "checkout" || options.inputKind === "checkout" && (!options.checkoutRoot || await realpath(
489
+ join3(options.outputDir, "node_modules/@publish.os/nextjs")
490
+ ) !== await realpath(options.checkoutRoot)) || cache.integrity !== await outputIntegrity(options) ? void 0 : {
491
+ current,
492
+ dependenciesChanged: cache.checkoutDependencyRevision !== options.checkoutDependencyRevision
493
+ };
494
+ } catch {
495
+ return;
496
+ }
497
+ }
498
+ async function recordPreviewCache(options) {
499
+ if (!options.revision) return;
500
+ let cache = {
501
+ version: 5,
502
+ inputKind: options.inputKind ?? "customer",
503
+ ...options.inputKind === "checkout" ? { runtimeGraph: "checkout-source" } : {},
504
+ revision: options.revision,
505
+ runtime: options.runtime,
506
+ frameworkIdentity: options.frameworkIdentity,
507
+ ...options.compilerRevision ? { compilerRevision: options.compilerRevision } : {},
508
+ ...options.checkoutDependencyRevision ? { checkoutDependencyRevision: options.checkoutDependencyRevision } : {},
509
+ url: options.url,
510
+ sourcePath: options.sourcePath,
511
+ integrity: await outputIntegrity(options)
512
+ };
513
+ await writeFile2(
514
+ join3(options.outputDir, CACHE_FILE),
515
+ `${JSON.stringify(cache)}
516
+ `
517
+ );
518
+ }
519
+
520
+ // src/lib/compiler/lifecycle/refresh-preview.ts
521
+ import {
522
+ cp,
523
+ lstat as lstat3,
524
+ mkdir,
525
+ readdir as readdir3,
526
+ readFile as readFile4,
527
+ rename,
528
+ rm as rm2,
529
+ writeFile as writeFile3
530
+ } from "fs/promises";
531
+ import { dirname as dirname2, join as join4, relative as relative2 } from "path";
532
+ var PRESERVED_PREVIEW_ENTRIES = /* @__PURE__ */ new Set([
533
+ "node_modules",
534
+ ".next",
535
+ ".operation-owner.json",
536
+ ".preview-cache.json",
537
+ PUBLIC_SEARCH_DIRECTORY
538
+ ]);
539
+ async function refreshPreview(options) {
540
+ let sync = async (source, target) => {
541
+ options.signal.throwIfAborted(), await assertLocalDirectory(source), await assertLocalDirectory(target);
542
+ let incoming = new Map(
543
+ (await readdir3(source, { withFileTypes: !0 })).map((entry) => [
544
+ entry.name,
545
+ entry
546
+ ])
547
+ ), previous = await readdir3(target, { withFileTypes: !0 }), preserved = (name) => {
548
+ let path = relative2(options.outputDir, join4(target, name)).replace(
549
+ /\\/g,
550
+ "/"
551
+ );
552
+ return PRESERVED_PREVIEW_ENTRIES.has(path) || path.startsWith(".refresh-");
553
+ };
554
+ for (let old of previous)
555
+ preserved(old.name) || incoming.has(old.name) || await rm2(join4(target, old.name), { recursive: !0, force: !0 });
556
+ for (let [name, entry] of incoming) {
557
+ if (preserved(name)) continue;
558
+ let from = join4(source, name), to = join4(target, name), old = await lstat3(to).catch((error) => {
559
+ if (error.code !== "ENOENT") throw error;
560
+ });
561
+ if (old?.isSymbolicLink() || entry.isSymbolicLink())
562
+ throw new AppError({
563
+ code: "FRAMEWORK_LOCAL_OUTPUT_REDIRECTED",
564
+ message: "Preview output was redirected. Restore the source-owned output before restarting preview."
565
+ });
566
+ if (entry.isDirectory() && old?.isDirectory())
567
+ await sync(from, to);
568
+ else if (entry.isFile() && old?.isFile()) {
569
+ if ((await readFile4(from)).equals(await readFile4(to))) continue;
570
+ await rename(from, to);
571
+ } else
572
+ old && await rm2(to, { recursive: !0, force: !0 }), await rename(from, to);
573
+ }
574
+ };
575
+ await assertLocalDirectory(options.incoming), await mkdir(join4(options.incoming, "public"), { recursive: !0 });
576
+ for (let path of PRESERVED_PREVIEW_ENTRIES) {
577
+ if (dirname2(path) === ".") continue;
578
+ (await lstat3(join4(options.outputDir, path)).catch(
579
+ (error) => {
580
+ if (error.code !== "ENOENT") throw error;
581
+ }
582
+ ))?.isDirectory() && await mkdir(join4(options.incoming, dirname2(path)), { recursive: !0 });
583
+ }
584
+ await sync(options.incoming, options.outputDir);
585
+ }
586
+ async function restartPreview(options) {
587
+ let previous = join4(options.incoming, "..", "previous"), previousIdentity = await assertLocalDirectory(options.outputDir);
588
+ await mkdir(previous);
589
+ let preserved = ["node_modules", ".next", ".operation-owner.json"];
590
+ for (let entry of await readdir3(options.outputDir))
591
+ preserved.includes(entry) || entry.startsWith(".refresh-") || await cp(join4(options.outputDir, entry), join4(previous, entry), {
592
+ recursive: !0
593
+ });
594
+ options.signal.throwIfAborted(), await assertLocalDirectory(options.outputDir, previousIdentity), await options.stop();
595
+ let movedDependencies = !1;
596
+ try {
597
+ options.dependencies && (await rename(
598
+ join4(options.outputDir, "node_modules"),
599
+ join4(previous, "node_modules")
600
+ ), movedDependencies = !0, await rename(
601
+ join4(options.incoming, "node_modules"),
602
+ join4(options.outputDir, "node_modules")
603
+ )), await refreshPreview(options), await options.start();
604
+ } catch (error) {
605
+ try {
606
+ await options.stop(), await assertLocalDirectory(options.outputDir, previousIdentity), movedDependencies && (await rename(
607
+ join4(options.outputDir, "node_modules"),
608
+ join4(options.incoming, "..", "failed-node_modules")
609
+ ).catch((cause) => {
610
+ if (cause.code !== "ENOENT") throw cause;
611
+ }), await rename(
612
+ join4(previous, "node_modules"),
613
+ join4(options.outputDir, "node_modules")
614
+ )), await refreshPreview({
615
+ incoming: previous,
616
+ outputDir: options.outputDir,
617
+ signal: AbortSignal.timeout(3e3)
618
+ });
619
+ let cache = await readFile4(join4(previous, ".preview-cache.json")).catch(
620
+ (cause) => {
621
+ if (cause.code !== "ENOENT") throw cause;
622
+ }
623
+ );
624
+ cache && await writeFile3(join4(options.outputDir, ".preview-cache.json"), cache), options.signal.aborted || await options.start();
625
+ } catch (cause) {
626
+ throw new AppError({
627
+ code: "FRAMEWORK_PREVIEW_RECOVERY_FAILED",
628
+ message: "The previous preview could not be restored. Generated recovery state was retained.",
629
+ fix: "Stop checkout dev and inspect the retained generated output before retrying.",
630
+ details: { cause: new AggregateError([error, cause]) }
631
+ });
632
+ }
633
+ throw error;
634
+ }
635
+ }
636
+
637
+ // src/lib/compiler/lifecycle/dev-operation.ts
638
+ async function readSourceSelection(sourceRoot) {
639
+ let raw = await readFile5(
640
+ join5(sourceRoot, "publish.os.config.json"),
641
+ "utf8"
642
+ ).catch(() => "");
643
+ try {
644
+ return JSON.parse(raw);
645
+ } catch {
646
+ return;
647
+ }
648
+ }
649
+ async function availablePort({
650
+ port,
651
+ host
652
+ }) {
653
+ return await new Promise((resolve) => {
654
+ let server = createServer();
655
+ server.unref(), server.once(
656
+ "error",
657
+ (error) => resolve(
658
+ host === "::1" && (error.code === "EAFNOSUPPORT" || error.code === "EADDRNOTAVAIL")
659
+ )
660
+ ), server.listen({ host, port }, () => server.close(() => resolve(!0)));
661
+ });
662
+ }
663
+ async function previewPort(requested, explicit) {
664
+ if (!Number.isInteger(requested) || requested < 1 || requested > 65535)
665
+ throw new AppError({
666
+ code: "FRAMEWORK_PREVIEW_PORT_INVALID",
667
+ message: "The preview port must be an integer from 1 through 65535. Set a valid --port value."
668
+ });
669
+ for (let port = requested; port <= 65535; port += 1) {
670
+ if (await availablePort({ port, host: "127.0.0.1" }) && await availablePort({ port, host: "::1" }) && await availablePort({ port }))
671
+ return port;
672
+ if (explicit) {
673
+ let alternative = await previewPort(
674
+ requested < 65535 ? requested + 1 : 8080,
675
+ !1
676
+ ).catch(() => {
677
+ });
678
+ throw new AppError({
679
+ code: "FRAMEWORK_PREVIEW_PORT_UNAVAILABLE",
680
+ message: `Port ${requested} is in use. Stop the server on that port${alternative ? ` or run publish.os dev --port ${alternative}` : " and choose another port"}.`
681
+ });
682
+ }
683
+ }
684
+ throw new AppError({
685
+ code: "FRAMEWORK_PREVIEW_PORT_UNAVAILABLE",
686
+ message: `No free preview port is available from ${requested} through 65535. Stop another local server or select a lower --port.`
687
+ });
688
+ }
689
+ async function runDevelopment(options) {
690
+ let requestedPort = options.request.port ?? 8080, port = await previewPort(
691
+ requestedPort,
692
+ options.request.portExplicit === !0
693
+ ), url = `http://localhost:${port}`, frameworkIdentity = options.request.context?.archive?.integrity ?? "", inputKind = options.request.context?.framework?.kind ?? "customer", framework = await readInstalledFramework();
694
+ options.request.context?.framework !== void 0 && (frameworkIdentity = await assertFrameworkSelection({
695
+ context: options.request.context,
696
+ framework,
697
+ runtime: void 0
698
+ }));
699
+ let sessionCancellation = new AbortController();
700
+ port !== requestedPort && options.onEvent?.({
701
+ type: "progress",
702
+ message: `Port ${requestedPort} is in use. Using ${port}.`
703
+ });
704
+ let scope = options.request.context?.framework?.kind === "checkout" ? createHash4("sha256").update(
705
+ JSON.stringify([
706
+ await realpath2(options.request.context.framework.packageRoot),
707
+ port
708
+ ])
709
+ ).digest("hex") : void 0;
710
+ return await withLocalOperation({
711
+ sourceRoot: options.request.paths.source,
712
+ outputDir: options.request.paths.output,
713
+ operation: "dev",
714
+ scope,
715
+ signal: options.signal ? AbortSignal.any([options.signal, sessionCancellation.signal]) : sessionCancellation.signal,
716
+ run: async (lifetime) => {
717
+ let localOptions = { ...options, signal: lifetime.signal }, stopped = !1, dirty = !1, refreshing, startupReconciliation, ready = !1, checkoutWatch, checkoutDependenciesDirty = !1, rejectSession = () => {
718
+ }, failed = new Promise((_resolve, reject) => {
719
+ rejectSession = reject;
720
+ });
721
+ failed.catch(() => {
722
+ });
723
+ let abortSession = () => rejectSession(lifetime.signal.reason);
724
+ lifetime.signal.addEventListener("abort", abortSession, { once: !0 });
725
+ let changeScheduler = createChangeScheduler({
726
+ onChange: () => {
727
+ dirty = !0;
728
+ },
729
+ onReady: () => {
730
+ ready && drain();
731
+ }
732
+ }), watchOptions = {
733
+ onChange: changeScheduler.notify,
734
+ onError: (cause) => {
735
+ let error = new AppError({
736
+ code: "FRAMEWORK_PREVIEW_WATCH_FAILED",
737
+ message: `The source watcher stopped: ${cause instanceof Error ? cause.message : String(cause)}. Restart preview after correcting the file-system error.`
738
+ });
739
+ sessionCancellation.abort(error), rejectSession(error);
740
+ }
741
+ }, sourceWatch = await watchSource({
742
+ ...watchOptions,
743
+ sourceRoot: lifetime.sourceRoot
744
+ });
745
+ if (lifetime.onShutdown(async () => {
746
+ stopped = !0, changeScheduler.stop(), await sourceWatch.stop(), await startupReconciliation, await refreshing;
747
+ }), options.request.context?.framework?.kind === "checkout") {
748
+ let packageRoot = options.request.context.framework.packageRoot;
749
+ checkoutWatch = await startCheckoutWatchForOperation({
750
+ lifetime,
751
+ watch: () => watchCheckout({
752
+ ...watchOptions,
753
+ packageRoot
754
+ })
755
+ });
756
+ }
757
+ let initialRevision = await sourceWatch.revision(), initialCompilerRevision = await checkoutWatch?.revision(), initialDependencyRevision = await checkoutWatch?.dependencyRevision(), initialConfig = await readSourceSelection(lifetime.sourceRoot) ?? {}, reuse = await reusablePreview({
758
+ outputDir: lifetime.outputDir,
759
+ revision: initialRevision,
760
+ runtime: options.request.context?.framework ? `${framework.packageName}@${framework.version}` : initialConfig.runtime ?? "",
761
+ frameworkIdentity,
762
+ compilerRevision: initialCompilerRevision,
763
+ checkoutDependencyRevision: initialDependencyRevision,
764
+ inputKind,
765
+ url,
766
+ sourcePath: options.request.context?.sourcePath ?? "publish.os",
767
+ checkoutRoot: options.request.context?.framework?.kind === "checkout" ? options.request.context.framework.packageRoot : void 0
768
+ });
769
+ checkoutDependenciesDirty = reuse?.dependenciesChanged ?? !1;
770
+ let validateSource = async () => (await import("./validate-local-source-SV44DBQT.js")).validateLocalSource({
771
+ options: localOptions,
772
+ sourceDir: lifetime.sourceDir,
773
+ sourceRoot: lifetime.sourceRoot
774
+ }), prepared = reuse ? void 0 : await validateSource(), selection = {
775
+ runtime: options.request.context?.framework ? `${framework.packageName}@${framework.version}` : prepared?.source.config.runtime ?? initialConfig.runtime
776
+ }, assertSelection = async () => {
777
+ if (options.request.context?.framework) return;
778
+ let config = await readSourceSelection(lifetime.sourceRoot);
779
+ if (config && config.runtime !== selection.runtime)
780
+ throw new AppError({
781
+ code: "FRAMEWORK_PREVIEW_RESTART_REQUIRED",
782
+ message: "The framework pin changed. Restart publish.os dev to use the new selection."
783
+ });
784
+ };
785
+ if (options.request.context?.ide) {
786
+ let { prepareIdeSupport } = await import("./ide-support-CU6Z5PVR.js"), ideSource = prepared?.source ?? (await validateSource()).source;
787
+ await prepareIdeSupport({
788
+ frameworkOptions: localOptions,
789
+ publishOsDir: lifetime.sourceRoot,
790
+ source: ideSource,
791
+ framework: prepared?.framework ?? framework
792
+ });
793
+ }
794
+ let compose = async (outputDir, preparedSource) => {
795
+ let { composeFrameworkSource } = await import("./compose-CVBJRAF6.js");
796
+ await composeFrameworkSource({
797
+ request: {
798
+ ...options.request,
799
+ paths: { source: lifetime.sourceDir, output: outputDir },
800
+ context: {
801
+ ...options.request.context,
802
+ previewUrl: url,
803
+ sourcePath: options.request.context?.sourcePath ?? "publish.os",
804
+ sourceRevision: "local-development"
805
+ }
806
+ },
807
+ source: preparedSource,
808
+ signal: lifetime.signal,
809
+ onProgress: (message) => options.onEvent?.({ type: "progress", message }),
810
+ onWarning: (warning) => options.onEvent?.({
811
+ type: "diagnostics",
812
+ diagnostics: {
813
+ diagnostics: [{ ...warning, severity: "warning" }]
814
+ }
815
+ })
816
+ });
817
+ }, search = async (outputDir) => {
818
+ options.onEvent?.({
819
+ type: "progress",
820
+ message: "Refreshing search index"
821
+ }), await startLocalProcess({
822
+ command: process.execPath,
823
+ args: [join5(outputDir, "scripts/build-search-index.mjs")],
824
+ cwd: outputDir,
825
+ signal: lifetime.signal,
826
+ onShutdown: lifetime.onShutdown,
827
+ environment: localProcessEnvironment({ mode: "development" })
828
+ }).completion;
829
+ };
830
+ prepared && (await approveLocalComposition({ options: localOptions }), await lifetime.replaceOutput(async (outputDir) => {
831
+ options.onEvent?.({ type: "progress", message: "Preparing preview" }), await compose(outputDir, prepared.source), await installLocalApp({
832
+ outputDir,
833
+ framework: prepared.framework,
834
+ options: localOptions,
835
+ lifetime
836
+ }), await search(outputDir), await assertSelection(), await recordPreviewCache({
837
+ outputDir,
838
+ revision: initialRevision,
839
+ runtime: selection.runtime ?? "",
840
+ frameworkIdentity,
841
+ compilerRevision: initialCompilerRevision,
842
+ checkoutDependencyRevision: initialDependencyRevision,
843
+ inputKind,
844
+ url,
845
+ sourcePath: options.request.context?.sourcePath ?? "publish.os"
846
+ });
847
+ }));
848
+ let outputIdentity = await assertLocalDirectory(lifetime.outputDir), assertOutput = async () => {
849
+ await assertLocalDirectory(lifetime.outputDir, outputIdentity), await assertOperationOutput({
850
+ sourceRoot: lifetime.sourceRoot,
851
+ outputDir: lifetime.outputDir,
852
+ operation: "dev",
853
+ scope
854
+ });
855
+ }, next, resolveSession = () => {
856
+ }, ended = new Promise((resolve) => {
857
+ resolveSession = resolve;
858
+ }), stopNext = async () => {
859
+ let current = next;
860
+ next = void 0, ready = !1, await current?.stop();
861
+ }, startNext = async (verifyStartup = !1) => {
862
+ let log = "", resolveReady = () => {
863
+ }, rejectReady = () => {
864
+ }, started = new Promise((resolve, reject) => {
865
+ resolveReady = resolve, rejectReady = reject;
866
+ }), observedReady = !1, observe = (value) => {
867
+ log = (log + value).slice(-4096), !(observedReady || !/Ready in\s+\S+/i.test(stripVTControlCharacters(log))) && (observedReady = !0, startupReconciliation = (async () => {
868
+ if (verifyStartup) {
869
+ let response = await fetch(
870
+ `${url}/_next/static/__publishos_ready__`,
871
+ {
872
+ signal: AbortSignal.any([
873
+ lifetime.signal,
874
+ AbortSignal.timeout(15e3)
875
+ ])
876
+ }
877
+ );
878
+ if (await response.body?.cancel(), response.status >= 500)
879
+ throw new AppError({
880
+ code: "FRAMEWORK_PREVIEW_START_FAILED",
881
+ message: "Next could not serve the restarted preview."
882
+ });
883
+ }
884
+ await sourceWatch.reconcileStartup(), await checkoutWatch?.reconcileStartup(), lifetime.signal.throwIfAborted(), !stopped && (ready = !0, options.onEvent?.({ type: "ready", url }), resolveReady(), drain());
885
+ })().catch(rejectReady));
886
+ }, nextExecutable = await realpath2(
887
+ join5(lifetime.outputDir, "node_modules/next/dist/bin/next")
888
+ );
889
+ options.onEvent?.({ type: "progress", message: "Starting Next" });
890
+ let current = startLocalProcess({
891
+ command: process.execPath,
892
+ args: [nextExecutable, "dev", "--port", String(port)],
893
+ cwd: lifetime.outputDir,
894
+ signal: lifetime.signal,
895
+ onShutdown: lifetime.onShutdown,
896
+ environment: localProcessEnvironment({ mode: "development" }),
897
+ onStdout: observe,
898
+ onStderr: observe
899
+ });
900
+ next = current, current.completion.then(
901
+ () => {
902
+ rejectReady(
903
+ new AppError({
904
+ code: "FRAMEWORK_PREVIEW_START_FAILED",
905
+ message: "Next stopped before preview readiness."
906
+ })
907
+ ), next === current && ready && resolveSession();
908
+ },
909
+ (error) => {
910
+ rejectReady(error), next === current && ready && !lifetime.signal.aborted && rejectSession(error);
911
+ }
912
+ );
913
+ let deadline = new AbortController();
914
+ try {
915
+ await Promise.race([
916
+ started,
917
+ delay(6e4, void 0, { signal: deadline.signal }).then(() => {
918
+ throw new AppError({
919
+ code: "FRAMEWORK_PREVIEW_START_FAILED",
920
+ message: "Next did not become ready within 60 seconds."
921
+ });
922
+ })
923
+ ]);
924
+ } finally {
925
+ deadline.abort();
926
+ }
927
+ }, refresh = async (compilerChanges) => {
928
+ checkoutDependenciesDirty ||= compilerChanges.some(
929
+ (change) => change.dependency
930
+ );
931
+ let revisionBefore = await sourceWatch.revision(), compilerRevisionBefore = await checkoutWatch?.revision(), dependencyRevisionBefore = await checkoutWatch?.dependencyRevision(), inputsCurrent = async () => revisionBefore !== void 0 && revisionBefore === await sourceWatch.revision() && (!checkoutWatch || compilerRevisionBefore !== void 0 && compilerRevisionBefore === await checkoutWatch.revision());
932
+ await assertSelection();
933
+ let validation = checkoutWatch ? void 0 : await (await import("./validate-local-source-SV44DBQT.js")).validateLocalSource({
934
+ options: localOptions,
935
+ sourceDir: lifetime.sourceDir,
936
+ sourceRoot: lifetime.sourceRoot
937
+ });
938
+ await assertSelection(), await assertOutput(), await assertGeneratedOutput({ outputDir: lifetime.outputDir, scope });
939
+ let temporary = await mkdtemp2(join5(lifetime.outputDir, ".refresh-")), identity = await assertLocalDirectory(temporary), retain = !1, recordGeneratedOutput, primaryFailure, cleanup = async () => {
940
+ try {
941
+ await assertOutput(), await assertLocalDirectory(temporary, identity), await recordGeneratedOutput?.(), await rm3(temporary, { recursive: !0, force: !0 });
942
+ } catch (error) {
943
+ if (!primaryFailure) throw error;
944
+ primaryFailure.error instanceof Error && (primaryFailure.error.cause = {
945
+ previous: primaryFailure.error.cause,
946
+ cleanup: error,
947
+ retained: temporary
948
+ });
949
+ }
950
+ }, acceptCompilation = (response) => {
951
+ for (let event of response.events)
952
+ (event.type === "diagnostics" || event.type === "progress") && options.onEvent?.(event);
953
+ if (response.result.status !== "success")
954
+ throw new AppError({
955
+ code: response.result.error?.code ?? "FRAMEWORK_CHECKOUT_COMPILE_FAILED",
956
+ message: response.result.error?.message ?? "The checkout compiler did not complete the update.",
957
+ fix: response.result.error?.fix ?? "Correct the reported error and save again. The previous preview remains available."
958
+ });
959
+ };
960
+ try {
961
+ let incoming = join5(temporary, "app");
962
+ if (checkoutWatch) {
963
+ compilerChanges.length && options.onEvent?.({
964
+ type: "restart",
965
+ target: "compiler",
966
+ reason: "Compiler inputs changed."
967
+ }), checkoutDependenciesDirty && (await prepareCheckoutDependencies({
968
+ packageRoot: framework.packageRoot,
969
+ workspaceRoot: checkoutWatch.workspaceRoot,
970
+ pnpmExecutable: options.request.context?.pnpmExecutable,
971
+ lifetime
972
+ }), checkoutDependenciesDirty = !1);
973
+ let request = {
974
+ ...options.request,
975
+ operation: "compose",
976
+ paths: { source: lifetime.sourceDir, output: incoming },
977
+ context: {
978
+ ...options.request.context,
979
+ previewUrl: url,
980
+ sourceRevision: "local-development",
981
+ sourcePath: options.request.context?.sourcePath ?? "publish.os"
982
+ }
983
+ }, response = await runCheckoutCompiler({ request, lifetime });
984
+ if (!await inputsCurrent())
985
+ return dirty = !0, !1;
986
+ acceptCompilation(response), framework = await readInstalledFramework();
987
+ } else validation && await compose(incoming, validation.source);
988
+ if (!await inputsCurrent())
989
+ return dirty = !0, !1;
990
+ await assertSelection(), await assertOutput();
991
+ let changed = async (name) => !(await readFile5(join5(incoming, name))).equals(
992
+ await readFile5(join5(lifetime.outputDir, name))
993
+ ), dependenciesChanged = checkoutWatch && (await changed("package.json") || await changed("pnpm-workspace.yaml") || await changed("pnpm-lock.yaml")), configurationChanged = checkoutWatch && (await changed("next.config.mjs") || await changed("next.config.base.mjs") || await changed("postcss.config.mjs"));
994
+ dependenciesChanged && await installLocalApp({
995
+ outputDir: incoming,
996
+ framework,
997
+ options: localOptions,
998
+ lifetime
999
+ });
1000
+ let nextFrameworkIdentity = checkoutWatch ? await assertFrameworkSelection({
1001
+ context: options.request.context,
1002
+ framework,
1003
+ runtime: void 0
1004
+ }) : frameworkIdentity;
1005
+ if (!await inputsCurrent())
1006
+ return dirty = !0, !1;
1007
+ if (recordGeneratedOutput = await prepareGeneratedOutputUpdate({
1008
+ sourceRoot: lifetime.sourceRoot,
1009
+ outputDir: lifetime.outputDir,
1010
+ scope,
1011
+ incoming,
1012
+ stagingDir: temporary
1013
+ }), dependenciesChanged || configurationChanged) {
1014
+ let serving = !!next;
1015
+ serving && options.onEvent?.({
1016
+ type: "restart",
1017
+ target: "next",
1018
+ reason: dependenciesChanged ? "App dependencies changed." : "Next startup configuration changed."
1019
+ }), await restartPreview({
1020
+ incoming,
1021
+ outputDir: lifetime.outputDir,
1022
+ dependencies: !!dependenciesChanged,
1023
+ signal: lifetime.signal,
1024
+ stop: stopNext,
1025
+ start: async () => {
1026
+ await search(lifetime.outputDir), serving && await startNext(!0);
1027
+ }
1028
+ });
1029
+ } else
1030
+ await refreshPreview({
1031
+ incoming,
1032
+ outputDir: lifetime.outputDir,
1033
+ signal: lifetime.signal
1034
+ }), await search(lifetime.outputDir);
1035
+ return frameworkIdentity = nextFrameworkIdentity, await recordGeneratedOutput?.(), recordGeneratedOutput = void 0, revisionBefore && await inputsCurrent() && await recordPreviewCache({
1036
+ outputDir: lifetime.outputDir,
1037
+ revision: revisionBefore,
1038
+ runtime: selection.runtime ?? "",
1039
+ frameworkIdentity,
1040
+ compilerRevision: compilerRevisionBefore,
1041
+ checkoutDependencyRevision: dependencyRevisionBefore,
1042
+ inputKind,
1043
+ url,
1044
+ sourcePath: options.request.context?.sourcePath ?? "publish.os"
1045
+ }), !0;
1046
+ } catch (error) {
1047
+ if (error instanceof AppError && (error.code === "FRAMEWORK_PROCESS_SHUTDOWN_FAILED" || error.code === "FRAMEWORK_PREVIEW_RECOVERY_FAILED") && (retain = !0), !retain && !lifetime.signal.aborted && !await inputsCurrent())
1048
+ return dirty = !0, !1;
1049
+ throw primaryFailure = { error }, error;
1050
+ } finally {
1051
+ retain || await cleanup();
1052
+ }
1053
+ };
1054
+ function drain() {
1055
+ refreshing || stopped || !ready || lifetime.signal.aborted || (refreshing = (async () => {
1056
+ for (; dirty && !stopped; ) {
1057
+ dirty = !1;
1058
+ let changes = await sourceWatch.takeChanges(), compilerChanges = await checkoutWatch?.takeChanges() ?? [];
1059
+ changes.length && options.onEvent?.({ type: "changes", changes });
1060
+ try {
1061
+ await refresh(compilerChanges) && options.onEvent?.({ type: "updated" });
1062
+ } catch (error) {
1063
+ if (lifetime.signal.aborted) return;
1064
+ if (error instanceof AppError && (error.code === "FRAMEWORK_PREVIEW_RESTART_REQUIRED" || error.code === "FRAMEWORK_PROCESS_SHUTDOWN_FAILED" || error.code === "FRAMEWORK_PREVIEW_RECOVERY_FAILED" || error.code.startsWith("FRAMEWORK_LOCAL_OUTPUT_"))) {
1065
+ rejectSession(error);
1066
+ return;
1067
+ }
1068
+ if (error instanceof AppError && error.code === "FRAMEWORK_SOURCE_INVALID")
1069
+ continue;
1070
+ options.onEvent?.({
1071
+ type: "diagnostics",
1072
+ diagnostics: {
1073
+ diagnostics: [
1074
+ {
1075
+ severity: "error",
1076
+ code: "FRAMEWORK_PREVIEW_REFRESH_FAILED",
1077
+ message: `Preview artifact refresh failed: ${error instanceof Error ? error.message : String(error)}`,
1078
+ correction: error instanceof AppError && error.fix ? error.fix : "Correct the source error and save again. The previous preview remains available."
1079
+ }
1080
+ ]
1081
+ }
1082
+ });
1083
+ }
1084
+ }
1085
+ })().finally(() => {
1086
+ refreshing = void 0, dirty && drain();
1087
+ }));
1088
+ }
1089
+ return reuse && !reuse.current && await refresh([]), await startNext(), await Promise.race([ended, failed]), { type: "result", status: "success" };
1090
+ }
1091
+ });
1092
+ }
1093
+ export {
1094
+ runDevelopment
1095
+ };