@void/vue 0.0.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/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # @void/vue
2
+
3
+ Vue adapter for Void Pages mode.
4
+
5
+ ## Setup
6
+
7
+ ```ts
8
+ import { defineConfig } from 'vite';
9
+ import { voidPlugin } from 'void';
10
+ import { voidVue } from '@void/vue/plugin';
11
+
12
+ export default defineConfig({
13
+ plugins: [voidPlugin(), voidVue()],
14
+ });
15
+ ```
16
+
17
+ ## Plugin
18
+
19
+ `voidVue(options?)` returns:
20
+
21
+ - `@vitejs/plugin-vue`
22
+ - the Vue pages plugin
23
+ - the Vue islands plugin
24
+
25
+ Options:
26
+
27
+ - `vue?` — forwarded to `@vitejs/plugin-vue`
28
+ - `viewTransitions?` — enable View Transitions for SPA navigation
29
+
30
+ ## Runtime
31
+
32
+ Main runtime APIs live at `@void/vue`:
33
+
34
+ - `Link`
35
+ - `useRouter()`
36
+ - `useNavigation()`
37
+ - `useShared()`
38
+ - `useForm()`
39
+ - `useIslandForm()`
40
+ - `action()`
41
+
42
+ Deferred helpers are exported from `@void/vue/deferred`.
43
+
44
+ ### Link
45
+
46
+ `Link` renders an `<a>` for GET navigation and a `<button>` for mutation methods:
47
+
48
+ ```vue
49
+ <Link href="/users" :data="{ page: 2, tag: ['active', 'new'] }">Filtered users</Link>
50
+ <Link href="/users" replace>Users</Link>
51
+ <Link href="/logout" reload-document>Sign out</Link>
52
+ ```
53
+
54
+ GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw.
55
+
56
+ `prefetch` and `reloadDocument` are GET-only and throw for mutation links. `onNavigate` can cancel client-side navigation by calling `event.preventDefault()`.
57
+
58
+ ### Forms
59
+
60
+ `useForm()` tracks form state for Pages actions. Use `pending` for in-flight
61
+ state, `errors` for field validation, and `error` for non-validation call-site
62
+ failures. The submit helpers return promises so boundary-class failures can
63
+ propagate through Vue async error handling or explicit `catch` handlers.
64
+
65
+ ```vue
66
+ <script setup lang="ts">
67
+ import { useForm } from '@void/vue';
68
+
69
+ const form = useForm('/users', { name: '', email: '' });
70
+ </script>
71
+
72
+ <template>
73
+ <form @submit.prevent="form.post()">
74
+ <input v-model="form.data.name" name="name" />
75
+ <p v-if="form.errors.name">{{ form.errors.name }}</p>
76
+ <p v-if="form.error">{{ form.error.message }}</p>
77
+ <button :disabled="form.pending">Save</button>
78
+ </form>
79
+ </template>
80
+ ```
81
+
82
+ Use `action()` for the awaitable imperative escape hatch. It returns
83
+ `{ ok: true, pageData }` or `{ ok: false, error }` for call-site action errors,
84
+ while boundary-class failures are thrown. `action()` uses `POST` by default and
85
+ accepts `{ method: "PUT" | "PATCH" | "DELETE" }`.
86
+
87
+ ## Pages
88
+
89
+ Pages are `.vue` files in `pages/` with companion `.server.ts` files:
90
+
91
+ ```vue
92
+ <script setup lang="ts">
93
+ defineProps<{ title: string }>();
94
+ </script>
95
+
96
+ <template>
97
+ <h1>{{ title }}</h1>
98
+ </template>
99
+ ```
100
+
101
+ ```ts
102
+ import { defineHandler } from 'void';
103
+
104
+ export const loader = defineHandler(() => ({ title: 'Home' }));
105
+ ```
106
+
107
+ ## Tests
108
+
109
+ - `test/unit/use-form.test.ts`
110
+ - `test/unit/prefetch.test.ts`
111
+ - `test/integration/vue-pages-client.test.ts`
112
+
113
+ Cross-package SSR/protocol coverage for Vue pages mode also lives in `framework/packages/void/test/integration/*`.
@@ -0,0 +1,79 @@
1
+ import { Component } from "vue";
2
+ import { ActionResult, NavigationState, VisitOptions, VoidActionError, VoidRouter } from "void/pages-client";
3
+ import { CloudContextVariables, DeferredState as Deferred, InferProps } from "void";
4
+ import { ActionFormOptions, ActionUrl, ResolveActionBody, ResolveActionParams } from "void/routes";
5
+
6
+ //#region src/runtime/link.d.ts
7
+ declare const Link: Component;
8
+ //#endregion
9
+ //#region src/runtime/use-router.d.ts
10
+ declare function useRouter(): VoidRouter;
11
+ //#endregion
12
+ //#region src/runtime/use-shared.d.ts
13
+ declare function useShared<T = CloudContextVariables["shared"]>(): T;
14
+ //#endregion
15
+ //#region src/runtime/use-form.d.ts
16
+ type FormSubmitOptions = Omit<VisitOptions, "method" | "data"> & {
17
+ data?: Record<string, unknown>;
18
+ };
19
+ declare function useForm<U extends ActionUrl & string>(url: U, defaults: ResolveActionBody<U>, options?: ActionFormOptions<U>): {
20
+ data: ResolveActionBody<U>;
21
+ errors: Partial<Record<keyof ResolveActionBody<U> & string, string>>;
22
+ error: VoidActionError | null;
23
+ pending: boolean;
24
+ hasChanges: boolean;
25
+ wasSuccessful: boolean;
26
+ recentlySuccessful: boolean;
27
+ post(opts?: FormSubmitOptions): Promise<void>;
28
+ put(opts?: FormSubmitOptions): Promise<void>;
29
+ patch(opts?: FormSubmitOptions): Promise<void>;
30
+ delete(opts?: FormSubmitOptions): Promise<void>;
31
+ reset(...fields: Array<keyof ResolveActionBody<U> & string>): void;
32
+ clearErrors(...fields: Array<keyof ResolveActionBody<U> & string>): void;
33
+ clearError(): void;
34
+ };
35
+ //#endregion
36
+ //#region src/runtime/use-navigation.d.ts
37
+ declare function useNavigation(): NavigationState;
38
+ //#endregion
39
+ //#region src/runtime/use-island-form.d.ts
40
+ interface IslandFormReturn<T extends Record<string, unknown>> {
41
+ data: T;
42
+ errors: Record<string, string>;
43
+ error: VoidActionError | null;
44
+ pending: boolean;
45
+ hasChanges: boolean;
46
+ wasSuccessful: boolean;
47
+ recentlySuccessful: boolean;
48
+ submit(url: string, method: string): Promise<void>;
49
+ post(url: string): Promise<void>;
50
+ put(url: string): Promise<void>;
51
+ patch(url: string): Promise<void>;
52
+ delete(url: string): Promise<void>;
53
+ reset(...fields: Array<keyof T & string>): void;
54
+ clearErrors(...fields: Array<string>): void;
55
+ clearError(): void;
56
+ }
57
+ /**
58
+ * Form composable for island pages. Uses fetch + page reload instead of the
59
+ * Void Router (which is not available in island mode).
60
+ */
61
+ declare function useIslandForm<T extends Record<string, unknown>>(defaults: T): IslandFormReturn<T>;
62
+ //#endregion
63
+ //#region src/runtime/action.d.ts
64
+ type ActionMethod = "POST" | "PUT" | "PATCH" | "DELETE";
65
+ type HasParams<U extends string> = [ResolveActionParams<U>] extends [never] ? false : true;
66
+ type ActionOptions<U extends string> = {
67
+ data?: ResolveActionBody<U>;
68
+ method?: ActionMethod;
69
+ } & (HasParams<U> extends true ? {
70
+ params: ResolveActionParams<U>;
71
+ } : {
72
+ params?: never;
73
+ });
74
+ /** Called during app initialization to store the router instance */
75
+ declare function setActionRouter(router: VoidRouter): void;
76
+ /** Programmatic one-shot page action call with Inertia page update */
77
+ declare function action<U extends ActionUrl & string>(url: U, ...args: HasParams<U> extends true ? [options: ActionOptions<U>] : [options?: ActionOptions<U>]): Promise<ActionResult>;
78
+ //#endregion
79
+ export { useIslandForm as a, useShared as c, setActionRouter as i, useRouter as l, InferProps as n, useNavigation as o, action as r, useForm as s, Deferred as t, Link as u };
@@ -0,0 +1,2 @@
1
+ import { a as useIslandForm, c as useShared, i as setActionRouter, l as useRouter, n as InferProps, o as useNavigation, r as action, s as useForm, t as Deferred, u as Link } from "./index-C0fE29Kv.mjs";
2
+ export { Deferred, InferProps, Link, action, setActionRouter, useForm, useIslandForm, useNavigation, useRouter, useShared };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as useForm, c as Link, i as useNavigation, n as setActionRouter, o as useShared, r as useIslandForm, s as useRouter, t as action } from "./runtime-DL_B0L_H.mjs";
2
+ export { Link, action, setActionRouter, useForm, useIslandForm, useNavigation, useRouter, useShared };
@@ -0,0 +1,11 @@
1
+ import vue from "@vitejs/plugin-vue";
2
+ import { Plugin } from "vite";
3
+
4
+ //#region src/plugin.d.ts
5
+ interface VoidVueOptions {
6
+ vue?: Parameters<typeof vue>[0];
7
+ viewTransitions?: boolean;
8
+ }
9
+ declare function voidVue(options?: VoidVueOptions): Array<Plugin>;
10
+ //#endregion
11
+ export { VoidVueOptions, voidVue };