@rsc-kit/core 0.30.44 → 0.30.45

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.
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// The contract every backend adapter keeps, as a suite it runs against itself.\n//\n// A backend answers rpc(), actions and guards over one endpoint, and every\n// difference between how it and the engine read that wire is a bug in an\n// app that nobody wrote: a nil slice arriving as null where the type said a\n// list, a timestamp the type called unknown, a refusal that did not come out\n// as the error a page checks for. Each was found by an app, one at a time.\n// This finds them before an adapter ships.\n//\n// The adapter registers the Conformance.* functions described in CASES, in\n// its own language, the way an app would write them; this calls them through\n// the real client and checks what arrives. Where the adapter's manifest types\n// a function, every value it sends is checked against that type too.\n//\n// rsc-kit-conformance --endpoint http://127.0.0.1:8080/__rsc/host-call \\\n// --secret test-secret --manifest rsc-host.json\n//\n// The test host's hostReply passes the same suite (conformance.test.ts), so\n// a page test faking the backend fakes what a real adapter does.\n\nimport { readFileSync } from 'node:fs'\nimport { argv, exit, stderr, stdout } from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { httpHostCalls } from './hostCalls.js'\nimport { isNotFoundSignal } from './notFound.js'\nimport { isActionRefusal } from './action.js'\nimport { withRedirect } from './redirect.js'\nimport { withRequest, withResponseDraft } from './request.js'\nimport { FLASH_COOKIE, readFlash } from './flashCookie.js'\nimport { ServerAuthenticationError, ServerAuthorizationError } from './js/errors.js'\n\ntype Schema = Record<string, unknown>\n\n/** A host-call client: the real one in a run, the test host's in core's own test. */\nexport type ConformanceCall = (name: string, ...args: unknown[]) => Promise<unknown>\n\nexport interface ConformanceOptions {\n /** The adapter's host-call endpoint, e.g. http://127.0.0.1:8080/__rsc/host-call. */\n endpoint: string\n /** The secret the adapter checks. */\n secret: string\n /** The adapter's rsc-host.json, parsed or as a path: its types are checked against what arrives. */\n manifest?:\n | string\n | { actions?: unknown; functions?: string[]; types?: Record<string, { result?: Schema }>; defs?: Record<string, Schema> }\n /** For a test: the fetch the client uses. */\n fetch?: typeof fetch\n}\n\nexport interface ConformanceResult {\n case: string\n ok: boolean\n /** What went wrong, when it did. */\n detail?: string\n}\n\n/**\n * What the adapter registers, and what each must do. Names are fixed; how\n * they are written is the adapter's - the point is that they are written the\n * way an app's would be, with the adapter's ordinary API.\n */\nexport const CASES = {\n 'Conformance.echo': 'Return its one argument unchanged: any JSON value, nested.',\n 'Conformance.emptyList': 'Return an empty list of objects, the way the language makes \"no rows\" (Go: a nil slice).',\n 'Conformance.time': \"Return the instant 2026-01-02T03:04:05Z as the language's own time value.\",\n 'Conformance.noTime': \"Return an absent time: a nil pointer, a null Carbon, typed as a time or nothing.\",\n 'Conformance.unauthenticated': 'Refuse as not signed in, the way the framework does.',\n 'Conformance.unauthorized': 'Refuse as signed in but not allowed.',\n 'Conformance.notFound': \"Refuse as not found (404), the way the framework does: Go's Refuse(404), Laravel's abort(404).\",\n 'Conformance.refuse': 'Refuse with status 429 and the message \"Slow down.\"',\n 'Conformance.refuseWithData':\n 'Refuse with status 409, the message \"Still in use\", and the data { blockers: [{ id: 7, href: \"/orders/7\" }] } - ' +\n \"the adapter's own refuse, carrying data for the page to act on.\",\n 'Conformance.invalid': 'Refuse the input: a validation error on the field \"name\".',\n 'Conformance.redirect': 'Send the visitor to /login.',\n 'Conformance.revalidate': 'Mark the region \"orders\" stale, and return \"ok\".',\n 'Conformance.fail': 'Fail unexpectedly: an ordinary error, not a refusal.',\n 'Conformance.authorization': \"Return the request's Authorization header, as the renderer forwarded it.\",\n 'Conformance.cookie': \"Return the request's Cookie header, as the renderer forwarded it.\",\n 'Conformance.login': 'Set a cookie named \"conformance_login\" on the response, the way a login sets its session cookie, and return \"ok\".',\n 'Conformance.flash':\n 'Leave the one-time message \"Saved.\" of kind \"success\" for the next page - the adapter\\'s flash, which @rsc-kit/core/useFlash shows - and return \"ok\".',\n 'Conformance.double': 'Take one integer and return it doubled. Arguments that do not fit - a string, none - fail it: a 500, not a refusal.',\n 'Conformance.invalidNested': 'Refuse the input with errors on the nested field \"address.city\" and on the form itself, under \"\".',\n '__rsc.middleware':\n 'Guards, run in the order named, stopping at the first that does not pass - none at all passes: \"conformance-allow\" passes; ' +\n '\"conformance-deny\" refuses; \"conformance-redirect\" sends the visitor to /conformance-login; a name with no guard refuses.',\n 'Conformance.change': 'Say the name \"conformance:changed\" changed, the way the adapter does from a webhook, and return \"ok\".',\n '__rsc.changed':\n 'Given { since: { name: version }, wait }: answer { versions } with every name whose version differs from since now, ' +\n 'and no other. A name never changed is at 0. A change moves a version to the larger of one past it and the time in ' +\n 'ms - never + 1 alone. May hold the call up to wait ms for one to differ; may answer at once.',\n} as const\n\nconst INSTANT = Date.parse('2026-01-02T03:04:05Z')\n\n/** Two JSON values alike, whatever order an object's keys were written in. */\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Array.isArray(a) || Array.isArray(b)) {\n return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, i) => sameValue(item, b[i]))\n }\n\n if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {\n const keys = Object.keys(a)\n\n return (\n keys.length === Object.keys(b).length &&\n keys.every((key) => sameValue((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n )\n }\n\n return a === b\n}\n\nconst ECHOES: unknown[] = [null, 0, -1.5, 'héllo ✓ \"quoted\"', [1, 'a', null], { a: { b: [true, false] }, c: '' }]\n\n/**\n * Run the suite against a client. Every case runs; none stops another.\n *\n * `revalidated` is where the client records what each call marked stale -\n * its onRevalidate - so the revalidation case can read it.\n */\nexport async function conformance(\n call: ConformanceCall,\n options: {\n revalidated: string[][]\n manifest?: ConformanceOptions['manifest']\n wrongSecret?: ConformanceCall\n /**\n * A POST straight to the endpoint, for what the client never sends:\n * malformed bodies, an oversized batch, no secret at all. `secret: false`\n * leaves the header off.\n */\n raw?: (body: string, options?: { secret?: boolean }) => Promise<Response>\n },\n): Promise<ConformanceResult[]> {\n const { revalidated, manifest, wrongSecret, raw } = options\n const results: ConformanceResult[] = []\n const types = typeof manifest === 'string' ? JSON.parse(readFileSync(manifest, 'utf-8')) : manifest\n\n const check = async (name: string, run: () => Promise<void>) => {\n try {\n await run()\n results.push({ case: name, ok: true })\n } catch (error) {\n results.push({ case: name, ok: false, detail: error instanceof Error ? error.message : String(error) })\n }\n }\n\n const expect = (ok: boolean, detail: string) => {\n if (!ok) throw new Error(detail)\n }\n\n const rejection = async (run: () => Promise<unknown>): Promise<unknown> => {\n try {\n const value = await run()\n\n throw new Error('answered ' + JSON.stringify(value) + ' instead of refusing')\n } catch (error) {\n return error\n }\n }\n\n /** The value against the type the adapter's manifest declares, when it declares one. */\n const typed = (name: string, value: unknown) => {\n const schema = types?.types?.[name]?.result\n\n if (!schema) return\n\n const problem = conformsTo(value, schema, types?.defs ?? {}, 'result')\n\n expect(problem === null, `the manifest types ${name}'s result, and what arrived does not fit it: ${problem}`)\n }\n\n await check('the manifest lists every Conformance function', async () => {\n if (!types) return\n\n const missing = Object.keys(CASES).filter((n) => !n.startsWith('__') && !types.functions?.includes(n))\n\n expect(missing.length === 0, 'not in functions: ' + missing.join(', '))\n })\n\n await check('the manifest\\'s actions is an object, even with none', async () => {\n if (!types) return\n\n expect(\n typeof types.actions === 'object' && types.actions !== null && !Array.isArray(types.actions),\n 'actions is ' + JSON.stringify(types.actions),\n )\n })\n\n await check('a value of any JSON shape comes back unchanged', async () => {\n for (const value of ECHOES) {\n const back = await call('Conformance.echo', value)\n\n expect(JSON.stringify(back) === JSON.stringify(value), `sent ${JSON.stringify(value)}, got ${JSON.stringify(back)}`)\n }\n })\n\n await check('\"no rows\" is an empty list, never null', async () => {\n const value = await call('Conformance.emptyList')\n\n expect(Array.isArray(value) && value.length === 0, 'got ' + JSON.stringify(value))\n typed('Conformance.emptyList', value)\n })\n\n await check('a time is an ISO 8601 string of the same instant', async () => {\n const value = await call('Conformance.time')\n\n expect(typeof value === 'string' && Date.parse(value) === INSTANT, 'got ' + JSON.stringify(value))\n typed('Conformance.time', value)\n })\n\n await check('an absent time is null', async () => {\n const value = await call('Conformance.noTime')\n\n expect(value === null, 'got ' + JSON.stringify(value))\n typed('Conformance.noTime', value)\n })\n\n await check('not signed in is the engine\\'s ServerAuthenticationError', async () => {\n const error = await rejection(() => call('Conformance.unauthenticated'))\n\n expect(error instanceof ServerAuthenticationError, 'got ' + String(error))\n })\n\n await check('not allowed is the engine\\'s ServerAuthorizationError', async () => {\n const error = await rejection(() => call('Conformance.unauthorized'))\n\n expect(error instanceof ServerAuthorizationError, 'got ' + String(error))\n })\n\n await check('not found is the engine\\'s notFound()', async () => {\n const error = await rejection(() => call('Conformance.notFound'))\n\n expect(isNotFoundSignal(error), 'got ' + String(error))\n })\n\n await check('a refusal keeps its status and its message', async () => {\n const error = (await rejection(() => call('Conformance.refuse'))) as Error & { refusalStatus?: number }\n\n // A refusal, not a failure: an action shows its message rather than\n // onError's, data or no data.\n expect(isActionRefusal(error), 'raised as ' + String(error) + ', not as a refusal - is refusalStatus in the reply?')\n expect(error.refusalStatus === 429, 'status ' + String(error.refusalStatus))\n expect(String(error.message).includes('Slow down.'), 'message ' + JSON.stringify(error.message))\n })\n\n await check('a refusal carries its data, its message and its status', async () => {\n const error = (await rejection(() => call('Conformance.refuseWithData'))) as Error & {\n refusalStatus?: number\n data?: unknown\n }\n\n expect(isActionRefusal(error), 'raised as ' + String(error) + ', not as a refusal - is refusalData in the reply?')\n expect(error.message === 'Still in use', 'message ' + JSON.stringify(error.message))\n expect(error.refusalStatus === 409, 'status ' + String(error.refusalStatus))\n // Compared as values, not as text: an object's keys have no order, and\n // Go writes a map's sorted.\n expect(\n sameValue(error.data, { blockers: [{ id: 7, href: '/orders/7' }] }),\n 'data ' + JSON.stringify(error.data),\n )\n })\n\n await check('refused input names its field', async () => {\n const error = (await rejection(() => call('Conformance.invalid'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.name) && error.errors.name.length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('a redirect is the engine\\'s redirect, to where it said', async () => {\n const taken = await withRedirect(async (seen) => {\n await rejection(() => call('Conformance.redirect'))\n\n return seen()\n })\n\n expect(taken?.location === '/login', 'redirect ' + JSON.stringify(taken))\n expect(taken!.status >= 300 && taken!.status < 400, 'status ' + taken?.status)\n })\n\n await check('in a batch, a revalidation stays with its own call', async () => {\n const before = revalidated.length\n\n await Promise.all([call('Conformance.revalidate'), call('Conformance.echo', 1), call('Conformance.echo', 2)])\n\n expect(revalidated.length - before === 1, 'revalidated ' + JSON.stringify(revalidated.slice(before)))\n })\n\n await check('a revalidation rides with the result', async () => {\n const value = await call('Conformance.revalidate')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n expect(revalidated.some((r) => r.includes('orders')), 'revalidated ' + JSON.stringify(revalidated))\n })\n\n await check('an unexpected failure is an error, not a refusal', async () => {\n const error = (await rejection(() => call('Conformance.fail'))) as Error & { refusalStatus?: number }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) && !error.refusalStatus && !isNotFoundSignal(error),\n 'got ' + String(error),\n )\n })\n\n await check('the visitor\\'s Authorization header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { authorization: 'Bearer conformance' } }), () =>\n call('Conformance.authorization'),\n )\n\n expect(value === 'Bearer conformance', 'got ' + JSON.stringify(value))\n })\n\n await check('the visitor\\'s Cookie header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { cookie: 'conformance=1; other=2' } }), () =>\n call('Conformance.cookie'),\n )\n\n expect(typeof value === 'string' && value.includes('conformance=1') && value.includes('other=2'), 'got ' + JSON.stringify(value))\n })\n\n await check('a cookie set during a call - a login - reaches the page\\'s response', async () => {\n const cookies = await withRequest(new Request('https://app.test/'), () =>\n withResponseDraft(async ({ taken }) => {\n const value = await call('Conformance.login')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n return taken().getSetCookie()\n }),\n )\n\n expect(cookies.some((c) => c.startsWith('conformance_login=')), 'Set-Cookie ' + JSON.stringify(cookies))\n })\n\n await check('a flash is a cookie the browser reads, kept after one the visitor still carries', async () => {\n // A message from the page before, not yet shown, is in the visitor's\n // cookie; the new one goes after it rather than over it.\n const carried = encodeURIComponent(JSON.stringify([{ message: 'Earlier.', kind: 'info' }]))\n const cookies = await withRequest(new Request('https://app.test/', { headers: { Cookie: `${FLASH_COOKIE}=${carried}` } }), () =>\n withResponseDraft(async ({ taken }) => {\n const value = await call('Conformance.flash')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n return taken().getSetCookie()\n }),\n )\n const cookie = cookies.find((c) => c.startsWith(`${FLASH_COOKIE}=`))\n\n expect(cookie !== undefined, 'Set-Cookie ' + JSON.stringify(cookies))\n // useFlash reads it with document.cookie: an HttpOnly cookie is never seen.\n expect(!/;\\s*httponly/i.test(cookie!), 'HttpOnly, so useFlash cannot read it: ' + cookie)\n\n // Read as useFlash reads it. An encrypted value is not JSON, and reads as nothing.\n let raw: string | undefined\n\n try {\n raw = decodeURIComponent(cookie!.slice(FLASH_COOKIE.length + 1).split(';')[0]!)\n } catch {}\n\n const messages = readFlash(raw)\n\n expect(\n sameValue(messages, [\n { message: 'Earlier.', kind: 'info' },\n { message: 'Saved.', kind: 'success' },\n ]),\n 'read as ' + JSON.stringify(messages) + ' from ' + cookie,\n )\n })\n\n await check('arguments are decoded to their types', async () => {\n const value = await call('Conformance.double', 21)\n\n expect(value === 42, 'got ' + JSON.stringify(value))\n })\n\n await check('arguments that do not fit fail the call, not refuse it', async () => {\n for (const args of [['twenty-one'], []]) {\n const error: unknown = await rejection(() => call('Conformance.double', ...args))\n const fields = error as { refusalStatus?: number; errors?: unknown }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) &&\n !fields.refusalStatus && fields.errors === undefined && !isNotFoundSignal(error),\n `with ${JSON.stringify(args)}: got ` + String(error),\n )\n }\n })\n\n await check('refused input names nested fields with dots, and the form under \"\"', async () => {\n const error = (await rejection(() => call('Conformance.invalidNested'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.['address.city']) && error.errors['address.city'].length > 0, 'errors ' + JSON.stringify(error.errors))\n expect(Array.isArray(error.errors?.['']) && error.errors[''].length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('calls in one batch are each answered, a refusal only its own', async () => {\n const [a, b, c] = await Promise.allSettled([\n call('Conformance.echo', 1),\n call('Conformance.unauthenticated'),\n call('Conformance.echo', 2),\n ])\n\n expect(a.status === 'fulfilled' && a.value === 1, 'first ' + JSON.stringify(a))\n expect(b.status === 'rejected' && b.reason instanceof ServerAuthenticationError, 'second ' + String((b as PromiseRejectedResult).reason))\n expect(c.status === 'fulfilled' && c.value === 2, 'third ' + JSON.stringify(c))\n })\n\n await check('no guards at all passes: what a health check asks', async () => {\n // The renderer's /_rsc/health asks with an empty list: it runs no app\n // code, and still proves the address, the secret and the adapter.\n const value = await call('__rsc.middleware', [])\n\n expect(value === true, 'got ' + JSON.stringify(value))\n })\n\n await check('a guard that passes answers true', async () => {\n const value = await call('__rsc.middleware', ['conformance-allow'])\n\n expect(value === true, 'got ' + JSON.stringify(value))\n })\n\n await check('a guard that refuses refuses', async () => {\n const value = await call('__rsc.middleware', ['conformance-deny']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n await check('a guard can send the visitor somewhere else', async () => {\n const taken = await withRedirect(async (seen) => {\n await call('__rsc.middleware', ['conformance-redirect']).catch(() => {})\n\n return seen()\n })\n\n expect(taken?.location === '/conformance-login', 'redirect ' + JSON.stringify(taken))\n })\n\n await check('guards run in order and stop at the first that does not pass', async () => {\n const after = await call('__rsc.middleware', ['conformance-allow', 'conformance-deny']).catch((e: unknown) => e)\n\n expect(after !== true, 'allow then deny answered true')\n\n // Deny first: the redirect after it must never be asked.\n const taken = await withRedirect(async (seen) => {\n const value = await call('__rsc.middleware', ['conformance-deny', 'conformance-redirect']).catch((e: unknown) => e)\n\n expect(value !== true, 'deny then redirect answered true')\n\n return seen()\n })\n\n expect(taken === null, 'the guard after a refusal ran: redirected to ' + JSON.stringify(taken))\n })\n\n await check('a guard nobody registered refuses: fail closed', async () => {\n const value = await call('__rsc.middleware', ['conformance-nobody-registered-this']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n const versionsOf = async (query: { since: Record<string, number>; wait?: number }) => {\n const answer = (await call('__rsc.changed', query)) as { versions?: Record<string, number> } | null\n\n expect(typeof answer?.versions === 'object' && answer.versions !== null, 'got ' + JSON.stringify(answer))\n\n return answer!.versions!\n }\n\n await check('a name nobody changed is at version 0, and unchanged from 0', async () => {\n const all = await versionsOf({ since: { 'conformance:never': -1 } })\n\n expect(all['conformance:never'] === 0, 'from -1: ' + JSON.stringify(all))\n\n const none = await versionsOf({ since: { 'conformance:never': 0 } })\n\n expect(Object.keys(none).length === 0, 'from 0: ' + JSON.stringify(none))\n })\n\n await check('saying a name changed moves its version', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const value = await call('Conformance.change')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n const moved = await versionsOf({ since: { 'conformance:changed': before } })\n\n expect(typeof moved['conformance:changed'] === 'number' && moved['conformance:changed'] !== before, 'from ' + before + ': ' + JSON.stringify(moved))\n })\n\n await check('a version is the time of the change, and never comes round again', async () => {\n // The larger of one past the old version and the time in ms: a counter\n // repeats once a pruned name starts again from 0, and a tab holding the\n // old value misses the next change. A minute's leeway for clock skew.\n const started = Date.now()\n\n await call('Conformance.change')\n\n const first = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(first >= started - 60_000, `a change at ${started} moved the version to ${first}: not a time in ms`)\n\n await call('Conformance.change')\n\n const second = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(second > first, `a second change moved ${first} to ${second}`)\n })\n\n await check('only the names that differ are answered', async () => {\n const current = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const answer = await versionsOf({ since: { 'conformance:changed': current, 'conformance:never': 5 } })\n\n expect(JSON.stringify(answer) === JSON.stringify({ 'conformance:never': 0 }), 'got ' + JSON.stringify(answer))\n })\n\n await check('waiting for a name to change is bounded by wait', async () => {\n const started = Date.now()\n const none = await versionsOf({ since: { 'conformance:never': 0 }, wait: 300 })\n const took = Date.now() - started\n\n expect(Object.keys(none).length === 0, 'got ' + JSON.stringify(none))\n expect(took < 3_000, 'took ' + took + 'ms')\n })\n\n if (raw) {\n const statusOf = async (body: string, secret = true) => (await raw(body, { secret })).status\n\n await check('a call with no secret at all is refused, 403', async () => {\n const status = await statusOf(JSON.stringify({ function: 'Conformance.echo', args: [1] }), false)\n\n expect(status === 403, 'answered ' + status)\n })\n\n await check('a function nobody registered is a 404', async () => {\n const status = await statusOf(JSON.stringify({ function: 'Conformance.nobodyRegisteredThis', args: [] }))\n\n expect(status === 404, 'answered ' + status)\n })\n\n await check('a malformed call is a 400: not JSON, no function, args not a list', async () => {\n for (const body of ['not json', JSON.stringify({ args: [] }), JSON.stringify({ function: 'Conformance.echo', args: 'x' })]) {\n const status = await statusOf(body)\n\n expect(status === 400, `${body} answered ${status}`)\n }\n })\n\n await check('a batch of more than 50 is refused, 413, before any call runs', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const calls = Array.from({ length: 51 }, () => ({ function: 'Conformance.change', args: [] }))\n const status = await statusOf(JSON.stringify({ calls }))\n const after = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(status === 413, 'answered ' + status)\n expect(after === before, 'calls ran: conformance:changed moved from ' + before + ' to ' + after)\n })\n }\n\n if (wrongSecret) {\n await check('a call with the wrong secret is refused', async () => {\n const value = await wrongSecret('Conformance.echo', 'should not run').catch((e: unknown) => e)\n\n expect(value !== 'should not run', 'it ran')\n })\n }\n\n return results\n}\n\n/** Run the suite against an adapter's endpoint. */\nexport async function runConformance(options: ConformanceOptions): Promise<ConformanceResult[]> {\n const revalidated: string[][] = []\n const client = (secret: string) =>\n httpHostCalls({\n endpoint: options.endpoint,\n secret,\n fetch: options.fetch,\n onRevalidate: (targets) => revalidated.push(targets),\n })\n\n const doFetch = options.fetch ?? globalThis.fetch\n\n return await conformance(client(options.secret), {\n revalidated,\n manifest: options.manifest,\n wrongSecret: client(options.secret + '-wrong'),\n raw: (body, { secret = true } = {}) =>\n doFetch(options.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...(secret ? { 'x-rsc-host-secret': options.secret } : {}) },\n body,\n }),\n })\n}\n\n/**\n * Whether a value fits the JSON Schema subset the manifest uses. Null when it\n * does; otherwise where and why it does not.\n */\nexport function conformsTo(value: unknown, schema: Schema, defs: Record<string, Schema>, at: string): string | null {\n if (!schema || Object.keys(schema).length === 0) return null\n\n const ref = schema.$ref\n\n if (typeof ref === 'string' && ref.startsWith('#/defs/')) {\n const target = defs[ref.slice(7)]\n\n return target ? conformsTo(value, target, defs, at) : `${at}: ${ref} is not in defs`\n }\n\n if (Array.isArray(schema.anyOf)) {\n const fits = (schema.anyOf as Schema[]).some((s) => conformsTo(value, s, defs, at) === null)\n\n return fits ? null : `${at}: ${JSON.stringify(value)} is none of ${JSON.stringify(schema.anyOf)}`\n }\n\n if (Array.isArray(schema.enum)) {\n return (schema.enum as unknown[]).includes(value) ? null : `${at}: ${JSON.stringify(value)} is not one of ${JSON.stringify(schema.enum)}`\n }\n\n const kind = Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value\n\n switch (schema.type) {\n case 'string':\n if (kind !== 'string') return `${at}: expected a string, got ${JSON.stringify(value)}`\n if (schema.format === 'date-time' && Number.isNaN(Date.parse(value as string))) return `${at}: ${JSON.stringify(value)} is not a date-time`\n return null\n case 'integer':\n return Number.isInteger(value) ? null : `${at}: expected an integer, got ${JSON.stringify(value)}`\n case 'number':\n return kind === 'number' ? null : `${at}: expected a number, got ${JSON.stringify(value)}`\n case 'boolean':\n return kind === 'boolean' ? null : `${at}: expected a boolean, got ${JSON.stringify(value)}`\n case 'null':\n return value === null ? null : `${at}: expected null, got ${JSON.stringify(value)}`\n case 'array': {\n if (kind !== 'array') return `${at}: expected an array, got ${JSON.stringify(value)}`\n for (const [i, item] of (value as unknown[]).entries()) {\n const problem = conformsTo(item, schema.items as Schema, defs, `${at}[${i}]`)\n if (problem) return problem\n }\n return null\n }\n case 'object': {\n if (kind !== 'object') return `${at}: expected an object, got ${JSON.stringify(value)}`\n const object = value as Record<string, unknown>\n const properties = (schema.properties ?? {}) as Record<string, Schema>\n for (const name of (schema.required as string[] | undefined) ?? []) {\n if (!(name in object)) return `${at}.${name}: required, and missing`\n }\n for (const [name, s] of Object.entries(properties)) {\n if (name in object) {\n const problem = conformsTo(object[name], s, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n const extra = schema.additionalProperties as Schema | undefined\n if (extra && !schema.properties) {\n for (const [name, item] of Object.entries(object)) {\n const problem = conformsTo(item, extra, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n return null\n }\n default:\n return null\n }\n}\n\n/** Print a result table, and say whether the adapter conforms. */\nexport function report(results: ConformanceResult[]): boolean {\n for (const r of results) {\n stdout.write(` ${r.ok ? '✓' : '✗'} ${r.case}${r.ok ? '' : '\\n ' + r.detail}\\n`)\n }\n\n const failed = results.filter((r) => !r.ok).length\n\n stdout.write(failed === 0 ? `\\n conforms: ${results.length} cases\\n` : `\\n ${failed} of ${results.length} cases failed\\n`)\n\n return failed === 0\n}\n\n// Run as a command, not when imported.\nif (import.meta.url === pathToFileURL(argv[1] ?? '').href || argv[1]?.endsWith('rsc-kit-conformance')) {\n const flag = (name: string) => {\n const at = argv.indexOf('--' + name)\n\n return at === -1 ? undefined : argv[at + 1]\n }\n\n const endpoint = flag('endpoint')\n const secret = flag('secret')\n\n if (!endpoint || !secret) {\n stderr.write('usage: rsc-kit-conformance --endpoint <url> --secret <secret> [--manifest rsc-host.json]\\n')\n exit(2)\n }\n\n runConformance({ endpoint, secret, manifest: flag('manifest') })\n .then((results) => exit(report(results) ? 0 : 1))\n .catch((error: unknown) => {\n stderr.write('rsc-kit-conformance: ' + (error instanceof Error ? error.message : String(error)) + '\\n')\n exit(1)\n })\n}\n"]}
1
+ {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// The contract every backend adapter keeps, as a suite it runs against itself.\n//\n// A backend answers rpc(), actions and guards over one endpoint, and every\n// difference between how it and the engine read that wire is a bug in an\n// app that nobody wrote: a nil slice arriving as null where the type said a\n// list, a timestamp the type called unknown, a refusal that did not come out\n// as the error a page checks for. Each was found by an app, one at a time.\n// This finds them before an adapter ships.\n//\n// The adapter registers the Conformance.* functions described in CASES, in\n// its own language, the way an app would write them; this calls them through\n// the real client and checks what arrives. Where the adapter's manifest types\n// a function, every value it sends is checked against that type too.\n//\n// HOMEPORT_PURGE_URL=http://127.0.0.1:8790/ <start the adapter>\n// rsc-kit-conformance --endpoint http://127.0.0.1:8080/__rsc/host-call \\\n// --secret test-secret --manifest rsc-host.json --purge-port 8790\n//\n// --purge-port is where the suite listens for the adapter's purges: a change\n// a backend makes never passes through the engine, so the backend tells a\n// CDN keeping its pages itself. Start the adapter with HOMEPORT_PURGE_URL\n// pointing at that port.\n//\n// The test host's hostReply passes the same suite (conformance.test.ts), so\n// a page test faking the backend fakes what a real adapter does.\n\nimport { readFileSync } from 'node:fs'\nimport { argv, exit, stderr, stdout } from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { httpHostCalls } from './hostCalls.js'\nimport { isNotFoundSignal } from './notFound.js'\nimport { isActionRefusal } from './action.js'\nimport { withRedirect } from './redirect.js'\nimport { withRequest, withResponseDraft } from './request.js'\nimport { FLASH_COOKIE, readFlash } from './flashCookie.js'\nimport { ServerAuthenticationError, ServerAuthorizationError } from './js/errors.js'\n\ntype Schema = Record<string, unknown>\n\n/** A host-call client: the real one in a run, the test host's in core's own test. */\nexport type ConformanceCall = (name: string, ...args: unknown[]) => Promise<unknown>\n\nexport interface ConformanceOptions {\n /** The adapter's host-call endpoint, e.g. http://127.0.0.1:8080/__rsc/host-call. */\n endpoint: string\n /** The secret the adapter checks. */\n secret: string\n /** The adapter's rsc-host.json, parsed or as a path: its types are checked against what arrives. */\n manifest?:\n | string\n | { actions?: unknown; functions?: string[]; types?: Record<string, { result?: Schema }>; defs?: Record<string, Schema> }\n /** For a test: the fetch the client uses. */\n fetch?: typeof fetch\n /** The port to hear the adapter's purges on: it was started with HOMEPORT_PURGE_URL=http://127.0.0.1:<port>/. */\n purgePort?: number\n}\n\n/** A purge as it arrived: what an adapter posted to HOMEPORT_PURGE_URL. */\nexport interface ArrivedPurge {\n method: string\n contentType: string | null\n body: string\n}\n\n/**\n * Where the suite hears purges. The suite hands it a handler, called for every\n * purge before it is answered - so the suite can look at the versions while the\n * adapter is still waiting, and see whether the purge followed the change.\n */\nexport type PurgeInbox = (handler: (purge: ArrivedPurge) => Promise<void>) => void\n\nexport interface ConformanceResult {\n case: string\n ok: boolean\n /** What went wrong, when it did. */\n detail?: string\n}\n\n/**\n * What the adapter registers, and what each must do. Names are fixed; how\n * they are written is the adapter's - the point is that they are written the\n * way an app's would be, with the adapter's ordinary API.\n */\nexport const CASES = {\n 'Conformance.echo': 'Return its one argument unchanged: any JSON value, nested.',\n 'Conformance.emptyList': 'Return an empty list of objects, the way the language makes \"no rows\" (Go: a nil slice).',\n 'Conformance.time': \"Return the instant 2026-01-02T03:04:05Z as the language's own time value.\",\n 'Conformance.noTime': \"Return an absent time: a nil pointer, a null Carbon, typed as a time or nothing.\",\n 'Conformance.unauthenticated': 'Refuse as not signed in, the way the framework does.',\n 'Conformance.unauthorized': 'Refuse as signed in but not allowed.',\n 'Conformance.notFound': \"Refuse as not found (404), the way the framework does: Go's Refuse(404), Laravel's abort(404).\",\n 'Conformance.refuse': 'Refuse with status 429 and the message \"Slow down.\"',\n 'Conformance.refuseWithData':\n 'Refuse with status 409, the message \"Still in use\", and the data { blockers: [{ id: 7, href: \"/orders/7\" }] } - ' +\n \"the adapter's own refuse, carrying data for the page to act on.\",\n 'Conformance.invalid': 'Refuse the input: a validation error on the field \"name\".',\n 'Conformance.redirect': 'Send the visitor to /login.',\n 'Conformance.revalidate': 'Mark the region \"orders\" stale, and return \"ok\".',\n 'Conformance.fail': 'Fail unexpectedly: an ordinary error, not a refusal.',\n 'Conformance.authorization': \"Return the request's Authorization header, as the renderer forwarded it.\",\n 'Conformance.cookie': \"Return the request's Cookie header, as the renderer forwarded it.\",\n 'Conformance.login': 'Set a cookie named \"conformance_login\" on the response, the way a login sets its session cookie, and return \"ok\".',\n 'Conformance.flash':\n 'Leave the one-time message \"Saved.\" of kind \"success\" for the next page - the adapter\\'s flash, which @rsc-kit/core/useFlash shows - and return \"ok\".',\n 'Conformance.double': 'Take one integer and return it doubled. Arguments that do not fit - a string, none - fail it: a 500, not a refusal.',\n 'Conformance.invalidNested': 'Refuse the input with errors on the nested field \"address.city\" and on the form itself, under \"\".',\n '__rsc.middleware':\n 'Guards, run in the order named, stopping at the first that does not pass - none at all passes: \"conformance-allow\" passes; ' +\n '\"conformance-deny\" refuses; \"conformance-redirect\" sends the visitor to /conformance-login; a name with no guard refuses.',\n 'Conformance.change': 'Say the name \"conformance:changed\" changed, the way the adapter does from a webhook, and return \"ok\".',\n '__rsc.changed':\n 'Given { since: { name: version }, wait }: answer { versions } with every name whose version differs from since now, ' +\n 'and no other. A name never changed is at 0. A change moves a version to the larger of one past it and the time in ' +\n 'ms - never + 1 alone. May hold the call up to wait ms for one to differ; may answer at once.',\n} as const\n\nconst INSTANT = Date.parse('2026-01-02T03:04:05Z')\n\n/** Two JSON values alike, whatever order an object's keys were written in. */\nfunction sameValue(a: unknown, b: unknown): boolean {\n if (Array.isArray(a) || Array.isArray(b)) {\n return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((item, i) => sameValue(item, b[i]))\n }\n\n if (typeof a === 'object' && a !== null && typeof b === 'object' && b !== null) {\n const keys = Object.keys(a)\n\n return (\n keys.length === Object.keys(b).length &&\n keys.every((key) => sameValue((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n )\n }\n\n return a === b\n}\n\nconst ECHOES: unknown[] = [null, 0, -1.5, 'héllo ✓ \"quoted\"', [1, 'a', null], { a: { b: [true, false] }, c: '' }]\n\n/**\n * Run the suite against a client. Every case runs; none stops another.\n *\n * `revalidated` is where the client records what each call marked stale -\n * its onRevalidate - so the revalidation case can read it.\n */\nexport async function conformance(\n call: ConformanceCall,\n options: {\n revalidated: string[][]\n manifest?: ConformanceOptions['manifest']\n wrongSecret?: ConformanceCall\n /**\n * A POST straight to the endpoint, for what the client never sends:\n * malformed bodies, an oversized batch, no secret at all. `secret: false`\n * leaves the header off.\n */\n raw?: (body: string, options?: { secret?: boolean }) => Promise<Response>\n /** Where the adapter's purges arrive. Without one, the purge cases fail: every adapter purges. */\n purges?: PurgeInbox\n },\n): Promise<ConformanceResult[]> {\n const { revalidated, manifest, wrongSecret, raw, purges } = options\n const results: ConformanceResult[] = []\n const types = typeof manifest === 'string' ? JSON.parse(readFileSync(manifest, 'utf-8')) : manifest\n\n const check = async (name: string, run: () => Promise<void>) => {\n try {\n await run()\n results.push({ case: name, ok: true })\n } catch (error) {\n results.push({ case: name, ok: false, detail: error instanceof Error ? error.message : String(error) })\n }\n }\n\n const expect = (ok: boolean, detail: string) => {\n if (!ok) throw new Error(detail)\n }\n\n const rejection = async (run: () => Promise<unknown>): Promise<unknown> => {\n try {\n const value = await run()\n\n throw new Error('answered ' + JSON.stringify(value) + ' instead of refusing')\n } catch (error) {\n return error\n }\n }\n\n /** The value against the type the adapter's manifest declares, when it declares one. */\n const typed = (name: string, value: unknown) => {\n const schema = types?.types?.[name]?.result\n\n if (!schema) return\n\n const problem = conformsTo(value, schema, types?.defs ?? {}, 'result')\n\n expect(problem === null, `the manifest types ${name}'s result, and what arrived does not fit it: ${problem}`)\n }\n\n await check('the manifest lists every Conformance function', async () => {\n if (!types) return\n\n const missing = Object.keys(CASES).filter((n) => !n.startsWith('__') && !types.functions?.includes(n))\n\n expect(missing.length === 0, 'not in functions: ' + missing.join(', '))\n })\n\n await check('the manifest\\'s actions is an object, even with none', async () => {\n if (!types) return\n\n expect(\n typeof types.actions === 'object' && types.actions !== null && !Array.isArray(types.actions),\n 'actions is ' + JSON.stringify(types.actions),\n )\n })\n\n await check('a value of any JSON shape comes back unchanged', async () => {\n for (const value of ECHOES) {\n const back = await call('Conformance.echo', value)\n\n expect(JSON.stringify(back) === JSON.stringify(value), `sent ${JSON.stringify(value)}, got ${JSON.stringify(back)}`)\n }\n })\n\n await check('\"no rows\" is an empty list, never null', async () => {\n const value = await call('Conformance.emptyList')\n\n expect(Array.isArray(value) && value.length === 0, 'got ' + JSON.stringify(value))\n typed('Conformance.emptyList', value)\n })\n\n await check('a time is an ISO 8601 string of the same instant', async () => {\n const value = await call('Conformance.time')\n\n expect(typeof value === 'string' && Date.parse(value) === INSTANT, 'got ' + JSON.stringify(value))\n typed('Conformance.time', value)\n })\n\n await check('an absent time is null', async () => {\n const value = await call('Conformance.noTime')\n\n expect(value === null, 'got ' + JSON.stringify(value))\n typed('Conformance.noTime', value)\n })\n\n await check('not signed in is the engine\\'s ServerAuthenticationError', async () => {\n const error = await rejection(() => call('Conformance.unauthenticated'))\n\n expect(error instanceof ServerAuthenticationError, 'got ' + String(error))\n })\n\n await check('not allowed is the engine\\'s ServerAuthorizationError', async () => {\n const error = await rejection(() => call('Conformance.unauthorized'))\n\n expect(error instanceof ServerAuthorizationError, 'got ' + String(error))\n })\n\n await check('not found is the engine\\'s notFound()', async () => {\n const error = await rejection(() => call('Conformance.notFound'))\n\n expect(isNotFoundSignal(error), 'got ' + String(error))\n })\n\n await check('a refusal keeps its status and its message', async () => {\n const error = (await rejection(() => call('Conformance.refuse'))) as Error & { refusalStatus?: number }\n\n // A refusal, not a failure: an action shows its message rather than\n // onError's, data or no data.\n expect(isActionRefusal(error), 'raised as ' + String(error) + ', not as a refusal - is refusalStatus in the reply?')\n expect(error.refusalStatus === 429, 'status ' + String(error.refusalStatus))\n expect(String(error.message).includes('Slow down.'), 'message ' + JSON.stringify(error.message))\n })\n\n await check('a refusal carries its data, its message and its status', async () => {\n const error = (await rejection(() => call('Conformance.refuseWithData'))) as Error & {\n refusalStatus?: number\n data?: unknown\n }\n\n expect(isActionRefusal(error), 'raised as ' + String(error) + ', not as a refusal - is refusalData in the reply?')\n expect(error.message === 'Still in use', 'message ' + JSON.stringify(error.message))\n expect(error.refusalStatus === 409, 'status ' + String(error.refusalStatus))\n // Compared as values, not as text: an object's keys have no order, and\n // Go writes a map's sorted.\n expect(\n sameValue(error.data, { blockers: [{ id: 7, href: '/orders/7' }] }),\n 'data ' + JSON.stringify(error.data),\n )\n })\n\n await check('refused input names its field', async () => {\n const error = (await rejection(() => call('Conformance.invalid'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.name) && error.errors.name.length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('a redirect is the engine\\'s redirect, to where it said', async () => {\n const taken = await withRedirect(async (seen) => {\n await rejection(() => call('Conformance.redirect'))\n\n return seen()\n })\n\n expect(taken?.location === '/login', 'redirect ' + JSON.stringify(taken))\n expect(taken!.status >= 300 && taken!.status < 400, 'status ' + taken?.status)\n })\n\n await check('in a batch, a revalidation stays with its own call', async () => {\n const before = revalidated.length\n\n await Promise.all([call('Conformance.revalidate'), call('Conformance.echo', 1), call('Conformance.echo', 2)])\n\n expect(revalidated.length - before === 1, 'revalidated ' + JSON.stringify(revalidated.slice(before)))\n })\n\n await check('a revalidation rides with the result', async () => {\n const value = await call('Conformance.revalidate')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n expect(revalidated.some((r) => r.includes('orders')), 'revalidated ' + JSON.stringify(revalidated))\n })\n\n await check('an unexpected failure is an error, not a refusal', async () => {\n const error = (await rejection(() => call('Conformance.fail'))) as Error & { refusalStatus?: number }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) && !error.refusalStatus && !isNotFoundSignal(error),\n 'got ' + String(error),\n )\n })\n\n await check('the visitor\\'s Authorization header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { authorization: 'Bearer conformance' } }), () =>\n call('Conformance.authorization'),\n )\n\n expect(value === 'Bearer conformance', 'got ' + JSON.stringify(value))\n })\n\n await check('the visitor\\'s Cookie header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { cookie: 'conformance=1; other=2' } }), () =>\n call('Conformance.cookie'),\n )\n\n expect(typeof value === 'string' && value.includes('conformance=1') && value.includes('other=2'), 'got ' + JSON.stringify(value))\n })\n\n await check('a cookie set during a call - a login - reaches the page\\'s response', async () => {\n const cookies = await withRequest(new Request('https://app.test/'), () =>\n withResponseDraft(async ({ taken }) => {\n const value = await call('Conformance.login')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n return taken().getSetCookie()\n }),\n )\n\n expect(cookies.some((c) => c.startsWith('conformance_login=')), 'Set-Cookie ' + JSON.stringify(cookies))\n })\n\n await check('a flash is a cookie the browser reads, kept after one the visitor still carries', async () => {\n // A message from the page before, not yet shown, is in the visitor's\n // cookie; the new one goes after it rather than over it.\n const carried = encodeURIComponent(JSON.stringify([{ message: 'Earlier.', kind: 'info' }]))\n const cookies = await withRequest(new Request('https://app.test/', { headers: { Cookie: `${FLASH_COOKIE}=${carried}` } }), () =>\n withResponseDraft(async ({ taken }) => {\n const value = await call('Conformance.flash')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n return taken().getSetCookie()\n }),\n )\n const cookie = cookies.find((c) => c.startsWith(`${FLASH_COOKIE}=`))\n\n expect(cookie !== undefined, 'Set-Cookie ' + JSON.stringify(cookies))\n // useFlash reads it with document.cookie: an HttpOnly cookie is never seen.\n expect(!/;\\s*httponly/i.test(cookie!), 'HttpOnly, so useFlash cannot read it: ' + cookie)\n\n // Read as useFlash reads it. An encrypted value is not JSON, and reads as nothing.\n let raw: string | undefined\n\n try {\n raw = decodeURIComponent(cookie!.slice(FLASH_COOKIE.length + 1).split(';')[0]!)\n } catch {}\n\n const messages = readFlash(raw)\n\n expect(\n sameValue(messages, [\n { message: 'Earlier.', kind: 'info' },\n { message: 'Saved.', kind: 'success' },\n ]),\n 'read as ' + JSON.stringify(messages) + ' from ' + cookie,\n )\n })\n\n await check('arguments are decoded to their types', async () => {\n const value = await call('Conformance.double', 21)\n\n expect(value === 42, 'got ' + JSON.stringify(value))\n })\n\n await check('arguments that do not fit fail the call, not refuse it', async () => {\n for (const args of [['twenty-one'], []]) {\n const error: unknown = await rejection(() => call('Conformance.double', ...args))\n const fields = error as { refusalStatus?: number; errors?: unknown }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) &&\n !fields.refusalStatus && fields.errors === undefined && !isNotFoundSignal(error),\n `with ${JSON.stringify(args)}: got ` + String(error),\n )\n }\n })\n\n await check('refused input names nested fields with dots, and the form under \"\"', async () => {\n const error = (await rejection(() => call('Conformance.invalidNested'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.['address.city']) && error.errors['address.city'].length > 0, 'errors ' + JSON.stringify(error.errors))\n expect(Array.isArray(error.errors?.['']) && error.errors[''].length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('calls in one batch are each answered, a refusal only its own', async () => {\n const [a, b, c] = await Promise.allSettled([\n call('Conformance.echo', 1),\n call('Conformance.unauthenticated'),\n call('Conformance.echo', 2),\n ])\n\n expect(a.status === 'fulfilled' && a.value === 1, 'first ' + JSON.stringify(a))\n expect(b.status === 'rejected' && b.reason instanceof ServerAuthenticationError, 'second ' + String((b as PromiseRejectedResult).reason))\n expect(c.status === 'fulfilled' && c.value === 2, 'third ' + JSON.stringify(c))\n })\n\n await check('no guards at all passes: what a health check asks', async () => {\n // The renderer's /_rsc/health asks with an empty list: it runs no app\n // code, and still proves the address, the secret and the adapter.\n const value = await call('__rsc.middleware', [])\n\n expect(value === true, 'got ' + JSON.stringify(value))\n })\n\n await check('a guard that passes answers true', async () => {\n const value = await call('__rsc.middleware', ['conformance-allow'])\n\n expect(value === true, 'got ' + JSON.stringify(value))\n })\n\n await check('a guard that refuses refuses', async () => {\n const value = await call('__rsc.middleware', ['conformance-deny']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n await check('a guard can send the visitor somewhere else', async () => {\n const taken = await withRedirect(async (seen) => {\n await call('__rsc.middleware', ['conformance-redirect']).catch(() => {})\n\n return seen()\n })\n\n expect(taken?.location === '/conformance-login', 'redirect ' + JSON.stringify(taken))\n })\n\n await check('guards run in order and stop at the first that does not pass', async () => {\n const after = await call('__rsc.middleware', ['conformance-allow', 'conformance-deny']).catch((e: unknown) => e)\n\n expect(after !== true, 'allow then deny answered true')\n\n // Deny first: the redirect after it must never be asked.\n const taken = await withRedirect(async (seen) => {\n const value = await call('__rsc.middleware', ['conformance-deny', 'conformance-redirect']).catch((e: unknown) => e)\n\n expect(value !== true, 'deny then redirect answered true')\n\n return seen()\n })\n\n expect(taken === null, 'the guard after a refusal ran: redirected to ' + JSON.stringify(taken))\n })\n\n await check('a guard nobody registered refuses: fail closed', async () => {\n const value = await call('__rsc.middleware', ['conformance-nobody-registered-this']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n const versionsOf = async (query: { since: Record<string, number>; wait?: number }) => {\n const answer = (await call('__rsc.changed', query)) as { versions?: Record<string, number> } | null\n\n expect(typeof answer?.versions === 'object' && answer.versions !== null, 'got ' + JSON.stringify(answer))\n\n return answer!.versions!\n }\n\n await check('a name nobody changed is at version 0, and unchanged from 0', async () => {\n const all = await versionsOf({ since: { 'conformance:never': -1 } })\n\n expect(all['conformance:never'] === 0, 'from -1: ' + JSON.stringify(all))\n\n const none = await versionsOf({ since: { 'conformance:never': 0 } })\n\n expect(Object.keys(none).length === 0, 'from 0: ' + JSON.stringify(none))\n })\n\n await check('saying a name changed moves its version', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const value = await call('Conformance.change')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n const moved = await versionsOf({ since: { 'conformance:changed': before } })\n\n expect(typeof moved['conformance:changed'] === 'number' && moved['conformance:changed'] !== before, 'from ' + before + ': ' + JSON.stringify(moved))\n })\n\n await check('a version is the time of the change, and never comes round again', async () => {\n // The larger of one past the old version and the time in ms: a counter\n // repeats once a pruned name starts again from 0, and a tab holding the\n // old value misses the next change. A minute's leeway for clock skew.\n const started = Date.now()\n\n await call('Conformance.change')\n\n const first = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(first >= started - 60_000, `a change at ${started} moved the version to ${first}: not a time in ms`)\n\n await call('Conformance.change')\n\n const second = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(second > first, `a second change moved ${first} to ${second}`)\n })\n\n // A purge, and the version of conformance:changed the moment it arrived.\n const arrived: { purge: ArrivedPurge; version: number | null }[] = []\n\n purges?.(async (purge) => {\n const version = await versionsOf({ since: { 'conformance:changed': -1 } })\n .then((v) => v['conformance:changed'] ?? 0)\n .catch(() => null)\n\n arrived.push({ purge, version })\n })\n\n await check('a change is purged: its name is posted to HOMEPORT_PURGE_URL as a tag', async () => {\n expect(\n purges !== undefined,\n 'no purge was heard: start the adapter with HOMEPORT_PURGE_URL=http://127.0.0.1:<port>/ and run the suite with --purge-port <port>',\n )\n\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const from = arrived.length\n\n await call('Conformance.change')\n\n // After the answer is allowed: a purge may wait until the call has\n // answered, as the engine's own does.\n const deadline = Date.now() + 5_000\n let mine: (typeof arrived)[number] | undefined\n\n while (!mine && Date.now() < deadline) {\n mine = arrived.slice(from).find(({ purge }) => tagsOf(purge).includes('conformance:changed'))\n\n if (!mine) await new Promise((resolve) => setTimeout(resolve, 25))\n }\n\n expect(mine !== undefined, `nothing was posted naming conformance:changed within 5s (got ${JSON.stringify(arrived.slice(from).map((a) => a.purge.body))})`)\n\n const { purge, version } = mine!\n\n expect(purge.method === 'POST', 'sent with ' + purge.method)\n expect((purge.contentType ?? '').startsWith('application/json'), 'Content-Type ' + purge.contentType)\n // After the version moved: a purge that arrives first lets a CDN fetch the\n // page again from a backend still answering the old data, and keep it.\n expect(version !== null && version !== before, `the purge arrived before the change was made: conformance:changed was still ${version}`)\n })\n\n await check('a purge is { tags: [...] } and nothing a CDN would refuse', async () => {\n const mine = arrived.find(({ purge }) => tagsOf(purge).includes('conformance:changed'))\n\n expect(mine !== undefined, 'no purge arrived to check')\n\n const body = JSON.parse(mine!.purge.body) as Record<string, unknown>\n const unknown = Object.keys(body).filter((key) => !['tags', 'paths', 'all'].includes(key))\n\n expect(unknown.length === 0, 'unknown keys: ' + unknown.join(', '))\n expect(Array.isArray(body.tags) && body.tags.every((t) => typeof t === 'string'), 'tags is ' + JSON.stringify(body.tags))\n expect((body.tags as string[]).length <= 100, 'more than 100 tags in one call')\n })\n\n await check('only the names that differ are answered', async () => {\n const current = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const answer = await versionsOf({ since: { 'conformance:changed': current, 'conformance:never': 5 } })\n\n expect(JSON.stringify(answer) === JSON.stringify({ 'conformance:never': 0 }), 'got ' + JSON.stringify(answer))\n })\n\n await check('waiting for a name to change is bounded by wait', async () => {\n const started = Date.now()\n const none = await versionsOf({ since: { 'conformance:never': 0 }, wait: 300 })\n const took = Date.now() - started\n\n expect(Object.keys(none).length === 0, 'got ' + JSON.stringify(none))\n expect(took < 3_000, 'took ' + took + 'ms')\n })\n\n if (raw) {\n const statusOf = async (body: string, secret = true) => (await raw(body, { secret })).status\n\n await check('a call with no secret at all is refused, 403', async () => {\n const status = await statusOf(JSON.stringify({ function: 'Conformance.echo', args: [1] }), false)\n\n expect(status === 403, 'answered ' + status)\n })\n\n await check('a function nobody registered is a 404', async () => {\n const status = await statusOf(JSON.stringify({ function: 'Conformance.nobodyRegisteredThis', args: [] }))\n\n expect(status === 404, 'answered ' + status)\n })\n\n await check('a malformed call is a 400: not JSON, no function, args not a list', async () => {\n for (const body of ['not json', JSON.stringify({ args: [] }), JSON.stringify({ function: 'Conformance.echo', args: 'x' })]) {\n const status = await statusOf(body)\n\n expect(status === 400, `${body} answered ${status}`)\n }\n })\n\n await check('a batch of more than 50 is refused, 413, before any call runs', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const calls = Array.from({ length: 51 }, () => ({ function: 'Conformance.change', args: [] }))\n const status = await statusOf(JSON.stringify({ calls }))\n const after = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(status === 413, 'answered ' + status)\n expect(after === before, 'calls ran: conformance:changed moved from ' + before + ' to ' + after)\n })\n }\n\n if (wrongSecret) {\n await check('a call with the wrong secret is refused', async () => {\n const value = await wrongSecret('Conformance.echo', 'should not run').catch((e: unknown) => e)\n\n expect(value !== 'should not run', 'it ran')\n })\n }\n\n return results\n}\n\n/** The tags a purge names; none when its body is not one. */\nfunction tagsOf(purge: ArrivedPurge): string[] {\n try {\n const tags = (JSON.parse(purge.body) as { tags?: unknown }).tags\n\n return Array.isArray(tags) ? tags.filter((t): t is string => typeof t === 'string') : []\n } catch {\n return []\n }\n}\n\n/** Hear purges on 127.0.0.1:port, answering each 202 once the suite has looked. */\nasync function listenForPurges(port: number): Promise<{ inbox: PurgeInbox; close: () => Promise<void> }> {\n const { createServer } = await import('node:http')\n let handler: ((purge: ArrivedPurge) => Promise<void>) | undefined\n\n const server = createServer((request, response) => {\n let body = ''\n\n request.setEncoding('utf8')\n request.on('data', (chunk: string) => (body += chunk))\n request.on('end', () => {\n const purge = { method: request.method ?? '', contentType: request.headers['content-type'] ?? null, body }\n\n void (handler ? handler(purge) : Promise.resolve()).finally(() => {\n response.writeHead(202).end()\n })\n })\n })\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject)\n server.listen(port, '127.0.0.1', resolve)\n })\n\n return {\n inbox: (next) => {\n handler = next\n },\n close: () => new Promise((resolve) => server.close(() => resolve())),\n }\n}\n\n/** Run the suite against an adapter's endpoint. */\nexport async function runConformance(options: ConformanceOptions): Promise<ConformanceResult[]> {\n const revalidated: string[][] = []\n const client = (secret: string) =>\n httpHostCalls({\n endpoint: options.endpoint,\n secret,\n fetch: options.fetch,\n onRevalidate: (targets) => revalidated.push(targets),\n })\n\n const doFetch = options.fetch ?? globalThis.fetch\n const listening = options.purgePort ? await listenForPurges(options.purgePort) : null\n\n try {\n return await suite()\n } finally {\n await listening?.close()\n }\n\n async function suite() {\n return await conformance(client(options.secret), {\n purges: listening?.inbox,\n revalidated,\n manifest: options.manifest,\n wrongSecret: client(options.secret + '-wrong'),\n raw: (body, { secret = true } = {}) =>\n doFetch(options.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...(secret ? { 'x-rsc-host-secret': options.secret } : {}) },\n body,\n }),\n })\n }\n}\n\n/**\n * Whether a value fits the JSON Schema subset the manifest uses. Null when it\n * does; otherwise where and why it does not.\n */\nexport function conformsTo(value: unknown, schema: Schema, defs: Record<string, Schema>, at: string): string | null {\n if (!schema || Object.keys(schema).length === 0) return null\n\n const ref = schema.$ref\n\n if (typeof ref === 'string' && ref.startsWith('#/defs/')) {\n const target = defs[ref.slice(7)]\n\n return target ? conformsTo(value, target, defs, at) : `${at}: ${ref} is not in defs`\n }\n\n if (Array.isArray(schema.anyOf)) {\n const fits = (schema.anyOf as Schema[]).some((s) => conformsTo(value, s, defs, at) === null)\n\n return fits ? null : `${at}: ${JSON.stringify(value)} is none of ${JSON.stringify(schema.anyOf)}`\n }\n\n if (Array.isArray(schema.enum)) {\n return (schema.enum as unknown[]).includes(value) ? null : `${at}: ${JSON.stringify(value)} is not one of ${JSON.stringify(schema.enum)}`\n }\n\n const kind = Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value\n\n switch (schema.type) {\n case 'string':\n if (kind !== 'string') return `${at}: expected a string, got ${JSON.stringify(value)}`\n if (schema.format === 'date-time' && Number.isNaN(Date.parse(value as string))) return `${at}: ${JSON.stringify(value)} is not a date-time`\n return null\n case 'integer':\n return Number.isInteger(value) ? null : `${at}: expected an integer, got ${JSON.stringify(value)}`\n case 'number':\n return kind === 'number' ? null : `${at}: expected a number, got ${JSON.stringify(value)}`\n case 'boolean':\n return kind === 'boolean' ? null : `${at}: expected a boolean, got ${JSON.stringify(value)}`\n case 'null':\n return value === null ? null : `${at}: expected null, got ${JSON.stringify(value)}`\n case 'array': {\n if (kind !== 'array') return `${at}: expected an array, got ${JSON.stringify(value)}`\n for (const [i, item] of (value as unknown[]).entries()) {\n const problem = conformsTo(item, schema.items as Schema, defs, `${at}[${i}]`)\n if (problem) return problem\n }\n return null\n }\n case 'object': {\n if (kind !== 'object') return `${at}: expected an object, got ${JSON.stringify(value)}`\n const object = value as Record<string, unknown>\n const properties = (schema.properties ?? {}) as Record<string, Schema>\n for (const name of (schema.required as string[] | undefined) ?? []) {\n if (!(name in object)) return `${at}.${name}: required, and missing`\n }\n for (const [name, s] of Object.entries(properties)) {\n if (name in object) {\n const problem = conformsTo(object[name], s, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n const extra = schema.additionalProperties as Schema | undefined\n if (extra && !schema.properties) {\n for (const [name, item] of Object.entries(object)) {\n const problem = conformsTo(item, extra, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n return null\n }\n default:\n return null\n }\n}\n\n/** Print a result table, and say whether the adapter conforms. */\nexport function report(results: ConformanceResult[]): boolean {\n for (const r of results) {\n stdout.write(` ${r.ok ? '✓' : '✗'} ${r.case}${r.ok ? '' : '\\n ' + r.detail}\\n`)\n }\n\n const failed = results.filter((r) => !r.ok).length\n\n stdout.write(failed === 0 ? `\\n conforms: ${results.length} cases\\n` : `\\n ${failed} of ${results.length} cases failed\\n`)\n\n return failed === 0\n}\n\n// Run as a command, not when imported.\nif (import.meta.url === pathToFileURL(argv[1] ?? '').href || argv[1]?.endsWith('rsc-kit-conformance')) {\n const flag = (name: string) => {\n const at = argv.indexOf('--' + name)\n\n return at === -1 ? undefined : argv[at + 1]\n }\n\n const endpoint = flag('endpoint')\n const secret = flag('secret')\n\n if (!endpoint || !secret) {\n stderr.write('usage: rsc-kit-conformance --endpoint <url> --secret <secret> --purge-port <port> [--manifest rsc-host.json]\\n')\n exit(2)\n }\n\n const purgePort = flag('purge-port')\n\n runConformance({ endpoint, secret, manifest: flag('manifest'), purgePort: purgePort ? Number(purgePort) : undefined })\n .then((results) => exit(report(results) ? 0 : 1))\n .catch((error: unknown) => {\n stderr.write('rsc-kit-conformance: ' + (error instanceof Error ? error.message : String(error)) + '\\n')\n exit(1)\n })\n}\n"]}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Telling a CDN that kept pages changed.
3
+ *
4
+ * A `revalidate` page goes out with `Cache-Tag`, and a CDN that purges by tag
5
+ * can drop it the moment one of those tags changes, rather than waiting out
6
+ * `s-maxage`. What calls the purge is the app's: every CDN has its own API, so
7
+ * the engine has one hook, `installPurge()`, and `changed(tag)` calls it with
8
+ * the names that changed - after the answer has gone, through `after()`, so a
9
+ * slow CDN never holds up the action that made the change.
10
+ *
11
+ * Homeport is the one installed for you: with `HOMEPORT_PURGE_URL` set, the
12
+ * hook is `homeportPurge()` unless the app installed another.
13
+ *
14
+ * A Laravel or Go backend changes its names itself (`Rsc::changed()`,
15
+ * `rsckit.Changed()`), and the engine never hears of it, so each backend
16
+ * purges for its own changes. This hook covers `changed()` called here.
17
+ */
18
+ /** What a purge drops: pages carrying any of these tags, pages at these paths, or everything. */
19
+ export interface Purge {
20
+ tags?: readonly string[];
21
+ paths?: readonly string[];
22
+ all?: boolean;
23
+ }
24
+ /** Sends a purge to a CDN. A rejection is logged; it never fails the change. */
25
+ export type Purger = (purge: Purge) => Promise<void> | void;
26
+ /** Install the app's purge. `null` takes it out, and Homeport's default with it. */
27
+ export declare function installPurge(purger: Purger | null): void;
28
+ /** The purge in use: the app's, else Homeport's when its url is set, else none. */
29
+ export declare function installedPurge(): Purger | null;
30
+ /**
31
+ * @internal For changed(): purge these tags once the answer has gone, or at
32
+ * once outside a request. Does nothing when no purge is installed.
33
+ */
34
+ export declare function purgeLater(tags: readonly string[]): void;
35
+ /**
36
+ * Send a purge now, through the installed purge. For an app's own use - a
37
+ * deploy step, a webhook - as well as changed()'s. Never throws: the change
38
+ * it follows is already made, and a CDN that missed it still drops the copy
39
+ * at `s-maxage`. The first failure is logged.
40
+ */
41
+ export declare function purge(what: Purge): Promise<void>;
42
+ /** Homeport takes at most this many tags, and this many paths, per call. */
43
+ export declare const HOMEPORT_PURGE_LIMIT = 100;
44
+ export interface HomeportPurgeOptions {
45
+ /** Where to post. Default `HOMEPORT_PURGE_URL`, which Homeport sets. */
46
+ url?: string;
47
+ /** For tests. */
48
+ fetch?: typeof fetch;
49
+ }
50
+ /**
51
+ * Homeport's purge: `POST {tags, paths, all}` to the url Homeport gives the
52
+ * app, no token - it is reachable only from inside the app's own network.
53
+ * Split into calls of 100 tags and 100 paths. A 429 is tried once more after
54
+ * its `Retry-After` (at most five seconds); anything else that is not a 2xx
55
+ * rejects.
56
+ */
57
+ export declare function homeportPurge(options?: HomeportPurgeOptions): Purger;
package/dist/purge.js ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Telling a CDN that kept pages changed.
3
+ *
4
+ * A `revalidate` page goes out with `Cache-Tag`, and a CDN that purges by tag
5
+ * can drop it the moment one of those tags changes, rather than waiting out
6
+ * `s-maxage`. What calls the purge is the app's: every CDN has its own API, so
7
+ * the engine has one hook, `installPurge()`, and `changed(tag)` calls it with
8
+ * the names that changed - after the answer has gone, through `after()`, so a
9
+ * slow CDN never holds up the action that made the change.
10
+ *
11
+ * Homeport is the one installed for you: with `HOMEPORT_PURGE_URL` set, the
12
+ * hook is `homeportPurge()` unless the app installed another.
13
+ *
14
+ * A Laravel or Go backend changes its names itself (`Rsc::changed()`,
15
+ * `rsckit.Changed()`), and the engine never hears of it, so each backend
16
+ * purges for its own changes. This hook covers `changed()` called here.
17
+ */
18
+ function hooks() {
19
+ return (globalThis[Symbol.for("rsc-kit.after")] ?? {
20
+ after: (work) => void Promise.resolve().then(work),
21
+ requestKey: () => null,
22
+ });
23
+ }
24
+ // On the global, like the cache store: an app installs through its own copy
25
+ // of the package, and the engine's copy is the one that calls it.
26
+ const PURGER = Symbol.for("rsc-kit.purger");
27
+ const globals = globalThis;
28
+ /** Install the app's purge. `null` takes it out, and Homeport's default with it. */
29
+ export function installPurge(purger) {
30
+ globals[PURGER] = purger;
31
+ }
32
+ /** The purge in use: the app's, else Homeport's when its url is set, else none. */
33
+ export function installedPurge() {
34
+ const installed = globals[PURGER];
35
+ if (installed !== undefined)
36
+ return installed;
37
+ const url = homeportPurgeUrl();
38
+ return url ? homeportPurge({ url }) : null;
39
+ }
40
+ function homeportPurgeUrl() {
41
+ return globalThis.process?.env?.HOMEPORT_PURGE_URL || undefined;
42
+ }
43
+ // The names an action changed go out as one purge when its answer has gone:
44
+ // three changed() calls send one request, not three. Gathered per request,
45
+ // so a request whose after() work never ran cannot hold back another's.
46
+ const pendingFor = new WeakMap();
47
+ /**
48
+ * @internal For changed(): purge these tags once the answer has gone, or at
49
+ * once outside a request. Does nothing when no purge is installed.
50
+ */
51
+ export function purgeLater(tags) {
52
+ if (tags.length === 0 || !installedPurge())
53
+ return;
54
+ const { after, requestKey } = hooks();
55
+ const key = requestKey();
56
+ if (!key) {
57
+ after(() => purge({ tags }));
58
+ return;
59
+ }
60
+ let pending = pendingFor.get(key);
61
+ if (pending) {
62
+ for (const tag of tags)
63
+ pending.add(tag);
64
+ return;
65
+ }
66
+ pending = new Set(tags);
67
+ pendingFor.set(key, pending);
68
+ const gathered = pending;
69
+ after(() => {
70
+ pendingFor.delete(key);
71
+ return purge({ tags: [...gathered] });
72
+ });
73
+ }
74
+ let warnedPurge = false;
75
+ /**
76
+ * Send a purge now, through the installed purge. For an app's own use - a
77
+ * deploy step, a webhook - as well as changed()'s. Never throws: the change
78
+ * it follows is already made, and a CDN that missed it still drops the copy
79
+ * at `s-maxage`. The first failure is logged.
80
+ */
81
+ export async function purge(what) {
82
+ const purger = installedPurge();
83
+ if (!purger)
84
+ return;
85
+ try {
86
+ await purger(what);
87
+ }
88
+ catch (error) {
89
+ if (!warnedPurge) {
90
+ warnedPurge = true;
91
+ console.warn("[rsc-kit] purging the CDN failed; its copy is dropped at s-maxage instead: " +
92
+ (error instanceof Error ? error.message : String(error)));
93
+ }
94
+ }
95
+ }
96
+ /** Homeport takes at most this many tags, and this many paths, per call. */
97
+ export const HOMEPORT_PURGE_LIMIT = 100;
98
+ /**
99
+ * Homeport's purge: `POST {tags, paths, all}` to the url Homeport gives the
100
+ * app, no token - it is reachable only from inside the app's own network.
101
+ * Split into calls of 100 tags and 100 paths. A 429 is tried once more after
102
+ * its `Retry-After` (at most five seconds); anything else that is not a 2xx
103
+ * rejects.
104
+ */
105
+ export function homeportPurge(options = {}) {
106
+ return async (what) => {
107
+ const url = options.url ?? homeportPurgeUrl();
108
+ if (!url)
109
+ throw new Error("homeportPurge() has no url: HOMEPORT_PURGE_URL is not set.");
110
+ const send = options.fetch ?? fetch;
111
+ const tags = [...(what.tags ?? [])];
112
+ const paths = [...(what.paths ?? [])];
113
+ const bodies = [];
114
+ if (what.all)
115
+ bodies.push({ all: true });
116
+ while (tags.length > 0 || paths.length > 0) {
117
+ const body = {};
118
+ const someTags = tags.splice(0, HOMEPORT_PURGE_LIMIT);
119
+ const somePaths = paths.splice(0, HOMEPORT_PURGE_LIMIT);
120
+ if (someTags.length > 0)
121
+ body.tags = someTags;
122
+ if (somePaths.length > 0)
123
+ body.paths = somePaths;
124
+ bodies.push(body);
125
+ }
126
+ for (const body of bodies) {
127
+ await post(send, url, body);
128
+ }
129
+ };
130
+ }
131
+ async function post(send, url, body, retried = false) {
132
+ const response = await send(url, {
133
+ method: "POST",
134
+ headers: { "Content-Type": "application/json" },
135
+ body: JSON.stringify(body),
136
+ });
137
+ await response.body?.cancel();
138
+ if (response.ok)
139
+ return;
140
+ if (response.status === 429 && !retried) {
141
+ const seconds = Math.min(Number(response.headers.get("Retry-After")) || 1, 5);
142
+ await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
143
+ return post(send, url, body, true);
144
+ }
145
+ throw new Error(`Homeport answered ${response.status} to a purge of ${JSON.stringify(body)}.`);
146
+ }
147
+ //# sourceMappingURL=purge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"purge.js","sourceRoot":"","sources":["../src/purge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Telling a CDN that kept pages changed.\n *\n * A `revalidate` page goes out with `Cache-Tag`, and a CDN that purges by tag\n * can drop it the moment one of those tags changes, rather than waiting out\n * `s-maxage`. What calls the purge is the app's: every CDN has its own API, so\n * the engine has one hook, `installPurge()`, and `changed(tag)` calls it with\n * the names that changed - after the answer has gone, through `after()`, so a\n * slow CDN never holds up the action that made the change.\n *\n * Homeport is the one installed for you: with `HOMEPORT_PURGE_URL` set, the\n * hook is `homeportPurge()` unless the app installed another.\n *\n * A Laravel or Go backend changes its names itself (`Rsc::changed()`,\n * `rsckit.Changed()`), and the engine never hears of it, so each backend\n * purges for its own changes. This hook covers `changed()` called here.\n */\n\n// Not imported: @rsc-kit/core/changed reaches this file and a client component\n// may import that, so request.ts - server-only - is found through the global\n// it sets when the server loads it. Without it, there is no request to wait\n// for, and a purge goes out at once.\ntype AfterHooks = { after: (work: () => unknown) => void; requestKey: () => object | null };\n\nfunction hooks(): AfterHooks {\n return (\n ((globalThis as Record<symbol, unknown>)[Symbol.for(\"rsc-kit.after\")] as AfterHooks | undefined) ?? {\n after: (work) => void Promise.resolve().then(work),\n requestKey: () => null,\n }\n );\n}\n\n/** What a purge drops: pages carrying any of these tags, pages at these paths, or everything. */\nexport interface Purge {\n tags?: readonly string[];\n paths?: readonly string[];\n all?: boolean;\n}\n\n/** Sends a purge to a CDN. A rejection is logged; it never fails the change. */\nexport type Purger = (purge: Purge) => Promise<void> | void;\n\n// On the global, like the cache store: an app installs through its own copy\n// of the package, and the engine's copy is the one that calls it.\nconst PURGER = Symbol.for(\"rsc-kit.purger\");\nconst globals = globalThis as unknown as Record<symbol, Purger | null | undefined>;\n\n/** Install the app's purge. `null` takes it out, and Homeport's default with it. */\nexport function installPurge(purger: Purger | null): void {\n globals[PURGER] = purger;\n}\n\n/** The purge in use: the app's, else Homeport's when its url is set, else none. */\nexport function installedPurge(): Purger | null {\n const installed = globals[PURGER];\n\n if (installed !== undefined) return installed;\n\n const url = homeportPurgeUrl();\n\n return url ? homeportPurge({ url }) : null;\n}\n\nfunction homeportPurgeUrl(): string | undefined {\n return (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env?.HOMEPORT_PURGE_URL || undefined;\n}\n\n// The names an action changed go out as one purge when its answer has gone:\n// three changed() calls send one request, not three. Gathered per request,\n// so a request whose after() work never ran cannot hold back another's.\nconst pendingFor = new WeakMap<object, Set<string>>();\n\n/**\n * @internal For changed(): purge these tags once the answer has gone, or at\n * once outside a request. Does nothing when no purge is installed.\n */\nexport function purgeLater(tags: readonly string[]): void {\n if (tags.length === 0 || !installedPurge()) return;\n\n const { after, requestKey } = hooks();\n const key = requestKey();\n\n if (!key) {\n after(() => purge({ tags }));\n\n return;\n }\n\n let pending = pendingFor.get(key);\n\n if (pending) {\n for (const tag of tags) pending.add(tag);\n\n return;\n }\n\n pending = new Set(tags);\n pendingFor.set(key, pending);\n\n const gathered = pending;\n\n after(() => {\n pendingFor.delete(key);\n\n return purge({ tags: [...gathered] });\n });\n}\n\nlet warnedPurge = false;\n\n/**\n * Send a purge now, through the installed purge. For an app's own use - a\n * deploy step, a webhook - as well as changed()'s. Never throws: the change\n * it follows is already made, and a CDN that missed it still drops the copy\n * at `s-maxage`. The first failure is logged.\n */\nexport async function purge(what: Purge): Promise<void> {\n const purger = installedPurge();\n\n if (!purger) return;\n\n try {\n await purger(what);\n } catch (error) {\n if (!warnedPurge) {\n warnedPurge = true;\n console.warn(\n \"[rsc-kit] purging the CDN failed; its copy is dropped at s-maxage instead: \" +\n (error instanceof Error ? error.message : String(error)),\n );\n }\n }\n}\n\n/** Homeport takes at most this many tags, and this many paths, per call. */\nexport const HOMEPORT_PURGE_LIMIT = 100;\n\nexport interface HomeportPurgeOptions {\n /** Where to post. Default `HOMEPORT_PURGE_URL`, which Homeport sets. */\n url?: string;\n /** For tests. */\n fetch?: typeof fetch;\n}\n\n/**\n * Homeport's purge: `POST {tags, paths, all}` to the url Homeport gives the\n * app, no token - it is reachable only from inside the app's own network.\n * Split into calls of 100 tags and 100 paths. A 429 is tried once more after\n * its `Retry-After` (at most five seconds); anything else that is not a 2xx\n * rejects.\n */\nexport function homeportPurge(options: HomeportPurgeOptions = {}): Purger {\n return async (what) => {\n const url = options.url ?? homeportPurgeUrl();\n\n if (!url) throw new Error(\"homeportPurge() has no url: HOMEPORT_PURGE_URL is not set.\");\n\n const send = options.fetch ?? fetch;\n const tags = [...(what.tags ?? [])];\n const paths = [...(what.paths ?? [])];\n const bodies: Purge[] = [];\n\n if (what.all) bodies.push({ all: true });\n\n while (tags.length > 0 || paths.length > 0) {\n const body: Purge = {};\n const someTags = tags.splice(0, HOMEPORT_PURGE_LIMIT);\n const somePaths = paths.splice(0, HOMEPORT_PURGE_LIMIT);\n\n if (someTags.length > 0) body.tags = someTags;\n if (somePaths.length > 0) body.paths = somePaths;\n bodies.push(body);\n }\n\n for (const body of bodies) {\n await post(send, url, body);\n }\n };\n}\n\nasync function post(send: typeof fetch, url: string, body: Purge, retried = false): Promise<void> {\n const response = await send(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n await response.body?.cancel();\n\n if (response.ok) return;\n\n if (response.status === 429 && !retried) {\n const seconds = Math.min(Number(response.headers.get(\"Retry-After\")) || 1, 5);\n\n await new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n\n return post(send, url, body, true);\n }\n\n throw new Error(`Homeport answered ${response.status} to a purge of ${JSON.stringify(body)}.`);\n}\n"]}
package/dist/request.d.ts CHANGED
@@ -270,6 +270,12 @@ export declare function noteFallback(text: string): void;
270
270
  * gone. Outside a request - a build - the work runs at once.
271
271
  */
272
272
  export declare function after(work: () => unknown): void;
273
+ /**
274
+ * @internal The request being answered, as an object to key per-request
275
+ * state on - null outside one. For work that gathers itself into one after():
276
+ * a purge of every name an action changed.
277
+ */
278
+ export declare function requestKey(): object | null;
273
279
  /**
274
280
  * @internal For the host: the work `after()` collected for this request, as
275
281
  * one promise that never rejects. Taken once; a second call has nothing.
package/dist/request.js CHANGED
@@ -742,6 +742,18 @@ export function after(work) {
742
742
  }
743
743
  store.after.push(work);
744
744
  }
745
+ /**
746
+ * @internal The request being answered, as an object to key per-request
747
+ * state on - null outside one. For work that gathers itself into one after():
748
+ * a purge of every name an action changed.
749
+ */
750
+ export function requestKey() {
751
+ const store = scope()?.getStore();
752
+ return store?.request ? store : null;
753
+ }
754
+ // For purge.ts, which @rsc-kit/core/changed brings into client code and so
755
+ // cannot import this file: the two calls it needs, on the global.
756
+ globalThis[Symbol.for("rsc-kit.after")] = { after, requestKey };
745
757
  function reportAfter(error) {
746
758
  console.error("[rsc-kit] after() work failed:", error);
747
759
  }