@void/vue 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { VoidActionError, categorizeActionError, cloneFormValue, createActionClient, formErrorMessage, formRetryMessage, formSubmissionBlocked, getValidationErrors, idleNavigationState, interpolateRouteParams, isAbortError, isEqualFormValue, isModifiedEvent, mergeDataIntoHref, parseFormResetArgs, scheduleFormRetry, ssrProxy, submitAction } from "void/pages-client";
1
+ import { cloneFormValue, createActionClient, formErrorMessage, formRetryMessage, formSubmissionBlocked, getValidationErrors, idleNavigationState, interpolateRouteParams, isAbortError, isEqualFormValue, isModifiedEvent, mergeDataIntoHref, parseFormResetArgs, scheduleFormRetry, ssrProxy, submitAction, submitIslandAction } from "void/pages-client";
2
2
  import { computed, defineComponent, h, inject, onMounted, onUnmounted, reactive, ref, shallowRef, watch } from "vue";
3
3
  //#region src/runtime/form.ts
4
4
  const Form = defineComponent({
@@ -335,15 +335,6 @@ function useNavigation() {
335
335
  }
336
336
  //#endregion
337
337
  //#region src/runtime/use-island-form.ts
338
- async function readActionErrorBody(response) {
339
- const contentType = response.headers.get("content-type") || "";
340
- try {
341
- if (contentType.includes("application/json")) return await response.json();
342
- return await response.text() || null;
343
- } catch {
344
- return null;
345
- }
346
- }
347
338
  /**
348
339
  * Form composable for island pages. Uses fetch + page reload instead of the
349
340
  * Void Router (which is not available in island mode).
@@ -380,16 +371,12 @@ function useIslandForm(defaults) {
380
371
  clearErrors();
381
372
  clearError();
382
373
  try {
383
- const response = await fetch(url, {
384
- method,
385
- headers: { "Content-Type": "application/json" },
386
- body: JSON.stringify(data)
387
- });
388
- if (response.redirected) {
389
- window.location.href = response.url;
374
+ const result = await submitIslandAction(url, method, data);
375
+ if (result.kind === "redirect") {
376
+ window.location.href = result.url;
390
377
  return;
391
378
  }
392
- if (response.ok) {
379
+ if (result.kind === "success") {
393
380
  wasSuccessful.value = true;
394
381
  recentlySuccessful.value = true;
395
382
  defaults_ = { ...data };
@@ -397,22 +384,8 @@ function useIslandForm(defaults) {
397
384
  recentlySuccessful.value = false;
398
385
  }, 2e3);
399
386
  window.location.reload();
400
- } else {
401
- const body = await readActionErrorBody(response);
402
- const actionError = new VoidActionError({
403
- body,
404
- status: response.status,
405
- statusText: response.statusText,
406
- url
407
- });
408
- const validationErrors = response.status === 422 ? getValidationErrors(body) : null;
409
- if (validationErrors) {
410
- Object.assign(errors, validationErrors);
411
- return;
412
- }
413
- if (categorizeActionError(response.status) === "boundary") throw actionError;
414
- error.value = actionError;
415
- }
387
+ } else if (result.kind === "validation") Object.assign(errors, result.errors);
388
+ else error.value = result.error;
416
389
  } finally {
417
390
  pending.value = false;
418
391
  }
package/dist/plugin.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import vue from "@vitejs/plugin-vue";
2
- import { generateComponentManifest, resolveEffectiveLayoutChain, resolvePagesDir, resolveStaticPageDataBuildOptions, scanPages } from "void/pages";
2
+ import { createPagesPlugin, generateComponentManifest, resolveEffectiveLayoutChain, resolvePagesDir, scanPages } from "void/pages";
3
3
  import { existsSync, readFileSync, readdirSync } from "node:fs";
4
4
  import nodePath from "node:path";
5
5
  import { normalizePath } from "vite";
@@ -313,7 +313,6 @@ initIslands(islands, hydrateIsland);
313
313
  }
314
314
  //#endregion
315
315
  //#region src/plugin-pages.ts
316
- const RENDERER_ID = "virtual:void-pages-renderer";
317
316
  const CLIENT_ENTRY_ID = "virtual:void-pages-client";
318
317
  /** Runtime helper injected into generated SSR and client page bundles. */
319
318
  const PATCH_PROPS_RUNTIME = `
@@ -389,30 +388,7 @@ function hasNonIslandPages(dir) {
389
388
  return false;
390
389
  }
391
390
  function pagesPlugin(pagesDir, options) {
392
- let pageScan = null;
393
- let isDev = false;
394
- let viteConfig;
395
- const root = options?.root ?? dirname(pagesDir);
396
391
  const normalizedPagesDir = normalizePath(pagesDir);
397
- let pendingRescan = null;
398
- const rescanPages = async () => {
399
- pageScan = existsSync(pagesDir) ? await scanPages(root, {
400
- pagesDir,
401
- environment: isDev ? "dev" : "prod"
402
- }) : null;
403
- };
404
- const runRescan = () => {
405
- pendingRescan ??= rescanPages().finally(() => {
406
- pendingRescan = null;
407
- });
408
- return pendingRescan;
409
- };
410
- const invalidatePageModules = (server) => {
411
- for (const env of Object.values(server.environments)) for (const id of ["\0" + RENDERER_ID, "\0" + CLIENT_ENTRY_ID]) {
412
- const mod = env.moduleGraph.getModuleById(id);
413
- if (mod) env.moduleGraph.invalidateModule(mod);
414
- }
415
- };
416
392
  return [{
417
393
  name: "void-vue:pages-transform",
418
394
  enforce: "pre",
@@ -439,58 +415,16 @@ function pagesPlugin(pagesDir, options) {
439
415
  };
440
416
  }
441
417
  }
442
- }, {
418
+ }, createPagesPlugin(pagesDir, {
443
419
  name: "void-vue:pages",
444
- async buildStart() {
445
- await runRescan();
446
- },
447
- resolveId: {
448
- filter: { id: /^virtual:void-pages-(renderer|client)$/ },
449
- handler(id) {
450
- return "\0" + id;
451
- }
452
- },
453
- load: {
454
- filter: { id: /^\0virtual:void-pages-(renderer|client)$/ },
455
- async handler(id) {
456
- if (isDev && pendingRescan) await pendingRescan;
457
- if (!pageScan && existsSync(pagesDir)) await runRescan();
458
- if (id === "\0" + RENDERER_ID) {
459
- if (!pageScan) return "export function renderPage() { throw new Error('No pages found'); }";
460
- return generateRendererModule(pageScan, pagesDir);
461
- }
462
- if (id === "\0" + CLIENT_ENTRY_ID) {
463
- if (!pageScan) return "";
464
- return generateClientEntry(pageScan, pagesDir, options?.viewTransitions, options?.prefetch, resolveStaticPageDataBuildOptions(root, { publicDir: viteConfig?.publicDir }));
465
- }
466
- }
420
+ root: options?.root,
421
+ generateRenderer(scan) {
422
+ return generateRendererModule(scan, pagesDir);
467
423
  },
468
- configureServer(server) {
469
- const handlePagesChange = async (path, event) => {
470
- const normalizedPath = normalizePath(path);
471
- if (normalizedPath !== normalizedPagesDir && !normalizedPath.startsWith(normalizedPagesDir + "/")) return;
472
- if (event === "change" && !normalizedPath.endsWith(".md")) return;
473
- try {
474
- await runRescan();
475
- } catch (error) {
476
- server.config.logger.error(error instanceof Error ? error.message : String(error), {
477
- error: error instanceof Error ? error : void 0,
478
- timestamp: true
479
- });
480
- return;
481
- }
482
- invalidatePageModules(server);
483
- };
484
- server.watcher.on("add", (path) => handlePagesChange(path, "add"));
485
- server.watcher.on("change", (path) => handlePagesChange(path, "change"));
486
- server.watcher.on("unlink", (path) => handlePagesChange(path, "unlink"));
424
+ generateClient(scan, staticPageData) {
425
+ return generateClientEntry(scan, pagesDir, options?.viewTransitions, options?.prefetch, staticPageData);
487
426
  },
488
- configResolved(config) {
489
- viteConfig = config;
490
- },
491
- config(_, env) {
492
- isDev = env.command === "serve";
493
- if (!existsSync(pagesDir)) return;
427
+ config({ isDev }) {
494
428
  if (isDev) return { optimizeDeps: { include: ["vue"] } };
495
429
  if (!hasNonIslandPages(pagesDir)) return;
496
430
  return { environments: { client: { build: {
@@ -498,7 +432,7 @@ function pagesPlugin(pagesDir, options) {
498
432
  rollupOptions: { input: { "pages-client": CLIENT_ENTRY_ID } }
499
433
  } } } };
500
434
  }
501
- }];
435
+ })];
502
436
  }
503
437
  function generateRendererModule(scan, pagesDir) {
504
438
  return `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@void/vue",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Vue pages, server rendering, forms, and navigation for Void.",
5
5
  "homepage": "https://void.cloud",
6
6
  "bugs": {
@@ -41,12 +41,12 @@
41
41
  "pathslash": "^0.1.0",
42
42
  "vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
43
43
  "vite-plus": "1.3.0",
44
- "void": "1.3.0",
44
+ "void": "1.4.0",
45
45
  "vue": "^3.5.44"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "vite": "^8.0.0",
49
- "void": "1.3.0",
49
+ "void": "1.4.0",
50
50
  "vue": "^3.5.0"
51
51
  },
52
52
  "scripts": {