@astrale-os/kernel-server 0.4.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.
Files changed (117) hide show
  1. package/dist/app/create.d.ts +48 -0
  2. package/dist/app/create.d.ts.map +1 -0
  3. package/dist/app/create.js +107 -0
  4. package/dist/app/create.js.map +1 -0
  5. package/dist/app/index.d.ts +4 -0
  6. package/dist/app/index.d.ts.map +1 -0
  7. package/dist/app/index.js +4 -0
  8. package/dist/app/index.js.map +1 -0
  9. package/dist/app/multiplexed.d.ts +53 -0
  10. package/dist/app/multiplexed.d.ts.map +1 -0
  11. package/dist/app/multiplexed.js +63 -0
  12. package/dist/app/multiplexed.js.map +1 -0
  13. package/dist/app/ws-upgrade.d.ts +35 -0
  14. package/dist/app/ws-upgrade.d.ts.map +1 -0
  15. package/dist/app/ws-upgrade.js +93 -0
  16. package/dist/app/ws-upgrade.js.map +1 -0
  17. package/dist/cors.d.ts +21 -0
  18. package/dist/cors.d.ts.map +1 -0
  19. package/dist/cors.js +17 -0
  20. package/dist/cors.js.map +1 -0
  21. package/dist/envelope/batch.d.ts +12 -0
  22. package/dist/envelope/batch.d.ts.map +1 -0
  23. package/dist/envelope/batch.js +90 -0
  24. package/dist/envelope/batch.js.map +1 -0
  25. package/dist/envelope/codec.d.ts +26 -0
  26. package/dist/envelope/codec.d.ts.map +1 -0
  27. package/dist/envelope/codec.js +52 -0
  28. package/dist/envelope/codec.js.map +1 -0
  29. package/dist/envelope/credential.d.ts +20 -0
  30. package/dist/envelope/credential.d.ts.map +1 -0
  31. package/dist/envelope/credential.js +32 -0
  32. package/dist/envelope/credential.js.map +1 -0
  33. package/dist/envelope/http.d.ts +30 -0
  34. package/dist/envelope/http.d.ts.map +1 -0
  35. package/dist/envelope/http.js +128 -0
  36. package/dist/envelope/http.js.map +1 -0
  37. package/dist/envelope/index.d.ts +6 -0
  38. package/dist/envelope/index.d.ts.map +1 -0
  39. package/dist/envelope/index.js +6 -0
  40. package/dist/envelope/index.js.map +1 -0
  41. package/dist/envelope/sse.d.ts +11 -0
  42. package/dist/envelope/sse.d.ts.map +1 -0
  43. package/dist/envelope/sse.js +73 -0
  44. package/dist/envelope/sse.js.map +1 -0
  45. package/dist/envelope/ws.d.ts +32 -0
  46. package/dist/envelope/ws.d.ts.map +1 -0
  47. package/dist/envelope/ws.js +136 -0
  48. package/dist/envelope/ws.js.map +1 -0
  49. package/dist/index.d.ts +11 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +17 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/jwks/discovery.d.ts +40 -0
  54. package/dist/jwks/discovery.d.ts.map +1 -0
  55. package/dist/jwks/discovery.js +113 -0
  56. package/dist/jwks/discovery.js.map +1 -0
  57. package/dist/jwks/index.d.ts +3 -0
  58. package/dist/jwks/index.d.ts.map +1 -0
  59. package/dist/jwks/index.js +3 -0
  60. package/dist/jwks/index.js.map +1 -0
  61. package/dist/jwks/issuers.d.ts +47 -0
  62. package/dist/jwks/issuers.d.ts.map +1 -0
  63. package/dist/jwks/issuers.js +76 -0
  64. package/dist/jwks/issuers.js.map +1 -0
  65. package/dist/jwks/keys.d.ts +44 -0
  66. package/dist/jwks/keys.d.ts.map +1 -0
  67. package/dist/jwks/keys.js +56 -0
  68. package/dist/jwks/keys.js.map +1 -0
  69. package/dist/plan/host-params.d.ts +13 -0
  70. package/dist/plan/host-params.d.ts.map +1 -0
  71. package/dist/plan/host-params.js +23 -0
  72. package/dist/plan/host-params.js.map +1 -0
  73. package/dist/plan/host.d.ts +24 -0
  74. package/dist/plan/host.d.ts.map +1 -0
  75. package/dist/plan/host.js +24 -0
  76. package/dist/plan/host.js.map +1 -0
  77. package/dist/plan/index.d.ts +4 -0
  78. package/dist/plan/index.d.ts.map +1 -0
  79. package/dist/plan/index.js +4 -0
  80. package/dist/plan/index.js.map +1 -0
  81. package/dist/plan/walk.d.ts +51 -0
  82. package/dist/plan/walk.d.ts.map +1 -0
  83. package/dist/plan/walk.js +110 -0
  84. package/dist/plan/walk.js.map +1 -0
  85. package/dist/render/binary.d.ts +19 -0
  86. package/dist/render/binary.d.ts.map +1 -0
  87. package/dist/render/binary.js +33 -0
  88. package/dist/render/binary.js.map +1 -0
  89. package/dist/render/body.d.ts +10 -0
  90. package/dist/render/body.d.ts.map +1 -0
  91. package/dist/render/body.js +17 -0
  92. package/dist/render/body.js.map +1 -0
  93. package/dist/render/index.d.ts +3 -0
  94. package/dist/render/index.d.ts.map +1 -0
  95. package/dist/render/index.js +3 -0
  96. package/dist/render/index.js.map +1 -0
  97. package/dist/routed/credential.d.ts +10 -0
  98. package/dist/routed/credential.d.ts.map +1 -0
  99. package/dist/routed/credential.js +55 -0
  100. package/dist/routed/credential.js.map +1 -0
  101. package/dist/routed/handler.d.ts +36 -0
  102. package/dist/routed/handler.d.ts.map +1 -0
  103. package/dist/routed/handler.js +119 -0
  104. package/dist/routed/handler.js.map +1 -0
  105. package/dist/routed/index.d.ts +5 -0
  106. package/dist/routed/index.d.ts.map +1 -0
  107. package/dist/routed/index.js +5 -0
  108. package/dist/routed/index.js.map +1 -0
  109. package/dist/routed/params.d.ts +40 -0
  110. package/dist/routed/params.d.ts.map +1 -0
  111. package/dist/routed/params.js +146 -0
  112. package/dist/routed/params.js.map +1 -0
  113. package/dist/routed/stream.d.ts +21 -0
  114. package/dist/routed/stream.d.ts.map +1 -0
  115. package/dist/routed/stream.js +69 -0
  116. package/dist/routed/stream.js.map +1 -0
  117. package/package.json +45 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * createKernelApp — Hono app builder for the kernel protocol.
3
+ *
4
+ * Walks a domain of MountableContract and mounts:
5
+ * - kernel HTTP envelope (POST) at each base URL
6
+ * - native HTTP routes per route binding
7
+ * - kernel WS upgrade at the same base URL when transports includes 'ws'
8
+ *
9
+ * Codecs are hardcoded (json + msgpack). Credentials for kernel HTTP are
10
+ * fixed to the Authorization header; route bindings can override via
11
+ * `route.credential`.
12
+ */
13
+ import type { KernelAPI } from '@astrale-os/kernel-api';
14
+ import type { MountableContract } from '@astrale-os/kernel-api/routed';
15
+ import type { Hono } from 'hono';
16
+ import type { CorsConfig } from '../cors';
17
+ import type { JwksKeys } from '../jwks';
18
+ import type { MountPlan, ServerHost } from '../plan';
19
+ import { type WsAdapter } from './ws-upgrade';
20
+ export type { WsAdapter };
21
+ export type KernelAppConfig = {
22
+ /** The kernel runtime handling dispatch. */
23
+ kernel: KernelAPI;
24
+ /** The domain's mountable contracts — produced by defineMethods(schema, methods). */
25
+ domain: MountableContract[];
26
+ /** Server host URL. Functions anchor against this (ambient functions mount here). */
27
+ host: ServerHost;
28
+ /** Required — OpenID Connect Discovery + JWKS endpoints. */
29
+ jwks: JwksKeys;
30
+ /** Allowed transports. 'http' is mandatory. 'ws' is opt-in. */
31
+ transports?: readonly ('http' | 'ws')[];
32
+ /** CORS configuration. Defaults to { origin: '*' }. */
33
+ cors?: CorsConfig;
34
+ /** Optional health endpoint path (defaults to '/health'; false disables). */
35
+ health?: string | false;
36
+ /** Pre-created Hono app (for attaching to an existing app). */
37
+ app?: Hono;
38
+ /**
39
+ * Runtime-specific WS adapter (from `hono/bun`, `@hono/node-ws`, `hono/deno`).
40
+ * Required when `transports` includes `'ws'`.
41
+ */
42
+ ws?: WsAdapter;
43
+ };
44
+ export declare function createKernelApp(config: KernelAppConfig): {
45
+ app: Hono;
46
+ plan: MountPlan;
47
+ };
48
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../app/create.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACtE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAMpD,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAE5D,YAAY,EAAE,SAAS,EAAE,CAAA;AAIzB,MAAM,MAAM,eAAe,GAAG;IAC5B,4CAA4C;IAC5C,MAAM,EAAE,SAAS,CAAA;IACjB,qFAAqF;IACrF,MAAM,EAAE,iBAAiB,EAAE,CAAA;IAC3B,qFAAqF;IACrF,IAAI,EAAE,UAAU,CAAA;IAChB,4DAA4D;IAC5D,IAAI,EAAE,QAAQ,CAAA;IACd,+DAA+D;IAC/D,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;IACvC,uDAAuD;IACvD,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACvB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,IAAI,CAAA;IACV;;;OAGG;IACH,EAAE,CAAC,EAAE,SAAS,CAAA;CACf,CAAA;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CA2FvF"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * createKernelApp — Hono app builder for the kernel protocol.
3
+ *
4
+ * Walks a domain of MountableContract and mounts:
5
+ * - kernel HTTP envelope (POST) at each base URL
6
+ * - native HTTP routes per route binding
7
+ * - kernel WS upgrade at the same base URL when transports includes 'ws'
8
+ *
9
+ * Codecs are hardcoded (json + msgpack). Credentials for kernel HTTP are
10
+ * fixed to the Authorization header; route bindings can override via
11
+ * `route.credential`.
12
+ */
13
+ import { Hono as HonoCtor } from 'hono';
14
+ import { createKernelDispatcher } from '../envelope/http';
15
+ import { mountJwks } from '../jwks/keys';
16
+ import { extractHostParams, walkDomain } from '../plan';
17
+ import { createRouteHandler } from '../routed/handler';
18
+ import { mountKernelWs } from './ws-upgrade';
19
+ const DEFAULT_CORS = { origin: '*' };
20
+ export function createKernelApp(config) {
21
+ const cors = config.cors ?? DEFAULT_CORS;
22
+ const app = config.app ?? new HonoCtor();
23
+ const transports = config.transports ?? ['http'];
24
+ if (!transports.includes('http')) {
25
+ throw new Error(`createKernelApp: transports must include 'http'`);
26
+ }
27
+ // 1. Walk domain → compute mount plan.
28
+ const plan = walkDomain(config.domain, config.host);
29
+ // 2. JWKS (always mounted).
30
+ mountJwks(app, { ...config.jwks, cors });
31
+ // 3. Health endpoint.
32
+ if (config.health !== false) {
33
+ app.get(config.health ?? '/health', (c) => c.json({ status: 'ok' }));
34
+ }
35
+ // 4. Kernel HTTP mounts — POST envelope at each unique base path.
36
+ // Because ambient functions all share the server's base path, and
37
+ // anchored functions re-use the same host, nearly always there's just
38
+ // one base path. For multi-domain servers with different remoteUrl
39
+ // base paths, we create one mount per path.
40
+ const hostParams = plan.hostMatcher
41
+ ? (req) => extractHostParams(plan.hostMatcher, req)
42
+ : undefined;
43
+ const dispatcher = createKernelDispatcher(cors, { hostParams });
44
+ const basePaths = new Set();
45
+ for (const basePath of plan.kernelMounts.keys()) {
46
+ basePaths.add(basePath === '' ? '/' : basePath);
47
+ }
48
+ if (basePaths.size === 0)
49
+ basePaths.add('/');
50
+ // 4a. WS upgrade (HTTP GET with Upgrade header) at each base path.
51
+ if (transports.includes('ws')) {
52
+ if (!config.ws) {
53
+ throw new Error(`createKernelApp: transports includes 'ws' but no WS adapter was passed. ` +
54
+ `Pass { ws: { upgradeWebSocket } } from your runtime's Hono adapter ` +
55
+ `(hono/bun, @hono/node-ws, hono/deno).`);
56
+ }
57
+ for (const wsPath of basePaths) {
58
+ mountKernelWs(app, wsPath, config.ws, config.kernel);
59
+ }
60
+ }
61
+ // 4b. HTTP POST envelope + OPTIONS preflight for each base path.
62
+ for (const path of basePaths) {
63
+ app.post(path, (c) => dispatcher(c.req.raw, config.kernel));
64
+ app.options(path, (c) => dispatcher(c.req.raw, config.kernel));
65
+ }
66
+ // 6. Route bindings — one Hono handler per mounted route.
67
+ for (const mountedRoute of plan.routes) {
68
+ const { route, fullPath } = mountedRoute;
69
+ const honoPath = toHonoPath(fullPath);
70
+ const handler = createRouteHandler({
71
+ method: mountedRoute.contract.ref,
72
+ route,
73
+ kernel: config.kernel,
74
+ cors,
75
+ hostParams,
76
+ auth: mountedRoute.contract.binding?.auth,
77
+ });
78
+ const mountHandler = async (c) => {
79
+ const pathParams = {};
80
+ for (const m of fullPath.matchAll(/\{(\w+)([+*])?\}/g)) {
81
+ const name = m[1];
82
+ const value = c.req.param(name);
83
+ if (value !== undefined)
84
+ pathParams[name] = decodeURIComponent(value);
85
+ }
86
+ return handler(c.req.raw, pathParams);
87
+ };
88
+ if (route.method === '*') {
89
+ app.all(honoPath, mountHandler);
90
+ }
91
+ else {
92
+ const verb = route.method.toLowerCase();
93
+ app[verb](honoPath, mountHandler);
94
+ }
95
+ // Always allow CORS preflight on routes.
96
+ app.options(honoPath, (c) => handler(c.req.raw, {}));
97
+ }
98
+ return { app, plan };
99
+ }
100
+ /** Convert spec path syntax `/tasks/{id}`, `/files/{name+}` and `/files/{name*}` to Hono syntax. */
101
+ function toHonoPath(path) {
102
+ return path
103
+ .replace(/\{(\w+)\+\}/g, ':$1{.+}')
104
+ .replace(/\{(\w+)\*\}/g, ':$1{.*}')
105
+ .replace(/\{(\w+)\}/g, ':$1');
106
+ }
107
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../app/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { createKernelApp, type KernelAppConfig, type WsAdapter } from './create';
2
+ export { createMultiplexedKernelApp, type MultiplexedKernelAppConfig, type KernelResolver, } from './multiplexed';
3
+ export { mountKernelWs } from './ws-upgrade';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../app/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAA;AAChF,OAAO,EACL,0BAA0B,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,cAAc,GACpB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { createKernelApp } from './create';
2
+ export { createMultiplexedKernelApp, } from './multiplexed';
3
+ export { mountKernelWs } from './ws-upgrade';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../app/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwC,MAAM,UAAU,CAAA;AAChF,OAAO,EACL,0BAA0B,GAG3B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * createMultiplexedKernelApp — Hono app for multi-instance kernel hosting.
3
+ *
4
+ * One HTTP server hosts many kernel instances under `/{id}/...` paths. Each
5
+ * incoming request is resolved to a kernel via the supplied `resolve()`
6
+ * function. The manager kernel (if any) is mounted at its own static prefix.
7
+ *
8
+ * Both the envelope HTTP dispatcher and the WS upgrade handler are built
9
+ * once at startup. The dispatcher takes `(req, kernel)` per request; the WS
10
+ * handler resolves its kernel once at upgrade time and pins it to the
11
+ * connection for its entire lifetime.
12
+ *
13
+ * Note: this skips per-instance domain mount-walking (no `domain` argument
14
+ * per request) — multiplexed servers dispatch all calls to the kernel layer
15
+ * regardless of binding. Anchored functions still work, since the binding is
16
+ * carried by the contract registered in the runtime.
17
+ */
18
+ import type { KernelAPI } from '@astrale-os/kernel-api';
19
+ import type { Hono } from 'hono';
20
+ import type { CorsConfig } from '../cors';
21
+ import type { JwksKeys, MultiplexedJwks } from '../jwks';
22
+ import { type WsAdapter } from './ws-upgrade';
23
+ /**
24
+ * Resolves a KernelAPI from an incoming request (multi-instance servers).
25
+ */
26
+ export type KernelResolver = (req: Request) => KernelAPI | null | Promise<KernelAPI | null>;
27
+ export type MultiplexedKernelAppConfig = {
28
+ /** Per-request kernel resolver (direct access — instance handles its own auth). */
29
+ resolve: KernelResolver;
30
+ /** Optional manager kernel hosted at a static prefix. */
31
+ manager?: {
32
+ kernel: KernelAPI;
33
+ prefix: string;
34
+ jwks: JwksKeys;
35
+ };
36
+ /** Path prefix for instance routes. Defaults to `/:id`. */
37
+ instancePrefix?: string;
38
+ /** Per-instance JWKS lookup. */
39
+ jwks: MultiplexedJwks;
40
+ cors?: CorsConfig;
41
+ health?: string | false;
42
+ app?: Hono;
43
+ /**
44
+ * Runtime-specific WS adapter (from `hono/bun`, `@hono/node-ws`, `hono/deno`).
45
+ * When provided, WS endpoints are mounted for the manager (if any) and all
46
+ * instances at `{instancePrefix}`. Omit to serve HTTP only.
47
+ */
48
+ ws?: WsAdapter;
49
+ };
50
+ export declare function createMultiplexedKernelApp(config: MultiplexedKernelAppConfig): {
51
+ app: Hono;
52
+ };
53
+ //# sourceMappingURL=multiplexed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multiplexed.d.ts","sourceRoot":"","sources":["../../app/multiplexed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAIxD,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAA;AAI5D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;AAE3F,MAAM,MAAM,0BAA0B,GAAG;IACvC,mFAAmF;IACnF,OAAO,EAAE,cAAc,CAAA;IACvB,yDAAyD;IACzD,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAA;IAC/D,2DAA2D;IAC3D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gCAAgC;IAChC,IAAI,EAAE,eAAe,CAAA;IACrB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IACvB,GAAG,CAAC,EAAE,IAAI,CAAA;IACV;;;;OAIG;IACH,EAAE,CAAC,EAAE,SAAS,CAAA;CACf,CAAA;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,GAAG;IAAE,GAAG,EAAE,IAAI,CAAA;CAAE,CA+C5F"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * createMultiplexedKernelApp — Hono app for multi-instance kernel hosting.
3
+ *
4
+ * One HTTP server hosts many kernel instances under `/{id}/...` paths. Each
5
+ * incoming request is resolved to a kernel via the supplied `resolve()`
6
+ * function. The manager kernel (if any) is mounted at its own static prefix.
7
+ *
8
+ * Both the envelope HTTP dispatcher and the WS upgrade handler are built
9
+ * once at startup. The dispatcher takes `(req, kernel)` per request; the WS
10
+ * handler resolves its kernel once at upgrade time and pins it to the
11
+ * connection for its entire lifetime.
12
+ *
13
+ * Note: this skips per-instance domain mount-walking (no `domain` argument
14
+ * per request) — multiplexed servers dispatch all calls to the kernel layer
15
+ * regardless of binding. Anchored functions still work, since the binding is
16
+ * carried by the contract registered in the runtime.
17
+ */
18
+ import { Hono as HonoCtor } from 'hono';
19
+ import { createKernelDispatcher } from '../envelope/http';
20
+ import { mountInstanceJwks, mountJwks } from '../jwks/keys';
21
+ import { mountKernelWs } from './ws-upgrade';
22
+ const DEFAULT_CORS = { origin: '*' };
23
+ export function createMultiplexedKernelApp(config) {
24
+ const cors = config.cors ?? DEFAULT_CORS;
25
+ const app = config.app ?? new HonoCtor();
26
+ const instancePrefix = config.instancePrefix ?? '/:id';
27
+ if (config.health !== false) {
28
+ app.get(typeof config.health === 'string' ? config.health : '/health', (c) => c.json({ status: 'ok' }));
29
+ }
30
+ // Single dispatcher, reused across manager + all instance kernels.
31
+ const dispatcher = createKernelDispatcher(cors);
32
+ // Manager kernel (if any) — static prefix, fixed kernel.
33
+ // POST + OPTIONS handle HTTP dispatch; GET is reserved for WS upgrade
34
+ // (matches createKernelApp's mount layout).
35
+ if (config.manager) {
36
+ const managerKernel = config.manager.kernel;
37
+ const managerPath = `${config.manager.prefix}/`;
38
+ app.post(managerPath, (c) => dispatcher(c.req.raw, managerKernel));
39
+ app.options(managerPath, (c) => dispatcher(c.req.raw, managerKernel));
40
+ mountJwks(app, { ...config.manager.jwks, cors });
41
+ if (config.ws) {
42
+ mountKernelWs(app, managerPath, config.ws, managerKernel);
43
+ }
44
+ }
45
+ // Per-instance JWKS
46
+ mountInstanceJwks(app, instancePrefix, { ...config.jwks, cors });
47
+ // Per-instance kernel envelope — kernel resolved per request.
48
+ const instancePath = `${instancePrefix}/`;
49
+ const httpDispatch = async (c) => {
50
+ const kernel = await config.resolve(c.req.raw);
51
+ if (!kernel)
52
+ return new Response('Instance not found', { status: 404 });
53
+ return dispatcher(c.req.raw, kernel);
54
+ };
55
+ app.post(instancePath, httpDispatch);
56
+ app.options(instancePath, httpDispatch);
57
+ // Per-instance WS upgrade — kernel resolved at upgrade time and pinned.
58
+ if (config.ws) {
59
+ mountKernelWs(app, instancePath, config.ws, config.resolve);
60
+ }
61
+ return { app };
62
+ }
63
+ //# sourceMappingURL=multiplexed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multiplexed.js","sourceRoot":"","sources":["../../app/multiplexed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Hono WS upgrade adapter — wires the kernel envelope WS connection class
3
+ * into a Hono app via the runtime-specific `upgradeWebSocket` shim.
4
+ *
5
+ * The adapter is supplied by the caller (`hono/bun`, `@hono/node-ws`,
6
+ * `hono/deno`) so that this module remains free of runtime imports.
7
+ *
8
+ * The kernel can be either a fixed `KernelAPI` (single-kernel servers) or a
9
+ * resolver called at upgrade time with the upgrade request (multi-instance
10
+ * servers). Once resolved, the kernel is pinned to the WS connection for its
11
+ * entire lifetime.
12
+ */
13
+ import type { KernelAPI } from '@astrale-os/kernel-api';
14
+ import type { Hono } from 'hono';
15
+ import type { UpgradeWebSocket } from 'hono/ws';
16
+ export type WsAdapter = {
17
+ upgradeWebSocket: UpgradeWebSocket;
18
+ };
19
+ /**
20
+ * Kernel source for a WS mount — either a fixed kernel or a per-request
21
+ * resolver. Resolvers may be async and return `null` to reject the upgrade.
22
+ */
23
+ export type WsKernelSource = KernelAPI | ((req: Request) => KernelAPI | null | Promise<KernelAPI | null>);
24
+ /**
25
+ * Mount the kernel WS handler at `path` on the Hono app.
26
+ *
27
+ * The handler shares the URL with the kernel HTTP handler — clients use the
28
+ * same base URL and switch transports via HTTP Upgrade negotiation.
29
+ *
30
+ * When `source` is a resolver, it is invoked once at upgrade time. A null
31
+ * result closes the socket with code 4004 (instance not found) before any
32
+ * messages are exchanged.
33
+ */
34
+ export declare function mountKernelWs(app: Hono, path: string, ws: WsAdapter, source: WsKernelSource): void;
35
+ //# sourceMappingURL=ws-upgrade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-upgrade.d.ts","sourceRoot":"","sources":["../../app/ws-upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,SAAS,CAAA;AAK1D,MAAM,MAAM,SAAS,GAAG;IACtB,gBAAgB,EAAE,gBAAgB,CAAA;CACnC,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAA;AAuBpE;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,cAAc,GACrB,IAAI,CAkDN"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Hono WS upgrade adapter — wires the kernel envelope WS connection class
3
+ * into a Hono app via the runtime-specific `upgradeWebSocket` shim.
4
+ *
5
+ * The adapter is supplied by the caller (`hono/bun`, `@hono/node-ws`,
6
+ * `hono/deno`) so that this module remains free of runtime imports.
7
+ *
8
+ * The kernel can be either a fixed `KernelAPI` (single-kernel servers) or a
9
+ * resolver called at upgrade time with the upgrade request (multi-instance
10
+ * servers). Once resolved, the kernel is pinned to the WS connection for its
11
+ * entire lifetime.
12
+ */
13
+ import { negotiateWsCodec } from '../envelope/codec';
14
+ import { KernelWsConnection } from '../envelope/ws';
15
+ function adaptHonoWs(ws) {
16
+ const raw = ws.raw;
17
+ return {
18
+ send(data) {
19
+ ws.send(data);
20
+ },
21
+ close(code, reason) {
22
+ ws.close(code, reason);
23
+ },
24
+ get readyState() {
25
+ return raw?.readyState ?? ws.readyState;
26
+ },
27
+ };
28
+ }
29
+ function isResolver(source) {
30
+ return typeof source === 'function';
31
+ }
32
+ /**
33
+ * Mount the kernel WS handler at `path` on the Hono app.
34
+ *
35
+ * The handler shares the URL with the kernel HTTP handler — clients use the
36
+ * same base URL and switch transports via HTTP Upgrade negotiation.
37
+ *
38
+ * When `source` is a resolver, it is invoked once at upgrade time. A null
39
+ * result closes the socket with code 4004 (instance not found) before any
40
+ * messages are exchanged.
41
+ */
42
+ export function mountKernelWs(app, path, ws, source) {
43
+ const route = ws.upgradeWebSocket((c) => {
44
+ const upgradeRequest = c.req.raw;
45
+ const codec = negotiateWsCodec(upgradeRequest);
46
+ let conn = null;
47
+ return {
48
+ async onOpen(_evt, wsCtx) {
49
+ if (!codec) {
50
+ wsCtx.close(4000, 'Unsupported codec');
51
+ return;
52
+ }
53
+ let kernel;
54
+ try {
55
+ kernel = isResolver(source) ? await source(upgradeRequest) : source;
56
+ }
57
+ catch (err) {
58
+ // A mount-time failure (e.g. a child kernel boot throwing) must not
59
+ // escape: this `onOpen` is async but the host WS adapter wraps it in
60
+ // a *synchronous* try/catch that cannot observe an async rejection,
61
+ // so an uncaught throw here becomes a process-killing unhandled
62
+ // rejection. Reject the upgrade by closing the socket instead — and
63
+ // log the error so a programmer bug (e.g. an unrelated TypeError
64
+ // bubbling up from the resolver) isn't silently masked as a benign
65
+ // mount fail.
66
+ // eslint-disable-next-line no-console -- diagnostic from boundary handler
67
+ console.error('[ws-upgrade] mount failed (socket closed 4005):', err);
68
+ wsCtx.close(4005, 'mount failed');
69
+ return;
70
+ }
71
+ if (!kernel) {
72
+ wsCtx.close(4004, 'Instance not found');
73
+ return;
74
+ }
75
+ conn = new KernelWsConnection(adaptHonoWs(wsCtx), codec, kernel);
76
+ conn.start();
77
+ },
78
+ onMessage(evt) {
79
+ conn?.handleMessage(evt.data);
80
+ },
81
+ onClose() {
82
+ conn?.handleClose();
83
+ conn = null;
84
+ },
85
+ onError(evt) {
86
+ const msg = evt instanceof ErrorEvent ? evt.message : `WebSocket error: ${evt.type}`;
87
+ conn?.handleError(new Error(msg));
88
+ },
89
+ };
90
+ });
91
+ app.get(path, route);
92
+ }
93
+ //# sourceMappingURL=ws-upgrade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-upgrade.js","sourceRoot":"","sources":["../../app/ws-upgrade.ts"],"names":[],"mappings":"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"}
package/dist/cors.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * CORS configuration and header builder.
3
+ *
4
+ * Cross-cutting helper consumed by every protocol handler. The shape mirrors
5
+ * the standard `Access-Control-*` headers; multi-origin matching belongs in
6
+ * framework-level middleware (e.g. Hono's `cors()`), not here.
7
+ */
8
+ export type CorsConfig = {
9
+ /**
10
+ * Allowed origin. Use '*' for any, or a single origin string.
11
+ *
12
+ * Note: HTTP `Access-Control-Allow-Origin` does not support multiple
13
+ * comma-separated origins. For multi-origin, implement per-request
14
+ * matching at the framework middleware level (e.g., Hono cors()).
15
+ */
16
+ origin: string;
17
+ methods?: string[];
18
+ headers?: string[];
19
+ };
20
+ export declare function buildCorsHeaders(cors: CorsConfig): Record<string, string>;
21
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../cors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQzE"}
package/dist/cors.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * CORS configuration and header builder.
3
+ *
4
+ * Cross-cutting helper consumed by every protocol handler. The shape mirrors
5
+ * the standard `Access-Control-*` headers; multi-origin matching belongs in
6
+ * framework-level middleware (e.g. Hono's `cors()`), not here.
7
+ */
8
+ export function buildCorsHeaders(cors) {
9
+ const origin = cors.origin;
10
+ return {
11
+ 'access-control-allow-origin': origin,
12
+ 'access-control-allow-methods': (cors.methods ?? ['POST', 'OPTIONS']).join(', '),
13
+ 'access-control-allow-headers': (cors.headers ?? ['content-type', 'authorization']).join(', '),
14
+ 'access-control-expose-headers': 'x-binary-result',
15
+ };
16
+ }
17
+ //# sourceMappingURL=cors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../cors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,MAAM,UAAU,gBAAgB,CAAC,IAAgB;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;IAC1B,OAAO;QACL,6BAA6B,EAAE,MAAM;QACrC,8BAA8B,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAChF,8BAA8B,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9F,+BAA+B,EAAE,iBAAiB;KACnD,CAAA;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Kernel envelope batch processing.
3
+ *
4
+ * A batch is an array of kernel envelope requests delivered in a single HTTP
5
+ * POST. Each is dispatched independently and the encoded responses are
6
+ * collected into an array. Notifications are dropped from the response;
7
+ * streams and binary results are rejected (those need their own connection).
8
+ */
9
+ import type { KernelAPI } from '@astrale-os/kernel-api';
10
+ import { type CodecEntry } from './codec';
11
+ export declare function handleBatch(raw: unknown[], kernel: KernelAPI, codecEntry: CodecEntry, req: Request, corsHeaders: Record<string, string>): Promise<Response>;
12
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../envelope/batch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAsB,MAAM,wBAAwB,CAAA;AAa3E,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAGzC,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,EAAE,EACd,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,OAAO,EACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,QAAQ,CAAC,CAmFnB"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Kernel envelope batch processing.
3
+ *
4
+ * A batch is an array of kernel envelope requests delivered in a single HTTP
5
+ * POST. Each is dispatched independently and the encoded responses are
6
+ * collected into an array. Notifications are dropped from the response;
7
+ * streams and binary results are rejected (those need their own connection).
8
+ */
9
+ import { KERNEL_ERROR_CODES, decodeKernelRequest, dispatch, encodeKernelError, encodeKernelRedirect, encodeKernelResponse, isBinaryResult, } from '@astrale-os/kernel-api';
10
+ import { toBody } from '../render';
11
+ import {} from './codec';
12
+ import { extractCredential } from './credential';
13
+ export async function handleBatch(raw, kernel, codecEntry, req, corsHeaders) {
14
+ if (raw.length === 0) {
15
+ return errorResponse(codecEntry, { code: KERNEL_ERROR_CODES.INVALID_REQUEST, message: 'Empty batch' }, corsHeaders, 400);
16
+ }
17
+ const auth = await extractCredential(req);
18
+ const results = Array.from({ length: raw.length }, () => null);
19
+ await Promise.all(raw.map(async (item, i) => {
20
+ let request;
21
+ try {
22
+ request = decodeKernelRequest(item);
23
+ }
24
+ catch (e) {
25
+ results[i] = encodeKernelError(null, {
26
+ code: KERNEL_ERROR_CODES.INVALID_REQUEST,
27
+ message: e instanceof Error ? e.message : 'Invalid request',
28
+ });
29
+ return;
30
+ }
31
+ const isAck = request.id === undefined;
32
+ let cred;
33
+ if (request.creds !== undefined) {
34
+ cred = request.creds;
35
+ }
36
+ else if (!auth.ok) {
37
+ results[i] = encodeKernelError(request.id ?? null, {
38
+ code: KERNEL_ERROR_CODES.AUTH_INVALID,
39
+ message: `Unsupported Authorization scheme: ${auth.scheme}`,
40
+ });
41
+ return;
42
+ }
43
+ else {
44
+ cred = auth.credential;
45
+ }
46
+ const res = await dispatch(request.method, request.params, cred, kernel, isAck ? { ack: true } : { id: request.id, isStream: false });
47
+ if (res.kind === 'ack')
48
+ return;
49
+ if (res.kind === 'stream') {
50
+ results[i] = encodeKernelError(request.id, {
51
+ code: KERNEL_ERROR_CODES.INVALID_REQUEST,
52
+ message: 'Streaming is not supported inside a batch',
53
+ });
54
+ return;
55
+ }
56
+ if (res.kind === 'redirect') {
57
+ results[i] = encodeKernelRedirect(res.id, res.redirection);
58
+ return;
59
+ }
60
+ if (res.kind === 'success') {
61
+ if (isBinaryResult(res.data)) {
62
+ results[i] = encodeKernelError(res.id, {
63
+ code: KERNEL_ERROR_CODES.INVALID_REQUEST,
64
+ message: 'Binary result is not supported inside a batch',
65
+ });
66
+ return;
67
+ }
68
+ results[i] = encodeKernelResponse(res.id, res.data);
69
+ return;
70
+ }
71
+ results[i] = encodeKernelError(res.id, res.error);
72
+ }));
73
+ const encoded = results.filter((r) => r !== null);
74
+ if (encoded.length === 0) {
75
+ return new Response(null, { status: 204, headers: corsHeaders });
76
+ }
77
+ const bytes = codecEntry.codec.encode(encoded);
78
+ return new Response(toBody(bytes), {
79
+ status: 200,
80
+ headers: { ...corsHeaders, 'content-type': codecEntry.kernelType },
81
+ });
82
+ }
83
+ function errorResponse(codecEntry, error, corsHeaders, httpStatus) {
84
+ const bytes = codecEntry.codec.encode(encodeKernelError(null, error));
85
+ return new Response(toBody(bytes), {
86
+ status: httpStatus,
87
+ headers: { ...corsHeaders, 'content-type': codecEntry.kernelType },
88
+ });
89
+ }
90
+ //# sourceMappingURL=batch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.js","sourceRoot":"","sources":["../../envelope/batch.ts"],"names":[],"mappings":"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"}