@client-compose/client 0.4.0 → 0.5.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 CHANGED
@@ -83,8 +83,20 @@ const res = await callAction(baseUrl, FollowUserV1, { userId }, { client, fetch:
83
83
  assert.equal(gateway.actionRequests()[0].input.userId, userId);
84
84
  ```
85
85
 
86
+ For code that calls the global `fetch` itself, such as a whole app rendered in a test,
87
+ `installFakeGateway(handlers)` puts the fake composer in its place; call `restore()` afterwards.
88
+
86
89
  For React, `@client-compose/react/testing` adds a provider config built around it.
87
90
 
91
+ ## Through your own server
92
+
93
+ `@client-compose/client/proxy` passes a browser's screen and action requests to the composer
94
+ through your server, so it can add what the browser mustn't hold, such as a session kept in an
95
+ httpOnly cookie. `createComposerProxy({ baseUrl, client, headers, onActionResponse })` checks each
96
+ request (anyone can call a server endpoint with anything), sets the client context and headers,
97
+ and returns the composer's failures as data. `@client-compose/react`'s `viaProxy` is the browser
98
+ half.
99
+
88
100
  ## Links
89
101
 
90
102
  - [Protocol spec](https://github.com/client-compose/client-compose/blob/main/spec/PROTOCOL.md)
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { type ActionDescriptor, type ActionRequest, type ActionResponse, type Capabilities, type ClientContext, type DeclaredError, type IslandDescriptor, type IslandEntry, type ScreenRequest, type ScreenResponse } from "@client-compose/protocol";
2
- type OkEntry<P = any> = IslandEntry<P> & {
2
+ type OkEntry<P = unknown> = IslandEntry<P> & {
3
3
  status: "ok";
4
4
  };
5
5
  type ErrorEntry = IslandEntry & {
6
6
  status: "error";
7
7
  };
8
- export type IslandRenderer<R, P = any> = (props: P, entry: OkEntry<P>) => R;
8
+ export type IslandRenderer<R, P = unknown> = (props: P, entry: OkEntry<P>) => R;
9
9
  export declare class IslandRegistry<R> {
10
10
  private renderers;
11
11
  /** Register a renderer for a generated island descriptor: `register(ProfileHeaderV2, (props) => …)`. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9,11 +9,15 @@ export class IslandRegistry {
9
9
  : [islandOrType.type, islandOrType.version, versionOrRender];
10
10
  if (!this.renderers.has(type))
11
11
  this.renderers.set(type, new Map());
12
+ // The registry hands each renderer the props of its own island type and version.
12
13
  this.renderers.get(type).set(version, render);
13
14
  return this;
14
15
  }
15
16
  capabilities() {
16
- return Object.fromEntries([...this.renderers].map(([type, versions]) => [type, [...versions.keys()].sort((a, b) => a - b)]));
17
+ return Object.fromEntries([...this.renderers].map(([type, versions]) => [
18
+ type,
19
+ [...versions.keys()].sort((a, b) => a - b),
20
+ ]));
17
21
  }
18
22
  get(type, version) {
19
23
  return this.renderers.get(type)?.get(version);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type ActionRequest, type ActionResponse, type ClientContext, type ScreenRequest, type ScreenResponse } from "@client-compose/protocol";
2
+ /** A screen request from the browser: the server sets the client context. */
3
+ export type ProxiedScreenRequest = Omit<ScreenRequest, "client">;
4
+ /** An action request from the browser: the server sets the client context. */
5
+ export type ProxiedActionRequest = Omit<ActionRequest, "client">;
6
+ /** The composer's response, or the status and body it failed with. */
7
+ export type ProxyResult<T> = {
8
+ ok: true;
9
+ response: T;
10
+ } | {
11
+ ok: false;
12
+ status: number;
13
+ body: string;
14
+ };
15
+ export interface ComposerProxyOptions {
16
+ /** Composer base URL. */
17
+ baseUrl: string;
18
+ /** The client context for each request, e.g. with the locale from the request's cookies. */
19
+ client: () => ClientContext | Promise<ClientContext>;
20
+ /** Extra headers for each request, e.g. `Authorization` from a session cookie. */
21
+ headers?: () => Record<string, string> | Promise<Record<string, string>>;
22
+ /** Extra options for every request, e.g. `{ cache: "no-store" }`. */
23
+ requestInit?: RequestInit & Record<string, unknown>;
24
+ /** Custom fetch implementation. Defaults to the global `fetch`. */
25
+ fetch?: typeof fetch;
26
+ /**
27
+ * Sees each action's response (ok or a declared error) before the browser does, and returns
28
+ * what the browser gets: e.g. keep a new session in a cookie, and take its token out.
29
+ */
30
+ onActionResponse?: (request: ActionRequest, response: ActionResponse) => ActionResponse | Promise<ActionResponse>;
31
+ }
32
+ export interface ComposerProxy {
33
+ /** Checks a browser's action request, then performs it with the server's context and headers. */
34
+ performAction(body: unknown): Promise<ProxyResult<ActionResponse>>;
35
+ /** Checks a browser's screen request, then loads it with the server's context and headers. */
36
+ loadScreen(body: unknown): Promise<ProxyResult<ScreenResponse>>;
37
+ }
38
+ export declare function isProxiedScreenRequest(value: unknown): value is ProxiedScreenRequest;
39
+ export declare function isProxiedActionRequest(value: unknown): value is ProxiedActionRequest;
40
+ export declare function createComposerProxy(options: ComposerProxyOptions): ComposerProxy;
41
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,KAAK,aAAa,EAElB,KAAK,aAAa,EAClB,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAIlC,6EAA6E;AAC7E,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AACjE,8EAA8E;AAC9E,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AAEjE,sEAAsE;AACtE,MAAM,MAAM,WAAW,CAAC,CAAC,IACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,MAAM,WAAW,oBAAoB;IACnC,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,MAAM,EAAE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACrD,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,qEAAqE;IACrE,WAAW,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,mEAAmE;IACnE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CACjB,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,cAAc,KACrB,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,iGAAiG;IACjG,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;IACnE,8FAA8F;IAC9F,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC;CACjE;AAkBD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAQpF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CASpF;AASD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAsChF"}
package/dist/proxy.js ADDED
@@ -0,0 +1,86 @@
1
+ // Passing a browser's screen and action requests to the composer through your own server, e.g. a
2
+ // Next.js Server Action or a Remix action. The server adds what the browser mustn't hold (a session
3
+ // kept in an httpOnly cookie) and vouches for the client context, so the browser's is ignored.
4
+ //
5
+ // const proxy = createComposerProxy({
6
+ // baseUrl: COMPOSER_URL,
7
+ // client: async () => ({ platform: "web", appVersion, locale: await getLocale() }),
8
+ // headers: async () => ({ Authorization: `Bearer ${await getSessionToken()}` }),
9
+ // });
10
+ // export async function performAction(body: unknown) { return proxy.performAction(body); }
11
+ //
12
+ // Anyone can call a server endpoint with anything, so requests are checked before they're sent on.
13
+ // Errors come back as data, since frameworks often strip thrown errors' details on the way to the
14
+ // browser.
15
+ import { PROTOCOL_VERSION, } from "@client-compose/protocol";
16
+ import { ActionFetchError, fetchAction, fetchScreen, ScreenFetchError } from "./index.js";
17
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
18
+ function isCapabilities(value) {
19
+ return (isRecord(value) &&
20
+ Object.values(value).every((versions) => Array.isArray(versions) && versions.every((v) => typeof v === "number")));
21
+ }
22
+ function isStringRecord(value) {
23
+ return isRecord(value) && Object.values(value).every((v) => typeof v === "string");
24
+ }
25
+ export function isProxiedScreenRequest(value) {
26
+ return (isRecord(value) &&
27
+ value.protocol === PROTOCOL_VERSION &&
28
+ typeof value.screen === "string" &&
29
+ (value.params === undefined || isStringRecord(value.params)) &&
30
+ isCapabilities(value.islands));
31
+ }
32
+ export function isProxiedActionRequest(value) {
33
+ return (isRecord(value) &&
34
+ value.protocol === PROTOCOL_VERSION &&
35
+ typeof value.action === "string" &&
36
+ typeof value.version === "number" &&
37
+ "input" in value &&
38
+ (value.idempotencyKey === undefined || typeof value.idempotencyKey === "string"));
39
+ }
40
+ /** What the composer itself answers to a malformed request. */
41
+ const BAD_REQUEST = {
42
+ ok: false,
43
+ status: 400,
44
+ body: JSON.stringify({ protocol: PROTOCOL_VERSION, error: { code: "bad_request" } }),
45
+ };
46
+ export function createComposerProxy(options) {
47
+ async function init() {
48
+ const headers = (await options.headers?.()) ?? {};
49
+ return { ...options.requestInit, headers: { ...options.requestInit?.headers, ...headers } };
50
+ }
51
+ async function performAction(body) {
52
+ if (!isProxiedActionRequest(body))
53
+ return BAD_REQUEST;
54
+ const request = { ...body, client: await options.client() };
55
+ try {
56
+ const response = await fetchAction(options.baseUrl, request, await init(), options.fetch);
57
+ return {
58
+ ok: true,
59
+ response: (await options.onActionResponse?.(request, response)) ?? response,
60
+ };
61
+ }
62
+ catch (error) {
63
+ if (error instanceof ActionFetchError)
64
+ return { ok: false, status: error.status, body: error.body };
65
+ throw error;
66
+ }
67
+ }
68
+ async function loadScreen(body) {
69
+ if (!isProxiedScreenRequest(body))
70
+ return BAD_REQUEST;
71
+ const request = { ...body, client: await options.client() };
72
+ try {
73
+ return {
74
+ ok: true,
75
+ response: await fetchScreen(options.baseUrl, request, await init(), options.fetch),
76
+ };
77
+ }
78
+ catch (error) {
79
+ if (error instanceof ScreenFetchError)
80
+ return { ok: false, status: error.status, body: error.body };
81
+ throw error;
82
+ }
83
+ }
84
+ return { performAction, loadScreen };
85
+ }
86
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
package/dist/testing.d.ts CHANGED
@@ -44,6 +44,15 @@ export interface FakeGateway {
44
44
  }
45
45
  /** A composer whose screens and actions are the handlers given. */
46
46
  export declare function createFakeGateway(handlers?: FakeGatewayHandlers): FakeGateway;
47
+ export interface InstalledFakeGateway extends FakeGateway {
48
+ /** Puts back the `fetch` that was there before. */
49
+ restore(): void;
50
+ }
51
+ /**
52
+ * A fake composer installed as the global `fetch`, for code that fetches by itself (e.g. a whole
53
+ * app rendered in a test). Call `restore()` after the test.
54
+ */
55
+ export declare function installFakeGateway(handlers?: FakeGatewayHandlers): InstalledFakeGateway;
47
56
  /** An island in a screen response, typed by its generated descriptor. */
48
57
  export declare function island<P>(key: string, descriptor: IslandDescriptor<P>, props: P): IslandEntry<P>;
49
58
  /** An island that failed on the composer (spec §3.4). */
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
package/dist/testing.js CHANGED
@@ -7,6 +7,8 @@
7
7
  // actions: { follow: () => actionOk(FollowUserV1, { followers: 8 }) },
8
8
  // });
9
9
  // // pass gateway.fetch as the client's fetch, then assert on gateway.actionRequests()
10
+ //
11
+ // For code that uses the global fetch itself, `installFakeGateway` puts one in its place.
10
12
  import { PROTOCOL_VERSION, } from "@client-compose/protocol";
11
13
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12
14
  function strings(value) {
@@ -23,7 +25,9 @@ function capabilities(value) {
23
25
  ]));
24
26
  }
25
27
  function clientContext(value) {
26
- if (!isRecord(value) || typeof value.platform !== "string" || typeof value.appVersion !== "string")
28
+ if (!isRecord(value) ||
29
+ typeof value.platform !== "string" ||
30
+ typeof value.appVersion !== "string")
27
31
  return undefined;
28
32
  return { ...value, platform: value.platform, appVersion: value.appVersion };
29
33
  }
@@ -109,6 +113,21 @@ export function createFakeGateway(handlers = {}) {
109
113
  actionRequests: () => requests.flatMap((r) => asActionRequest(r) ?? []),
110
114
  };
111
115
  }
116
+ /**
117
+ * A fake composer installed as the global `fetch`, for code that fetches by itself (e.g. a whole
118
+ * app rendered in a test). Call `restore()` after the test.
119
+ */
120
+ export function installFakeGateway(handlers = {}) {
121
+ const gateway = createFakeGateway(handlers);
122
+ const original = globalThis.fetch;
123
+ globalThis.fetch = gateway.fetch;
124
+ return {
125
+ ...gateway,
126
+ restore: () => {
127
+ globalThis.fetch = original;
128
+ },
129
+ };
130
+ }
112
131
  // ---- Responses ----
113
132
  /** An island in a screen response, typed by its generated descriptor. */
114
133
  export function island(key, descriptor, props) {
@@ -120,7 +139,10 @@ export function islandError(key, descriptor, error) {
120
139
  }
121
140
  /** A screen response. */
122
141
  export function screen(id, islands, meta) {
123
- return { status: 200, body: { protocol: PROTOCOL_VERSION, screen: id, islands, ...(meta && { meta }) } };
142
+ return {
143
+ status: 200,
144
+ body: { protocol: PROTOCOL_VERSION, screen: id, islands, ...(meta && { meta }) },
145
+ };
124
146
  }
125
147
  /** A screen request that fails, e.g. `screenError(404, "not_found")` or `screenError(401, "unauthenticated")`. */
126
148
  export function screenError(status, code) {
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@client-compose/client",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Framework-agnostic Client Compose client: island registry, screen requests and render planning.",
5
5
  "keywords": [
6
6
  "client-compose",
@@ -26,6 +26,10 @@
26
26
  "types": "./dist/index.d.ts",
27
27
  "default": "./dist/index.js"
28
28
  },
29
+ "./proxy": {
30
+ "types": "./dist/proxy.d.ts",
31
+ "default": "./dist/proxy.js"
32
+ },
29
33
  "./testing": {
30
34
  "types": "./dist/testing.d.ts",
31
35
  "default": "./dist/testing.js"
@@ -43,7 +47,7 @@
43
47
  "@client-compose/protocol": "0.3.0"
44
48
  },
45
49
  "devDependencies": {
46
- "@client-compose/conformance": "0.4.0"
50
+ "@client-compose/conformance": "0.5.0"
47
51
  },
48
52
  "publishConfig": {
49
53
  "access": "public"
package/src/index.ts CHANGED
@@ -2,7 +2,6 @@
2
2
  // `R` is whatever your UI layer renders: a React element, a DOM node, a string...
3
3
 
4
4
  import {
5
- PROTOCOL_VERSION,
6
5
  type ActionDescriptor,
7
6
  type ActionRequest,
8
7
  type ActionResponse,
@@ -11,14 +10,15 @@ import {
11
10
  type DeclaredError,
12
11
  type IslandDescriptor,
13
12
  type IslandEntry,
13
+ PROTOCOL_VERSION,
14
14
  type ScreenRequest,
15
15
  type ScreenResponse,
16
16
  } from "@client-compose/protocol";
17
17
 
18
- type OkEntry<P = any> = IslandEntry<P> & { status: "ok" };
18
+ type OkEntry<P = unknown> = IslandEntry<P> & { status: "ok" };
19
19
  type ErrorEntry = IslandEntry & { status: "error" };
20
20
 
21
- export type IslandRenderer<R, P = any> = (props: P, entry: OkEntry<P>) => R;
21
+ export type IslandRenderer<R, P = unknown> = (props: P, entry: OkEntry<P>) => R;
22
22
 
23
23
  export class IslandRegistry<R> {
24
24
  private renderers = new Map<string, Map<number, IslandRenderer<R>>>();
@@ -36,13 +36,17 @@ export class IslandRegistry<R> {
36
36
  ? [islandOrType, versionOrRender as number, maybeRender!]
37
37
  : [islandOrType.type, islandOrType.version, versionOrRender as IslandRenderer<R, P>];
38
38
  if (!this.renderers.has(type)) this.renderers.set(type, new Map());
39
- this.renderers.get(type)!.set(version, render);
39
+ // The registry hands each renderer the props of its own island type and version.
40
+ this.renderers.get(type)!.set(version, render as IslandRenderer<R>);
40
41
  return this;
41
42
  }
42
43
 
43
44
  capabilities(): Capabilities {
44
45
  return Object.fromEntries(
45
- [...this.renderers].map(([type, versions]) => [type, [...versions.keys()].sort((a, b) => a - b)]),
46
+ [...this.renderers].map(([type, versions]) => [
47
+ type,
48
+ [...versions.keys()].sort((a, b) => a - b),
49
+ ]),
46
50
  );
47
51
  }
48
52
 
@@ -226,6 +230,11 @@ export async function callAction<I, R, E extends DeclaredError>(
226
230
  input: I,
227
231
  options: CallActionOptions,
228
232
  ): Promise<ActionResponse<R, E>> {
229
- const request = buildActionRequest(action, input, options.client, options.idempotencyKey ?? newIdempotencyKey());
233
+ const request = buildActionRequest(
234
+ action,
235
+ input,
236
+ options.client,
237
+ options.idempotencyKey ?? newIdempotencyKey(),
238
+ );
230
239
  return (await fetchAction(baseUrl, request, options.init, options.fetch)) as ActionResponse<R, E>;
231
240
  }
package/src/proxy.ts ADDED
@@ -0,0 +1,147 @@
1
+ // Passing a browser's screen and action requests to the composer through your own server, e.g. a
2
+ // Next.js Server Action or a Remix action. The server adds what the browser mustn't hold (a session
3
+ // kept in an httpOnly cookie) and vouches for the client context, so the browser's is ignored.
4
+ //
5
+ // const proxy = createComposerProxy({
6
+ // baseUrl: COMPOSER_URL,
7
+ // client: async () => ({ platform: "web", appVersion, locale: await getLocale() }),
8
+ // headers: async () => ({ Authorization: `Bearer ${await getSessionToken()}` }),
9
+ // });
10
+ // export async function performAction(body: unknown) { return proxy.performAction(body); }
11
+ //
12
+ // Anyone can call a server endpoint with anything, so requests are checked before they're sent on.
13
+ // Errors come back as data, since frameworks often strip thrown errors' details on the way to the
14
+ // browser.
15
+
16
+ import {
17
+ type ActionRequest,
18
+ type ActionResponse,
19
+ type Capabilities,
20
+ type ClientContext,
21
+ PROTOCOL_VERSION,
22
+ type ScreenRequest,
23
+ type ScreenResponse,
24
+ } from "@client-compose/protocol";
25
+
26
+ import { ActionFetchError, fetchAction, fetchScreen, ScreenFetchError } from "./index.ts";
27
+
28
+ /** A screen request from the browser: the server sets the client context. */
29
+ export type ProxiedScreenRequest = Omit<ScreenRequest, "client">;
30
+ /** An action request from the browser: the server sets the client context. */
31
+ export type ProxiedActionRequest = Omit<ActionRequest, "client">;
32
+
33
+ /** The composer's response, or the status and body it failed with. */
34
+ export type ProxyResult<T> =
35
+ { ok: true; response: T } | { ok: false; status: number; body: string };
36
+
37
+ export interface ComposerProxyOptions {
38
+ /** Composer base URL. */
39
+ baseUrl: string;
40
+ /** The client context for each request, e.g. with the locale from the request's cookies. */
41
+ client: () => ClientContext | Promise<ClientContext>;
42
+ /** Extra headers for each request, e.g. `Authorization` from a session cookie. */
43
+ headers?: () => Record<string, string> | Promise<Record<string, string>>;
44
+ /** Extra options for every request, e.g. `{ cache: "no-store" }`. */
45
+ requestInit?: RequestInit & Record<string, unknown>;
46
+ /** Custom fetch implementation. Defaults to the global `fetch`. */
47
+ fetch?: typeof fetch;
48
+ /**
49
+ * Sees each action's response (ok or a declared error) before the browser does, and returns
50
+ * what the browser gets: e.g. keep a new session in a cookie, and take its token out.
51
+ */
52
+ onActionResponse?: (
53
+ request: ActionRequest,
54
+ response: ActionResponse,
55
+ ) => ActionResponse | Promise<ActionResponse>;
56
+ }
57
+
58
+ export interface ComposerProxy {
59
+ /** Checks a browser's action request, then performs it with the server's context and headers. */
60
+ performAction(body: unknown): Promise<ProxyResult<ActionResponse>>;
61
+ /** Checks a browser's screen request, then loads it with the server's context and headers. */
62
+ loadScreen(body: unknown): Promise<ProxyResult<ScreenResponse>>;
63
+ }
64
+
65
+ const isRecord = (value: unknown): value is Record<string, unknown> =>
66
+ typeof value === "object" && value !== null && !Array.isArray(value);
67
+
68
+ function isCapabilities(value: unknown): value is Capabilities {
69
+ return (
70
+ isRecord(value) &&
71
+ Object.values(value).every(
72
+ (versions) => Array.isArray(versions) && versions.every((v) => typeof v === "number"),
73
+ )
74
+ );
75
+ }
76
+
77
+ function isStringRecord(value: unknown): value is Record<string, string> {
78
+ return isRecord(value) && Object.values(value).every((v) => typeof v === "string");
79
+ }
80
+
81
+ export function isProxiedScreenRequest(value: unknown): value is ProxiedScreenRequest {
82
+ return (
83
+ isRecord(value) &&
84
+ value.protocol === PROTOCOL_VERSION &&
85
+ typeof value.screen === "string" &&
86
+ (value.params === undefined || isStringRecord(value.params)) &&
87
+ isCapabilities(value.islands)
88
+ );
89
+ }
90
+
91
+ export function isProxiedActionRequest(value: unknown): value is ProxiedActionRequest {
92
+ return (
93
+ isRecord(value) &&
94
+ value.protocol === PROTOCOL_VERSION &&
95
+ typeof value.action === "string" &&
96
+ typeof value.version === "number" &&
97
+ "input" in value &&
98
+ (value.idempotencyKey === undefined || typeof value.idempotencyKey === "string")
99
+ );
100
+ }
101
+
102
+ /** What the composer itself answers to a malformed request. */
103
+ const BAD_REQUEST = {
104
+ ok: false,
105
+ status: 400,
106
+ body: JSON.stringify({ protocol: PROTOCOL_VERSION, error: { code: "bad_request" } }),
107
+ } as const;
108
+
109
+ export function createComposerProxy(options: ComposerProxyOptions): ComposerProxy {
110
+ async function init(): Promise<RequestInit> {
111
+ const headers = (await options.headers?.()) ?? {};
112
+ return { ...options.requestInit, headers: { ...options.requestInit?.headers, ...headers } };
113
+ }
114
+
115
+ async function performAction(body: unknown): Promise<ProxyResult<ActionResponse>> {
116
+ if (!isProxiedActionRequest(body)) return BAD_REQUEST;
117
+ const request: ActionRequest = { ...body, client: await options.client() };
118
+ try {
119
+ const response = await fetchAction(options.baseUrl, request, await init(), options.fetch);
120
+ return {
121
+ ok: true,
122
+ response: (await options.onActionResponse?.(request, response)) ?? response,
123
+ };
124
+ } catch (error) {
125
+ if (error instanceof ActionFetchError)
126
+ return { ok: false, status: error.status, body: error.body };
127
+ throw error;
128
+ }
129
+ }
130
+
131
+ async function loadScreen(body: unknown): Promise<ProxyResult<ScreenResponse>> {
132
+ if (!isProxiedScreenRequest(body)) return BAD_REQUEST;
133
+ const request: ScreenRequest = { ...body, client: await options.client() };
134
+ try {
135
+ return {
136
+ ok: true,
137
+ response: await fetchScreen(options.baseUrl, request, await init(), options.fetch),
138
+ };
139
+ } catch (error) {
140
+ if (error instanceof ScreenFetchError)
141
+ return { ok: false, status: error.status, body: error.body };
142
+ throw error;
143
+ }
144
+ }
145
+
146
+ return { performAction, loadScreen };
147
+ }
package/src/testing.ts CHANGED
@@ -7,9 +7,10 @@
7
7
  // actions: { follow: () => actionOk(FollowUserV1, { followers: 8 }) },
8
8
  // });
9
9
  // // pass gateway.fetch as the client's fetch, then assert on gateway.actionRequests()
10
+ //
11
+ // For code that uses the global fetch itself, `installFakeGateway` puts one in its place.
10
12
 
11
13
  import {
12
- PROTOCOL_VERSION,
13
14
  type ActionDescriptor,
14
15
  type ActionEffects,
15
16
  type Capabilities,
@@ -18,6 +19,7 @@ import {
18
19
  type IslandDescriptor,
19
20
  type IslandEntry,
20
21
  type IslandError,
22
+ PROTOCOL_VERSION,
21
23
  type ScreenMeta,
22
24
  } from "@client-compose/protocol";
23
25
 
@@ -75,7 +77,9 @@ const isRecord = (value: unknown): value is Record<string, unknown> =>
75
77
 
76
78
  function strings(value: unknown): Record<string, string> {
77
79
  if (!isRecord(value)) return {};
78
- return Object.fromEntries(Object.entries(value).filter((e): e is [string, string] => typeof e[1] === "string"));
80
+ return Object.fromEntries(
81
+ Object.entries(value).filter((e): e is [string, string] => typeof e[1] === "string"),
82
+ );
79
83
  }
80
84
 
81
85
  function capabilities(value: unknown): Capabilities {
@@ -89,7 +93,12 @@ function capabilities(value: unknown): Capabilities {
89
93
  }
90
94
 
91
95
  function clientContext(value: unknown): ClientContext | undefined {
92
- if (!isRecord(value) || typeof value.platform !== "string" || typeof value.appVersion !== "string") return undefined;
96
+ if (
97
+ !isRecord(value) ||
98
+ typeof value.platform !== "string" ||
99
+ typeof value.appVersion !== "string"
100
+ )
101
+ return undefined;
93
102
  return { ...value, platform: value.platform, appVersion: value.appVersion } as ClientContext;
94
103
  }
95
104
 
@@ -115,7 +124,8 @@ function headersOf(init: HeadersInit | undefined): Record<string, string> {
115
124
 
116
125
  function asScreenRequest(request: RecordedRequest): RecordedScreenRequest | undefined {
117
126
  const { body } = request;
118
- if (!request.url.includes("/screens/") || !isRecord(body) || typeof body.screen !== "string") return undefined;
127
+ if (!request.url.includes("/screens/") || !isRecord(body) || typeof body.screen !== "string")
128
+ return undefined;
119
129
  return {
120
130
  ...request,
121
131
  screen: body.screen,
@@ -127,7 +137,8 @@ function asScreenRequest(request: RecordedRequest): RecordedScreenRequest | unde
127
137
 
128
138
  function asActionRequest(request: RecordedRequest): RecordedActionRequest | undefined {
129
139
  const { body } = request;
130
- if (!request.url.includes("/actions/") || !isRecord(body) || typeof body.action !== "string") return undefined;
140
+ if (!request.url.includes("/actions/") || !isRecord(body) || typeof body.action !== "string")
141
+ return undefined;
131
142
  return {
132
143
  ...request,
133
144
  action: body.action,
@@ -165,7 +176,9 @@ export function createFakeGateway(handlers: FakeGatewayHandlers = {}): FakeGatew
165
176
  const actionRequest = asActionRequest(request);
166
177
  const actionHandler = actionRequest && handlers.actions?.[actionRequest.action];
167
178
  if (actionRequest && actionHandler) return respond(actionHandler(actionRequest));
168
- throw new Error(`fake gateway: no handler for ${request.method} ${request.url} ${JSON.stringify(request.body)}`);
179
+ throw new Error(
180
+ `fake gateway: no handler for ${request.method} ${request.url} ${JSON.stringify(request.body)}`,
181
+ );
169
182
  }
170
183
  return {
171
184
  fetch: fakeFetch,
@@ -175,6 +188,27 @@ export function createFakeGateway(handlers: FakeGatewayHandlers = {}): FakeGatew
175
188
  };
176
189
  }
177
190
 
191
+ export interface InstalledFakeGateway extends FakeGateway {
192
+ /** Puts back the `fetch` that was there before. */
193
+ restore(): void;
194
+ }
195
+
196
+ /**
197
+ * A fake composer installed as the global `fetch`, for code that fetches by itself (e.g. a whole
198
+ * app rendered in a test). Call `restore()` after the test.
199
+ */
200
+ export function installFakeGateway(handlers: FakeGatewayHandlers = {}): InstalledFakeGateway {
201
+ const gateway = createFakeGateway(handlers);
202
+ const original = globalThis.fetch;
203
+ globalThis.fetch = gateway.fetch;
204
+ return {
205
+ ...gateway,
206
+ restore: () => {
207
+ globalThis.fetch = original;
208
+ },
209
+ };
210
+ }
211
+
178
212
  // ---- Responses ----
179
213
 
180
214
  /** An island in a screen response, typed by its generated descriptor. */
@@ -183,13 +217,24 @@ export function island<P>(key: string, descriptor: IslandDescriptor<P>, props: P
183
217
  }
184
218
 
185
219
  /** An island that failed on the composer (spec §3.4). */
186
- export function islandError(key: string, descriptor: IslandDescriptor<unknown>, error: IslandError): IslandEntry {
220
+ export function islandError(
221
+ key: string,
222
+ descriptor: IslandDescriptor<unknown>,
223
+ error: IslandError,
224
+ ): IslandEntry {
187
225
  return { key, type: descriptor.type, version: descriptor.version, status: "error", error };
188
226
  }
189
227
 
190
228
  /** A screen response. */
191
- export function screen(id: string, islands: IslandEntry<unknown>[], meta?: ScreenMeta): FakeResponse {
192
- return { status: 200, body: { protocol: PROTOCOL_VERSION, screen: id, islands, ...(meta && { meta }) } };
229
+ export function screen(
230
+ id: string,
231
+ islands: IslandEntry<unknown>[],
232
+ meta?: ScreenMeta,
233
+ ): FakeResponse {
234
+ return {
235
+ status: 200,
236
+ body: { protocol: PROTOCOL_VERSION, screen: id, islands, ...(meta && { meta }) },
237
+ };
193
238
  }
194
239
 
195
240
  /** A screen request that fails, e.g. `screenError(404, "not_found")` or `screenError(401, "unauthenticated")`. */
@@ -208,7 +253,10 @@ export function actionOk<I, R, E extends DeclaredError>(
208
253
  }
209
254
 
210
255
  /** An action that ended with one of its declared errors. */
211
- export function actionError<I, R, E extends DeclaredError>(action: ActionDescriptor<I, R, E>, error: E): FakeResponse {
256
+ export function actionError<I, R, E extends DeclaredError>(
257
+ action: ActionDescriptor<I, R, E>,
258
+ error: E,
259
+ ): FakeResponse {
212
260
  const base = { protocol: PROTOCOL_VERSION, action: action.action, version: action.version };
213
261
  return { status: 200, body: { ...base, status: "error", error } };
214
262
  }