@rsc-kit/core 0.29.10 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/action.d.ts +69 -9
  2. package/dist/action.js +78 -3
  3. package/dist/action.js.map +1 -1
  4. package/dist/conformance.d.ts +1 -0
  5. package/dist/conformance.js +24 -0
  6. package/dist/conformance.js.map +1 -1
  7. package/dist/headers.d.ts +0 -5
  8. package/dist/headers.js +0 -5
  9. package/dist/headers.js.map +1 -1
  10. package/dist/host.d.ts +3 -8
  11. package/dist/host.js +49 -73
  12. package/dist/host.js.map +1 -1
  13. package/dist/hostCalls.d.ts +7 -0
  14. package/dist/hostCalls.js +7 -1
  15. package/dist/hostCalls.js.map +1 -1
  16. package/dist/inlineFlight.d.ts +9 -0
  17. package/dist/inlineFlight.js +126 -0
  18. package/dist/inlineFlight.js.map +1 -0
  19. package/dist/js/Form.d.ts +24 -6
  20. package/dist/js/Form.js +11 -2
  21. package/dist/js/Form.js.map +1 -1
  22. package/dist/js/SegmentBoundary.js +4 -14
  23. package/dist/js/SegmentBoundary.js.map +1 -1
  24. package/dist/js/createViteRscApp.js +5 -8
  25. package/dist/js/createViteRscApp.js.map +1 -1
  26. package/dist/js/inlinePayload.d.ts +6 -0
  27. package/dist/js/inlinePayload.js +56 -0
  28. package/dist/js/inlinePayload.js.map +1 -0
  29. package/dist/js/pagePayload.d.ts +1 -1
  30. package/dist/js/pagePayload.js +2 -2
  31. package/dist/js/pagePayload.js.map +1 -1
  32. package/dist/js/useAction.d.ts +9 -6
  33. package/dist/js/useAction.js.map +1 -1
  34. package/dist/testHost.d.ts +6 -2
  35. package/dist/testHost.js +6 -2
  36. package/dist/testHost.js.map +1 -1
  37. package/dist/testing.d.ts +16 -0
  38. package/dist/testing.js +30 -1
  39. package/dist/testing.js.map +1 -1
  40. package/dist/vite.js +61 -24
  41. package/dist/vite.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/bootPayloads.d.ts +0 -18
  44. package/dist/bootPayloads.js +0 -81
  45. package/dist/bootPayloads.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsc-kit/core",
3
- "version": "0.29.10",
3
+ "version": "0.30.1",
4
4
  "description": "React Server Components as a Vite plugin. Routing, streaming, server actions, typed urls and build-time prerendering — deploy to Bun, Node, Workers, Vercel or Deno.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,18 +0,0 @@
1
- /** How long a payload waits for its browser. */
2
- export declare const BOOT_HOLD_MS = 10000;
3
- export interface HeldPayload {
4
- payload: ReadableStream;
5
- /** The headers the boot answer carries beside the payload: the layout chain, the depth. */
6
- headers: Record<string, string>;
7
- at: number;
8
- }
9
- /** A token no one can guess: 128 bits, url-safe. */
10
- export declare function bootToken(): string;
11
- /** Keep a render's payload for the boot fetch that follows its document. */
12
- export declare function holdBootPayload(token: string, payload: ReadableStream, headers: Record<string, string>, now?: number): void;
13
- /** The payload for a token, once. Null for a token not held, redeemed or expired. */
14
- export declare function takeBootPayload(token: string, now?: number): HeldPayload | null;
15
- /** How many are held, for tests. */
16
- export declare function heldBootPayloads(): number;
17
- /** Forget everything, for tests. */
18
- export declare function clearBootPayloads(): void;
@@ -1,81 +0,0 @@
1
- // One render per visit.
2
- //
3
- // Hydrating server components needs the serialised tree, not the HTML, and a
4
- // document does not carry its own payload - inlined, decode and hydration
5
- // become one long task (#231). So the client fetches it, and that fetch used
6
- // to render the whole page a second time: the same reads, the same queries,
7
- // a moment after the document's render had made exactly that payload and
8
- // thrown it away.
9
- //
10
- // Now the document's render keeps its payload here for the few seconds it
11
- // takes the browser to come back for it, under a token written into the
12
- // document that only that browser holds. The boot fetch redeems the token
13
- // and is answered with the payload the document was made from - which is
14
- // also the one it should hydrate against: two renders a moment apart could
15
- // disagree, and the one that made the HTML cannot.
16
- //
17
- // A token is redeemed once. A payload nobody comes back for - a route with
18
- // no runtime, a browser that left, a Worker isolate other than the one that
19
- // rendered - is cancelled when it expires, and the boot fetch that misses
20
- // renders as it always did. Missing costs a render; it never costs a wrong
21
- // answer.
22
- /** How long a payload waits for its browser. */
23
- export const BOOT_HOLD_MS = 10_000;
24
- /** At most this many held at once; the oldest is dropped first. */
25
- const MAX_HELD = 500;
26
- const held = new Map();
27
- /** A token no one can guess: 128 bits, url-safe. */
28
- export function bootToken() {
29
- const bytes = new Uint8Array(16);
30
- crypto.getRandomValues(bytes);
31
- let out = "";
32
- for (const b of bytes)
33
- out += b.toString(16).padStart(2, "0");
34
- return out;
35
- }
36
- /** Keep a render's payload for the boot fetch that follows its document. */
37
- export function holdBootPayload(token, payload, headers, now = Date.now()) {
38
- sweep(now);
39
- if (held.size >= MAX_HELD) {
40
- const oldest = held.keys().next().value;
41
- if (oldest !== undefined)
42
- drop(oldest);
43
- }
44
- held.set(token, { payload, headers, at: now });
45
- }
46
- /** The payload for a token, once. Null for a token not held, redeemed or expired. */
47
- export function takeBootPayload(token, now = Date.now()) {
48
- const found = held.get(token);
49
- if (!found)
50
- return null;
51
- held.delete(token);
52
- if (now - found.at >= BOOT_HOLD_MS) {
53
- void found.payload.cancel().catch(() => { });
54
- return null;
55
- }
56
- return found;
57
- }
58
- /** Let go of what nobody came back for. */
59
- function sweep(now) {
60
- for (const [token, entry] of held) {
61
- if (now - entry.at < BOOT_HOLD_MS)
62
- break;
63
- drop(token);
64
- }
65
- }
66
- function drop(token) {
67
- const entry = held.get(token);
68
- held.delete(token);
69
- if (entry)
70
- void entry.payload.cancel().catch(() => { });
71
- }
72
- /** How many are held, for tests. */
73
- export function heldBootPayloads() {
74
- return held.size;
75
- }
76
- /** Forget everything, for tests. */
77
- export function clearBootPayloads() {
78
- for (const token of [...held.keys()])
79
- drop(token);
80
- }
81
- //# sourceMappingURL=bootPayloads.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bootPayloads.js","sourceRoot":"","sources":["../src/bootPayloads.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,6EAA6E;AAC7E,4EAA4E;AAC5E,yEAAyE;AACzE,kBAAkB;AAClB,EAAE;AACF,0EAA0E;AAC1E,wEAAwE;AACxE,0EAA0E;AAC1E,yEAAyE;AACzE,2EAA2E;AAC3E,mDAAmD;AACnD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,UAAU;AAEV,gDAAgD;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAEnC,mEAAmE;AACnE,MAAM,QAAQ,GAAG,GAAG,CAAC;AASrB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAC;AAE5C,oDAAoD;AACpD,MAAM,UAAU,SAAS;IACvB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAEjC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAE9B,IAAI,GAAG,GAAG,EAAE,CAAC;IAEb,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE9D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,OAAuB,EACvB,OAA+B,EAC/B,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAEhB,KAAK,CAAC,GAAG,CAAC,CAAC;IAEX,IAAI,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QAExC,IAAI,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;AACjD,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAE9B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnB,IAAI,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,YAAY,EAAE,CAAC;QACnC,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAE5C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,2CAA2C;AAC3C,SAAS,KAAK,CAAC,GAAW;IACxB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAClC,IAAI,GAAG,GAAG,KAAK,CAAC,EAAE,GAAG,YAAY;YAAE,MAAM;QAEzC,IAAI,CAAC,KAAK,CAAC,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,KAAa;IACzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAE9B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnB,IAAI,KAAK;QAAE,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,iBAAiB;IAC/B,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC","sourcesContent":["// One render per visit.\n//\n// Hydrating server components needs the serialised tree, not the HTML, and a\n// document does not carry its own payload - inlined, decode and hydration\n// become one long task (#231). So the client fetches it, and that fetch used\n// to render the whole page a second time: the same reads, the same queries,\n// a moment after the document's render had made exactly that payload and\n// thrown it away.\n//\n// Now the document's render keeps its payload here for the few seconds it\n// takes the browser to come back for it, under a token written into the\n// document that only that browser holds. The boot fetch redeems the token\n// and is answered with the payload the document was made from - which is\n// also the one it should hydrate against: two renders a moment apart could\n// disagree, and the one that made the HTML cannot.\n//\n// A token is redeemed once. A payload nobody comes back for - a route with\n// no runtime, a browser that left, a Worker isolate other than the one that\n// rendered - is cancelled when it expires, and the boot fetch that misses\n// renders as it always did. Missing costs a render; it never costs a wrong\n// answer.\n\n/** How long a payload waits for its browser. */\nexport const BOOT_HOLD_MS = 10_000;\n\n/** At most this many held at once; the oldest is dropped first. */\nconst MAX_HELD = 500;\n\nexport interface HeldPayload {\n payload: ReadableStream;\n /** The headers the boot answer carries beside the payload: the layout chain, the depth. */\n headers: Record<string, string>;\n at: number;\n}\n\nconst held = new Map<string, HeldPayload>();\n\n/** A token no one can guess: 128 bits, url-safe. */\nexport function bootToken(): string {\n const bytes = new Uint8Array(16);\n\n crypto.getRandomValues(bytes);\n\n let out = \"\";\n\n for (const b of bytes) out += b.toString(16).padStart(2, \"0\");\n\n return out;\n}\n\n/** Keep a render's payload for the boot fetch that follows its document. */\nexport function holdBootPayload(\n token: string,\n payload: ReadableStream,\n headers: Record<string, string>,\n now = Date.now(),\n): void {\n sweep(now);\n\n if (held.size >= MAX_HELD) {\n const oldest = held.keys().next().value;\n\n if (oldest !== undefined) drop(oldest);\n }\n\n held.set(token, { payload, headers, at: now });\n}\n\n/** The payload for a token, once. Null for a token not held, redeemed or expired. */\nexport function takeBootPayload(token: string, now = Date.now()): HeldPayload | null {\n const found = held.get(token);\n\n if (!found) return null;\n\n held.delete(token);\n\n if (now - found.at >= BOOT_HOLD_MS) {\n void found.payload.cancel().catch(() => {});\n\n return null;\n }\n\n return found;\n}\n\n/** Let go of what nobody came back for. */\nfunction sweep(now: number): void {\n for (const [token, entry] of held) {\n if (now - entry.at < BOOT_HOLD_MS) break;\n\n drop(token);\n }\n}\n\nfunction drop(token: string): void {\n const entry = held.get(token);\n\n held.delete(token);\n\n if (entry) void entry.payload.cancel().catch(() => {});\n}\n\n/** How many are held, for tests. */\nexport function heldBootPayloads(): number {\n return held.size;\n}\n\n/** Forget everything, for tests. */\nexport function clearBootPayloads(): void {\n for (const token of [...held.keys()]) drop(token);\n}\n"]}