@lunora/nuxt 1.0.0-alpha.29 → 1.0.0-alpha.290

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 CHANGED
@@ -79,19 +79,20 @@ export { ShardDO } from "./lunora/server";
79
79
  `lunora/server.ts` is your built Lunora app (`defineApp().build()`) — its default
80
80
  export is the worker (a `fetch` entrypoint), and it re-exports `ShardDO`. The
81
81
  module aliases the `#lunora/app` virtual to it (configurable via the `lunora.appEntry`
82
- option, default `~/lunora/server`) and serves it at the `/_lunora/**` route
83
- (prefix configurable via `lunora.prefix`).
82
+ option, default `~/lunora/server`) and serves it at the `/_lunora/**` route.
84
83
 
85
84
  ## Options
86
85
 
87
86
  | Option | Default | Description |
88
87
  | ---------- | ----------------- | --------------------------------------------------------- |
89
88
  | `appEntry` | `~/lunora/server` | Module specifier of the Lunora app entry (`#lunora/app`). |
90
- | `prefix` | `/_lunora` | URL prefix the Lunora realtime plane is mounted at. |
89
+
90
+ The `/_lunora/**` mount is fixed: the worker routes on those exact paths and the
91
+ generated client calls them.
91
92
 
92
93
  ## How it works
93
94
 
94
- - **The route** (`addServerHandler` at `prefix/**`): reconstructs a Web `Request`
95
+ - **The route** (`addServerHandler` at `/_lunora/**`): reconstructs a Web `Request`
95
96
  from the H3 event, resolves the Cloudflare `env`/`ExecutionContext` off it
96
97
  (tolerating both `event.context.cloudflare` and `event.req.runtime.cloudflare`),
97
98
  and forwards to your app's `fetch`. A missing Cloudflare runtime answers a clear 500.
package/dist/module.d.mts CHANGED
@@ -1,9 +1,78 @@
1
- import * as nuxt_schema from 'nuxt/schema';
2
-
1
+ import { defineNuxtModule } from '@nuxt/kit';
2
+ /**
3
+ * Check that `worker.ts` at the project root actually re-exports `ShardDO` —
4
+ * not just that the file exists. Extracted from `setup()` so it is testable
5
+ * without booting Nuxt (`defineNuxtModule`'s `setup` needs full Nuxt Kit
6
+ * scaffolding to invoke; this plain function does not).
7
+ *
8
+ * All three outcomes — missing file, unreadable file, present-but-no-`ShardDO`-
9
+ * export — WARN and return; none of them throws. Matches the module's existing
10
+ * stance ("we can't write the user's file, so warn... rather than fail an
11
+ * otherwise-valid build") and the `@lunora/astro` precedent this mirrors.
12
+ */
13
+ declare const checkWorkerEntry: (rootDirectory: string, warn: (message: string) => void) => void;
14
+ /**
15
+ * One entry of Nuxt's resolved plugin list (`app.plugins` at `app:resolve`):
16
+ * an absolute `src` plus the `mode` Nuxt derived for it. Declared structurally
17
+ * for the same reason as {@link LunoraNuxtModule} — `@nuxt/schema`, which owns
18
+ * `NuxtPlugin`, is not a resolvable dependency here — and `NuxtPlugin[]`
19
+ * satisfies it.
20
+ */
21
+ interface ResolvedNuxtPlugin {
22
+ mode?: "all" | "client" | "server";
23
+ src: string;
24
+ }
25
+ /**
26
+ * Warn when the project's ONLY `LunoraClient` provider is a client-only plugin.
27
+ *
28
+ * `@lunora/vue`'s composables call `useLunora()` unconditionally — ahead of
29
+ * their own browser guard — and it throws when nothing is injected. A
30
+ * `plugins/lunora.client.ts` by definition never runs on the server, so the
31
+ * first server-rendered page touching Lunora answers 500 with
32
+ * `useLunora(): no LunoraClient provided`. The fix is dropping `.client` from
33
+ * the filename plus a universal way to read the origin, which the warning says.
34
+ *
35
+ * Takes Nuxt's own resolved plugin list (`app.plugins`, from the `app:resolve`
36
+ * hook) rather than scanning `plugins/` itself. That is the whole point: Nuxt
37
+ * loads plugins with a two-pattern, ONE-level glob — top-level entries plus a
38
+ * subdirectory's `index` file — over every layer's configured plugins dir, so
39
+ * a filesystem scan of its own has to mirror the glob, the extension list,
40
+ * `dir.plugins` and every layer — and gets the answer WRONG in both directions
41
+ * when it doesn't. A recursive scan counts `plugins/lib/make-client.ts` (an
42
+ * ordinary colocated helper Nuxt never loads) as a universal provider and goes
43
+ * silent on a genuinely broken app. Reading `mode` off the resolved entry also
44
+ * drops the `.client` filename rule, since that is what Nuxt derived it from.
45
+ *
46
+ * Detection of the provider itself is the same shape as
47
+ * {@link looksLikeShardDoExport}: a documented keyword test, not a TS parse,
48
+ * because the outcome is a build-time warning. Its imprecision is a
49
+ * `createLunora` mention inside a comment, whose only cost is a warning
50
+ * pointing at a file that is already about the client.
51
+ *
52
+ * Silence requires a provider Nuxt loads on the server — `mode` `"all"` or
53
+ * `"server"` — not merely a working app: an app that confines every Lunora
54
+ * usage to `<ClientOnly>` is correct with a client-only provider and still
55
+ * warns, which is why the message names that case as a reason to ignore it.
56
+ */
57
+ declare const checkClientOnlyProvider: (plugins: ReadonlyArray<ResolvedNuxtPlugin>, warn: (message: string) => void) => void;
58
+ /** Options for the `@lunora/nuxt` module (configurable under the `lunora` key in `nuxt.config`). */
3
59
  interface ModuleOptions {
4
- appEntry: string;
5
- prefix: string;
60
+ /**
61
+ * Module specifier of the Lunora app entry — its default export is the built
62
+ * worker (`defineApp().build()` / `createWorker(...)`) and it re-exports
63
+ * `ShardDO`. Aliased to the `#lunora/app` virtual the server route imports.
64
+ */
65
+ appEntry: string;
6
66
  }
7
- declare const _default: nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
8
-
9
- export { _default as default };
67
+ /**
68
+ * Return type of `defineNuxtModule<ModuleOptions>({...})` — the value overload of
69
+ * `defineNuxtModule` (the one taking a definition), extracted structurally so the
70
+ * default export has a locally-nameable type under `isolatedDeclarations` without
71
+ * importing `NuxtModule` from `@nuxt/schema` (not a resolvable dependency here).
72
+ */
73
+ type LunoraNuxtModule = typeof defineNuxtModule<ModuleOptions> extends {
74
+ (definition: infer _Definition): infer Result;
75
+ (): unknown;
76
+ } ? Result : never;
77
+ declare const lunoraNuxtModule: LunoraNuxtModule;
78
+ export { ModuleOptions, ResolvedNuxtPlugin, checkClientOnlyProvider, checkWorkerEntry, lunoraNuxtModule as default };
@@ -0,0 +1,78 @@
1
+ import { defineNuxtModule } from '@nuxt/kit';
2
+ /**
3
+ * Check that `worker.ts` at the project root actually re-exports `ShardDO` —
4
+ * not just that the file exists. Extracted from `setup()` so it is testable
5
+ * without booting Nuxt (`defineNuxtModule`'s `setup` needs full Nuxt Kit
6
+ * scaffolding to invoke; this plain function does not).
7
+ *
8
+ * All three outcomes — missing file, unreadable file, present-but-no-`ShardDO`-
9
+ * export — WARN and return; none of them throws. Matches the module's existing
10
+ * stance ("we can't write the user's file, so warn... rather than fail an
11
+ * otherwise-valid build") and the `@lunora/astro` precedent this mirrors.
12
+ */
13
+ declare const checkWorkerEntry: (rootDirectory: string, warn: (message: string) => void) => void;
14
+ /**
15
+ * One entry of Nuxt's resolved plugin list (`app.plugins` at `app:resolve`):
16
+ * an absolute `src` plus the `mode` Nuxt derived for it. Declared structurally
17
+ * for the same reason as {@link LunoraNuxtModule} — `@nuxt/schema`, which owns
18
+ * `NuxtPlugin`, is not a resolvable dependency here — and `NuxtPlugin[]`
19
+ * satisfies it.
20
+ */
21
+ interface ResolvedNuxtPlugin {
22
+ mode?: "all" | "client" | "server";
23
+ src: string;
24
+ }
25
+ /**
26
+ * Warn when the project's ONLY `LunoraClient` provider is a client-only plugin.
27
+ *
28
+ * `@lunora/vue`'s composables call `useLunora()` unconditionally — ahead of
29
+ * their own browser guard — and it throws when nothing is injected. A
30
+ * `plugins/lunora.client.ts` by definition never runs on the server, so the
31
+ * first server-rendered page touching Lunora answers 500 with
32
+ * `useLunora(): no LunoraClient provided`. The fix is dropping `.client` from
33
+ * the filename plus a universal way to read the origin, which the warning says.
34
+ *
35
+ * Takes Nuxt's own resolved plugin list (`app.plugins`, from the `app:resolve`
36
+ * hook) rather than scanning `plugins/` itself. That is the whole point: Nuxt
37
+ * loads plugins with a two-pattern, ONE-level glob — top-level entries plus a
38
+ * subdirectory's `index` file — over every layer's configured plugins dir, so
39
+ * a filesystem scan of its own has to mirror the glob, the extension list,
40
+ * `dir.plugins` and every layer — and gets the answer WRONG in both directions
41
+ * when it doesn't. A recursive scan counts `plugins/lib/make-client.ts` (an
42
+ * ordinary colocated helper Nuxt never loads) as a universal provider and goes
43
+ * silent on a genuinely broken app. Reading `mode` off the resolved entry also
44
+ * drops the `.client` filename rule, since that is what Nuxt derived it from.
45
+ *
46
+ * Detection of the provider itself is the same shape as
47
+ * {@link looksLikeShardDoExport}: a documented keyword test, not a TS parse,
48
+ * because the outcome is a build-time warning. Its imprecision is a
49
+ * `createLunora` mention inside a comment, whose only cost is a warning
50
+ * pointing at a file that is already about the client.
51
+ *
52
+ * Silence requires a provider Nuxt loads on the server — `mode` `"all"` or
53
+ * `"server"` — not merely a working app: an app that confines every Lunora
54
+ * usage to `<ClientOnly>` is correct with a client-only provider and still
55
+ * warns, which is why the message names that case as a reason to ignore it.
56
+ */
57
+ declare const checkClientOnlyProvider: (plugins: ReadonlyArray<ResolvedNuxtPlugin>, warn: (message: string) => void) => void;
58
+ /** Options for the `@lunora/nuxt` module (configurable under the `lunora` key in `nuxt.config`). */
59
+ interface ModuleOptions {
60
+ /**
61
+ * Module specifier of the Lunora app entry — its default export is the built
62
+ * worker (`defineApp().build()` / `createWorker(...)`) and it re-exports
63
+ * `ShardDO`. Aliased to the `#lunora/app` virtual the server route imports.
64
+ */
65
+ appEntry: string;
66
+ }
67
+ /**
68
+ * Return type of `defineNuxtModule<ModuleOptions>({...})` — the value overload of
69
+ * `defineNuxtModule` (the one taking a definition), extracted structurally so the
70
+ * default export has a locally-nameable type under `isolatedDeclarations` without
71
+ * importing `NuxtModule` from `@nuxt/schema` (not a resolvable dependency here).
72
+ */
73
+ type LunoraNuxtModule = typeof defineNuxtModule<ModuleOptions> extends {
74
+ (definition: infer _Definition): infer Result;
75
+ (): unknown;
76
+ } ? Result : never;
77
+ declare const lunoraNuxtModule: LunoraNuxtModule;
78
+ export { ModuleOptions, ResolvedNuxtPlugin, checkClientOnlyProvider, checkWorkerEntry, lunoraNuxtModule as default };
package/dist/module.json CHANGED
@@ -1,9 +1,5 @@
1
1
  {
2
2
  "configKey": "lunora",
3
3
  "name": "@lunora/nuxt",
4
- "version": "1.0.0-alpha.28",
5
- "builder": {
6
- "@nuxt/module-builder": "1.0.2",
7
- "unbuild": "unknown"
8
- }
9
- }
4
+ "version": "1.0.0-alpha.289"
5
+ }
package/dist/module.mjs CHANGED
@@ -1,72 +1 @@
1
- import { existsSync } from 'node:fs';
2
- import { join, resolve, dirname } from 'node:path';
3
- import { defineNuxtModule, createResolver, addServerHandler, useLogger } from '@nuxt/kit';
4
-
5
- const resolveTildePath = (specifier, rootDirectory, sourceDirectory) => {
6
- if (specifier.startsWith("~~/")) {
7
- return join(rootDirectory, specifier.slice(3));
8
- }
9
- if (specifier.startsWith("~/")) {
10
- return join(sourceDirectory, specifier.slice(2));
11
- }
12
- if (specifier.startsWith("./") || specifier.startsWith("../")) {
13
- return join(rootDirectory, specifier);
14
- }
15
- return specifier;
16
- };
17
-
18
- const JS_EXTENSION_SUFFIX = /\.js$/;
19
- const lunoraTsSourceResolver = (rootDirectory) => {
20
- const lunoraDirectory = join(rootDirectory, "lunora");
21
- return {
22
- name: "lunora:nitro-ts-source-resolve",
23
- resolveId: {
24
- handler(source, importer) {
25
- if (!source.endsWith(".js")) {
26
- return void 0;
27
- }
28
- let absolute;
29
- if (source.startsWith("#lunora/")) {
30
- absolute = join(lunoraDirectory, source.slice("#lunora/".length));
31
- } else if (source.startsWith(".") && importer !== void 0) {
32
- absolute = resolve(dirname(importer), source);
33
- }
34
- if (absolute === void 0) {
35
- return void 0;
36
- }
37
- const tsSource = absolute.replace(JS_EXTENSION_SUFFIX, ".ts");
38
- return existsSync(tsSource) ? tsSource : void 0;
39
- },
40
- order: "pre"
41
- }
42
- };
43
- };
44
- const module$1 = defineNuxtModule({
45
- defaults: {
46
- appEntry: "~/lunora/server",
47
- prefix: "/_lunora"
48
- },
49
- meta: {
50
- configKey: "lunora",
51
- name: "@lunora/nuxt"
52
- },
53
- setup(options, nuxt) {
54
- const resolver = createResolver(import.meta.url);
55
- nuxt.options.alias["#lunora/app"] = resolveTildePath(options.appEntry, nuxt.options.rootDir, nuxt.options.srcDir);
56
- nuxt.hook("nitro:config", (nitroConfig) => {
57
- const plugins = [...nitroConfig.rollupConfig?.plugins ?? [], lunoraTsSourceResolver(nuxt.options.rootDir)];
58
- nitroConfig.rollupConfig = { ...nitroConfig.rollupConfig, plugins };
59
- });
60
- addServerHandler({
61
- handler: resolver.resolve("./runtime/server/lunora"),
62
- route: `${options.prefix}/**`
63
- });
64
- if (!existsSync(join(nuxt.options.rootDir, "worker.ts"))) {
65
- useLogger("@lunora/nuxt").warn(
66
- 'missing worker.ts at the project root \u2014 add a wrapper that re-exports Nitro\'s handler and `ShardDO` (`export { default } from "./.output/server/index.mjs"; export { ShardDO } from "./lunora/server";`) and point wrangler\'s `main` at it, so the SHARD Durable Object is exported from the deployed worker.'
67
- );
68
- }
69
- }
70
- });
71
-
72
- export { module$1 as default };
1
+ import{existsSync as d,readFileSync as c}from"node:fs";import{join as s,resolve as m,dirname as E}from"node:path";import{defineNuxtModule as f,createResolver as g,addServerHandler as v,useLogger as u}from"@nuxt/kit";const S=String.raw`\/\*[\s\S]*?\*\/`,w=String.raw`\/\/[^\n]*`,R=String.raw`"(?:[^"\\\n]|\\.)*"`,O=String.raw`'(?:[^'\\\n]|\\.)*'`,T=String.raw`\x60(?:[^\x60\\$]|\\.|\$(?!\{))*\x60`,h=new RegExp([S,w,R,O,T].join("|"),"gu"),D=/[^\n]/gu,p=e=>e.replaceAll(D," "),i=e=>e.replaceAll(h,p),N=e=>e.replaceAll(h,r=>r.startsWith("//")||r.startsWith("/*")?p(r):r),_=(e,r,o)=>e.startsWith("~~/")?s(r,e.slice(3)):e.startsWith("~/")?s(o,e.slice(2)):e.startsWith("./")||e.startsWith("../")?s(r,e):e,x=/\.js$/,L=e=>{const r=s(e,"lunora");return{name:"lunora:nitro-ts-source-resolve",resolveId:{handler(o,t){if(!o.endsWith(".js"))return;let n;if(o.startsWith("#lunora/")?n=s(r,o.slice(8)):o.startsWith(".")&&t!==void 0&&(n=m(E(t),o)),n===void 0)return;const a=n.replace(x,".ts");return d(a)?a:void 0},order:"pre"}}},l='import nitro from "./.output/server/index.mjs"; import app, { ShardDO } from "./lunora/server"; export { ShardDO }; export default { ...nitro, email: (m, e, x) => app.email?.(m, e, x), queue: (b, e, x) => app.queue?.(b, e, x), scheduled: (c, e, x) => app.scheduled(c, e, x) };',k=/\bexport\b/u,y=/\bShardDO\b/u,A=/\bexport\s*\*\s*from\s*["'][^"']*lunora[^"']*["']/gu,b=e=>{const r=i(e);return[...N(e).matchAll(A)].some(({index:o})=>r[o]===e[o])},I=/\bscheduled\b/u,P=e=>{const r=i(e);return k.test(r)?y.test(r)||b(e):!1},C=(e,r)=>{const o=s(e,"worker.ts");if(!d(o)){r(`missing worker.ts at the project root — add a wrapper that re-exports Nitro's handler and \`ShardDO\` (\`${l}\`) and point wrangler's \`main\` at it, so the SHARD Durable Object is exported from the deployed worker.`);return}let t;try{t=c(o,"utf8")}catch(n){const a=n instanceof Error?n.message:String(n);r(`could not read worker.ts at the project root (${a}) — skipping the \`ShardDO\` export check.`);return}P(t)||r(`worker.ts at the project root does not appear to export \`ShardDO\` — add \`export { ShardDO } from "./lunora/server";\` (e.g. \`${l}\`) and point wrangler's \`main\` at it, so the SHARD Durable Object is exported from the deployed worker.`),I.test(i(t))||r(`worker.ts at the project root does not forward \`scheduled\` — re-exporting Nitro's \`default\` gives Cloudflare a \`scheduled\` entrypoint that only fires an empty \`cloudflare:scheduled\` hook, so a cron declared in \`lunora/crons.ts\` is provisioned and then runs nothing. Compose the two instead (\`${l}\`), which forwards \`queue\` and \`email\` too — Nitro's exports for those fire empty hooks the same way, and a queue consumer that returns without throwing ACKS its batch.`)},W=/\bcreateLunora\b/u,j=e=>{try{return W.test(i(c(e,"utf8")))}catch{return!1}},U=(e,r)=>{const o=e.filter(t=>j(t.src));o.length===0||o.some(t=>t.mode!=="client")||r(`the only plugin providing a \`LunoraClient\` is client-only (${o.map(t=>t.src).join(", ")}) — \`@lunora/vue\`'s composables resolve the client during SSR too and throw \`useLunora(): no LunoraClient provided\` without one, so the first server-rendered page that touches Lunora answers 500. Drop the \`.client\` from the filename to make the plugin universal, and read the origin with \`useRequestURL().origin\`, which resolves from the incoming request on the server and from \`window.location\` in the browser. Ignore this if every Lunora usage is confined to \`<ClientOnly>\`, which never renders on the server.`)},$="/_lunora",K=f({defaults:{appEntry:"~/lunora/server"},meta:{configKey:"lunora",name:"@lunora/nuxt"},setup(e,r){const o=g(import.meta.url);r.options.alias["#lunora/app"]=_(e.appEntry,r.options.rootDir,r.options.srcDir),r.hook("nitro:config",t=>{const n=[...t.rollupConfig?.plugins??[],L(r.options.rootDir)];t.rollupConfig={...t.rollupConfig,plugins:n}}),v({handler:o.resolve("./runtime/server/lunora"),route:`${$}/**`}),C(r.options.rootDir,t=>{u("@lunora/nuxt").warn(t)}),r.hook("app:resolve",t=>{U(t.plugins,n=>{u("@lunora/nuxt").warn(n)})})}});export{U as checkClientOnlyProvider,C as checkWorkerEntry,K as default};
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Resolve the Cloudflare per-request `env` (bindings) and `ExecutionContext`
3
+ * from a Nitro/H3 event, tolerating the two shapes Nitro has shipped.
4
+ *
5
+ * Legacy `event.context.cloudflare.{ env, context }` — surfaced by
6
+ * `nitro-cloudflare-dev` in `nuxt dev` and by older `cloudflare_module` builds,
7
+ * where `context` is the `ExecutionContext` (`waitUntil` / `passThroughOnException`).
8
+ *
9
+ * Newer `event.req.runtime.cloudflare.{ env, ctx }` — the Nitro runtime accessor
10
+ * (Nitro v2.10+ / Nuxt 4), where the `ExecutionContext` is `ctx`.
11
+ *
12
+ * Both are read defensively so the delegating handler works across the version
13
+ * range a scaffolded app might pin, in both dev and the deployed worker. When
14
+ * neither is present (no Cloudflare runtime — e.g. a Node preview), `env` is
15
+ * `undefined` and the caller surfaces a clear error.
16
+ *
17
+ * Typed against a structural `H3EventLike` rather than `nitropack`'s `H3Event`
18
+ * so this seam stays pure (no Nitro types needed) and unit-testable with a plain
19
+ * object — a real `H3Event` is still assignable here.
20
+ */
21
+ import { ExecutionContextLike } from '@lunora/runtime';
22
+ export type { ExecutionContextLike } from '@lunora/runtime';
23
+ /** The `{ env, context|ctx }` payload Nitro attaches for the Cloudflare runtime. */
24
+ interface CloudflareEventBag {
25
+ context?: ExecutionContextLike;
26
+ ctx?: ExecutionContextLike;
27
+ env?: Record<string, unknown>;
28
+ }
29
+ /**
30
+ * Structural view of the bits of an H3 event the resolver reads. Both legacy
31
+ * (`context.cloudflare`) and current (`req.runtime.cloudflare`) shapes are
32
+ * optional so a real H3 `H3Event` is assignable here.
33
+ */
34
+ interface H3EventLike {
35
+ context?: {
36
+ cloudflare?: CloudflareEventBag;
37
+ };
38
+ req?: {
39
+ runtime?: {
40
+ cloudflare?: CloudflareEventBag;
41
+ };
42
+ };
43
+ }
44
+ /** Resolved Cloudflare runtime for one request: the bindings `env` and the optional `ExecutionContext`. */
45
+ interface ResolvedCloudflare {
46
+ ctx?: ExecutionContextLike;
47
+ env?: Record<string, unknown>;
48
+ }
49
+ /**
50
+ * Pull the Cloudflare `env` + `ExecutionContext` off a Nitro/H3 event, checking
51
+ * the legacy `event.context.cloudflare` shape first (present under
52
+ * `nitro-cloudflare-dev` in dev) and the newer `event.req.runtime.cloudflare`
53
+ * shape second. Returns `{}` when neither is present.
54
+ */
55
+ declare const resolveCloudflare: (event: H3EventLike) => ResolvedCloudflare;
56
+ export { type H3EventLike, type ResolvedCloudflare, resolveCloudflare };
@@ -1,24 +1,56 @@
1
- import type { ExecutionContextLike } from "@lunora/runtime";
1
+ /**
2
+ * Resolve the Cloudflare per-request `env` (bindings) and `ExecutionContext`
3
+ * from a Nitro/H3 event, tolerating the two shapes Nitro has shipped.
4
+ *
5
+ * Legacy `event.context.cloudflare.{ env, context }` — surfaced by
6
+ * `nitro-cloudflare-dev` in `nuxt dev` and by older `cloudflare_module` builds,
7
+ * where `context` is the `ExecutionContext` (`waitUntil` / `passThroughOnException`).
8
+ *
9
+ * Newer `event.req.runtime.cloudflare.{ env, ctx }` — the Nitro runtime accessor
10
+ * (Nitro v2.10+ / Nuxt 4), where the `ExecutionContext` is `ctx`.
11
+ *
12
+ * Both are read defensively so the delegating handler works across the version
13
+ * range a scaffolded app might pin, in both dev and the deployed worker. When
14
+ * neither is present (no Cloudflare runtime — e.g. a Node preview), `env` is
15
+ * `undefined` and the caller surfaces a clear error.
16
+ *
17
+ * Typed against a structural `H3EventLike` rather than `nitropack`'s `H3Event`
18
+ * so this seam stays pure (no Nitro types needed) and unit-testable with a plain
19
+ * object — a real `H3Event` is still assignable here.
20
+ */
21
+ import { ExecutionContextLike } from '@lunora/runtime';
22
+ export type { ExecutionContextLike } from '@lunora/runtime';
23
+ /** The `{ env, context|ctx }` payload Nitro attaches for the Cloudflare runtime. */
2
24
  interface CloudflareEventBag {
3
- context?: ExecutionContextLike;
4
- ctx?: ExecutionContextLike;
5
- env?: Record<string, unknown>;
25
+ context?: ExecutionContextLike;
26
+ ctx?: ExecutionContextLike;
27
+ env?: Record<string, unknown>;
6
28
  }
29
+ /**
30
+ * Structural view of the bits of an H3 event the resolver reads. Both legacy
31
+ * (`context.cloudflare`) and current (`req.runtime.cloudflare`) shapes are
32
+ * optional so a real H3 `H3Event` is assignable here.
33
+ */
7
34
  interface H3EventLike {
8
- context?: {
9
- cloudflare?: CloudflareEventBag;
10
- };
11
- req?: {
12
- runtime?: {
13
- cloudflare?: CloudflareEventBag;
14
- };
35
+ context?: {
36
+ cloudflare?: CloudflareEventBag;
37
+ };
38
+ req?: {
39
+ runtime?: {
40
+ cloudflare?: CloudflareEventBag;
15
41
  };
42
+ };
16
43
  }
44
+ /** Resolved Cloudflare runtime for one request: the bindings `env` and the optional `ExecutionContext`. */
17
45
  interface ResolvedCloudflare {
18
- ctx?: ExecutionContextLike;
19
- env?: Record<string, unknown>;
46
+ ctx?: ExecutionContextLike;
47
+ env?: Record<string, unknown>;
20
48
  }
49
+ /**
50
+ * Pull the Cloudflare `env` + `ExecutionContext` off a Nitro/H3 event, checking
51
+ * the legacy `event.context.cloudflare` shape first (present under
52
+ * `nitro-cloudflare-dev` in dev) and the newer `event.req.runtime.cloudflare`
53
+ * shape second. Returns `{}` when neither is present.
54
+ */
21
55
  declare const resolveCloudflare: (event: H3EventLike) => ResolvedCloudflare;
22
- export type { H3EventLike, ResolvedCloudflare };
23
- export { resolveCloudflare };
24
- export { type ExecutionContextLike } from "@lunora/runtime";
56
+ export { type H3EventLike, type ResolvedCloudflare, resolveCloudflare };
@@ -0,0 +1 @@
1
+ const r=n=>{const e=n.context?.cloudflare;if(e?.env)return{ctx:e.context??e.ctx,env:e.env};const t=n.req?.runtime?.cloudflare;return t?.env?{ctx:t.ctx??t.context,env:t.env}:{}};export{r as resolveCloudflare};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Resolve the inbound web `Request` from an H3 event across the h3 v1 → v2 break.
3
+ *
4
+ * v1 exposes `toWebRequest(event)`; the v2 web-standards rewrite removed it and
5
+ * carries the web `Request` directly as `event.req`. The `@lunora/nuxt` peer is
6
+ * `h3: "^1.15.0"` (v1 — what Nuxt 4 / Nitro 2 run today); the v2 `event.req`
7
+ * branch is forward-compat for when a stable h3 v2 ships and the peer widens. We
8
+ * feature-detect `toWebRequest` at runtime rather than importing it statically —
9
+ * a named `import { toWebRequest }` would throw at module-eval under v2 (missing export).
10
+ *
11
+ * Kept as a pure helper (the `h3` namespace + event in, a `Request` out) so both
12
+ * branches are unit-tested without booting Nitro or installing a second h3 major.
13
+ */
14
+ interface H3RequestNamespace {
15
+ toWebRequest?: unknown;
16
+ }
17
+ declare const resolveWebRequest: (h3: H3RequestNamespace, event: unknown) => Request;
18
+ export { type H3RequestNamespace, resolveWebRequest };
@@ -1,6 +1,18 @@
1
+ /**
2
+ * Resolve the inbound web `Request` from an H3 event across the h3 v1 → v2 break.
3
+ *
4
+ * v1 exposes `toWebRequest(event)`; the v2 web-standards rewrite removed it and
5
+ * carries the web `Request` directly as `event.req`. The `@lunora/nuxt` peer is
6
+ * `h3: "^1.15.0"` (v1 — what Nuxt 4 / Nitro 2 run today); the v2 `event.req`
7
+ * branch is forward-compat for when a stable h3 v2 ships and the peer widens. We
8
+ * feature-detect `toWebRequest` at runtime rather than importing it statically —
9
+ * a named `import { toWebRequest }` would throw at module-eval under v2 (missing export).
10
+ *
11
+ * Kept as a pure helper (the `h3` namespace + event in, a `Request` out) so both
12
+ * branches are unit-tested without booting Nitro or installing a second h3 major.
13
+ */
1
14
  interface H3RequestNamespace {
2
- toWebRequest?: unknown;
15
+ toWebRequest?: unknown;
3
16
  }
4
17
  declare const resolveWebRequest: (h3: H3RequestNamespace, event: unknown) => Request;
5
- export type { H3RequestNamespace };
6
- export { resolveWebRequest };
18
+ export { type H3RequestNamespace, resolveWebRequest };
@@ -0,0 +1 @@
1
+ const o=(e,t)=>typeof e.toWebRequest=="function"?e.toWebRequest(t):t.req;export{o as resolveWebRequest};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The Lunora ↔ Nitro delegation seam. Given a Lunora worker (the
3
+ * `defineApp().build()` app or a bare `createWorker(...)` result) and the
4
+ * Cloudflare runtime resolved off the request event, forward the inbound
5
+ * `Request` — RPC (`POST /_lunora/rpc`), WebSocket upgrade (`/_lunora/ws`), and
6
+ * the admin plane (`/_lunora/admin/*`) — straight to `worker.fetch`.
7
+ *
8
+ * This is the single-worker composition the void.cloud Nuxt approach uses,
9
+ * inverted: instead of Lunora owning the worker entry, Lunora is mounted
10
+ * inside* Nitro as a server route, and the `ShardDO` class is re-exported to
11
+ * the Cloudflare worker entrypoint via the project's root `worker.ts` wrapper.
12
+ *
13
+ * Kept framework-neutral (a `LunoraWorkerLike` + the resolved `env`/`ctx`, not
14
+ * an H3 event) so it can be unit-tested with a stub worker — no Nuxt or workerd
15
+ * boot required. The thin H3 adapter that reads `env`/`ctx` off the event and
16
+ * the raw `Request`/`Response` lives in the `[...].ts` route module.
17
+ */
18
+ import { ExecutionContextLike } from '@lunora/runtime';
19
+ export { NOOP_EXECUTION_CONTEXT } from '@lunora/runtime';
20
+ /**
21
+ * Structural view of the Lunora worker the route delegates to — just the
22
+ * `fetch` entrypoint. Both `createWorker(...)` and the generated
23
+ * `defineApp().build()` app satisfy it (a `ComposedApp` is a superset). Declared
24
+ * locally so `@lunora/nuxt` doesn't hard-depend on `@lunora/runtime`'s worker type.
25
+ */
26
+ interface LunoraWorkerLike {
27
+ fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response> | Response;
28
+ }
29
+ /**
30
+ * Forward one inbound request to the Lunora worker. `env` must be the Cloudflare
31
+ * bindings (carrying the `SHARD` Durable Object namespace); when it is missing
32
+ * the Cloudflare runtime wasn't available (e.g. a non-CF preview), so we answer
33
+ * a clear 500 rather than handing the worker an `undefined` env.
34
+ */
35
+ declare const delegateToLunora: (worker: LunoraWorkerLike, request: Request, env: Record<string, unknown> | undefined, context?: ExecutionContextLike) => Promise<Response>;
36
+ export { type LunoraWorkerLike, delegateToLunora };
@@ -1,8 +1,36 @@
1
- import type { ExecutionContextLike } from "@lunora/runtime";
1
+ /**
2
+ * The Lunora ↔ Nitro delegation seam. Given a Lunora worker (the
3
+ * `defineApp().build()` app or a bare `createWorker(...)` result) and the
4
+ * Cloudflare runtime resolved off the request event, forward the inbound
5
+ * `Request` — RPC (`POST /_lunora/rpc`), WebSocket upgrade (`/_lunora/ws`), and
6
+ * the admin plane (`/_lunora/admin/*`) — straight to `worker.fetch`.
7
+ *
8
+ * This is the single-worker composition the void.cloud Nuxt approach uses,
9
+ * inverted: instead of Lunora owning the worker entry, Lunora is mounted
10
+ * inside* Nitro as a server route, and the `ShardDO` class is re-exported to
11
+ * the Cloudflare worker entrypoint via the project's root `worker.ts` wrapper.
12
+ *
13
+ * Kept framework-neutral (a `LunoraWorkerLike` + the resolved `env`/`ctx`, not
14
+ * an H3 event) so it can be unit-tested with a stub worker — no Nuxt or workerd
15
+ * boot required. The thin H3 adapter that reads `env`/`ctx` off the event and
16
+ * the raw `Request`/`Response` lives in the `[...].ts` route module.
17
+ */
18
+ import { ExecutionContextLike } from '@lunora/runtime';
19
+ export { NOOP_EXECUTION_CONTEXT } from '@lunora/runtime';
20
+ /**
21
+ * Structural view of the Lunora worker the route delegates to — just the
22
+ * `fetch` entrypoint. Both `createWorker(...)` and the generated
23
+ * `defineApp().build()` app satisfy it (a `ComposedApp` is a superset). Declared
24
+ * locally so `@lunora/nuxt` doesn't hard-depend on `@lunora/runtime`'s worker type.
25
+ */
2
26
  interface LunoraWorkerLike {
3
- fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response> | Response;
27
+ fetch: (request: Request, env: unknown, context: ExecutionContextLike) => Promise<Response> | Response;
4
28
  }
29
+ /**
30
+ * Forward one inbound request to the Lunora worker. `env` must be the Cloudflare
31
+ * bindings (carrying the `SHARD` Durable Object namespace); when it is missing
32
+ * the Cloudflare runtime wasn't available (e.g. a non-CF preview), so we answer
33
+ * a clear 500 rather than handing the worker an `undefined` env.
34
+ */
5
35
  declare const delegateToLunora: (worker: LunoraWorkerLike, request: Request, env: Record<string, unknown> | undefined, context?: ExecutionContextLike) => Promise<Response>;
6
- export type { LunoraWorkerLike };
7
- export { delegateToLunora };
8
- export { NOOP_EXECUTION_CONTEXT } from "@lunora/runtime";
36
+ export { type LunoraWorkerLike, delegateToLunora };
@@ -0,0 +1 @@
1
+ import{NOOP_EXECUTION_CONTEXT as n}from"@lunora/runtime";import{NOOP_EXECUTION_CONTEXT as l}from"@lunora/runtime";const s=async(o,r,e,t)=>e?o.fetch(r,e,t??n):Response.json({error:{code:"LUNORA_RUNTIME_UNAVAILABLE",message:"Lunora could not read the Cloudflare bindings from the request. The `/_lunora/**` route only works on the Cloudflare Workers runtime (deployed, or `nuxt dev` with `nitro-cloudflare-dev`)."}},{status:500});export{l as NOOP_EXECUTION_CONTEXT,s as delegateToLunora};
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Nitro server handler mounted at `/_lunora/**` by the `@lunora/nuxt` module
3
+ * (`addServerHandler`). It is the single-worker seam: every Lunora RPC,
4
+ * WebSocket upgrade, and admin request is forwarded to the project's Lunora
5
+ * worker, which runs *inside* the same Nitro/Cloudflare worker the rest of the
6
+ * Nuxt app deploys as.
7
+ *
8
+ * The worker instance is the project's composed app, imported through the
9
+ * `#lunora/app` virtual the module registers (it points at the app entry — by
10
+ * default `~/lunora/server`, where `defineApp().build()` lives and re-exports
11
+ * `ShardDO`). The same `ShardDO` is re-exported to the Cloudflare worker
12
+ * entrypoint via the project's root `worker.ts` wrapper (`wrangler.jsonc`'s
13
+ * `main`), so one deploy carries both the SSR handler and the Durable Object class.
14
+ *
15
+ * This file is only ever bundled by Nitro; `h3`'s `defineEventHandler` is its
16
+ * sole framework entry. We use a namespace import so the seam spans the h3
17
+ * v1 → v2 break: v1 exposes `toWebRequest(event)`, while the v2 web-standards
18
+ * rewrite removed it and carries the web `Request` directly as `event.req`. A
19
+ * static `import { toWebRequest }` would throw at module-eval under v2 (missing
20
+ * named export), so `resolveWebRequest` feature-detects it at runtime instead.
21
+ */
22
+ import { QueryObject } from 'ufo';
23
+ import { Hooks } from 'crossws';
24
+ import { IncomingMessage, ServerResponse } from 'node:http';
25
+ interface NodeEventContext {
26
+ req: IncomingMessage & {
27
+ originalUrl?: string;
28
+ };
29
+ res: ServerResponse;
30
+ }
31
+ interface WebEventContext {
32
+ request?: Request;
33
+ url?: URL;
34
+ }
35
+ declare class H3Event<_RequestT extends EventHandlerRequest = EventHandlerRequest> implements Pick<FetchEvent, "respondWith"> {
36
+ "__is_event__": boolean;
37
+ node: NodeEventContext;
38
+ web?: WebEventContext;
39
+ context: H3EventContext;
40
+ _method?: HTTPMethod;
41
+ _path?: string;
42
+ _headers?: Headers;
43
+ _requestBody?: BodyInit;
44
+ _handled: boolean;
45
+ _onBeforeResponseCalled: boolean | undefined;
46
+ _onAfterResponseCalled: boolean | undefined;
47
+ constructor(req: IncomingMessage, res: ServerResponse);
48
+ get method(): HTTPMethod;
49
+ get path(): string;
50
+ get headers(): Headers;
51
+ get handled(): boolean;
52
+ respondWith(response: Response | PromiseLike<Response>): Promise<void>;
53
+ toString(): string;
54
+ toJSON(): string;
55
+ /** @deprecated Please use `event.node.req` instead. */
56
+ get req(): IncomingMessage & {
57
+ originalUrl?: string;
58
+ };
59
+ /** @deprecated Please use `event.node.res` instead. */
60
+ get res(): ServerResponse<IncomingMessage>;
61
+ }
62
+ type SessionDataT = Record<string, any>;
63
+ type SessionData<T extends SessionDataT = SessionDataT> = T;
64
+ declare const getSessionPromise: unique symbol;
65
+ interface Session<T extends SessionDataT = SessionDataT> {
66
+ id: string;
67
+ createdAt: number;
68
+ data: SessionData<T>;
69
+ [getSessionPromise]?: Promise<Session<T>>;
70
+ }
71
+ type RouterMethod = Lowercase<HTTPMethod>;
72
+ interface RouteNode {
73
+ handlers: Partial<Record<RouterMethod | "all", EventHandler>>;
74
+ path: string;
75
+ }
76
+ type HTTPMethod = "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
77
+ interface H3EventContext extends Record<string, any> {
78
+ params?: Record<string, string>;
79
+ /**
80
+ * Matched router Node
81
+ *
82
+ * @experimental The object structure may change in non-major version.
83
+ */
84
+ matchedRoute?: RouteNode;
85
+ sessions?: Record<string, Session>;
86
+ clientAddress?: string;
87
+ }
88
+ type EventHandlerResponse<T = any> = T | Promise<T>;
89
+ interface EventHandlerRequest {
90
+ body?: any;
91
+ query?: QueryObject;
92
+ routerParams?: Record<string, string>;
93
+ }
94
+ type MaybePromise<T> = T | Promise<T>;
95
+ type EventHandlerResolver = (path: string) => MaybePromise<undefined | {
96
+ route?: string;
97
+ handler: EventHandler;
98
+ }>;
99
+ interface EventHandler<Request extends EventHandlerRequest = EventHandlerRequest, Response extends EventHandlerResponse = EventHandlerResponse> {
100
+ __is_handler__?: true;
101
+ __resolve__?: EventHandlerResolver;
102
+ __websocket__?: Partial<Hooks>;
103
+ (event: H3Event<Request>): Response;
104
+ }
105
+ /**
106
+ * Forward `/_lunora/**` to the Lunora worker. We reconstruct a Web `Request`
107
+ * from the H3 event (Lunora speaks the Web Fetch contract — RPC bodies and the
108
+ * WebSocket `Upgrade` handshake), resolve the Cloudflare `env`/`ExecutionContext`
109
+ * off the event, and return the worker's `Response` verbatim (H3 streams it,
110
+ * including a `101 Switching Protocols` upgrade with its `webSocket`).
111
+ */
112
+ declare const lunoraEventHandler: EventHandler;
113
+ export { lunoraEventHandler as default };
@@ -1,3 +1,113 @@
1
- import * as h3 from "h3";
2
- declare const _default: h3.EventHandler<h3.EventHandlerRequest, Promise<Response>>;
3
- export default _default;
1
+ /**
2
+ * Nitro server handler mounted at `/_lunora/**` by the `@lunora/nuxt` module
3
+ * (`addServerHandler`). It is the single-worker seam: every Lunora RPC,
4
+ * WebSocket upgrade, and admin request is forwarded to the project's Lunora
5
+ * worker, which runs *inside* the same Nitro/Cloudflare worker the rest of the
6
+ * Nuxt app deploys as.
7
+ *
8
+ * The worker instance is the project's composed app, imported through the
9
+ * `#lunora/app` virtual the module registers (it points at the app entry — by
10
+ * default `~/lunora/server`, where `defineApp().build()` lives and re-exports
11
+ * `ShardDO`). The same `ShardDO` is re-exported to the Cloudflare worker
12
+ * entrypoint via the project's root `worker.ts` wrapper (`wrangler.jsonc`'s
13
+ * `main`), so one deploy carries both the SSR handler and the Durable Object class.
14
+ *
15
+ * This file is only ever bundled by Nitro; `h3`'s `defineEventHandler` is its
16
+ * sole framework entry. We use a namespace import so the seam spans the h3
17
+ * v1 → v2 break: v1 exposes `toWebRequest(event)`, while the v2 web-standards
18
+ * rewrite removed it and carries the web `Request` directly as `event.req`. A
19
+ * static `import { toWebRequest }` would throw at module-eval under v2 (missing
20
+ * named export), so `resolveWebRequest` feature-detects it at runtime instead.
21
+ */
22
+ import { QueryObject } from 'ufo';
23
+ import { Hooks } from 'crossws';
24
+ import { IncomingMessage, ServerResponse } from 'node:http';
25
+ interface NodeEventContext {
26
+ req: IncomingMessage & {
27
+ originalUrl?: string;
28
+ };
29
+ res: ServerResponse;
30
+ }
31
+ interface WebEventContext {
32
+ request?: Request;
33
+ url?: URL;
34
+ }
35
+ declare class H3Event<_RequestT extends EventHandlerRequest = EventHandlerRequest> implements Pick<FetchEvent, "respondWith"> {
36
+ "__is_event__": boolean;
37
+ node: NodeEventContext;
38
+ web?: WebEventContext;
39
+ context: H3EventContext;
40
+ _method?: HTTPMethod;
41
+ _path?: string;
42
+ _headers?: Headers;
43
+ _requestBody?: BodyInit;
44
+ _handled: boolean;
45
+ _onBeforeResponseCalled: boolean | undefined;
46
+ _onAfterResponseCalled: boolean | undefined;
47
+ constructor(req: IncomingMessage, res: ServerResponse);
48
+ get method(): HTTPMethod;
49
+ get path(): string;
50
+ get headers(): Headers;
51
+ get handled(): boolean;
52
+ respondWith(response: Response | PromiseLike<Response>): Promise<void>;
53
+ toString(): string;
54
+ toJSON(): string;
55
+ /** @deprecated Please use `event.node.req` instead. */
56
+ get req(): IncomingMessage & {
57
+ originalUrl?: string;
58
+ };
59
+ /** @deprecated Please use `event.node.res` instead. */
60
+ get res(): ServerResponse<IncomingMessage>;
61
+ }
62
+ type SessionDataT = Record<string, any>;
63
+ type SessionData<T extends SessionDataT = SessionDataT> = T;
64
+ declare const getSessionPromise: unique symbol;
65
+ interface Session<T extends SessionDataT = SessionDataT> {
66
+ id: string;
67
+ createdAt: number;
68
+ data: SessionData<T>;
69
+ [getSessionPromise]?: Promise<Session<T>>;
70
+ }
71
+ type RouterMethod = Lowercase<HTTPMethod>;
72
+ interface RouteNode {
73
+ handlers: Partial<Record<RouterMethod | "all", EventHandler>>;
74
+ path: string;
75
+ }
76
+ type HTTPMethod = "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
77
+ interface H3EventContext extends Record<string, any> {
78
+ params?: Record<string, string>;
79
+ /**
80
+ * Matched router Node
81
+ *
82
+ * @experimental The object structure may change in non-major version.
83
+ */
84
+ matchedRoute?: RouteNode;
85
+ sessions?: Record<string, Session>;
86
+ clientAddress?: string;
87
+ }
88
+ type EventHandlerResponse<T = any> = T | Promise<T>;
89
+ interface EventHandlerRequest {
90
+ body?: any;
91
+ query?: QueryObject;
92
+ routerParams?: Record<string, string>;
93
+ }
94
+ type MaybePromise<T> = T | Promise<T>;
95
+ type EventHandlerResolver = (path: string) => MaybePromise<undefined | {
96
+ route?: string;
97
+ handler: EventHandler;
98
+ }>;
99
+ interface EventHandler<Request extends EventHandlerRequest = EventHandlerRequest, Response extends EventHandlerResponse = EventHandlerResponse> {
100
+ __is_handler__?: true;
101
+ __resolve__?: EventHandlerResolver;
102
+ __websocket__?: Partial<Hooks>;
103
+ (event: H3Event<Request>): Response;
104
+ }
105
+ /**
106
+ * Forward `/_lunora/**` to the Lunora worker. We reconstruct a Web `Request`
107
+ * from the H3 event (Lunora speaks the Web Fetch contract — RPC bodies and the
108
+ * WebSocket `Upgrade` handshake), resolve the Cloudflare `env`/`ExecutionContext`
109
+ * off the event, and return the worker's `Response` verbatim (H3 streams it,
110
+ * including a `101 Switching Protocols` upgrade with its `webSocket`).
111
+ */
112
+ declare const lunoraEventHandler: EventHandler;
113
+ export { lunoraEventHandler as default };
@@ -0,0 +1 @@
1
+ import*as e from"h3";import a from"#lunora/app";import{resolveCloudflare as l}from"../cloudflare.mjs";import{resolveWebRequest as m}from"../h3-request.mjs";import{delegateToLunora as s}from"../handler.mjs";const i=e.defineEventHandler(async r=>{const{ctx:o,env:t}=l(r),n=m(e,r);return s(a,n,t,o)});export{i as default};
package/dist/server.d.mts CHANGED
@@ -1 +1 @@
1
- export { ArgsOf, AuthLike, FunctionReference, HeadersSource, Preloaded, ReturnOf, ServerClientOptions, ServerSession, createServerClient, deserializePreloaded, getServerSession, preloadQuery, preloadedQueryResult, serializePreloaded } from '@lunora/client/ssr';
1
+ export { type ArgsOf, type AuthLike, type FunctionReference, type HeadersSource, type Preloaded, type ReturnOf, type ServerClientOptions, type ServerSession, createServerClient, deserializePreloaded, getServerSession, preloadQuery, preloadedQueryResult, serializePreloaded } from '@lunora/client/ssr';
@@ -0,0 +1 @@
1
+ export { type ArgsOf, type AuthLike, type FunctionReference, type HeadersSource, type Preloaded, type ReturnOf, type ServerClientOptions, type ServerSession, createServerClient, deserializePreloaded, getServerSession, preloadQuery, preloadedQueryResult, serializePreloaded } from '@lunora/client/ssr';
package/dist/server.mjs CHANGED
@@ -1 +1 @@
1
- export { createServerClient, deserializePreloaded, getServerSession, preloadQuery, preloadedQueryResult, serializePreloaded } from '@lunora/client/ssr';
1
+ import{createServerClient as d,deserializePreloaded as l,getServerSession as a,preloadQuery as o,preloadedQueryResult as i,serializePreloaded as s}from"@lunora/client/ssr";export{d as createServerClient,l as deserializePreloaded,a as getServerSession,o as preloadQuery,i as preloadedQueryResult,s as serializePreloaded};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/nuxt",
3
- "version": "1.0.0-alpha.29",
3
+ "version": "1.0.0-alpha.290",
4
4
  "description": "Nuxt module for Lunora — single-worker composition (mounts /_lunora/* into Nitro) plus reactive-loader server helpers",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -35,14 +35,14 @@
35
35
  "sideEffects": false,
36
36
  "main": "./dist/module.mjs",
37
37
  "module": "./dist/module.mjs",
38
- "types": "./dist/types.d.mts",
38
+ "types": "./dist/module.d.ts",
39
39
  "exports": {
40
40
  ".": {
41
- "types": "./dist/types.d.mts",
41
+ "types": "./dist/module.d.ts",
42
42
  "import": "./dist/module.mjs"
43
43
  },
44
44
  "./server": {
45
- "types": "./dist/server.d.mts",
45
+ "types": "./dist/server.d.ts",
46
46
  "import": "./dist/server.mjs"
47
47
  },
48
48
  "./package.json": "./package.json"
@@ -51,13 +51,13 @@
51
51
  "access": "public"
52
52
  },
53
53
  "dependencies": {
54
- "@lunora/client": "1.0.0-alpha.21",
55
- "@lunora/runtime": "1.0.0-alpha.26",
56
- "@nuxt/kit": "^4.4.8"
54
+ "@lunora/client": "1.0.0-alpha.273",
55
+ "@lunora/runtime": "1.0.0-alpha.263",
56
+ "@nuxt/kit": "^4.5.2"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "h3": "^1.15.0",
60
- "nuxt": "^4.0.0"
60
+ "nuxt": "^4.0.3"
61
61
  },
62
62
  "peerDependenciesMeta": {
63
63
  "h3": {
@@ -1,12 +0,0 @@
1
- const resolveCloudflare = (event) => {
2
- const fromContext = event.context?.cloudflare;
3
- if (fromContext?.env) {
4
- return { ctx: fromContext.context ?? fromContext.ctx, env: fromContext.env };
5
- }
6
- const fromRuntime = event.req?.runtime?.cloudflare;
7
- if (fromRuntime?.env) {
8
- return { ctx: fromRuntime.ctx ?? fromRuntime.context, env: fromRuntime.env };
9
- }
10
- return {};
11
- };
12
- export { resolveCloudflare };
@@ -1,2 +0,0 @@
1
- const resolveWebRequest = (h3, event) => typeof h3.toWebRequest === "function" ? h3.toWebRequest(event) : event.req;
2
- export { resolveWebRequest };
@@ -1,17 +0,0 @@
1
- import { NOOP_EXECUTION_CONTEXT } from "@lunora/runtime";
2
- const delegateToLunora = async (worker, request, env, context) => {
3
- if (!env) {
4
- return Response.json(
5
- {
6
- error: {
7
- code: "LUNORA_RUNTIME_UNAVAILABLE",
8
- message: "Lunora could not read the Cloudflare bindings from the request. The `/_lunora/**` route only works on the Cloudflare Workers runtime (deployed, or `nuxt dev` with `nitro-cloudflare-dev`)."
9
- }
10
- },
11
- { status: 500 }
12
- );
13
- }
14
- return worker.fetch(request, env, context ?? NOOP_EXECUTION_CONTEXT);
15
- };
16
- export { delegateToLunora };
17
- export { NOOP_EXECUTION_CONTEXT } from "@lunora/runtime";
@@ -1,10 +0,0 @@
1
- import * as h3 from "h3";
2
- import lunoraApp from "#lunora/app";
3
- import { resolveCloudflare } from "../cloudflare.js";
4
- import { resolveWebRequest } from "../h3-request.js";
5
- import { delegateToLunora } from "../handler.js";
6
- export default h3.defineEventHandler(async (event) => {
7
- const { ctx, env } = resolveCloudflare(event);
8
- const request = resolveWebRequest(h3, event);
9
- return delegateToLunora(lunoraApp, request, env, ctx);
10
- });
package/dist/types.d.mts DELETED
@@ -1,7 +0,0 @@
1
- import type { NuxtModule } from '@nuxt/schema'
2
-
3
- import type { default as Module } from './module.mjs'
4
-
5
- export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
-
7
- export { default } from './module.mjs'