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