@fougere/transport-http 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/client.d.ts +22 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +96 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonrpc.d.ts +35 -0
- package/dist/jsonrpc.d.ts.map +1 -0
- package/dist/jsonrpc.js +15 -0
- package/dist/jsonrpc.js.map +1 -0
- package/dist/serve.d.ts +28 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +66 -0
- package/dist/serve.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +50 -0
- package/dist/server.js.map +1 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fougere contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @fougere/transport-http
|
|
2
|
+
> The call contract, on the wire
|
|
3
|
+
JSON-RPC 2.0, one route: `POST /_fougere/call`. `serve()` hosts a frond in its own
|
|
4
|
+
process; `createHttpTransport()` calls it from another.
|
|
5
|
+
|
|
6
|
+
No RPC without travel: in-process, a call stays a direct memory execution.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @fougere/transport-http
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
Part of [Fougere](https://github.com/chok/fougere) — one schema, a gradient from
|
|
16
|
+
monolith to distributed, the same user code.
|
|
17
|
+
Reference documentation: [the site](https://chok.github.io/fougere/) (en/fr).
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sending half — frame the call, POST it, unframe the result.
|
|
3
|
+
*
|
|
4
|
+
* Failure vocabulary is FougereError only: a transport failure becomes a
|
|
5
|
+
* typed error (SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, BAD_GATEWAY), an
|
|
6
|
+
* application failure comes back as the FougereError the façade threw.
|
|
7
|
+
*/
|
|
8
|
+
import { type Transport, type FrondCall, type InvocationContext } from '@fougere/core/contract';
|
|
9
|
+
import type { RpcRequest, RpcResponse } from './jsonrpc.js';
|
|
10
|
+
export type { RpcRequest, RpcResponse } from './jsonrpc.js';
|
|
11
|
+
/** Frame a call as a JSON-RPC request. */
|
|
12
|
+
export declare function frameCall(call: FrondCall, invocation: InvocationContext, id: number): RpcRequest;
|
|
13
|
+
/** Unframe a JSON-RPC response — the result, or the revived FougereError thrown. */
|
|
14
|
+
export declare function unframeResponse(response: RpcResponse, call: FrondCall): unknown;
|
|
15
|
+
export interface HttpTransportOptions {
|
|
16
|
+
/** Abort a call after this long. A timed-out call may have executed — it is never retried. */
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
/** Extra attempts on connection failures only — the request provably never left. */
|
|
19
|
+
retries?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function createHttpTransport(baseUrl: string, options?: HttpTransportOptions): Transport;
|
|
22
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACzH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE5D,0CAA0C;AAC1C,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,GAAG,UAAU,CAEhG;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAW/E;AAED,MAAM,WAAW,oBAAoB;IACnC,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,CA6DlG"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sending half — frame the call, POST it, unframe the result.
|
|
3
|
+
*
|
|
4
|
+
* Failure vocabulary is FougereError only: a transport failure becomes a
|
|
5
|
+
* typed error (SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, BAD_GATEWAY), an
|
|
6
|
+
* application failure comes back as the FougereError the façade threw.
|
|
7
|
+
*/
|
|
8
|
+
import { FougereError, ErrorCode } from '@fougere/core/contract';
|
|
9
|
+
/** Frame a call as a JSON-RPC request. */
|
|
10
|
+
export function frameCall(call, invocation, id) {
|
|
11
|
+
return { jsonrpc: '2.0', id, method: `${call.entity}.${call.op}`, params: invocation };
|
|
12
|
+
}
|
|
13
|
+
/** Unframe a JSON-RPC response — the result, or the revived FougereError thrown. */
|
|
14
|
+
export function unframeResponse(response, call) {
|
|
15
|
+
if ('error' in response) {
|
|
16
|
+
if (response.error.data !== undefined)
|
|
17
|
+
throw FougereError.fromJSON(response.error.data);
|
|
18
|
+
throw new FougereError({
|
|
19
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
20
|
+
message: `${response.error.message} (rpc ${response.error.code})`,
|
|
21
|
+
entity: call.entity,
|
|
22
|
+
operation: call.op,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return response.result;
|
|
26
|
+
}
|
|
27
|
+
/** Failures where the request never reached the other side — safe to retry. */
|
|
28
|
+
const CONNECTION_FAILURES = new Set(['ECONNREFUSED', 'ENOTFOUND', 'EAI_AGAIN']);
|
|
29
|
+
export function createHttpTransport(baseUrl, options = {}) {
|
|
30
|
+
const url = `${baseUrl.replace(/\/$/, '')}/_fougere/call`;
|
|
31
|
+
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
32
|
+
const retries = options.retries ?? 1;
|
|
33
|
+
let nextId = 1;
|
|
34
|
+
return async (call, invocation) => {
|
|
35
|
+
const request = frameCall(call, invocation, nextId++);
|
|
36
|
+
for (let attempt = 0;; attempt++) {
|
|
37
|
+
let res;
|
|
38
|
+
try {
|
|
39
|
+
res = await fetch(url, {
|
|
40
|
+
method: 'POST',
|
|
41
|
+
headers: { 'content-type': 'application/json' },
|
|
42
|
+
body: JSON.stringify(request),
|
|
43
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (isTimeout(err)) {
|
|
48
|
+
throw new FougereError({
|
|
49
|
+
code: ErrorCode.GATEWAY_TIMEOUT,
|
|
50
|
+
message: `${call.entity}.${call.op} timed out after ${timeoutMs}ms (${baseUrl})`,
|
|
51
|
+
entity: call.entity,
|
|
52
|
+
operation: call.op,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (attempt < retries && isConnectionFailure(err))
|
|
56
|
+
continue;
|
|
57
|
+
throw new FougereError({
|
|
58
|
+
code: ErrorCode.SERVICE_UNAVAILABLE,
|
|
59
|
+
message: `${baseUrl} unreachable: ${err?.message ?? err}`,
|
|
60
|
+
entity: call.entity,
|
|
61
|
+
operation: call.op,
|
|
62
|
+
cause: err,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (!res.ok) {
|
|
66
|
+
throw new FougereError({
|
|
67
|
+
code: ErrorCode.BAD_GATEWAY,
|
|
68
|
+
message: `${baseUrl} answered HTTP ${res.status} — not a Fougere receiver?`,
|
|
69
|
+
entity: call.entity,
|
|
70
|
+
operation: call.op,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
let response;
|
|
74
|
+
try {
|
|
75
|
+
response = (await res.json());
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
throw new FougereError({
|
|
79
|
+
code: ErrorCode.BAD_GATEWAY,
|
|
80
|
+
message: `${baseUrl} answered non-JSON`,
|
|
81
|
+
entity: call.entity,
|
|
82
|
+
operation: call.op,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return unframeResponse(response, call);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function isTimeout(err) {
|
|
90
|
+
return err instanceof DOMException && (err.name === 'TimeoutError' || err.name === 'AbortError');
|
|
91
|
+
}
|
|
92
|
+
function isConnectionFailure(err) {
|
|
93
|
+
const code = err?.cause?.code;
|
|
94
|
+
return typeof code === 'string' && CONNECTION_FAILURES.has(code);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createHttpTransport, frameCall, unframeResponse, type HttpTransportOptions } from './client.js';
|
|
2
|
+
export { handleRpc } from './server.js';
|
|
3
|
+
export { serve, type ServeOptions, type RunningReceiver } from './serve.js';
|
|
4
|
+
export { APP_ERROR, PARSE_ERROR, INVALID_REQUEST } from './jsonrpc.js';
|
|
5
|
+
export type { RpcRequest, RpcResponse, RpcErrorShape } from './jsonrpc.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACzG,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAA6B,MAAM,aAAa,CAAC;AACzG,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,KAAK,EAA2C,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC 2.0 framing — the standard written form of a call.
|
|
3
|
+
*
|
|
4
|
+
* The spec is the reuse: these few lines follow it, no lib adds anything.
|
|
5
|
+
* `method` is `entity.op`; `params` is the InvocationContext untouched.
|
|
6
|
+
* A FougereError travels whole in `error.data` (spec keeps `error.code`
|
|
7
|
+
* for integers — the semantic code lives in the data).
|
|
8
|
+
*/
|
|
9
|
+
export interface RpcRequest {
|
|
10
|
+
jsonrpc: '2.0';
|
|
11
|
+
id: number | string;
|
|
12
|
+
method: string;
|
|
13
|
+
params?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface RpcErrorShape {
|
|
16
|
+
code: number;
|
|
17
|
+
message: string;
|
|
18
|
+
data?: unknown;
|
|
19
|
+
}
|
|
20
|
+
export type RpcResponse = {
|
|
21
|
+
jsonrpc: '2.0';
|
|
22
|
+
id: number | string | null;
|
|
23
|
+
result: unknown;
|
|
24
|
+
} | {
|
|
25
|
+
jsonrpc: '2.0';
|
|
26
|
+
id: number | string | null;
|
|
27
|
+
error: RpcErrorShape;
|
|
28
|
+
};
|
|
29
|
+
/** Application failure — a FougereError, carried in error.data. */
|
|
30
|
+
export declare const APP_ERROR = -32000;
|
|
31
|
+
/** Body wasn't JSON (spec-reserved). */
|
|
32
|
+
export declare const PARSE_ERROR = -32700;
|
|
33
|
+
/** Not a valid JSON-RPC 2.0 call (spec-reserved). */
|
|
34
|
+
export declare const INVALID_REQUEST = -32600;
|
|
35
|
+
//# sourceMappingURL=jsonrpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.d.ts","sourceRoot":"","sources":["../src/jsonrpc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;IACf,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC/D;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAEzE,mEAAmE;AACnE,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,wCAAwC;AACxC,eAAO,MAAM,WAAW,SAAS,CAAC;AAClC,qDAAqD;AACrD,eAAO,MAAM,eAAe,SAAS,CAAC"}
|
package/dist/jsonrpc.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC 2.0 framing — the standard written form of a call.
|
|
3
|
+
*
|
|
4
|
+
* The spec is the reuse: these few lines follow it, no lib adds anything.
|
|
5
|
+
* `method` is `entity.op`; `params` is the InvocationContext untouched.
|
|
6
|
+
* A FougereError travels whole in `error.data` (spec keeps `error.code`
|
|
7
|
+
* for integers — the semantic code lives in the data).
|
|
8
|
+
*/
|
|
9
|
+
/** Application failure — a FougereError, carried in error.data. */
|
|
10
|
+
export const APP_ERROR = -32000;
|
|
11
|
+
/** Body wasn't JSON (spec-reserved). */
|
|
12
|
+
export const PARSE_ERROR = -32700;
|
|
13
|
+
/** Not a valid JSON-RPC 2.0 call (spec-reserved). */
|
|
14
|
+
export const INVALID_REQUEST = -32600;
|
|
15
|
+
//# sourceMappingURL=jsonrpc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonrpc.js","sourceRoot":"","sources":["../src/jsonrpc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,mEAAmE;AACnE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC;AAChC,wCAAwC;AACxC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAK,CAAC;AAClC,qDAAqD;AACrD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,CAAC"}
|
package/dist/serve.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Transport } from '@fougere/core';
|
|
2
|
+
export interface ServeOptions {
|
|
3
|
+
/** Port to listen on. 0 (default) picks a free one. */
|
|
4
|
+
port?: number;
|
|
5
|
+
/**
|
|
6
|
+
* The addresses this receiver may bind. Default: loopback only.
|
|
7
|
+
*
|
|
8
|
+
* A receiver reads the caller's identity off the wire and re-establishes
|
|
9
|
+
* nothing, so reaching beyond the machine is a decision its operator takes
|
|
10
|
+
* — stating it here IS taking it. The default is what a frond on a laptop
|
|
11
|
+
* wants; a container wants `hosts: ['0.0.0.0']` and says so.
|
|
12
|
+
*/
|
|
13
|
+
hosts?: string[];
|
|
14
|
+
/** Which address to bind. Must be one of `hosts`. Defaults to its first. */
|
|
15
|
+
host?: string;
|
|
16
|
+
/** Maximum JSON-RPC body size. Default: 1 MiB. */
|
|
17
|
+
maxBodyBytes?: number;
|
|
18
|
+
/** Time allowed to receive a request. Default: 15 seconds. */
|
|
19
|
+
requestTimeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface RunningReceiver {
|
|
22
|
+
port: number;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/** What a frond binds when nobody says otherwise. */
|
|
26
|
+
export declare const LOOPBACK_HOSTS: string[];
|
|
27
|
+
export declare function serve(runner: Transport, options?: ServeOptions): Promise<RunningReceiver>;
|
|
28
|
+
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,qDAAqD;AACrD,eAAO,MAAM,cAAc,UAAoC,CAAC;AAEhE,wBAAgB,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyD7F"}
|
package/dist/serve.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone receiver — enough to host a Frond in its own process.
|
|
3
|
+
*
|
|
4
|
+
* Plain node:http, one route: POST /_fougere/call. Mounting the receiving
|
|
5
|
+
* half inside an existing server (@fougere/http, Nitro) is layer-2 work.
|
|
6
|
+
*/
|
|
7
|
+
import { createServer } from 'node:http';
|
|
8
|
+
import { PARSE_ERROR } from './jsonrpc.js';
|
|
9
|
+
import { handleRpc } from './server.js';
|
|
10
|
+
/** What a frond binds when nobody says otherwise. */
|
|
11
|
+
export const LOOPBACK_HOSTS = ['127.0.0.1', 'localhost', '::1'];
|
|
12
|
+
export function serve(runner, options = {}) {
|
|
13
|
+
const allowed = options.hosts ?? LOOPBACK_HOSTS;
|
|
14
|
+
if (allowed.length === 0) {
|
|
15
|
+
return Promise.reject(new Error('A Fougere receiver needs at least one host to bind, `hosts` is empty'));
|
|
16
|
+
}
|
|
17
|
+
const host = options.host ?? allowed[0];
|
|
18
|
+
// A receiver trusts the `state` it is handed — the caller's identity arrives on
|
|
19
|
+
// the wire and nothing here re-establishes it. `hosts` is where that fact meets a
|
|
20
|
+
// deployment: the default keeps it on the machine, and widening it is written down
|
|
21
|
+
// rather than inferred. A shared link secret would not help — whoever holds it can
|
|
22
|
+
// claim any user — so the answer stays identity at the Frond.
|
|
23
|
+
if (!allowed.includes(host)) {
|
|
24
|
+
return Promise.reject(new Error(`A Fougere receiver binds one of [${allowed.join(', ')}], got '${host}' — add it to \`hosts\` to allow it`));
|
|
25
|
+
}
|
|
26
|
+
const maxBodyBytes = options.maxBodyBytes ?? 1024 * 1024;
|
|
27
|
+
const server = createServer(async (req, res) => {
|
|
28
|
+
if (req.method !== 'POST' || req.url !== '/_fougere/call') {
|
|
29
|
+
res.writeHead(404).end();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const chunks = [];
|
|
33
|
+
let size = 0;
|
|
34
|
+
for await (const value of req) {
|
|
35
|
+
const chunk = Buffer.from(value);
|
|
36
|
+
size += chunk.length;
|
|
37
|
+
if (size > maxBodyBytes) {
|
|
38
|
+
res.writeHead(413, { 'content-type': 'application/json' }).end(JSON.stringify({ error: 'Payload too large' }));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
chunks.push(chunk);
|
|
42
|
+
}
|
|
43
|
+
let response;
|
|
44
|
+
try {
|
|
45
|
+
const raw = JSON.parse(Buffer.concat(chunks).toString('utf8'));
|
|
46
|
+
response = await handleRpc(runner, raw);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
response = { jsonrpc: '2.0', id: null, error: { code: PARSE_ERROR, message: 'Parse error' } };
|
|
50
|
+
}
|
|
51
|
+
res.writeHead(200, { 'content-type': 'application/json' }).end(JSON.stringify(response));
|
|
52
|
+
});
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
server.once('error', reject);
|
|
55
|
+
server.requestTimeout = options.requestTimeoutMs ?? 15_000;
|
|
56
|
+
server.listen(options.port ?? 0, host, () => {
|
|
57
|
+
const address = server.address();
|
|
58
|
+
const port = typeof address === 'object' && address !== null ? address.port : 0;
|
|
59
|
+
resolve({
|
|
60
|
+
port,
|
|
61
|
+
close: () => new Promise((done, fail) => server.close((err) => (err ? fail(err) : done()))),
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Receiving half — unframe the call, run it, frame what comes out.
|
|
3
|
+
*
|
|
4
|
+
* Judges nothing: validation and middlewares live with the handler, inside
|
|
5
|
+
* the runner. The error a façade throws is framed whole, never flattened.
|
|
6
|
+
*/
|
|
7
|
+
import { type Transport } from '@fougere/core';
|
|
8
|
+
import { type RpcResponse } from './jsonrpc.js';
|
|
9
|
+
export declare function handleRpc(runner: Transport, raw: unknown): Promise<RpcResponse>;
|
|
10
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAkE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/G,OAAO,EAA+C,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE7F,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CA2CrF"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Receiving half — unframe the call, run it, frame what comes out.
|
|
3
|
+
*
|
|
4
|
+
* Judges nothing: validation and middlewares live with the handler, inside
|
|
5
|
+
* the runner. The error a façade throws is framed whole, never flattened.
|
|
6
|
+
*/
|
|
7
|
+
import { FougereError, ErrorCode, toPublicError } from '@fougere/core';
|
|
8
|
+
import { APP_ERROR, INVALID_REQUEST } from './jsonrpc.js';
|
|
9
|
+
export async function handleRpc(runner, raw) {
|
|
10
|
+
const req = raw;
|
|
11
|
+
const id = typeof req?.id === 'number' || typeof req?.id === 'string' ? req.id : null;
|
|
12
|
+
if (!req || req.jsonrpc !== '2.0' || typeof req.method !== 'string' || id === null) {
|
|
13
|
+
return { jsonrpc: '2.0', id, error: { code: INVALID_REQUEST, message: 'Invalid JSON-RPC 2.0 request' } };
|
|
14
|
+
}
|
|
15
|
+
const dot = req.method.indexOf('.');
|
|
16
|
+
if (dot <= 0 || dot === req.method.length - 1) {
|
|
17
|
+
return {
|
|
18
|
+
jsonrpc: '2.0',
|
|
19
|
+
id,
|
|
20
|
+
error: { code: INVALID_REQUEST, message: `Invalid method '${req.method}' — expected 'entity.op'` },
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const entity = req.method.slice(0, dot);
|
|
24
|
+
const op = req.method.slice(dot + 1);
|
|
25
|
+
// Fresh objects — middlewares deposit into state, nothing may be shared.
|
|
26
|
+
const sent = (req.params ?? {});
|
|
27
|
+
const invocation = {
|
|
28
|
+
params: sent.params ?? {},
|
|
29
|
+
query: sent.query ?? {},
|
|
30
|
+
body: sent.body,
|
|
31
|
+
state: sent.state ?? {},
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
return { jsonrpc: '2.0', id, result: await runner({ entity, op }, invocation) };
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
const failure = err instanceof FougereError
|
|
38
|
+
? err
|
|
39
|
+
: new FougereError({
|
|
40
|
+
code: ErrorCode.INTERNAL_ERROR,
|
|
41
|
+
message: err?.message ?? 'Internal error',
|
|
42
|
+
entity,
|
|
43
|
+
operation: op,
|
|
44
|
+
cause: err,
|
|
45
|
+
});
|
|
46
|
+
const data = toPublicError(failure);
|
|
47
|
+
return { jsonrpc: '2.0', id, error: { code: APP_ERROR, message: data.message, data } };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAA0C,MAAM,eAAe,CAAC;AAC/G,OAAO,EAAE,SAAS,EAAE,eAAe,EAAqC,MAAM,cAAc,CAAC;AAE7F,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAAiB,EAAE,GAAY;IAC7D,MAAM,GAAG,GAAG,GAAiC,CAAC;IAC9C,MAAM,EAAE,GAAG,OAAO,GAAG,EAAE,EAAE,KAAK,QAAQ,IAAI,OAAO,GAAG,EAAE,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAEtF,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,IAAI,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QACnF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,8BAA8B,EAAE,EAAE,CAAC;IAC3G,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO;YACL,OAAO,EAAE,KAAK;YACd,EAAE;YACF,KAAK,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,mBAAmB,GAAG,CAAC,MAAM,0BAA0B,EAAE;SACnG,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAErC,yEAAyE;IACzE,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,EAAE,CAA+B,CAAC;IAC9D,MAAM,UAAU,GAAsB;QACpC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;KACxB,CAAC;IAEF,IAAI,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC;IAClF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,YAAY;YACzC,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,IAAI,YAAY,CAAC;gBACf,IAAI,EAAE,SAAS,CAAC,cAAc;gBAC9B,OAAO,EAAG,GAAa,EAAE,OAAO,IAAI,gBAAgB;gBACpD,MAAM;gBACN,SAAS,EAAE,EAAE;gBACb,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;QACP,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;IACzF,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fougere/transport-http",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "The call contract on the wire, in JSON-RPC 2.0 (server + client).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/chok/fougere.git",
|
|
9
|
+
"directory": "packages/transport/http"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./client": {
|
|
20
|
+
"types": "./dist/client.d.ts",
|
|
21
|
+
"import": "./dist/client.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@fougere/core": "0.1.0-alpha.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"jiti": "^2.6.1",
|
|
32
|
+
"@fougere/schema": "0.1.0-alpha.0",
|
|
33
|
+
"@fougere/container-fougere": "0.1.0-alpha.0"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "rm -rf dist && tsc",
|
|
40
|
+
"test": "vitest run",
|
|
41
|
+
"test:watch": "vitest",
|
|
42
|
+
"typecheck": "tsc --noEmit -p tsconfig.test.json"
|
|
43
|
+
}
|
|
44
|
+
}
|