@rsc-kit/core 0.16.3 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/barrelImports.d.ts +6 -0
  2. package/dist/barrelImports.js +93 -0
  3. package/dist/barrelImports.js.map +1 -0
  4. package/dist/buildReport.d.ts +6 -1
  5. package/dist/buildReport.js +16 -18
  6. package/dist/buildReport.js.map +1 -1
  7. package/dist/cache.js +8 -4
  8. package/dist/cache.js.map +1 -1
  9. package/dist/clientEntries.d.ts +32 -0
  10. package/dist/clientEntries.js +107 -0
  11. package/dist/clientEntries.js.map +1 -0
  12. package/dist/clientImports.d.ts +36 -0
  13. package/dist/clientImports.js +36 -0
  14. package/dist/clientImports.js.map +1 -0
  15. package/dist/devReload.d.ts +19 -0
  16. package/dist/devReload.js +32 -0
  17. package/dist/devReload.js.map +1 -0
  18. package/dist/events.d.ts +57 -0
  19. package/dist/events.js +113 -0
  20. package/dist/events.js.map +1 -0
  21. package/dist/host.d.ts +16 -6
  22. package/dist/host.js +219 -124
  23. package/dist/host.js.map +1 -1
  24. package/dist/hostCalls.d.ts +27 -0
  25. package/dist/hostCalls.js +127 -12
  26. package/dist/hostCalls.js.map +1 -1
  27. package/dist/hostRouting.d.ts +53 -0
  28. package/dist/hostRouting.js +100 -0
  29. package/dist/hostRouting.js.map +1 -0
  30. package/dist/js/DefaultRouteError.d.ts +3 -0
  31. package/dist/js/DefaultRouteError.js +61 -0
  32. package/dist/js/DefaultRouteError.js.map +1 -0
  33. package/dist/js/Form.js +54 -6
  34. package/dist/js/Form.js.map +1 -1
  35. package/dist/js/Link.d.ts +0 -3
  36. package/dist/js/Link.js +3 -6
  37. package/dist/js/Link.js.map +1 -1
  38. package/dist/js/SegmentBoundary.d.ts +38 -2
  39. package/dist/js/SegmentBoundary.js +51 -13
  40. package/dist/js/SegmentBoundary.js.map +1 -1
  41. package/dist/js/createViteRscApp.js +32 -17
  42. package/dist/js/createViteRscApp.js.map +1 -1
  43. package/dist/js/devNotice.d.ts +2 -2
  44. package/dist/js/devNotice.js +17 -7
  45. package/dist/js/devNotice.js.map +1 -1
  46. package/dist/js/fallbackReport.d.ts +2 -0
  47. package/dist/js/fallbackReport.js +51 -0
  48. package/dist/js/fallbackReport.js.map +1 -0
  49. package/dist/js/navigate.d.ts +1 -1
  50. package/dist/js/navigate.js +55 -23
  51. package/dist/js/navigate.js.map +1 -1
  52. package/dist/js/queryClient.d.ts +2 -1
  53. package/dist/js/queryClient.js +0 -12
  54. package/dist/js/queryClient.js.map +1 -1
  55. package/dist/js/router.d.ts +2 -2
  56. package/dist/js/router.js.map +1 -1
  57. package/dist/js/segmentStore.d.ts +2 -0
  58. package/dist/js/segmentStore.js +21 -1
  59. package/dist/js/segmentStore.js.map +1 -1
  60. package/dist/js/staleAssets.js +10 -1
  61. package/dist/js/staleAssets.js.map +1 -1
  62. package/dist/js/standardSchema.d.ts +6 -0
  63. package/dist/js/standardSchema.js +19 -1
  64. package/dist/js/standardSchema.js.map +1 -1
  65. package/dist/js/useEvents.d.ts +25 -0
  66. package/dist/js/useEvents.js +78 -0
  67. package/dist/js/useEvents.js.map +1 -0
  68. package/dist/js/useLinkStatus.d.ts +14 -1
  69. package/dist/js/useLinkStatus.js +15 -1
  70. package/dist/js/useLinkStatus.js.map +1 -1
  71. package/dist/js/usePolling.d.ts +29 -0
  72. package/dist/js/usePolling.js +141 -0
  73. package/dist/js/usePolling.js.map +1 -0
  74. package/dist/manifest.d.ts +18 -1
  75. package/dist/manifest.js.map +1 -1
  76. package/dist/metadata.d.ts +94 -15
  77. package/dist/metadata.js.map +1 -1
  78. package/dist/metadataRoutes.d.ts +61 -0
  79. package/dist/metadataRoutes.js +173 -0
  80. package/dist/metadataRoutes.js.map +1 -0
  81. package/dist/prerender.js +44 -10
  82. package/dist/prerender.js.map +1 -1
  83. package/dist/reactCache.d.ts +1 -0
  84. package/dist/reactCache.js +52 -0
  85. package/dist/reactCache.js.map +1 -0
  86. package/dist/redirect.d.ts +16 -2
  87. package/dist/redirect.js +10 -19
  88. package/dist/redirect.js.map +1 -1
  89. package/dist/request.d.ts +18 -1
  90. package/dist/request.js +91 -5
  91. package/dist/request.js.map +1 -1
  92. package/dist/revalidate.d.ts +6 -4
  93. package/dist/revalidate.js +6 -5
  94. package/dist/revalidate.js.map +1 -1
  95. package/dist/routes.d.ts +16 -3
  96. package/dist/routes.js +5 -5
  97. package/dist/routes.js.map +1 -1
  98. package/dist/routing.d.ts +2 -2
  99. package/dist/routing.js +47 -25
  100. package/dist/routing.js.map +1 -1
  101. package/dist/useSsr.d.ts +19 -0
  102. package/dist/useSsr.js +104 -0
  103. package/dist/useSsr.js.map +1 -0
  104. package/dist/vite.d.ts +86 -9
  105. package/dist/vite.js +827 -24
  106. package/dist/vite.js.map +1 -1
  107. package/package.json +13 -1
@@ -0,0 +1,57 @@
1
+ /**
2
+ * A route that streams: server-sent events from an async generator.
3
+ *
4
+ * // app/api/orders/[id]/events/route.ts
5
+ * export const GET = events(async function* ({ params, signal }) {
6
+ * for await (const status of orderStatus((await params).id, { signal })) {
7
+ * yield { status }
8
+ * }
9
+ * })
10
+ *
11
+ * An ordinary route.ts, so it lives beside its pages, runs the middleware.ts
12
+ * above it and takes the same params. What this adds is the framing - one
13
+ * `data:` line per yield, JSON - a keepalive comment every fifteen seconds
14
+ * so a proxy does not drop an idle stream, the headers a stream needs, and
15
+ * an end to the generator when the browser goes away, which is what `signal`
16
+ * is for. `useEvents` on the client reads it.
17
+ *
18
+ * Not a query. A query answers once and is cacheable; a stream answers for
19
+ * as long as the tab is open and is not. A server component cannot await a
20
+ * stream, so it has no place in the payload either.
21
+ */
22
+ export interface EventsInput<P = Record<string, string>> {
23
+ params: Promise<P>;
24
+ searchParams: Promise<URLSearchParams>;
25
+ /** Aborted when the browser disconnects. Pass it on, or check `aborted`. */
26
+ signal: AbortSignal;
27
+ request: Request;
28
+ }
29
+ /** A message with a name or an id, for a client that listens by name or resumes. Made by `named()`. */
30
+ export interface NamedEvent {
31
+ readonly [NAMED]: true;
32
+ event?: string;
33
+ id?: string;
34
+ data: unknown;
35
+ }
36
+ declare const NAMED: unique symbol;
37
+ /**
38
+ * A message with a name or an id: `yield named('paid', order)`, or
39
+ * `named('paid', order, { id: order.id })` for one a client can resume from.
40
+ * Built by a function rather than by shape, so a message that happens to
41
+ * have a `data` key is still data, and the generator's own type stays the
42
+ * type of what it yields.
43
+ */
44
+ export declare function named<D>(event: string, data: D, options?: {
45
+ id?: string;
46
+ }): NamedEvent;
47
+ /** How often a comment goes out on an idle stream, so a proxy keeps it open. */
48
+ export declare const KEEPALIVE_MS = 15000;
49
+ /** One message, framed. */
50
+ export declare function frame(value: unknown): string;
51
+ export declare function events<P = Record<string, string>, T = unknown>(produce: (input: EventsInput<P>) => AsyncIterable<T | NamedEvent>, options?: {
52
+ keepaliveMs?: number;
53
+ }): (request: Request, input: {
54
+ params: Promise<P>;
55
+ searchParams: Promise<URLSearchParams>;
56
+ }) => Response;
57
+ export {};
package/dist/events.js ADDED
@@ -0,0 +1,113 @@
1
+ /**
2
+ * A route that streams: server-sent events from an async generator.
3
+ *
4
+ * // app/api/orders/[id]/events/route.ts
5
+ * export const GET = events(async function* ({ params, signal }) {
6
+ * for await (const status of orderStatus((await params).id, { signal })) {
7
+ * yield { status }
8
+ * }
9
+ * })
10
+ *
11
+ * An ordinary route.ts, so it lives beside its pages, runs the middleware.ts
12
+ * above it and takes the same params. What this adds is the framing - one
13
+ * `data:` line per yield, JSON - a keepalive comment every fifteen seconds
14
+ * so a proxy does not drop an idle stream, the headers a stream needs, and
15
+ * an end to the generator when the browser goes away, which is what `signal`
16
+ * is for. `useEvents` on the client reads it.
17
+ *
18
+ * Not a query. A query answers once and is cacheable; a stream answers for
19
+ * as long as the tab is open and is not. A server component cannot await a
20
+ * stream, so it has no place in the payload either.
21
+ */
22
+ const NAMED = Symbol.for("@rsc-kit/core.named-event");
23
+ /**
24
+ * A message with a name or an id: `yield named('paid', order)`, or
25
+ * `named('paid', order, { id: order.id })` for one a client can resume from.
26
+ * Built by a function rather than by shape, so a message that happens to
27
+ * have a `data` key is still data, and the generator's own type stays the
28
+ * type of what it yields.
29
+ */
30
+ export function named(event, data, options = {}) {
31
+ return { [NAMED]: true, event, id: options.id, data };
32
+ }
33
+ /** How often a comment goes out on an idle stream, so a proxy keeps it open. */
34
+ export const KEEPALIVE_MS = 15_000;
35
+ function isNamed(value) {
36
+ return (typeof value === "object" &&
37
+ value !== null &&
38
+ value[NAMED] === true);
39
+ }
40
+ /** One message, framed. */
41
+ export function frame(value) {
42
+ const named = isNamed(value) ? value : null;
43
+ const lines = [];
44
+ if (named?.event)
45
+ lines.push(`event: ${named.event}`);
46
+ if (named?.id)
47
+ lines.push(`id: ${named.id}`);
48
+ lines.push(`data: ${JSON.stringify(named ? named.data : value)}`);
49
+ return lines.join("\n") + "\n\n";
50
+ }
51
+ export function events(produce, options = {}) {
52
+ const keepaliveMs = options.keepaliveMs ?? KEEPALIVE_MS;
53
+ return (request, input) => {
54
+ const controller = new AbortController();
55
+ const encoder = new TextEncoder();
56
+ request.signal.addEventListener("abort", () => controller.abort(), {
57
+ once: true,
58
+ });
59
+ const stream = new ReadableStream({
60
+ async start(sink) {
61
+ // The retry hint first, so a browser that loses the connection waits
62
+ // a moment rather than hammering.
63
+ sink.enqueue(encoder.encode("retry: 1000\n\n"));
64
+ const keepalive = setInterval(() => {
65
+ try {
66
+ sink.enqueue(encoder.encode(": keepalive\n\n"));
67
+ }
68
+ catch {
69
+ // Closed between the check and the write; the loop below ends it.
70
+ }
71
+ }, keepaliveMs);
72
+ try {
73
+ for await (const value of produce({
74
+ ...input,
75
+ signal: controller.signal,
76
+ request,
77
+ })) {
78
+ if (controller.signal.aborted)
79
+ break;
80
+ sink.enqueue(encoder.encode(frame(value)));
81
+ }
82
+ }
83
+ catch (error) {
84
+ if (!controller.signal.aborted)
85
+ sink.error(error);
86
+ }
87
+ finally {
88
+ clearInterval(keepalive);
89
+ if (!controller.signal.aborted) {
90
+ try {
91
+ sink.close();
92
+ }
93
+ catch {
94
+ // Already closed by the consumer.
95
+ }
96
+ }
97
+ }
98
+ },
99
+ cancel() {
100
+ controller.abort();
101
+ },
102
+ });
103
+ return new Response(stream, {
104
+ headers: {
105
+ "Content-Type": "text/event-stream; charset=utf-8",
106
+ "Cache-Control": "no-store",
107
+ // Nginx buffers by default, which turns a stream into one late burst.
108
+ "X-Accel-Buffering": "no",
109
+ },
110
+ });
111
+ };
112
+ }
113
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A route that streams: server-sent events from an async generator.\n *\n * // app/api/orders/[id]/events/route.ts\n * export const GET = events(async function* ({ params, signal }) {\n * for await (const status of orderStatus((await params).id, { signal })) {\n * yield { status }\n * }\n * })\n *\n * An ordinary route.ts, so it lives beside its pages, runs the middleware.ts\n * above it and takes the same params. What this adds is the framing - one\n * `data:` line per yield, JSON - a keepalive comment every fifteen seconds\n * so a proxy does not drop an idle stream, the headers a stream needs, and\n * an end to the generator when the browser goes away, which is what `signal`\n * is for. `useEvents` on the client reads it.\n *\n * Not a query. A query answers once and is cacheable; a stream answers for\n * as long as the tab is open and is not. A server component cannot await a\n * stream, so it has no place in the payload either.\n */\n\nexport interface EventsInput<P = Record<string, string>> {\n params: Promise<P>;\n searchParams: Promise<URLSearchParams>;\n /** Aborted when the browser disconnects. Pass it on, or check `aborted`. */\n signal: AbortSignal;\n request: Request;\n}\n\n/** A message with a name or an id, for a client that listens by name or resumes. Made by `named()`. */\nexport interface NamedEvent {\n readonly [NAMED]: true;\n event?: string;\n id?: string;\n data: unknown;\n}\n\nconst NAMED = Symbol.for(\"@rsc-kit/core.named-event\");\n\n/**\n * A message with a name or an id: `yield named('paid', order)`, or\n * `named('paid', order, { id: order.id })` for one a client can resume from.\n * Built by a function rather than by shape, so a message that happens to\n * have a `data` key is still data, and the generator's own type stays the\n * type of what it yields.\n */\nexport function named<D>(\n event: string,\n data: D,\n options: { id?: string } = {},\n): NamedEvent {\n return { [NAMED]: true, event, id: options.id, data };\n}\n\n/** How often a comment goes out on an idle stream, so a proxy keeps it open. */\nexport const KEEPALIVE_MS = 15_000;\n\nfunction isNamed(value: unknown): value is NamedEvent {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { [NAMED]?: true })[NAMED] === true\n );\n}\n\n/** One message, framed. */\nexport function frame(value: unknown): string {\n const named = isNamed(value) ? value : null;\n const lines: string[] = [];\n\n if (named?.event) lines.push(`event: ${named.event}`);\n if (named?.id) lines.push(`id: ${named.id}`);\n lines.push(`data: ${JSON.stringify(named ? named.data : value)}`);\n\n return lines.join(\"\\n\") + \"\\n\\n\";\n}\n\nexport function events<P = Record<string, string>, T = unknown>(\n produce: (input: EventsInput<P>) => AsyncIterable<T | NamedEvent>,\n options: { keepaliveMs?: number } = {},\n): (\n request: Request,\n input: { params: Promise<P>; searchParams: Promise<URLSearchParams> },\n) => Response {\n const keepaliveMs = options.keepaliveMs ?? KEEPALIVE_MS;\n\n return (request, input) => {\n const controller = new AbortController();\n const encoder = new TextEncoder();\n\n request.signal.addEventListener(\"abort\", () => controller.abort(), {\n once: true,\n });\n\n const stream = new ReadableStream<Uint8Array>({\n async start(sink) {\n // The retry hint first, so a browser that loses the connection waits\n // a moment rather than hammering.\n sink.enqueue(encoder.encode(\"retry: 1000\\n\\n\"));\n\n const keepalive = setInterval(() => {\n try {\n sink.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n } catch {\n // Closed between the check and the write; the loop below ends it.\n }\n }, keepaliveMs);\n\n try {\n for await (const value of produce({\n ...input,\n signal: controller.signal,\n request,\n })) {\n if (controller.signal.aborted) break;\n\n sink.enqueue(encoder.encode(frame(value)));\n }\n } catch (error) {\n if (!controller.signal.aborted) sink.error(error);\n } finally {\n clearInterval(keepalive);\n\n if (!controller.signal.aborted) {\n try {\n sink.close();\n } catch {\n // Already closed by the consumer.\n }\n }\n }\n },\n cancel() {\n controller.abort();\n },\n });\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n // Nginx buffers by default, which turns a stream into one late burst.\n \"X-Accel-Buffering\": \"no\",\n },\n });\n };\n}\n"]}
package/dist/host.d.ts CHANGED
@@ -1,9 +1,19 @@
1
- export { revalidate } from './revalidate.js';
2
- export { redirect } from './redirect.js';
3
- export { matchIntercept, matchRoute, sharedDepth } from './routing.js';
4
- export type { MatchedRoute } from './routing.js';
5
- import type { MatchedRoute } from './routing.js';
6
- import type { RouteManifest } from './manifest.js';
1
+ /**
2
+ * @internal For a host adapter that embeds the engine. An app imports this
3
+ * from `@rsc-kit/core/revalidate`.
4
+ */
5
+ export { revalidate } from "./revalidate.js";
6
+ /**
7
+ * @internal For a host adapter that embeds the engine. An app imports this
8
+ * from `@rsc-kit/core/redirect` - the one the guides teach, and the one an
9
+ * editor should offer first.
10
+ */
11
+ export { redirect } from "./redirect.js";
12
+ /** @internal For a host adapter. An app never matches its own routes. */
13
+ export { matchIntercept, matchRoute, sharedDepth } from "./routing.js";
14
+ export type { MatchedRoute } from "./routing.js";
15
+ import type { MatchedRoute } from "./routing.js";
16
+ import type { RouteManifest } from "./manifest.js";
7
17
  /** The built server bundle. Only the parts a host calls. */
8
18
  export interface RscEngine {
9
19
  /** The route table this bundle was built from. */