@arpabet/vrpc-nuxt 0.2.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,42 @@
1
+ # @arpabet/vrpc-nuxt
2
+
3
+ Nuxt 3/4 module for [value-rpc](https://github.com/arpabet/value-rpc).
4
+
5
+ ```ts
6
+ // nuxt.config.ts
7
+ export default defineNuxtConfig({
8
+ modules: ["@arpabet/vrpc-nuxt"],
9
+ vrpc: {
10
+ url: "/rpc", // same-origin wss in production
11
+ timeoutMs: 5000,
12
+ },
13
+ });
14
+ ```
15
+
16
+ - Registers a **client-only** plugin: SSR renders the pending state; the
17
+ browser connects after hydration (no WebSocket per SSR render).
18
+ - Auto-imports `useVrpc`, `useVrpcCall`, `useVrpcStream`, `useVrpcConnection`.
19
+ - Runtime-config driven: override per deployment with `NUXT_PUBLIC_VRPC_URL`
20
+ (and `NUXT_PUBLIC_VRPC_TIMEOUT_MS`, …).
21
+ - A relative `url` like `/rpc` is resolved against the page origin with the
22
+ matching `ws:`/`wss:` scheme.
23
+
24
+ ### Dev connectivity
25
+
26
+ In production, serve the app and a same-origin `/rpc` endpoint from one host so
27
+ `url: "/rpc"` connects same-origin (no CORS, no origin patterns). In **dev**,
28
+ the browser and the Go server are on different ports, so either:
29
+
30
+ - **connect directly** to the server with an absolute dev URL and allow the
31
+ origin server-side (`valueserver.WithWebSocketOrigins(...)`) — the reliable
32
+ option, since Nitro's `devProxy` forwards HTTP but does **not** upgrade
33
+ WebSockets; or
34
+ - use Vite/`@arpabet/vrpc-vue` (whose dev proxy does handle WS) for a same-origin
35
+ dev experience.
36
+
37
+ The `devProxy` option still wires a Nitro `devProxy` entry (useful for any HTTP
38
+ routes), but do not rely on it for the WebSocket itself.
39
+
40
+ For SSR-critical data, query the same Go server from Nitro server routes and
41
+ pass results through `useAsyncData`; a shared Nitro-side vrpc client is the
42
+ phase-2 plan (WEB.md §6.6).
@@ -0,0 +1,36 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface VrpcModuleOptions {
4
+ /**
5
+ * WebSocket endpoint. Overridable at runtime via
6
+ * NUXT_PUBLIC_VRPC_URL (runtimeConfig.public.vrpc.url). In dev, prefer a
7
+ * relative "/rpc" together with the devProxy option.
8
+ */
9
+ url: string;
10
+ /** "msgpack" (default, works with every server) or "json". */
11
+ codec?: "msgpack" | "json";
12
+ /** Default unary timeout / request SLA in ms. */
13
+ timeoutMs?: number;
14
+ /** Open the connection at app start instead of on first call. */
15
+ eager?: boolean;
16
+ /**
17
+ * Dev-server proxy target for the WebSocket endpoint, e.g.
18
+ * "http://localhost:9000". Adds a Nitro devProxy for `url` (same-origin in
19
+ * dev: no CORS, no origin patterns, no mixed content).
20
+ */
21
+ devProxy?: string;
22
+ }
23
+ declare const _default: _nuxt_schema.NuxtModule<VrpcModuleOptions, VrpcModuleOptions, false>;
24
+
25
+ declare module "@nuxt/schema" {
26
+ interface PublicRuntimeConfig {
27
+ vrpc: {
28
+ url: string;
29
+ codec?: "msgpack" | "json" | undefined;
30
+ timeoutMs?: number | undefined;
31
+ eager?: boolean | undefined;
32
+ };
33
+ }
34
+ }
35
+
36
+ export { type VrpcModuleOptions, _default as default };
package/dist/module.js ADDED
@@ -0,0 +1,42 @@
1
+ // src/module.ts
2
+ import { addImports, addPlugin, createResolver, defineNuxtModule } from "@nuxt/kit";
3
+ import { defu } from "defu";
4
+ var module_default = defineNuxtModule({
5
+ meta: {
6
+ name: "@arpabet/vrpc-nuxt",
7
+ configKey: "vrpc",
8
+ compatibility: { nuxt: ">=3.13.0" }
9
+ },
10
+ defaults: {
11
+ url: "/rpc",
12
+ codec: "msgpack",
13
+ timeoutMs: 5e3,
14
+ eager: false
15
+ },
16
+ setup(options, nuxt) {
17
+ const resolver = createResolver(import.meta.url);
18
+ const existing = nuxt.options.runtimeConfig.public.vrpc ?? {};
19
+ nuxt.options.runtimeConfig.public.vrpc = {
20
+ url: existing.url ?? options.url,
21
+ codec: existing.codec ?? options.codec ?? "msgpack",
22
+ timeoutMs: existing.timeoutMs ?? options.timeoutMs ?? 5e3,
23
+ eager: existing.eager ?? options.eager ?? false
24
+ };
25
+ addPlugin(resolver.resolve("./runtime/plugin.client"));
26
+ for (const name of ["useVrpc", "useVrpcCall", "useVrpcStream", "useVrpcConnection"]) {
27
+ addImports({ name, from: "@arpabet/vrpc-vue" });
28
+ }
29
+ if (options.devProxy && nuxt.options.dev) {
30
+ const opts = nuxt.options;
31
+ opts.nitro = opts.nitro ?? {};
32
+ opts.nitro.devProxy = defu(opts.nitro.devProxy, {
33
+ [options.url]: { target: options.devProxy + options.url, ws: true }
34
+ });
35
+ }
36
+ nuxt.options.build.transpile.push("@arpabet/vrpc", "@arpabet/vrpc-vue");
37
+ }
38
+ });
39
+ export {
40
+ module_default as default
41
+ };
42
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/module.ts"],"sourcesContent":["/*\n * Copyright (c) 2026 Karagatan LLC.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { addImports, addPlugin, createResolver, defineNuxtModule } from \"@nuxt/kit\";\nimport { defu } from \"defu\";\n\nexport interface VrpcModuleOptions {\n /**\n * WebSocket endpoint. Overridable at runtime via\n * NUXT_PUBLIC_VRPC_URL (runtimeConfig.public.vrpc.url). In dev, prefer a\n * relative \"/rpc\" together with the devProxy option.\n */\n url: string;\n /** \"msgpack\" (default, works with every server) or \"json\". */\n codec?: \"msgpack\" | \"json\";\n /** Default unary timeout / request SLA in ms. */\n timeoutMs?: number;\n /** Open the connection at app start instead of on first call. */\n eager?: boolean;\n /**\n * Dev-server proxy target for the WebSocket endpoint, e.g.\n * \"http://localhost:9000\". Adds a Nitro devProxy for `url` (same-origin in\n * dev: no CORS, no origin patterns, no mixed content).\n */\n devProxy?: string;\n}\n\nexport default defineNuxtModule<VrpcModuleOptions>({\n meta: {\n name: \"@arpabet/vrpc-nuxt\",\n configKey: \"vrpc\",\n compatibility: { nuxt: \">=3.13.0\" },\n },\n defaults: {\n url: \"/rpc\",\n codec: \"msgpack\",\n timeoutMs: 5000,\n eager: false,\n },\n setup(options, nuxt) {\n const resolver = createResolver(import.meta.url);\n\n // Expose the client options via runtime config so NUXT_PUBLIC_VRPC_* env\n // vars can override them per deployment.\n const existing = (nuxt.options.runtimeConfig.public.vrpc ?? {}) as Partial<VrpcModuleOptions>;\n nuxt.options.runtimeConfig.public.vrpc = {\n url: existing.url ?? options.url,\n codec: existing.codec ?? options.codec ?? \"msgpack\",\n timeoutMs: existing.timeoutMs ?? options.timeoutMs ?? 5000,\n eager: existing.eager ?? options.eager ?? false,\n };\n\n // SSR policy (WEB.md §6.6): the plugin is client-only. Server-side\n // rendering shows the pending state; the browser connects and fills.\n addPlugin(resolver.resolve(\"./runtime/plugin.client\"));\n\n // Auto-import the composables.\n for (const name of [\"useVrpc\", \"useVrpcCall\", \"useVrpcStream\", \"useVrpcConnection\"]) {\n addImports({ name, from: \"@arpabet/vrpc-vue\" });\n }\n\n // Same-origin dev proxy for the WS endpoint. (Typed loosely: NuxtOptions\n // only carries the nitro key when nitropack's types are installed.)\n if (options.devProxy && nuxt.options.dev) {\n const opts = nuxt.options as unknown as {\n nitro?: { devProxy?: Record<string, unknown> };\n };\n opts.nitro = opts.nitro ?? {};\n opts.nitro.devProxy = defu(opts.nitro.devProxy, {\n [options.url]: { target: options.devProxy + options.url, ws: true },\n });\n }\n\n // The runtime plugin imports these; make sure Vite pre-bundles them.\n nuxt.options.build.transpile.push(\"@arpabet/vrpc\", \"@arpabet/vrpc-vue\");\n },\n});\n\ndeclare module \"@nuxt/schema\" {\n interface PublicRuntimeConfig {\n vrpc: {\n url: string;\n codec?: \"msgpack\" | \"json\" | undefined;\n timeoutMs?: number | undefined;\n eager?: boolean | undefined;\n };\n }\n}\n"],"mappings":";AAKA,SAAS,YAAY,WAAW,gBAAgB,wBAAwB;AACxE,SAAS,YAAY;AAuBrB,IAAO,iBAAQ,iBAAoC;AAAA,EACjD,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,eAAe,EAAE,MAAM,WAAW;AAAA,EACpC;AAAA,EACA,UAAU;AAAA,IACR,KAAK;AAAA,IACL,OAAO;AAAA,IACP,WAAW;AAAA,IACX,OAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS,MAAM;AACnB,UAAM,WAAW,eAAe,YAAY,GAAG;AAI/C,UAAM,WAAY,KAAK,QAAQ,cAAc,OAAO,QAAQ,CAAC;AAC7D,SAAK,QAAQ,cAAc,OAAO,OAAO;AAAA,MACvC,KAAK,SAAS,OAAO,QAAQ;AAAA,MAC7B,OAAO,SAAS,SAAS,QAAQ,SAAS;AAAA,MAC1C,WAAW,SAAS,aAAa,QAAQ,aAAa;AAAA,MACtD,OAAO,SAAS,SAAS,QAAQ,SAAS;AAAA,IAC5C;AAIA,cAAU,SAAS,QAAQ,yBAAyB,CAAC;AAGrD,eAAW,QAAQ,CAAC,WAAW,eAAe,iBAAiB,mBAAmB,GAAG;AACnF,iBAAW,EAAE,MAAM,MAAM,oBAAoB,CAAC;AAAA,IAChD;AAIA,QAAI,QAAQ,YAAY,KAAK,QAAQ,KAAK;AACxC,YAAM,OAAO,KAAK;AAGlB,WAAK,QAAQ,KAAK,SAAS,CAAC;AAC5B,WAAK,MAAM,WAAW,KAAK,KAAK,MAAM,UAAU;AAAA,QAC9C,CAAC,QAAQ,GAAG,GAAG,EAAE,QAAQ,QAAQ,WAAW,QAAQ,KAAK,IAAI,KAAK;AAAA,MACpE,CAAC;AAAA,IACH;AAGA,SAAK,QAAQ,MAAM,UAAU,KAAK,iBAAiB,mBAAmB;AAAA,EACxE;AACF,CAAC;","names":[]}
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright (c) 2026 Karagatan LLC.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ // Client-only plugin: creates the shared vrpc client from runtime config.
7
+ // SSR never opens a WebSocket (WEB.md §6.6); pages render their pending
8
+ // state on the server and the browser fills after hydration.
9
+
10
+ import { defineNuxtPlugin, useRuntimeConfig } from "#app";
11
+ import { createVrpc } from "@arpabet/vrpc-vue";
12
+
13
+ export default defineNuxtPlugin((nuxtApp) => {
14
+ const cfg = useRuntimeConfig().public.vrpc ?? {};
15
+ const url = resolveUrl(cfg.url || "/rpc");
16
+ nuxtApp.vueApp.use(
17
+ createVrpc({
18
+ url,
19
+ codec: cfg.codec || "msgpack",
20
+ timeoutMs: cfg.timeoutMs ?? 5000,
21
+ eager: cfg.eager ?? false,
22
+ }),
23
+ );
24
+ });
25
+
26
+ // Accepts absolute ws(s):// URLs, or a path like "/rpc" resolved against the
27
+ // page origin with the matching ws/wss scheme.
28
+ function resolveUrl(url) {
29
+ if (/^wss?:\/\//.test(url)) return url;
30
+ if (/^https?:\/\//.test(url)) return url.replace(/^http/, "ws");
31
+ const scheme = location.protocol === "https:" ? "wss" : "ws";
32
+ return `${scheme}://${location.host}${url.startsWith("/") ? url : `/${url}`}`;
33
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@arpabet/vrpc-nuxt",
3
+ "version": "0.2.0",
4
+ "description": "Nuxt module for value-rpc: client plugin, auto-imported composables, runtime config",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/module.d.ts",
10
+ "import": "./dist/module.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsup && rm -rf dist/runtime && cp -R src/runtime dist/runtime",
19
+ "typecheck": "tsc --noEmit"
20
+ },
21
+ "dependencies": {
22
+ "@arpabet/vrpc": "^0.2.0",
23
+ "@arpabet/vrpc-vue": "^0.2.0",
24
+ "@nuxt/kit": ">=3.13.0 <5",
25
+ "defu": "^6.1.4"
26
+ },
27
+ "devDependencies": {
28
+ "@nuxt/schema": ">=3.13.0 <5",
29
+ "tsup": "^8.3.0",
30
+ "typescript": "^5.6.0"
31
+ },
32
+ "engines": {
33
+ "node": ">=22"
34
+ },
35
+ "keywords": [
36
+ "nuxt",
37
+ "nuxt-module",
38
+ "rpc",
39
+ "websocket",
40
+ "value-rpc"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "https://github.com/arpabet/value-rpc-js.git",
48
+ "directory": "packages/vrpc-nuxt"
49
+ }
50
+ }