@evjs/runtime 0.0.1-alpha.1
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 +39 -0
- package/esm/client/create-app.d.ts +48 -0
- package/esm/client/create-app.d.ts.map +1 -0
- package/esm/client/create-app.js +39 -0
- package/esm/client/create-app.js.map +1 -0
- package/esm/client/index.d.ts +9 -0
- package/esm/client/index.d.ts.map +1 -0
- package/esm/client/index.js +7 -0
- package/esm/client/index.js.map +1 -0
- package/esm/client/route.d.ts +9 -0
- package/esm/client/route.d.ts.map +1 -0
- package/esm/client/route.js +8 -0
- package/esm/client/route.js.map +1 -0
- package/esm/client/rpc.d.ts +29 -0
- package/esm/client/rpc.d.ts.map +1 -0
- package/esm/client/rpc.js +45 -0
- package/esm/client/rpc.js.map +1 -0
- package/esm/index.d.ts +9 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +9 -0
- package/esm/index.js.map +1 -0
- package/esm/server/app.d.ts +25 -0
- package/esm/server/app.d.ts.map +1 -0
- package/esm/server/app.js +29 -0
- package/esm/server/app.js.map +1 -0
- package/esm/server/handler.d.ts +29 -0
- package/esm/server/handler.d.ts.map +1 -0
- package/esm/server/handler.js +48 -0
- package/esm/server/handler.js.map +1 -0
- package/esm/server/index.d.ts +7 -0
- package/esm/server/index.d.ts.map +1 -0
- package/esm/server/index.js +6 -0
- package/esm/server/index.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @evjs/runtime
|
|
2
|
+
|
|
3
|
+
Core runtime for the **ev** framework. It provides isomorphic utilities for client-side routing, state management, and server-side RPC handling via Hono.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @evjs/runtime
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- **`createApp`**: A unified factory to bootstrap TanStack Router + Query.
|
|
14
|
+
- **Routing**: Re-exports the full power of `@tanstack/react-router`.
|
|
15
|
+
- **RPC**: Internal logic for calling `"use server"` functions from the client.
|
|
16
|
+
- **Hono Server**: `createServer()` starts a Hono-based API server for RPC.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Client Entry
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { createApp, createRootRoute } from "@evjs/runtime";
|
|
24
|
+
|
|
25
|
+
const rootRoute = createRootRoute({ component: Root });
|
|
26
|
+
const app = createApp({ routeTree: rootRoute });
|
|
27
|
+
|
|
28
|
+
app.render("#app");
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Server Entry
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { createServer } from "@evjs/runtime/server";
|
|
35
|
+
|
|
36
|
+
createServer({ port: 3001 });
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The Hono server mounts an RPC endpoint at `/api/rpc` (configurable via `rpcEndpoint`). Server functions are auto-discovered by `EvWebpackPlugin` — no manual imports needed.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { QueryClient, type QueryClientConfig } from "@tanstack/react-query";
|
|
2
|
+
import type { AnyRoute, AnyRouter } from "@tanstack/react-router";
|
|
3
|
+
/**
|
|
4
|
+
* Options for creating an ev application.
|
|
5
|
+
*/
|
|
6
|
+
export interface CreateAppOptions<TRouteTree extends AnyRoute> {
|
|
7
|
+
/** The root route tree produced by createRootRoute and addChildren. */
|
|
8
|
+
routeTree: TRouteTree;
|
|
9
|
+
/**
|
|
10
|
+
* Optional configuration for the TanStack Router.
|
|
11
|
+
*/
|
|
12
|
+
routerOptions?: Omit<Parameters<typeof import("@tanstack/react-router").createRouter>[0], "routeTree">;
|
|
13
|
+
/**
|
|
14
|
+
* Optional configuration for the TanStack Query Client.
|
|
15
|
+
*/
|
|
16
|
+
queryClientConfig?: QueryClientConfig;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* An initialized ev application instance.
|
|
20
|
+
*/
|
|
21
|
+
export interface App {
|
|
22
|
+
/** The TanStack Router instance. */
|
|
23
|
+
router: AnyRouter;
|
|
24
|
+
/** The TanStack Query Client instance. */
|
|
25
|
+
queryClient: QueryClient;
|
|
26
|
+
/**
|
|
27
|
+
* Mount the application into the DOM.
|
|
28
|
+
* @param container - A CSS selector string or an HTMLElement.
|
|
29
|
+
*/
|
|
30
|
+
render(container: string | HTMLElement): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create a new ev application instance.
|
|
34
|
+
*
|
|
35
|
+
* This function initializes the router and query client and returns
|
|
36
|
+
* an app object that can be mounted into the DOM.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Application configuration options.
|
|
39
|
+
* @returns An initialized App instance.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* const app = createApp({ routeTree });
|
|
44
|
+
* app.render("#app");
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function createApp<TRouteTree extends AnyRoute>(options: CreateAppOptions<TRouteTree>): App;
|
|
48
|
+
//# sourceMappingURL=create-app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-app.d.ts","sourceRoot":"","sources":["../../src/client/create-app.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,iBAAiB,EAEvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIlE;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,UAAU,SAAS,QAAQ;IAC3D,uEAAuE;IACvE,SAAS,EAAE,UAAU,CAAC;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,IAAI,CAClB,UAAU,CAAC,cAAc,wBAAwB,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,EACnE,WAAW,CACZ,CAAC;IACF;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,GAAG;IAClB,oCAAoC;IACpC,MAAM,EAAE,SAAS,CAAC;IAClB,0CAA0C;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,UAAU,SAAS,QAAQ,EACnD,OAAO,EAAE,gBAAgB,CAAC,UAAU,CAAC,GACpC,GAAG,CA+BL"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { QueryClient, QueryClientProvider, } from "@tanstack/react-query";
|
|
3
|
+
import { createRouter, RouterProvider } from "@tanstack/react-router";
|
|
4
|
+
import { createRoot } from "react-dom/client";
|
|
5
|
+
/**
|
|
6
|
+
* Create a new ev application instance.
|
|
7
|
+
*
|
|
8
|
+
* This function initializes the router and query client and returns
|
|
9
|
+
* an app object that can be mounted into the DOM.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Application configuration options.
|
|
12
|
+
* @returns An initialized App instance.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* const app = createApp({ routeTree });
|
|
17
|
+
* app.render("#app");
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function createApp(options) {
|
|
21
|
+
const { routeTree, routerOptions, queryClientConfig } = options;
|
|
22
|
+
const queryClient = new QueryClient(queryClientConfig);
|
|
23
|
+
const router = createRouter({
|
|
24
|
+
...routerOptions,
|
|
25
|
+
routeTree,
|
|
26
|
+
});
|
|
27
|
+
function render(container) {
|
|
28
|
+
const el = typeof container === "string"
|
|
29
|
+
? document.querySelector(container)
|
|
30
|
+
: container;
|
|
31
|
+
if (!el) {
|
|
32
|
+
throw new Error(`[ev] Could not find container element: ${String(container)}`);
|
|
33
|
+
}
|
|
34
|
+
const root = createRoot(el);
|
|
35
|
+
root.render(_jsx(QueryClientProvider, { client: queryClient, children: _jsx(RouterProvider, { router: router }) }));
|
|
36
|
+
}
|
|
37
|
+
return { router, queryClient, render };
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=create-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-app.js","sourceRoot":"","sources":["../../src/client/create-app.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,WAAW,EAEX,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAoC9C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CACvB,OAAqC;IAErC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAEhE,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAG,YAAY,CAAC;QAC1B,GAAG,aAAa;QAChB,SAAS;KAC4B,CAAC,CAAC;IAEzC,SAAS,MAAM,CAAC,SAA+B;QAC7C,MAAM,EAAE,GACN,OAAO,SAAS,KAAK,QAAQ;YAC3B,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAc,SAAS,CAAC;YAChD,CAAC,CAAC,SAAS,CAAC;QAEhB,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,KAAK,CACb,0CAA0C,MAAM,CAAC,SAAS,CAAC,EAAE,CAC9D,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CACT,KAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,YACtC,KAAC,cAAc,IAAC,MAAM,EAAE,MAAM,GAAI,GACd,CACvB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side runtime utilities.
|
|
3
|
+
*/
|
|
4
|
+
export type { App, CreateAppOptions } from "./create-app";
|
|
5
|
+
export { createApp } from "./create-app";
|
|
6
|
+
export * from "./route";
|
|
7
|
+
export { __ev_rpc, configureRpc } from "./rpc";
|
|
8
|
+
export type { RpcOptions } from "./rpc";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing utilities re-exported from @tanstack/react-router.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core primitives for building file-based
|
|
5
|
+
* or code-based routing in the ev framework.
|
|
6
|
+
*/
|
|
7
|
+
export type { AnyRootRoute, AnyRoute, AnyRouteMatch, AnyRouter, ErrorComponentProps, ErrorRouteComponent, LinkOptions, LinkProps, NavigateOptions, NotFoundError, NotFoundRouteComponent, NotFoundRouteProps, RegisteredRouter, RouteComponent, RouteMatch, RouterOptions, RouterState, SearchSchemaInput, } from "@tanstack/react-router";
|
|
8
|
+
export { CatchBoundary, CatchNotFound, createLink, createRootRoute, createRootRouteWithContext, createRoute, createRouteMask, createRouter, DefaultGlobalNotFound, ErrorComponent, getRouteApi, isNotFound, isRedirect, Link, lazyRouteComponent, linkOptions, Navigate, notFound, Outlet, RouterProvider, redirect, useBlocker, useCanGoBack, useLoaderData, useLoaderDeps, useLocation, useMatch, useMatchRoute, useNavigate, useParams, useRouteContext, useRouter, useRouterState, useSearch, } from "@tanstack/react-router";
|
|
9
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/client/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,eAAe,EACf,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,aAAa,EACb,WAAW,EACX,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,eAAe,EACf,0BAA0B,EAC1B,WAAW,EACX,eAAe,EACf,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,UAAU,EACV,UAAU,EACV,IAAI,EACJ,kBAAkB,EAClB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,cAAc,EACd,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,EACX,SAAS,EACT,eAAe,EACf,SAAS,EACT,cAAc,EACd,SAAS,GACV,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing utilities re-exported from @tanstack/react-router.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the core primitives for building file-based
|
|
5
|
+
* or code-based routing in the ev framework.
|
|
6
|
+
*/
|
|
7
|
+
export { CatchBoundary, CatchNotFound, createLink, createRootRoute, createRootRouteWithContext, createRoute, createRouteMask, createRouter, DefaultGlobalNotFound, ErrorComponent, getRouteApi, isNotFound, isRedirect, Link, lazyRouteComponent, linkOptions, Navigate, notFound, Outlet, RouterProvider, redirect, useBlocker, useCanGoBack, useLoaderData, useLoaderDeps, useLocation, useMatch, useMatchRoute, useNavigate, useParams, useRouteContext, useRouter, useRouterState, useSearch, } from "@tanstack/react-router";
|
|
8
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/client/route.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,OAAO,EACL,aAAa,EACb,aAAa,EACb,UAAU,EACV,eAAe,EACf,0BAA0B,EAC1B,WAAW,EACX,eAAe,EACf,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,UAAU,EACV,UAAU,EACV,IAAI,EACJ,kBAAkB,EAClB,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,cAAc,EACd,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,EACX,SAAS,EACT,eAAe,EACf,SAAS,EACT,cAAc,EACd,SAAS,GACV,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side RPC helper for calling server functions.
|
|
3
|
+
*
|
|
4
|
+
* When the Webpack loader transforms a `"use server"` module for the client
|
|
5
|
+
* bundle, each exported function is replaced with a stub that calls
|
|
6
|
+
* `__ev_rpc(fnId, args)`. This module provides that helper.
|
|
7
|
+
*/
|
|
8
|
+
export interface RpcOptions {
|
|
9
|
+
/** Base URL for the RPC endpoint. Defaults to the current origin. */
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
/** Path prefix for the RPC endpoint. Defaults to `/api/rpc`. */
|
|
12
|
+
endpoint?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Configure the RPC client. Call once at app startup if you need to
|
|
16
|
+
* customise the endpoint URL.
|
|
17
|
+
*/
|
|
18
|
+
export declare function configureRpc(options: RpcOptions): void;
|
|
19
|
+
/**
|
|
20
|
+
* Call a server function by its unique ID.
|
|
21
|
+
*
|
|
22
|
+
* @param fnId - The unique identifier assigned to the server function by the
|
|
23
|
+
* Webpack loader (e.g. `"user_server_getUser"`).
|
|
24
|
+
* @param args - The arguments to pass to the server function. Must be
|
|
25
|
+
* JSON-serializable.
|
|
26
|
+
* @returns A promise that resolves with the server function's return value.
|
|
27
|
+
*/
|
|
28
|
+
export declare function __ev_rpc(fnId: string, args: unknown[]): Promise<unknown>;
|
|
29
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/client/rpc.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAEtD;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAqB9E"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side RPC helper for calling server functions.
|
|
3
|
+
*
|
|
4
|
+
* When the Webpack loader transforms a `"use server"` module for the client
|
|
5
|
+
* bundle, each exported function is replaced with a stub that calls
|
|
6
|
+
* `__ev_rpc(fnId, args)`. This module provides that helper.
|
|
7
|
+
*/
|
|
8
|
+
let _options = {
|
|
9
|
+
baseUrl: "",
|
|
10
|
+
endpoint: "/api/rpc",
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Configure the RPC client. Call once at app startup if you need to
|
|
14
|
+
* customise the endpoint URL.
|
|
15
|
+
*/
|
|
16
|
+
export function configureRpc(options) {
|
|
17
|
+
_options = { ..._options, ...options };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Call a server function by its unique ID.
|
|
21
|
+
*
|
|
22
|
+
* @param fnId - The unique identifier assigned to the server function by the
|
|
23
|
+
* Webpack loader (e.g. `"user_server_getUser"`).
|
|
24
|
+
* @param args - The arguments to pass to the server function. Must be
|
|
25
|
+
* JSON-serializable.
|
|
26
|
+
* @returns A promise that resolves with the server function's return value.
|
|
27
|
+
*/
|
|
28
|
+
export async function __ev_rpc(fnId, args) {
|
|
29
|
+
const url = `${_options.baseUrl}${_options.endpoint}`;
|
|
30
|
+
const res = await fetch(url, {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: { "Content-Type": "application/json" },
|
|
33
|
+
body: JSON.stringify({ fnId, args }),
|
|
34
|
+
});
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
const text = await res.text().catch(() => res.statusText);
|
|
37
|
+
throw new Error(`[ev/rpc] Server function "${fnId}" failed (${res.status}): ${text}`);
|
|
38
|
+
}
|
|
39
|
+
const payload = await res.json();
|
|
40
|
+
if (payload.error) {
|
|
41
|
+
throw new Error(`[ev/rpc] Server function "${fnId}" threw: ${payload.error}`);
|
|
42
|
+
}
|
|
43
|
+
return payload.result;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=rpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/client/rpc.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,IAAI,QAAQ,GAAyB;IACnC,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,UAAU;CACrB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAmB;IAC9C,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAe;IAC1D,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;IAEtD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KACrC,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,aAAa,GAAG,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAEjC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,YAAY,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC"}
|
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @evjs/runtime
|
|
3
|
+
*
|
|
4
|
+
* Core runtime for the ev framework, providing isomorphic utilities
|
|
5
|
+
* for client-side routing, state management, and server-side RPC handling.
|
|
6
|
+
*/
|
|
7
|
+
export * as client from "./client/index";
|
|
8
|
+
export * as server from "./server/index";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC"}
|
package/esm/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @evjs/runtime
|
|
3
|
+
*
|
|
4
|
+
* Core runtime for the ev framework, providing isomorphic utilities
|
|
5
|
+
* for client-side routing, state management, and server-side RPC handling.
|
|
6
|
+
*/
|
|
7
|
+
export * as client from "./client/index";
|
|
8
|
+
export * as server from "./server/index";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server application factory.
|
|
3
|
+
*
|
|
4
|
+
* Creates a Hono app with RPC middleware and starts a Node.js HTTP
|
|
5
|
+
* server via @hono/node-server.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from "hono";
|
|
8
|
+
/** Options for createServer. */
|
|
9
|
+
export interface CreateServerOptions {
|
|
10
|
+
/** Port to listen on. Defaults to 3001. */
|
|
11
|
+
port?: number;
|
|
12
|
+
/** RPC endpoint path. Defaults to "/api/rpc". */
|
|
13
|
+
rpcEndpoint?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create and start an ev API server.
|
|
17
|
+
*
|
|
18
|
+
* Mounts the RPC middleware at `/api/rpc` and starts listening.
|
|
19
|
+
* In Stage 3, this will be extended with SSR middleware.
|
|
20
|
+
*
|
|
21
|
+
* @param options - Server configuration.
|
|
22
|
+
* @returns The Hono app instance (for extension or testing).
|
|
23
|
+
*/
|
|
24
|
+
export declare function createServer(options?: CreateServerOptions): Hono;
|
|
25
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,gCAAgC;AAChC,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAahE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server application factory.
|
|
3
|
+
*
|
|
4
|
+
* Creates a Hono app with RPC middleware and starts a Node.js HTTP
|
|
5
|
+
* server via @hono/node-server.
|
|
6
|
+
*/
|
|
7
|
+
import { Hono } from "hono";
|
|
8
|
+
import { serve } from "@hono/node-server";
|
|
9
|
+
import { createRpcMiddleware } from "./handler";
|
|
10
|
+
/**
|
|
11
|
+
* Create and start an ev API server.
|
|
12
|
+
*
|
|
13
|
+
* Mounts the RPC middleware at `/api/rpc` and starts listening.
|
|
14
|
+
* In Stage 3, this will be extended with SSR middleware.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Server configuration.
|
|
17
|
+
* @returns The Hono app instance (for extension or testing).
|
|
18
|
+
*/
|
|
19
|
+
export function createServer(options) {
|
|
20
|
+
const { port = 3001, rpcEndpoint = "/api/rpc" } = options ?? {};
|
|
21
|
+
const app = new Hono();
|
|
22
|
+
// Mount RPC endpoint
|
|
23
|
+
app.route(rpcEndpoint, createRpcMiddleware());
|
|
24
|
+
serve({ fetch: app.fetch, port }, (info) => {
|
|
25
|
+
console.log(`ev server running at http://localhost:${info.port}`);
|
|
26
|
+
});
|
|
27
|
+
return app;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/server/app.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAUhD;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,OAA6B;IACxD,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,WAAW,GAAG,UAAU,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAEhE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,qBAAqB;IACrB,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAE9C,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;QACzC,OAAO,CAAC,GAAG,CAAC,yCAAyC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono middleware for dispatching RPC calls to registered server functions.
|
|
3
|
+
*
|
|
4
|
+
* The Webpack server-fn-loader calls `registerServerFn()` at module load
|
|
5
|
+
* time, populating the registry. This middleware handles incoming
|
|
6
|
+
* `POST /api/rpc` requests and dispatches them to the correct function.
|
|
7
|
+
*/
|
|
8
|
+
import { Hono } from "hono";
|
|
9
|
+
/** A registered server function. */
|
|
10
|
+
type ServerFn = (...args: unknown[]) => Promise<unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Register a server function so it can be invoked via RPC.
|
|
13
|
+
* Called automatically by the Webpack-transformed server bundles at load time.
|
|
14
|
+
*
|
|
15
|
+
* @param fnId - The unique ID for this function.
|
|
16
|
+
* @param fn - The actual function implementation.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerServerFn(fnId: string, fn: ServerFn): void;
|
|
19
|
+
/**
|
|
20
|
+
* Create a Hono sub-app that handles RPC requests.
|
|
21
|
+
*
|
|
22
|
+
* Expects `POST /` with JSON body `{ fnId: string, args: unknown[] }`.
|
|
23
|
+
* Responds with `{ result: unknown }` on success or `{ error: string }` on failure.
|
|
24
|
+
*
|
|
25
|
+
* @returns A Hono app to be mounted at the desired path (e.g. `/api/rpc`).
|
|
26
|
+
*/
|
|
27
|
+
export declare function createRpcMiddleware(): Hono;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/server/handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,oCAAoC;AACpC,KAAK,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAKzD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAEjE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAwB1C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hono middleware for dispatching RPC calls to registered server functions.
|
|
3
|
+
*
|
|
4
|
+
* The Webpack server-fn-loader calls `registerServerFn()` at module load
|
|
5
|
+
* time, populating the registry. This middleware handles incoming
|
|
6
|
+
* `POST /api/rpc` requests and dispatches them to the correct function.
|
|
7
|
+
*/
|
|
8
|
+
import { Hono } from "hono";
|
|
9
|
+
/** Internal registry mapping function IDs to implementations. */
|
|
10
|
+
const registry = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Register a server function so it can be invoked via RPC.
|
|
13
|
+
* Called automatically by the Webpack-transformed server bundles at load time.
|
|
14
|
+
*
|
|
15
|
+
* @param fnId - The unique ID for this function.
|
|
16
|
+
* @param fn - The actual function implementation.
|
|
17
|
+
*/
|
|
18
|
+
export function registerServerFn(fnId, fn) {
|
|
19
|
+
registry.set(fnId, fn);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a Hono sub-app that handles RPC requests.
|
|
23
|
+
*
|
|
24
|
+
* Expects `POST /` with JSON body `{ fnId: string, args: unknown[] }`.
|
|
25
|
+
* Responds with `{ result: unknown }` on success or `{ error: string }` on failure.
|
|
26
|
+
*
|
|
27
|
+
* @returns A Hono app to be mounted at the desired path (e.g. `/api/rpc`).
|
|
28
|
+
*/
|
|
29
|
+
export function createRpcMiddleware() {
|
|
30
|
+
const rpc = new Hono();
|
|
31
|
+
rpc.post("/", async (c) => {
|
|
32
|
+
const { fnId, args } = await c.req.json();
|
|
33
|
+
const fn = registry.get(fnId);
|
|
34
|
+
if (!fn) {
|
|
35
|
+
return c.json({ error: `Server function "${fnId}" not found` }, 404);
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const result = await fn(...(args ?? []));
|
|
39
|
+
return c.json({ result });
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
43
|
+
return c.json({ error: message }, 500);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return rpc;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../src/server/handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAK5B,iEAAiE;AACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,EAAY;IACzD,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAGnC,CAAC;QAEL,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,IAAI,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YACzC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,YAAY,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@evjs/runtime",
|
|
3
|
+
"version": "0.0.1-alpha.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@hono/node-server": "^1.19.11",
|
|
7
|
+
"@tanstack/react-query": "^5.90.21",
|
|
8
|
+
"@tanstack/react-router": "^1.163.3",
|
|
9
|
+
"hono": "^4.12.5"
|
|
10
|
+
},
|
|
11
|
+
"peerDependencies": {
|
|
12
|
+
"react": ">=18.0.0",
|
|
13
|
+
"react-dom": ">=18.0.0"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.7.3"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/evjs/evjs#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/evjs/evjs/issues"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/evjs/evjs.git"
|
|
25
|
+
},
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"author": "xusd320",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./esm/index.d.ts",
|
|
32
|
+
"import": "./esm/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./client": {
|
|
35
|
+
"types": "./esm/client/index.d.ts",
|
|
36
|
+
"import": "./esm/client/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./server": {
|
|
39
|
+
"types": "./esm/server/index.d.ts",
|
|
40
|
+
"import": "./esm/server/index.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc",
|
|
45
|
+
"check-types": "tsc --noEmit",
|
|
46
|
+
"prepublishOnly": "npm run build"
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"esm"
|
|
50
|
+
]
|
|
51
|
+
}
|