@nifrajs/client 0.1.0-alpha.1 → 0.1.0-alpha.2
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 +8 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +23 -3
- package/dist/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +23 -4
package/README.md
CHANGED
|
@@ -28,3 +28,11 @@ const { ok, status, data, error } = await api.users({ id: "42" }).get()
|
|
|
28
28
|
runtime with `fetch`.
|
|
29
29
|
|
|
30
30
|
ESM-only. MIT.
|
|
31
|
+
|
|
32
|
+
## For AI agents
|
|
33
|
+
|
|
34
|
+
Start with [`LLM.md`](./LLM.md) — this package's contract card (the exports you call + its footguns),
|
|
35
|
+
one cheap read instead of the whole corpus. For the wider framework: the repo's
|
|
36
|
+
[`AGENTS.md`](../../AGENTS.md) is the copy-paste quick reference, and
|
|
37
|
+
[`llms-full.txt`](../../llms-full.txt) is the full machine-readable corpus. Run `nifra check` as the
|
|
38
|
+
done-gate, or `nifra mcp` to give the agent live project tools.
|
package/dist/client.d.ts
CHANGED
|
@@ -33,6 +33,14 @@ export declare function client<const C extends ContractShape>(contract: C, baseU
|
|
|
33
33
|
* lifecycle (validation, middleware, contracts). For SSR loaders. Typed from `App` exactly like
|
|
34
34
|
* the network client. The `(url, init) → Request` bridge is required because the client calls
|
|
35
35
|
* `fetch(url, init)` while `app.fetch` takes a `Request`.
|
|
36
|
+
*
|
|
37
|
+
* The returned typed proxy ALSO carries a real `fetch(url, init)` method — the same in-process
|
|
38
|
+
* bridge — so `createWebApp({ api: inProcessClient(backend) })` can **auto-mount** the backend over
|
|
39
|
+
* HTTP at `/api/*` (it dispatches `api.fetch(req.url, req)` to the backend, no hand-written
|
|
40
|
+
* `server-bun.ts` `/api/*` branch). Without this, `api.fetch` would resolve to a *route* sub-proxy
|
|
41
|
+
* (a call to `/fetch`), not the backend's own `fetch` — so the mount can't reach the app. The `fetch`
|
|
42
|
+
* key is intercepted on the proxy and shadows any (non-existent) `/fetch` route segment; no app
|
|
43
|
+
* defines a literal `/fetch` route reached via the typed proxy, so this is backward-compatible.
|
|
36
44
|
*/
|
|
37
45
|
export declare function inProcessClient<App extends {
|
|
38
46
|
fetch(request: Request): Response | Promise<Response>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAa7D;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE9E,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;AAClF,wBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAClD,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,aAAa,GACtB,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAerC
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAa7D;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE9E,MAAM,WAAW,aAAa;IAC5B,oFAAoF;IACpF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACzB;AAQD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;AAClF,wBAAgB,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAClD,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,aAAa,GACtB,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;AAerC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,GAAG,SAAS;IAAE,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAE,EACrE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAgB/D;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,wBAAkB,CAAA"}
|
package/dist/client.js
CHANGED
|
@@ -22,11 +22,31 @@ export function client(arg1, arg2, arg3) {
|
|
|
22
22
|
* lifecycle (validation, middleware, contracts). For SSR loaders. Typed from `App` exactly like
|
|
23
23
|
* the network client. The `(url, init) → Request` bridge is required because the client calls
|
|
24
24
|
* `fetch(url, init)` while `app.fetch` takes a `Request`.
|
|
25
|
+
*
|
|
26
|
+
* The returned typed proxy ALSO carries a real `fetch(url, init)` method — the same in-process
|
|
27
|
+
* bridge — so `createWebApp({ api: inProcessClient(backend) })` can **auto-mount** the backend over
|
|
28
|
+
* HTTP at `/api/*` (it dispatches `api.fetch(req.url, req)` to the backend, no hand-written
|
|
29
|
+
* `server-bun.ts` `/api/*` branch). Without this, `api.fetch` would resolve to a *route* sub-proxy
|
|
30
|
+
* (a call to `/fetch`), not the backend's own `fetch` — so the mount can't reach the app. The `fetch`
|
|
31
|
+
* key is intercepted on the proxy and shadows any (non-existent) `/fetch` route segment; no app
|
|
32
|
+
* defines a literal `/fetch` route reached via the typed proxy, so this is backward-compatible.
|
|
25
33
|
*/
|
|
26
34
|
export function inProcessClient(app, options) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
// The in-process bridge: the client speaks `fetch(url, init)` (the `FetchFn` shape) while the app's
|
|
36
|
+
// own `fetch` takes a `Request`. Reused both as the proxy's per-call transport (below) and as the
|
|
37
|
+
// mount hook exposed as `.fetch`.
|
|
38
|
+
const bridge = (url, init) => Promise.resolve(app.fetch(new Request(url, init)));
|
|
39
|
+
const proxy = client("http://nifra.internal", { ...options, fetch: bridge });
|
|
40
|
+
// Expose the bridge as a real `.fetch` for `createWebApp`'s `/api/*` auto-mount. An outer Proxy
|
|
41
|
+
// intercepts only the `fetch` key and delegates everything else to the typed route proxy, so the
|
|
42
|
+
// end-to-end-typed call surface (`api.users({ id }).get()`) is unchanged. The declared return type
|
|
43
|
+
// stays `Treaty<App>`: `.fetch` is an internal mount seam, not part of the public typed API.
|
|
44
|
+
return new Proxy(proxy, {
|
|
45
|
+
get(targetProxy, key, receiver) {
|
|
46
|
+
if (key === "fetch")
|
|
47
|
+
return bridge;
|
|
48
|
+
return Reflect.get(targetProxy, key, receiver);
|
|
49
|
+
},
|
|
30
50
|
});
|
|
31
51
|
}
|
|
32
52
|
/**
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC;IAC9C,KAAK;IACL,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,SAAS;CACV,CAAC,CAAA;AACF,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAA;AA0CzE,MAAM,UAAU,MAAM,CACpB,IAA4B,EAC5B,IAA6B,EAC7B,IAAoB;IAEpB,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAAe,CAAA;IAClE,MAAM,OAAO,GAAG,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAkC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;IAC7F,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;IACnE,+EAA+E;IAC/E,6EAA6E;IAC7E,oCAAoC;IACpC,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACvC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -72,14 +72,33 @@ export function client(
|
|
|
72
72
|
* lifecycle (validation, middleware, contracts). For SSR loaders. Typed from `App` exactly like
|
|
73
73
|
* the network client. The `(url, init) → Request` bridge is required because the client calls
|
|
74
74
|
* `fetch(url, init)` while `app.fetch` takes a `Request`.
|
|
75
|
+
*
|
|
76
|
+
* The returned typed proxy ALSO carries a real `fetch(url, init)` method — the same in-process
|
|
77
|
+
* bridge — so `createWebApp({ api: inProcessClient(backend) })` can **auto-mount** the backend over
|
|
78
|
+
* HTTP at `/api/*` (it dispatches `api.fetch(req.url, req)` to the backend, no hand-written
|
|
79
|
+
* `server-bun.ts` `/api/*` branch). Without this, `api.fetch` would resolve to a *route* sub-proxy
|
|
80
|
+
* (a call to `/fetch`), not the backend's own `fetch` — so the mount can't reach the app. The `fetch`
|
|
81
|
+
* key is intercepted on the proxy and shadows any (non-existent) `/fetch` route segment; no app
|
|
82
|
+
* defines a literal `/fetch` route reached via the typed proxy, so this is backward-compatible.
|
|
75
83
|
*/
|
|
76
84
|
export function inProcessClient<
|
|
77
85
|
App extends { fetch(request: Request): Response | Promise<Response> },
|
|
78
86
|
>(app: App, options?: Omit<ClientOptions, "fetch">): Treaty<App> {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
// The in-process bridge: the client speaks `fetch(url, init)` (the `FetchFn` shape) while the app's
|
|
88
|
+
// own `fetch` takes a `Request`. Reused both as the proxy's per-call transport (below) and as the
|
|
89
|
+
// mount hook exposed as `.fetch`.
|
|
90
|
+
const bridge: FetchFn = (url, init) => Promise.resolve(app.fetch(new Request(url, init)))
|
|
91
|
+
const proxy = client<App>("http://nifra.internal", { ...options, fetch: bridge })
|
|
92
|
+
// Expose the bridge as a real `.fetch` for `createWebApp`'s `/api/*` auto-mount. An outer Proxy
|
|
93
|
+
// intercepts only the `fetch` key and delegates everything else to the typed route proxy, so the
|
|
94
|
+
// end-to-end-typed call surface (`api.users({ id }).get()`) is unchanged. The declared return type
|
|
95
|
+
// stays `Treaty<App>`: `.fetch` is an internal mount seam, not part of the public typed API.
|
|
96
|
+
return new Proxy(proxy as object, {
|
|
97
|
+
get(targetProxy, key, receiver) {
|
|
98
|
+
if (key === "fetch") return bridge
|
|
99
|
+
return Reflect.get(targetProxy, key, receiver)
|
|
100
|
+
},
|
|
101
|
+
}) as Treaty<App>
|
|
83
102
|
}
|
|
84
103
|
|
|
85
104
|
/**
|