void 0.7.5 → 0.7.7

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 (66) hide show
  1. package/dist/{auth-DrfOTMmr.d.mts → auth-DmuALf16.d.mts} +4 -4
  2. package/dist/{better-auth-shared-CZsIpjey.d.mts → better-auth-shared-HXlHRw02.d.mts} +15 -15
  3. package/dist/cli/cli.mjs +14 -14
  4. package/dist/{config-BIa9HwVX.mjs → config-DqkeX_Fa.mjs} +5 -5
  5. package/dist/{db-RqxhOT2E.mjs → db-BnKZW1J7.mjs} +26 -22
  6. package/dist/{deploy-CRIz77mw.mjs → deploy-D3t53kng.mjs} +46 -16
  7. package/dist/{domain-CDQhvYNZ.mjs → domain-ClDdX9I1.mjs} +24 -1
  8. package/dist/{dotenv-DwO4ti0Z.mjs → dotenv-zdFCCgFU.mjs} +26 -26
  9. package/dist/{env-CnrQY2b6.mjs → env-CU97_4YK.mjs} +1 -1
  10. package/dist/{env-helpers-CbeM_7-k.d.mts → env-helpers-Dw95CU8e.d.mts} +4 -4
  11. package/dist/{env-validation-DJKjR_8q.mjs → env-validation-Bc_aiBUm.mjs} +1 -1
  12. package/dist/{fetch-error-DflegrF3.d.mts → fetch-error-DZ868Xq4.d.mts} +4 -4
  13. package/dist/{gen-C0EY2k27.mjs → gen-CpeKIqlM.mjs} +2 -2
  14. package/dist/{handler-dKQWyF-G.d.mts → handler-DJTuxB10.d.mts} +24 -27
  15. package/dist/{head-CZGAunBV.d.mts → head-C7QW7UY1.d.mts} +5 -6
  16. package/dist/{headers-YVkHjOyq.mjs → headers-C7Yf6_CN.mjs} +1 -1
  17. package/dist/index.d.mts +3 -3
  18. package/dist/index.mjs +501 -63
  19. package/dist/{init-FMZ29UZW.mjs → init-CTtDfVVo.mjs} +4 -4
  20. package/dist/{node-DFqMcZR1.mjs → node-DHVCtkgt.mjs} +1 -1
  21. package/dist/pages/client.d.mts +35 -41
  22. package/dist/pages/head-client.d.mts +1 -1
  23. package/dist/pages/head.d.mts +1 -1
  24. package/dist/pages/head.mjs +4 -4
  25. package/dist/pages/index.d.mts +6 -6
  26. package/dist/pages/index.mjs +6 -6
  27. package/dist/pages/islands-plugin.d.mts +4 -13
  28. package/dist/pages/islands-plugin.mjs +2 -64
  29. package/dist/pages/prefetch.d.mts +5 -5
  30. package/dist/pages/protocol.d.mts +2 -2
  31. package/dist/pages/protocol.mjs +98 -14
  32. package/dist/plugin-inference-CXUuq0aC.mjs +577 -0
  33. package/dist/{prepare-PqAbhLte.mjs → prepare-CKzO06-Z.mjs} +4 -4
  34. package/dist/{preset-jKn1hQwP.mjs → preset-BhnZpb7t.mjs} +1 -1
  35. package/dist/{protocol-DxGzKEz2.d.mts → protocol-D7r_deVZ.d.mts} +7 -4
  36. package/dist/{route-types-DReF1gUY.mjs → route-types-Cnqj_8a7.mjs} +2 -2
  37. package/dist/runtime/ai.d.mts +33 -40
  38. package/dist/runtime/auth.d.mts +1 -1
  39. package/dist/runtime/better-auth-pg.d.mts +1 -1
  40. package/dist/runtime/better-auth.d.mts +1 -1
  41. package/dist/runtime/client.d.mts +2 -2
  42. package/dist/runtime/env-helpers.d.mts +1 -1
  43. package/dist/runtime/env-helpers.mjs +3 -3
  44. package/dist/runtime/env-public-client.d.mts +3 -3
  45. package/dist/runtime/env-public.d.mts +7 -7
  46. package/dist/runtime/fetch-stream.d.mts +1 -1
  47. package/dist/runtime/fetch.d.mts +1 -1
  48. package/dist/runtime/handler.d.mts +1 -1
  49. package/dist/runtime/handler.mjs +3 -3
  50. package/dist/runtime/isr.d.mts +2 -2
  51. package/dist/runtime/kv.d.mts +12 -12
  52. package/dist/runtime/live-server.d.mts +4 -4
  53. package/dist/runtime/live.d.mts +2 -2
  54. package/dist/runtime/migration-handler.d.mts +6 -6
  55. package/dist/runtime/seed.d.mts +4 -4
  56. package/dist/runtime/validator.d.mts +1 -1
  57. package/dist/runtime/ws-server.d.mts +8 -8
  58. package/dist/runtime/ws.d.mts +21 -21
  59. package/dist/{scan-QtRTdh94.mjs → scan-B8iEm8xn.mjs} +6 -6
  60. package/dist/{scan-Ba4hFwlH.mjs → scan-CWfLxtOe.mjs} +8 -8
  61. package/dist/{standard-schema-BfGDWXff.d.mts → standard-schema-D2qvCEYV.d.mts} +14 -14
  62. package/dist/sveltekit.d.mts +3 -5
  63. package/dist/types-DG_Ynnyd.d.mts +42 -0
  64. package/package.json +3 -3
  65. package/dist/plugin-inference-CCtRkt9O.mjs +0 -2476
  66. package/dist/types-AdKzPp2C.d.mts +0 -57
package/dist/index.mjs CHANGED
@@ -4,20 +4,20 @@ import { u as require_picocolors } from "./output-BwlcIYSR.mjs";
4
4
  import { n as loadVoidAuthConfig, t as findVoidAuthConfig } from "./config-CvHtTM0q.mjs";
5
5
  import { r as readProjectConfig } from "./project-TqORyHn8.mjs";
6
6
  import { c as getToken, u as isStagingMode } from "./client-DCqnMpDt.mjs";
7
- import { C as resolveSandboxConfig, S as isSandboxEnabled, _ as readExistingLiveBindingConfig, a as prerenderPagesNode, b as syncWranglerBindings, c as filterLoadedEnv, d as LIVE_MIGRATION_TAG, f as ensureWranglerCompatibilityDate, g as normalizeWranglerCompatibilityFlags, h as nextDurableObjectMigrationTag, i as prerenderPages, l as resolveRemoteMode, m as hasDurableObjectSqliteMigration, n as resolveDistDir, o as DEFAULT_PROXY_URL, p as ensureWranglerNodejsAlsFlag, r as resolveWorkerDirName, s as STAGING_PROXY_URL, u as stripInternalEnvKeys, v as readWranglerCompat, x as SANDBOX_MIGRATION_TAG, y as resolveLiveBindingConfig } from "./deploy-CRIz77mw.mjs";
8
- import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-BIa9HwVX.mjs";
9
- import { i as scanJobsSync, n as scanWebSocketRoutesSync, r as scanQueuesSync, t as scanRoutes } from "./scan-QtRTdh94.mjs";
10
- import { a as SSR_CLIENT_ENTRY_RELATIVE_PATHS, c as validateSsrEntries, f as isIdentifier, g as walk, i as inferProjectBindings, l as validateSsrEntry, m as isMemberExpression, n as FRAMEWORK_SCAN_DIRS, o as SSR_SERVER_ENTRY_RELATIVE_PATHS, p as isLiteral, r as detectFramework, t as DEFAULT_SCAN_DIRS, u as inferBindingsFromSource } from "./plugin-inference-CCtRkt9O.mjs";
7
+ import { C as isSandboxEnabled, S as SANDBOX_MIGRATION_TAG, _ as normalizeWranglerCompatibilityFlags, a as prerenderPagesNode, b as resolveLiveBindingConfig, c as filterLoadedEnv, d as LIVE_MIGRATION_TAG, f as ensureWranglerCompat, g as nextDurableObjectMigrationTag, h as hasDurableObjectSqliteMigration, i as prerenderPages, l as resolveRemoteMode, m as ensureWranglerNodejsAlsFlag, n as resolveDistDir, o as DEFAULT_PROXY_URL, p as ensureWranglerCompatibilityDate, r as resolveWorkerDirName, s as STAGING_PROXY_URL, u as stripInternalEnvKeys, v as readExistingLiveBindingConfig, w as resolveSandboxConfig, x as syncWranglerBindings, y as readWranglerCompat } from "./deploy-D3t53kng.mjs";
8
+ import { c as getDatabaseDialect, f as readConfig, l as isNodeTarget, p as resolveBindingNames } from "./config-DqkeX_Fa.mjs";
9
+ import { i as scanJobsSync, n as scanWebSocketRoutesSync, r as scanQueuesSync, t as scanRoutes } from "./scan-B8iEm8xn.mjs";
10
+ import { a as SSR_CLIENT_ENTRY_RELATIVE_PATHS, c as validateSsrEntries, f as isIdentifier, g as walk, i as inferProjectBindings, l as validateSsrEntry, m as isMemberExpression, n as FRAMEWORK_SCAN_DIRS, o as SSR_SERVER_ENTRY_RELATIVE_PATHS, p as isLiteral, r as detectFramework, t as DEFAULT_SCAN_DIRS, u as inferBindingsFromSource } from "./plugin-inference-CXUuq0aC.mjs";
11
11
  import { i as voidWarn, n as voidError, r as voidLog, t as setShowTimestamp } from "./log-DXdqnmhF.mjs";
12
- import { r as parseDotenvFile } from "./dotenv-DwO4ti0Z.mjs";
13
- import { i as generateDbDts, n as generateQueueTypes, r as DRIZZLE_OPERATORS, t as generateRouteTypes } from "./route-types-DReF1gUY.mjs";
12
+ import { r as parseDotenvFile } from "./dotenv-zdFCCgFU.mjs";
13
+ import { i as generateDbDts, n as generateQueueTypes, r as DRIZZLE_OPERATORS, t as generateRouteTypes } from "./route-types-Cnqj_8a7.mjs";
14
14
  import { n as ensureProjectTsconfig } from "./project-tsconfig-DfkESbDL.mjs";
15
15
  import { t as discoverSchema } from "./discover-B7FkXBLB.mjs";
16
16
  import { t as MagicString } from "./magic-string.es-D6g9UnIy.mjs";
17
17
  import { n as generateEnvTypes, t as findEnvFile } from "./env-types-DknSA4SO.mjs";
18
- import { a as loadUserEnvFile } from "./env-validation-DJKjR_8q.mjs";
19
- import { i as resolveLayoutIds } from "./scan-Ba4hFwlH.mjs";
20
- import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-YVkHjOyq.mjs";
18
+ import { a as loadUserEnvFile } from "./env-validation-Bc_aiBUm.mjs";
19
+ import { i as resolveLayoutIds } from "./scan-CWfLxtOe.mjs";
20
+ import { n as lintDuplicateSources, r as mergeRoutingRules, t as lintDestinationSplats } from "./headers-C7Yf6_CN.mjs";
21
21
  import { n as generateVoidAuthDrizzleSchema, t as generateVoidAuthDatabaseModule } from "./drizzle-C-NRqGhx.mjs";
22
22
  import { t as INTERNAL_BINDING_PREFIXES } from "./env-raw-DtfQ9E31.mjs";
23
23
  import { n as defer } from "./defer-2ARBu8Et.mjs";
@@ -27,8 +27,374 @@ import { fileURLToPath, pathToFileURL } from "node:url";
27
27
  import { cloudflare } from "@cloudflare/vite-plugin";
28
28
  import { loadEnv, normalizePath, parseSync } from "vite";
29
29
  import { homedir } from "node:os";
30
- //#region src/plugin-dev-triggers-hint.ts
30
+ import { init, parse } from "es-module-lexer";
31
+ //#region src/pages/dev-css-assets.ts
31
32
  var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
33
+ const DEV_CSS_ASSET_MODULE_ID = "virtual:void-pages-dev-assets";
34
+ const DEV_CSS_ASSET_ENDPOINT = "/__void/dev/pages-css";
35
+ const DEV_CSS_ASSET_GUARD_HEADER = "X-Void-Dev-Asset-Request";
36
+ const DEV_CSS_ASSET_GUARD_VALUE = "pages-css";
37
+ const CSS_REQUEST_RE = /\.(?:css|scss|sass|less|styl|stylus|pcss|postcss)(?:$|[?#])/;
38
+ const STYLE_QUERY_RE = /[?&](?:vue|svelte|island-style)\b.*[?&]type=style\b|[?&]type=style\b/;
39
+ const CSS_BYPASS_RE = /[?&](?:raw|url|worker|sharedworker)\b/;
40
+ const INLINE_CSS_EXPORT_RE = /(?:export\s+default|__vite__css\s*=)\s*("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`(?:[^`\\]|\\.)*`)/;
41
+ const VITE_DEV_ID_RE = /const\s+__vite__id\s*=\s*("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/;
42
+ const SKIPPABLE_VIRTUAL_URL_RE = /^(?:\/@id\/__x00__)?virtual:void-client-(?:browser|worker)(?:$|[?#])/;
43
+ function splitQueryHash(value) {
44
+ const index = value.search(/[?#]/);
45
+ if (index === -1) return {
46
+ pathname: value,
47
+ suffix: ""
48
+ };
49
+ return {
50
+ pathname: value.slice(0, index),
51
+ suffix: value.slice(index)
52
+ };
53
+ }
54
+ function normalizeDevCssUrl(id, root) {
55
+ const normalized = normalizePath(id);
56
+ if (normalized.startsWith("/@id/")) return normalized;
57
+ if (normalized.startsWith("\0")) return "/@id/__x00__" + normalized.slice(1);
58
+ if (normalized.startsWith("virtual:")) return "/@id/__x00__" + normalized;
59
+ const { pathname, suffix } = splitQueryHash(normalized);
60
+ const normalizedRoot = normalizePath(root);
61
+ if (pathname === normalizedRoot || pathname.startsWith(normalizedRoot + "/")) return "/" + normalizePath(pathname.slice(normalizedRoot.length + 1)) + suffix;
62
+ if (pathname.startsWith("/@fs/") || pathname.startsWith("/@vite/") || pathname === "/@vite/client" || pathname.startsWith("/@react-refresh") || pathname.startsWith("/node_modules/.vite/")) return normalized;
63
+ if (pathname.startsWith("/")) {
64
+ const rootFirstSegment = normalizedRoot.split("/").filter(Boolean)[0];
65
+ if (rootFirstSegment && !pathname.startsWith(`/${rootFirstSegment}/`)) return normalized;
66
+ return "/@fs" + pathname + suffix;
67
+ }
68
+ return normalized;
69
+ }
70
+ function normalizeRequestUrl(url) {
71
+ return normalizePath(url).replace(/^\/@id\/__x00__/, "\0");
72
+ }
73
+ function toTransformRequestUrl(url) {
74
+ return normalizeRequestUrl(url);
75
+ }
76
+ function isCssRequest(url) {
77
+ return !CSS_BYPASS_RE.test(url) && (CSS_REQUEST_RE.test(url) || STYLE_QUERY_RE.test(url));
78
+ }
79
+ function isOptimizedDepUrl(url) {
80
+ return normalizePath(url).startsWith("/node_modules/.vite/deps/");
81
+ }
82
+ function isSkippableVirtualUrl(url) {
83
+ const normalized = normalizePath(url);
84
+ return SKIPPABLE_VIRTUAL_URL_RE.test(normalized) || normalized.charCodeAt(0) === 0 && /^virtual:void-client-(?:browser|worker)(?:$|[?#])/.test(normalized.slice(1));
85
+ }
86
+ function appendInlineQuery(url) {
87
+ const parsed = new URL(url, "http://void.local");
88
+ if (!parsed.searchParams.has("inline")) parsed.searchParams.append("inline", "");
89
+ return parsed.pathname + parsed.search + parsed.hash;
90
+ }
91
+ function extractInlineCss(code) {
92
+ const match = code.match(INLINE_CSS_EXPORT_RE);
93
+ if (!match) throw new Error("Unable to extract inline CSS from Vite transform output.");
94
+ const raw = match[1];
95
+ if (raw.startsWith("`")) throw new Error("Unexpected template literal inline CSS output.");
96
+ return JSON.parse(raw);
97
+ }
98
+ function extractViteDevId(code) {
99
+ const match = code.match(VITE_DEV_ID_RE);
100
+ if (!match) return;
101
+ return JSON.parse(match[1]);
102
+ }
103
+ function createOrderedEdgeStore(root) {
104
+ let version = 0;
105
+ const byKey = /* @__PURE__ */ new Map();
106
+ const aliasesForId = (id) => {
107
+ const normalized = normalizePath(id);
108
+ const aliases = new Set([normalized, normalizeDevCssUrl(normalized, root)]);
109
+ if (normalized.startsWith("/@id/__x00__")) aliases.add(normalized.replace("/@id/__x00__", "\0"));
110
+ return [...aliases];
111
+ };
112
+ return {
113
+ get version() {
114
+ return version;
115
+ },
116
+ set(importer, edges) {
117
+ version++;
118
+ for (const key of aliasesForId(importer)) byKey.set(key, edges);
119
+ },
120
+ deleteForId(id) {
121
+ let deleted = false;
122
+ for (const key of aliasesForId(id)) deleted = byKey.delete(key) || deleted;
123
+ if (deleted) version++;
124
+ },
125
+ getForNode(node) {
126
+ const keys = [node.url, node.id].filter((value) => typeof value === "string");
127
+ for (const key of keys) {
128
+ const direct = byKey.get(normalizePath(key));
129
+ if (direct) return direct;
130
+ const url = normalizeDevCssUrl(key, root);
131
+ const byUrl = byKey.get(url) ?? byKey.get(normalizeRequestUrl(url));
132
+ if (byUrl) return byUrl;
133
+ }
134
+ const staticUrls = node.staticImportedUrls;
135
+ return staticUrls ? [...staticUrls] : void 0;
136
+ }
137
+ };
138
+ }
139
+ var DevCssProvider = class {
140
+ cache = /* @__PURE__ */ new Map();
141
+ graphVersion = 0;
142
+ constructor(server, root, edgeStore) {
143
+ this.server = server;
144
+ this.root = root;
145
+ this.edgeStore = edgeStore;
146
+ }
147
+ invalidate() {
148
+ this.graphVersion++;
149
+ this.cache.clear();
150
+ }
151
+ async collect(rootPhases) {
152
+ const normalizedPhases = rootPhases.map((phase) => phase.map((root) => normalizeDevCssUrl(root, this.root)));
153
+ const cacheKey = JSON.stringify({
154
+ roots: normalizedPhases,
155
+ graphVersion: this.graphVersion,
156
+ edgeVersion: this.edgeStore.version
157
+ });
158
+ const cached = this.cache.get(cacheKey);
159
+ if (cached) return cached;
160
+ const environment = this.server.environments.client;
161
+ const graph = environment.moduleGraph;
162
+ const seen = /* @__PURE__ */ new Set();
163
+ const seenCssUrls = /* @__PURE__ */ new Set();
164
+ const cssUrls = [];
165
+ const cssViteDevIds = /* @__PURE__ */ new Map();
166
+ const addByUrl = async (rawUrl) => {
167
+ const url = normalizeDevCssUrl(rawUrl, this.root);
168
+ if (isOptimizedDepUrl(url)) return;
169
+ const requestUrl = toTransformRequestUrl(url);
170
+ let result;
171
+ try {
172
+ result = await environment.transformRequest(requestUrl);
173
+ } catch (error) {
174
+ if (!isSkippableVirtualUrl(url)) this.server.config.logger.warnOnce(`[void] Skipping dev CSS traversal for ${url}: ${error instanceof Error ? error.message : String(error)}`);
175
+ return;
176
+ }
177
+ const node = await graph.getModuleByUrl(url) ?? (requestUrl !== url ? await graph.getModuleByUrl(requestUrl) : void 0);
178
+ if (node) await visit(node, result?.code);
179
+ };
180
+ const visit = async (node, transformedCode) => {
181
+ if (seen.has(node)) return;
182
+ seen.add(node);
183
+ if (isCssRequest(node.url)) {
184
+ if (!seenCssUrls.has(node.url)) {
185
+ seenCssUrls.add(node.url);
186
+ cssUrls.push(node.url);
187
+ }
188
+ const viteDevId = transformedCode ? extractViteDevId(transformedCode) : void 0;
189
+ cssViteDevIds.set(node.url, viteDevId ?? node.id ?? node.url);
190
+ return;
191
+ }
192
+ if (isOptimizedDepUrl(node.url)) return;
193
+ const staticUrls = this.edgeStore.getForNode(node);
194
+ if (!staticUrls) {
195
+ this.server.config.logger.warnOnce(`[void] Missing ordered static import metadata for ${node.url}; skipping broad dev CSS traversal.`);
196
+ return;
197
+ }
198
+ for (const dep of staticUrls) await addByUrl(dep);
199
+ };
200
+ for (const roots of normalizedPhases) for (const root of roots) await addByUrl(root);
201
+ const assets = [];
202
+ for (const url of cssUrls) {
203
+ const inlineUrl = appendInlineQuery(url);
204
+ const result = await environment.transformRequest(inlineUrl);
205
+ if (!result) continue;
206
+ assets.push({
207
+ url,
208
+ id: cssViteDevIds.get(url) ?? url,
209
+ css: extractInlineCss(result.code)
210
+ });
211
+ }
212
+ this.cache.set(cacheKey, assets);
213
+ if (this.cache.size > 100) {
214
+ const oldest = this.cache.keys().next().value;
215
+ if (oldest) this.cache.delete(oldest);
216
+ }
217
+ return assets;
218
+ }
219
+ };
220
+ async function readJsonBody(req) {
221
+ const chunks = [];
222
+ for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
223
+ if (chunks.length === 0) return {};
224
+ return JSON.parse(Buffer.concat(chunks).toString("utf-8"));
225
+ }
226
+ function getInternalDevOrigin(server) {
227
+ const address = server.httpServer?.address();
228
+ if (address && typeof address === "object") {
229
+ const protocol = server.config.server.https ? "https" : "http";
230
+ const rawHost = address.address === "::" || address.address === "0.0.0.0" ? "127.0.0.1" : address.address;
231
+ return `${protocol}://${rawHost.includes(":") ? `[${rawHost}]` : rawHost}:${address.port}`;
232
+ }
233
+ const localUrl = server.resolvedUrls?.local[0];
234
+ if (localUrl) return new URL(localUrl).origin;
235
+ return `${server.config.server.https ? "https" : "http"}://127.0.0.1:${server.config.server.port ?? 5173}`;
236
+ }
237
+ function pagesDevCssAssetsPlugin(root, token) {
238
+ const edgeStore = createOrderedEdgeStore(root);
239
+ let provider = null;
240
+ let viteServer = null;
241
+ return [{
242
+ name: "void:pages-dev-css-assets",
243
+ apply: "serve",
244
+ resolveId(id) {
245
+ if (id !== "virtual:void-pages-dev-assets") return;
246
+ if (this.environment?.name === "client") throw new Error(`${DEV_CSS_ASSET_MODULE_ID} is server-only and cannot be imported by client code.`);
247
+ return "\0" + DEV_CSS_ASSET_MODULE_ID;
248
+ },
249
+ load(id) {
250
+ if (id !== "\0virtual:void-pages-dev-assets") return;
251
+ if (this.environment?.name === "client") throw new Error(`${DEV_CSS_ASSET_MODULE_ID} is server-only and cannot be loaded by client code.`);
252
+ const internalOrigin = viteServer ? getInternalDevOrigin(viteServer) : "http://127.0.0.1:5173";
253
+ return `
254
+ const TOKEN = ${JSON.stringify(token)};
255
+ const INTERNAL_ORIGIN = ${JSON.stringify(internalOrigin)};
256
+ const ENDPOINT = ${JSON.stringify(DEV_CSS_ASSET_ENDPOINT)};
257
+ const GUARD_HEADER = ${JSON.stringify(DEV_CSS_ASSET_GUARD_HEADER)};
258
+ const GUARD_VALUE = ${JSON.stringify(DEV_CSS_ASSET_GUARD_VALUE)};
259
+
260
+ function createDevCssRequest(url, payload, signal) {
261
+ return new Request(url, {
262
+ method: "POST",
263
+ headers: {
264
+ "Authorization": "Bearer " + TOKEN,
265
+ "Content-Type": "application/json",
266
+ [GUARD_HEADER]: GUARD_VALUE,
267
+ },
268
+ body: JSON.stringify(payload),
269
+ signal,
270
+ });
271
+ }
272
+
273
+ async function readDevCssResponse(response) {
274
+ if (!response.ok) {
275
+ throw new Error("HTTP " + response.status);
276
+ }
277
+ const body = await response.json();
278
+ return Array.isArray(body.assets) ? body.assets : [];
279
+ }
280
+
281
+ export async function getVoidPagesDevCss(request, env, payload) {
282
+ const controller = new AbortController();
283
+ const timeout = setTimeout(() => controller.abort(), 1500);
284
+ const attempts = [];
285
+ if (env?.ASSETS && typeof env.ASSETS.fetch === "function") {
286
+ attempts.push({
287
+ fetcher: env.ASSETS,
288
+ label: "ASSETS",
289
+ url: new URL(ENDPOINT, request.url).toString(),
290
+ });
291
+ } else {
292
+ attempts.push({
293
+ fetcher: "global",
294
+ label: INTERNAL_ORIGIN,
295
+ url: new URL(ENDPOINT, INTERNAL_ORIGIN).toString(),
296
+ });
297
+ }
298
+ try {
299
+ let lastError;
300
+ let lastLabel = "unknown";
301
+ for (const attempt of attempts) {
302
+ try {
303
+ const request = createDevCssRequest(attempt.url, payload, controller.signal);
304
+ const response =
305
+ attempt.fetcher === "global"
306
+ ? await fetch(request)
307
+ : await attempt.fetcher.fetch(request);
308
+ return await readDevCssResponse(response);
309
+ } catch (error) {
310
+ lastError = error;
311
+ lastLabel = attempt.label;
312
+ }
313
+ }
314
+ throw new Error(
315
+ lastLabel + ": " + (lastError instanceof Error ? lastError.message : String(lastError)),
316
+ );
317
+ } catch (error) {
318
+ console.warn("[void] dev CSS collection failed:", error instanceof Error ? error.message : String(error));
319
+ return [];
320
+ } finally {
321
+ clearTimeout(timeout);
322
+ }
323
+ }
324
+ `;
325
+ },
326
+ configureServer(server) {
327
+ viteServer = server;
328
+ provider = new DevCssProvider(server, root, edgeStore);
329
+ const invalidate = () => provider?.invalidate();
330
+ server.watcher.on("add", invalidate);
331
+ server.watcher.on("change", invalidate);
332
+ server.watcher.on("unlink", invalidate);
333
+ server.middlewares.use(async (req, res, next) => {
334
+ if (!req.url) return next();
335
+ const url = new URL(req.url, "http://void.local");
336
+ if (url.pathname === "/@id/virtual:void-pages-dev-assets" || url.pathname === "/@id/__x00__virtual:void-pages-dev-assets") {
337
+ res.statusCode = 404;
338
+ res.end("Not Found");
339
+ return;
340
+ }
341
+ if (url.pathname !== "/__void/dev/pages-css") return next();
342
+ if (req.method !== "POST") {
343
+ res.statusCode = 405;
344
+ res.end("Method Not Allowed");
345
+ return;
346
+ }
347
+ if (req.headers["X-Void-Dev-Asset-Request".toLowerCase()] !== "pages-css") {
348
+ res.statusCode = 403;
349
+ res.end("Forbidden");
350
+ return;
351
+ }
352
+ if (req.headers.authorization !== `Bearer ${token}`) {
353
+ res.statusCode = 401;
354
+ res.end("Unauthorized");
355
+ return;
356
+ }
357
+ try {
358
+ const body = await readJsonBody(req);
359
+ const rootPhases = Array.isArray(body.rootPhases) ? body.rootPhases : [];
360
+ const assets = await provider.collect(rootPhases);
361
+ res.statusCode = 200;
362
+ res.setHeader("Content-Type", "application/json");
363
+ res.end(JSON.stringify({ assets }));
364
+ } catch (error) {
365
+ server.config.logger.warn(`[void] dev CSS collection failed: ${error instanceof Error ? error.message : String(error)}`);
366
+ res.statusCode = 200;
367
+ res.setHeader("Content-Type", "application/json");
368
+ res.end(JSON.stringify({ assets: [] }));
369
+ }
370
+ });
371
+ }
372
+ }, {
373
+ name: "void:pages-dev-css-static-edges",
374
+ apply: "serve",
375
+ enforce: "post",
376
+ async transform(code, id) {
377
+ if (this.environment?.name !== "client") return;
378
+ if (id.includes("/node_modules/.vite/")) return;
379
+ await init;
380
+ let imports;
381
+ try {
382
+ [imports] = parse(code);
383
+ } catch {
384
+ return;
385
+ }
386
+ const edges = [];
387
+ for (const item of imports) {
388
+ if (item.d !== -1 || !item.n) continue;
389
+ const resolved = await this.resolve(item.n, id, { skipSelf: true });
390
+ if (resolved?.id) edges.push(normalizeDevCssUrl(resolved.id, root));
391
+ }
392
+ edgeStore.set(id, edges);
393
+ }
394
+ }];
395
+ }
396
+ //#endregion
397
+ //#region src/plugin-dev-triggers-hint.ts
32
398
  /**
33
399
  * Prints a one-shot hint on dev server start when the project has crons
34
400
  * or queues, explaining how to trigger them locally. Both default Void mode
@@ -428,17 +794,17 @@ function buildOffsetIndex(code) {
428
794
  return { lineStarts };
429
795
  }
430
796
  function offsetToLineCol(index, offset) {
431
- const arr = index.lineStarts;
432
- let lo = 0;
433
- let hi = arr.length - 1;
434
- while (lo < hi) {
435
- const mid = lo + hi + 1 >>> 1;
436
- if (arr[mid] <= offset) lo = mid;
437
- else hi = mid - 1;
797
+ const lineStarts = index.lineStarts;
798
+ let lowerBound = 0;
799
+ let upperBound = lineStarts.length - 1;
800
+ while (lowerBound < upperBound) {
801
+ const midpoint = lowerBound + upperBound + 1 >>> 1;
802
+ if (lineStarts[midpoint] <= offset) lowerBound = midpoint;
803
+ else upperBound = midpoint - 1;
438
804
  }
439
805
  return {
440
- line: lo + 1,
441
- column: offset - arr[lo] + 1
806
+ line: lowerBound + 1,
807
+ column: offset - lineStarts[lowerBound] + 1
442
808
  };
443
809
  }
444
810
  /**
@@ -731,10 +1097,10 @@ function frameworkTriggersPlugin(root, options) {
731
1097
  };
732
1098
  }
733
1099
  function generateModule(root, jobs, queues, devTriggerToken) {
734
- const jobImports = jobs.map((j, i) => `import __job${i} from ${JSON.stringify(join(root, "crons", j.filePath))};`).join("\n");
735
- const queueImports = queues.map((q, i) => `import __queue${i} from ${JSON.stringify(join(root, "queues", q.filePath))};`).join("\n");
736
- const jobTable = jobs.map((j, i) => ` { crons: ${JSON.stringify(j.crons)}, handler: __job${i} }`).join(",\n");
737
- const queueTable = queues.map((q, i) => ` { name: ${JSON.stringify(q.name)}, handler: __queue${i} }`).join(",\n");
1100
+ const jobImports = jobs.map((job, jobIndex) => `import __job${jobIndex} from ${JSON.stringify(join(root, "crons", job.filePath))};`).join("\n");
1101
+ const queueImports = queues.map((queue, queueIndex) => `import __queue${queueIndex} from ${JSON.stringify(join(root, "queues", queue.filePath))};`).join("\n");
1102
+ const jobTable = jobs.map((job, jobIndex) => ` { crons: ${JSON.stringify(job.crons)}, handler: __job${jobIndex} }`).join(",\n");
1103
+ const queueTable = queues.map((queue, queueIndex) => ` { name: ${JSON.stringify(queue.name)}, handler: __queue${queueIndex} }`).join(",\n");
738
1104
  return `// @ts-nocheck — Auto-generated by Void in dev. Do NOT edit. Regenerated on every config load.
739
1105
  ${jobImports}
740
1106
  ${queueImports}
@@ -991,11 +1357,11 @@ export default defineEventHandler(async (event) => {
991
1357
  */
992
1358
  function analogDevTriggerInjectPlugin(root) {
993
1359
  const routeDir = join(root, ANALOG_ROUTE_DIR_RELATIVE);
994
- const routePaths = ANALOG_TRIGGERS.map((t) => ({
995
- ...t,
996
- path: join(routeDir, `${t.file}.ts`)
1360
+ const routePaths = ANALOG_TRIGGERS.map((trigger) => ({
1361
+ ...trigger,
1362
+ path: join(routeDir, `${trigger.file}.ts`)
997
1363
  }));
998
- const gitignoreLines = ANALOG_TRIGGERS.map((t) => `${ANALOG_ROUTE_DIR_RELATIVE}/${t.file}.ts`);
1364
+ const gitignoreLines = ANALOG_TRIGGERS.map((trigger) => `${ANALOG_ROUTE_DIR_RELATIVE}/${trigger.file}.ts`);
999
1365
  const dispatchPath = frameworkTriggersDispatchPath(root);
1000
1366
  const ensureFiles = () => {
1001
1367
  mkdirSync(routeDir, { recursive: true });
@@ -1026,7 +1392,7 @@ function analogDevTriggerInjectPlugin(root) {
1026
1392
  return;
1027
1393
  }
1028
1394
  const path = req.url ?? "";
1029
- const match = ANALOG_TRIGGERS.find((t) => path === `/__void/${t.user}`);
1395
+ const match = ANALOG_TRIGGERS.find((trigger) => path === `/__void/${trigger.user}`);
1030
1396
  if (!match) {
1031
1397
  next();
1032
1398
  return;
@@ -1036,8 +1402,8 @@ function analogDevTriggerInjectPlugin(root) {
1036
1402
  for await (const chunk of req) chunks.push(chunk);
1037
1403
  const body = Buffer.concat(chunks);
1038
1404
  const headers = new Headers();
1039
- for (const [k, v] of Object.entries(req.headers)) if (typeof v === "string") headers.set(k, v);
1040
- else if (Array.isArray(v)) headers.set(k, v.join(", "));
1405
+ for (const [key, value] of Object.entries(req.headers)) if (typeof value === "string") headers.set(key, value);
1406
+ else if (Array.isArray(value)) headers.set(key, value.join(", "));
1041
1407
  const host = req.headers.host ?? "localhost";
1042
1408
  const upstream = await fetch(`http://${host}/api/__void/${match.file}`, {
1043
1409
  method: "POST",
@@ -1045,7 +1411,7 @@ function analogDevTriggerInjectPlugin(root) {
1045
1411
  body
1046
1412
  });
1047
1413
  res.statusCode = upstream.status;
1048
- upstream.headers.forEach((v, k) => res.setHeader(k, v));
1414
+ upstream.headers.forEach((value, key) => res.setHeader(key, value));
1049
1415
  res.end(Buffer.from(await upstream.arrayBuffer()));
1050
1416
  } catch (err) {
1051
1417
  next(err);
@@ -1202,7 +1568,7 @@ function migrationPlugin(root, dialect, databaseId = "local", persistRoot = join
1202
1568
  if (applied.length > 0) voidLog(`Applied ${applied.length} migration(s): ${applied.join(", ")}`);
1203
1569
  }
1204
1570
  if (auth?.enabled) {
1205
- const { runLocalVoidAuthMigrations } = await import("./node-DFqMcZR1.mjs");
1571
+ const { runLocalVoidAuthMigrations } = await import("./node-DHVCtkgt.mjs");
1206
1572
  await runLocalVoidAuthMigrations(root, dialect, persistRoot, databaseId, auth.configPath);
1207
1573
  voidLog("Applied Better Auth migrations");
1208
1574
  }
@@ -1953,6 +2319,16 @@ function pushDefaultErrorPageHelpers(lines, options) {
1953
2319
  lines.push(` return /<\\/body\\s*>/i.test(html) ? html.replace(/<\\/body\\s*>/i, overlay + "</body>") : html + overlay;`);
1954
2320
  lines.push(`}`);
1955
2321
  lines.push("");
2322
+ lines.push(`function __voidGetErrorAssetCss(error) {`);
2323
+ lines.push(` const tags = error && (typeof error === "object" || typeof error === "function") ? error.__voidPageAssetTags : null;`);
2324
+ lines.push(` return tags && typeof tags.css === "string" ? tags.css : "";`);
2325
+ lines.push(`}`);
2326
+ lines.push("");
2327
+ lines.push(`function __voidInjectErrorAssetCss(html, css) {`);
2328
+ lines.push(` if (!css) return html;`);
2329
+ lines.push(` return /<\\/head\\s*>/i.test(html) ? html.replace(/<\\/head\\s*>/i, css + "</head>") : css + html;`);
2330
+ lines.push(`}`);
2331
+ lines.push("");
1956
2332
  lines.push(`function __voidRenderErrorPage(request, status, title, error) {`);
1957
2333
  lines.push(` const heading = status + ": " + title;`);
1958
2334
  lines.push(` const prefix = status + ": ";`);
@@ -1963,6 +2339,7 @@ function pushDefaultErrorPageHelpers(lines, options) {
1963
2339
  lines.push(` <meta charset="utf-8">`);
1964
2340
  lines.push(` <meta name="viewport" content="width=device-width, initial-scale=1">`);
1965
2341
  lines.push(` <title>\${__voidEscapeHtml(heading)}</title>`);
2342
+ lines.push(` \${__voidGetErrorAssetCss(error)}`);
1966
2343
  lines.push(` <style>`);
1967
2344
  lines.push(` :root {`);
1968
2345
  lines.push(` color-scheme: light dark;`);
@@ -2615,6 +2992,7 @@ function compilePageRoutes(lines, scan, pages, options) {
2615
2992
  lines.push(`import { handlePageGet, handlePageMutation } from ${JSON.stringify(pages.protocolPath)};`);
2616
2993
  lines.push(`import { renderHeadToString, renderHtmlAttrs, renderBodyAttrs } from ${JSON.stringify(pages.headPath)};`);
2617
2994
  lines.push(`import { renderPage } from "virtual:void-pages-renderer";`);
2995
+ if (options.dev) lines.push(`import { getVoidPagesDevCss } from "virtual:void-pages-dev-assets";`);
2618
2996
  const hasIslandPages = scan.pages.pages.some((p) => p.island);
2619
2997
  if (hasIslandPages) lines.push(`import { renderIslandPage } from "virtual:void-islands-renderer";`);
2620
2998
  lines.push("");
@@ -2636,11 +3014,18 @@ function compilePageRoutes(lines, scan, pages, options) {
2636
3014
  lines.push(` return { css: "", preloads, body: bodyTag };`);
2637
3015
  lines.push(`}`);
2638
3016
  lines.push("");
3017
+ if (options.dev) {
3018
+ lines.push(`async function collectVoidDevCss(request, env, kind, componentId, rootPhases) {`);
3019
+ lines.push(` const devCss = await getVoidPagesDevCss(request, env, { kind, componentId, rootPhases });`);
3020
+ lines.push(` return Array.isArray(devCss) ? devCss : [];`);
3021
+ lines.push(`}`);
3022
+ lines.push("");
3023
+ }
2639
3024
  lines.push(`function collectPagesManifestFiles(manifest, entryId) {`);
2640
3025
  lines.push(` const seen = new Set();`);
2641
3026
  lines.push(` const toVisit = [entryId];`);
2642
- lines.push(` while (toVisit.length > 0) {`);
2643
- lines.push(` const currentId = toVisit.pop();`);
3027
+ lines.push(` for (let index = 0; index < toVisit.length; index++) {`);
3028
+ lines.push(` const currentId = toVisit[index];`);
2644
3029
  lines.push(` if (seen.has(currentId)) continue;`);
2645
3030
  lines.push(` seen.add(currentId);`);
2646
3031
  lines.push(` const chunk = manifest[currentId];`);
@@ -2652,56 +3037,58 @@ function compilePageRoutes(lines, scan, pages, options) {
2652
3037
  lines.push("");
2653
3038
  const relPagesDir = pages.pagesDirRelative;
2654
3039
  const pageCssKeys = {};
3040
+ const pageDevRootPhases = {};
3041
+ const projectRoot = options.projectRoot;
3042
+ const toDevRootUrl = (absolutePath) => "/" + absolutePath.replaceAll("\\", "/").slice(projectRoot.replaceAll("\\", "/").length + 1);
3043
+ const virtualDevUrl = (id) => "/@id/__x00__" + id;
2655
3044
  for (const page of scan.pages.pages) {
2656
- const keys = [`${relPagesDir}/${page.componentPath}`];
3045
+ const keys = [];
3046
+ const routeRootPhases = [[virtualDevUrl(page.island ? pages.islandClientEntryId ?? pages.clientEntryId : pages.clientEntryId)]];
3047
+ if (page.island && pages.mdClientEntryId) routeRootPhases[0].push(virtualDevUrl(pages.mdClientEntryId));
2657
3048
  const layoutIds = resolveLayoutIds(page, scan.pages.layouts, scan.pages.namedLayouts);
3049
+ const layoutRoots = [];
2658
3050
  for (const layoutId of layoutIds) {
2659
3051
  const layout = scan.pages.layouts.find((l) => (l.directory ? `${l.directory}/layout` : "layout") === layoutId);
2660
3052
  if (layout) {
2661
3053
  keys.push(`${relPagesDir}/${layout.filePath}`);
3054
+ layoutRoots.push(toDevRootUrl(`${pages.pagesDir}/${layout.filePath}`));
2662
3055
  continue;
2663
3056
  }
2664
3057
  const named = scan.pages.namedLayouts.find((nl) => {
2665
3058
  return (nl.directory ? `${nl.directory}/_layouts/${nl.name}` : `_layouts/${nl.name}`) === layoutId;
2666
3059
  });
2667
- if (named) keys.push(`${relPagesDir}/${named.filePath}`);
3060
+ if (named) {
3061
+ keys.push(`${relPagesDir}/${named.filePath}`);
3062
+ layoutRoots.push(toDevRootUrl(`${pages.pagesDir}/${named.filePath}`));
3063
+ }
2668
3064
  }
3065
+ keys.push(`${relPagesDir}/${page.componentPath}`);
3066
+ routeRootPhases.push(layoutRoots);
3067
+ routeRootPhases.push([toDevRootUrl(`${pages.pagesDir}/${page.componentPath}`)]);
2669
3068
  pageCssKeys[page.componentId] = keys;
3069
+ pageDevRootPhases[page.componentId] = routeRootPhases.filter((phase) => phase.length > 0);
2670
3070
  }
2671
3071
  lines.push(`const PAGE_CSS_KEYS = ${JSON.stringify(pageCssKeys)};`);
3072
+ if (options.dev) lines.push(`const PAGE_DEV_ROOT_PHASES = ${JSON.stringify(pageDevRootPhases)};`);
2672
3073
  lines.push("");
2673
3074
  lines.push(`function collectRouteCss(manifest, entryId, pageKeys) {`);
2674
3075
  lines.push(` const cssFiles = new Set();`);
2675
3076
  lines.push(` const visited = new Set();`);
2676
- lines.push(` const toVisit = [entryId];`);
2677
- lines.push(` while (toVisit.length > 0) {`);
2678
- lines.push(` const id = toVisit.pop();`);
2679
- lines.push(` if (visited.has(id)) continue;`);
3077
+ lines.push(` function visit(id) {`);
3078
+ lines.push(` if (visited.has(id)) return;`);
2680
3079
  lines.push(` visited.add(id);`);
2681
3080
  lines.push(` const chunk = manifest[id];`);
2682
- lines.push(` if (!chunk) continue;`);
3081
+ lines.push(` if (!chunk) return;`);
2683
3082
  lines.push(` if (Array.isArray(chunk.css)) {`);
2684
3083
  lines.push(` for (const f of chunk.css) cssFiles.add(f);`);
2685
3084
  lines.push(` }`);
2686
3085
  lines.push(` if (Array.isArray(chunk.imports)) {`);
2687
- lines.push(` for (const i of chunk.imports) toVisit.push(i);`);
3086
+ lines.push(` for (const i of chunk.imports) visit(i);`);
2688
3087
  lines.push(` }`);
2689
3088
  lines.push(` }`);
3089
+ lines.push(` visit(entryId);`);
2690
3090
  lines.push(` for (const key of pageKeys) {`);
2691
- lines.push(` const stack = [key];`);
2692
- lines.push(` while (stack.length > 0) {`);
2693
- lines.push(` const id = stack.pop();`);
2694
- lines.push(` if (visited.has(id)) continue;`);
2695
- lines.push(` visited.add(id);`);
2696
- lines.push(` const chunk = manifest[id];`);
2697
- lines.push(` if (!chunk) continue;`);
2698
- lines.push(` if (Array.isArray(chunk.css)) {`);
2699
- lines.push(` for (const f of chunk.css) cssFiles.add(f);`);
2700
- lines.push(` }`);
2701
- lines.push(` if (Array.isArray(chunk.imports)) {`);
2702
- lines.push(` for (const i of chunk.imports) stack.push(i);`);
2703
- lines.push(` }`);
2704
- lines.push(` }`);
3091
+ lines.push(` visit(key);`);
2705
3092
  lines.push(` }`);
2706
3093
  lines.push(` return cssFiles;`);
2707
3094
  lines.push(`}`);
@@ -2725,7 +3112,10 @@ function compilePageRoutes(lines, scan, pages, options) {
2725
3112
  lines.push(` const manifest = await loadPagesManifest(request, env);`);
2726
3113
  lines.push(` if (!manifest || typeof manifest !== "object") {`);
2727
3114
  lines.push(` if (!import.meta.env.DEV) return { css: "", preloads: "", body: "" };`);
2728
- lines.push(` return getPagesDevClientTags();`);
3115
+ if (options.dev) {
3116
+ lines.push(` const tags = getPagesDevClientTags();`);
3117
+ lines.push(` return { ...tags, devCss: await collectVoidDevCss(request, env, "pages", componentId, PAGE_DEV_ROOT_PHASES[componentId] || [[PAGES_CLIENT_ENTRY_URL]]) };`);
3118
+ } else lines.push(` return getPagesDevClientTags();`);
2729
3119
  lines.push(` }`);
2730
3120
  lines.push(` const entry = manifest[PAGES_CLIENT_ENTRY_ID];`);
2731
3121
  lines.push(` if (!entry || typeof entry !== "object" || typeof entry.file !== "string") {`);
@@ -2774,7 +3164,10 @@ function compilePageRoutes(lines, scan, pages, options) {
2774
3164
  lines.push(` const manifest = await loadPagesManifest(request, env);`);
2775
3165
  lines.push(` if (!manifest || typeof manifest !== "object") {`);
2776
3166
  lines.push(` if (!import.meta.env.DEV) return { css: "", preloads: "", body: "" };`);
2777
- lines.push(` return getIslandsDevClientTags();`);
3167
+ if (options.dev) {
3168
+ lines.push(` const tags = getIslandsDevClientTags();`);
3169
+ lines.push(` return { ...tags, devCss: await collectVoidDevCss(request, env, "islands", componentId, PAGE_DEV_ROOT_PHASES[componentId] || [[ISLANDS_CLIENT_ENTRY_URL]]) };`);
3170
+ } else lines.push(` return getIslandsDevClientTags();`);
2778
3171
  lines.push(` }`);
2779
3172
  lines.push(` const entry = manifest[ISLANDS_CLIENT_ENTRY_ID];`);
2780
3173
  lines.push(` if (!entry || typeof entry !== "object" || typeof entry.file !== "string") {`);
@@ -2896,6 +3289,15 @@ function compilePageRoutes(lines, scan, pages, options) {
2896
3289
  lines.push(` const errReq = new Request(new URL("/" + status + ".html", c.req.url));`);
2897
3290
  lines.push(` const errRes = await assets.fetch(errReq);`);
2898
3291
  lines.push(` if (errRes.ok) {`);
3292
+ lines.push(` const assetCss = __voidGetErrorAssetCss(error);`);
3293
+ lines.push(` if (assetCss) {`);
3294
+ lines.push(` const html = __voidInjectErrorAssetCss(await errRes.text(), assetCss);`);
3295
+ lines.push(` const body = __VOID_DEV && status === 500 && error && __voidShouldServeHtmlErrorPage(c.req.raw) ? __voidInjectDevErrorOverlay(html, __voidRenderDevErrorOverlay(c.req.raw, status, fallbackText, error)) : html;`);
3296
+ lines.push(` return new Response(c.req.method === "HEAD" ? null : body, {`);
3297
+ lines.push(` status,`);
3298
+ lines.push(` headers: { "content-type": "text/html; charset=utf-8" },`);
3299
+ lines.push(` });`);
3300
+ lines.push(` }`);
2899
3301
  lines.push(` if (__VOID_DEV && status === 500 && error && __voidShouldServeHtmlErrorPage(c.req.raw)) {`);
2900
3302
  lines.push(` const overlay = __voidRenderDevErrorOverlay(c.req.raw, status, fallbackText, error);`);
2901
3303
  lines.push(` const html = await errRes.text();`);
@@ -4096,6 +4498,15 @@ const SANDBOX_SDK_IMPORT = "@cloudflare/sandbox";
4096
4498
  const SANDBOX_SDK_IMPORT_FILTER = /^@cloudflare\/sandbox$/;
4097
4499
  const DEFAULT_WORKER_ENVIRONMENT_NAME = "void_worker";
4098
4500
  const DEFAULT_WORKER_OUT_DIR = "dist/ssr";
4501
+ const DEV_ASSET_ROUTING_EXCLUSIONS = [
4502
+ "!/@vite/*",
4503
+ "!/@id/*",
4504
+ "!/@fs/*",
4505
+ "!/@react-refresh",
4506
+ "!/@svelte/*",
4507
+ "!/node_modules/*",
4508
+ "!/__uno.css"
4509
+ ];
4099
4510
  function resolveSandboxSdkEntry() {
4100
4511
  return fileURLToPath(import.meta.resolve(SANDBOX_SDK_IMPORT));
4101
4512
  }
@@ -4138,6 +4549,23 @@ function createSandboxSdkResolvePlugin() {
4138
4549
  }
4139
4550
  };
4140
4551
  }
4552
+ function createWranglerCompatPersistPlugin(root, config) {
4553
+ let persisted = false;
4554
+ const persist = () => {
4555
+ if (persisted || isNodeTarget(config.target)) return;
4556
+ persisted = true;
4557
+ ensureWranglerCompat(root, config);
4558
+ };
4559
+ return {
4560
+ name: "void:wrangler-compat-persist",
4561
+ buildStart() {
4562
+ persist();
4563
+ },
4564
+ configureServer() {
4565
+ persist();
4566
+ }
4567
+ };
4568
+ }
4141
4569
  /**
4142
4570
  * Read Void auth credentials for local dev AI proxy access.
4143
4571
  * Returns a discriminated union so callers can distinguish
@@ -4307,8 +4735,8 @@ function voidPlugin(options) {
4307
4735
  if (detected && (detected.class === "b" || detected.class === "c")) {
4308
4736
  const bindingNames = resolveBindingNames(config.inference?.bindings);
4309
4737
  const frameworkPersistRoot = join(root, ".wrangler", "state");
4310
- const syncFrameworkCompat = () => {
4311
- if (ensureWranglerCompatibilityDate(root, readWranglerCompat(root, config).compatibilityDate)) voidLog("Synced compatibility_date to wrangler config");
4738
+ const syncFrameworkCompat = (compat) => {
4739
+ if (ensureWranglerCompatibilityDate(root, compat.compatibilityDate)) voidLog("Synced compatibility_date to wrangler config");
4312
4740
  };
4313
4741
  return [
4314
4742
  createCloudflareBuiltinsExternalPlugin(),
@@ -4316,15 +4744,21 @@ function voidPlugin(options) {
4316
4744
  name: "void:wrangler-compat",
4317
4745
  enforce: "pre",
4318
4746
  config(_, env) {
4319
- syncFrameworkCompat();
4747
+ syncFrameworkCompat(ensureWranglerCompat(root, config));
4320
4748
  if (env.command !== "serve") return;
4321
4749
  if (ensureWranglerNodejsAlsFlag(root)) voidLog("Synced nodejs_als to wrangler config");
4750
+ },
4751
+ buildStart() {
4752
+ syncFrameworkCompat(ensureWranglerCompat(root, config));
4753
+ },
4754
+ configureServer() {
4755
+ syncFrameworkCompat(ensureWranglerCompat(root, config));
4322
4756
  }
4323
4757
  },
4324
4758
  {
4325
4759
  name: "void:wrangler-sync",
4326
4760
  configResolved(resolvedConfig) {
4327
- syncFrameworkCompat();
4761
+ syncFrameworkCompat(readWranglerCompat(root, config));
4328
4762
  if (resolvedConfig.command !== "serve") return;
4329
4763
  if (syncWranglerBindings(root, bindings, {
4330
4764
  bindingNames,
@@ -4495,7 +4929,7 @@ function voidPlugin(options) {
4495
4929
  ...env
4496
4930
  };
4497
4931
  const assets = workerConfig.assets;
4498
- if (command === "serve" && assets) delete assets.run_worker_first;
4932
+ if (command === "serve" && assets?.run_worker_first) assets.run_worker_first = [...DEV_ASSET_ROUTING_EXCLUSIONS, "/**"];
4499
4933
  const watchConfig = { server: { watch: { ignored } } };
4500
4934
  if (!isNodeTarget(config.target) && config.output !== "static") {
4501
4935
  const envNames = framework === "vinext-app" ? ["rsc", "ssr"] : ["ssr"];
@@ -4617,6 +5051,7 @@ function voidPlugin(options) {
4617
5051
  } : void 0;
4618
5052
  return [
4619
5053
  createCloudflareBuiltinsExternalPlugin(),
5054
+ createWranglerCompatPersistPlugin(root, config),
4620
5055
  restartPlugin(),
4621
5056
  bindingWatchPlugin,
4622
5057
  envPlugin,
@@ -4656,6 +5091,7 @@ function voidPlugin(options) {
4656
5091
  restartPlugin(),
4657
5092
  envPlugin,
4658
5093
  envSchemaPlugin(root),
5094
+ ...pagesDevCssAssetsPlugin(root, devTriggerToken),
4659
5095
  routingPlugin(root, {
4660
5096
  isAuthEnabled: () => false,
4661
5097
  devTriggerToken,
@@ -4686,6 +5122,7 @@ function voidPlugin(options) {
4686
5122
  return [
4687
5123
  createCloudflareBuiltinsExternalPlugin(),
4688
5124
  createDefaultWorkerEnvironmentPlugin(),
5125
+ createWranglerCompatPersistPlugin(root, config),
4689
5126
  restartPlugin(),
4690
5127
  bindingWatchPlugin,
4691
5128
  envPlugin,
@@ -4694,6 +5131,7 @@ function voidPlugin(options) {
4694
5131
  envClientFoldPlugin(),
4695
5132
  clientStubsPlugin,
4696
5133
  ...bindings.needsSandbox ? [createSandboxSdkResolvePlugin()] : [],
5134
+ ...pagesDevCssAssetsPlugin(root, devTriggerToken),
4697
5135
  routingPlugin(root, {
4698
5136
  isAuthEnabled: () => authEnabled,
4699
5137
  devTriggerToken,