netjes 0.0.0-stage → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -2
  3. package/bin/netjes.mjs +13 -0
  4. package/cli/agents.mjs +66 -0
  5. package/cli/commands.mjs +467 -0
  6. package/cli/help.mjs +89 -0
  7. package/cli/info.mjs +454 -0
  8. package/cli/main.mjs +167 -0
  9. package/cli/packages.mjs +19 -0
  10. package/cli/process-io.mjs +163 -0
  11. package/cli/routes.mjs +31 -0
  12. package/cli/scaffold.mjs +193 -0
  13. package/cli/suggest.mjs +50 -0
  14. package/cli/terminal.mjs +40 -0
  15. package/dist/actions.d.ts +98 -0
  16. package/dist/actions.d.ts.map +1 -0
  17. package/dist/actions.js +176 -0
  18. package/dist/actions.js.map +1 -0
  19. package/dist/client-entry.d.ts +2 -0
  20. package/dist/client-entry.d.ts.map +1 -0
  21. package/dist/client-entry.js +126 -0
  22. package/dist/client-entry.js.map +1 -0
  23. package/dist/deferred.d.ts +39 -0
  24. package/dist/deferred.d.ts.map +1 -0
  25. package/dist/deferred.js +123 -0
  26. package/dist/deferred.js.map +1 -0
  27. package/dist/define-page.d.ts +15 -0
  28. package/dist/define-page.d.ts.map +1 -0
  29. package/dist/define-page.js +27 -0
  30. package/dist/define-page.js.map +1 -0
  31. package/dist/document.d.ts +19 -0
  32. package/dist/document.d.ts.map +1 -0
  33. package/dist/document.js +17 -0
  34. package/dist/document.js.map +1 -0
  35. package/dist/draft-mode.d.ts +5 -0
  36. package/dist/draft-mode.d.ts.map +1 -0
  37. package/dist/draft-mode.js +6 -0
  38. package/dist/draft-mode.js.map +1 -0
  39. package/dist/dynamic.d.ts +20 -0
  40. package/dist/dynamic.d.ts.map +1 -0
  41. package/dist/dynamic.js +37 -0
  42. package/dist/dynamic.js.map +1 -0
  43. package/dist/form-data.d.ts +10 -0
  44. package/dist/form-data.d.ts.map +1 -0
  45. package/dist/form-data.js +10 -0
  46. package/dist/form-data.js.map +1 -0
  47. package/dist/form.d.ts +35 -0
  48. package/dist/form.d.ts.map +1 -0
  49. package/dist/form.js +80 -0
  50. package/dist/form.js.map +1 -0
  51. package/dist/href.d.ts +25 -0
  52. package/dist/href.d.ts.map +1 -0
  53. package/dist/href.js +71 -0
  54. package/dist/href.js.map +1 -0
  55. package/dist/image.d.ts +36 -0
  56. package/dist/image.d.ts.map +1 -0
  57. package/dist/image.js +60 -0
  58. package/dist/image.js.map +1 -0
  59. package/dist/index.d.ts +18 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +14 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/link.d.ts +17 -0
  64. package/dist/link.d.ts.map +1 -0
  65. package/dist/link.js +46 -0
  66. package/dist/link.js.map +1 -0
  67. package/dist/locale.d.ts +3 -0
  68. package/dist/locale.d.ts.map +1 -0
  69. package/dist/locale.js +6 -0
  70. package/dist/locale.js.map +1 -0
  71. package/dist/metadata.d.ts +83 -0
  72. package/dist/metadata.d.ts.map +1 -0
  73. package/dist/metadata.js +100 -0
  74. package/dist/metadata.js.map +1 -0
  75. package/dist/modules.d.ts +74 -0
  76. package/dist/modules.d.ts.map +1 -0
  77. package/dist/modules.js +85 -0
  78. package/dist/modules.js.map +1 -0
  79. package/dist/nonce.d.ts +8 -0
  80. package/dist/nonce.d.ts.map +1 -0
  81. package/dist/nonce.js +12 -0
  82. package/dist/nonce.js.map +1 -0
  83. package/dist/payload.d.ts +171 -0
  84. package/dist/payload.d.ts.map +1 -0
  85. package/dist/payload.js +273 -0
  86. package/dist/payload.js.map +1 -0
  87. package/dist/public-config.d.ts +11 -0
  88. package/dist/public-config.d.ts.map +1 -0
  89. package/dist/public-config.js +10 -0
  90. package/dist/public-config.js.map +1 -0
  91. package/dist/query.d.ts +22 -0
  92. package/dist/query.d.ts.map +1 -0
  93. package/dist/query.js +68 -0
  94. package/dist/query.js.map +1 -0
  95. package/dist/render-cleanup.d.ts +6 -0
  96. package/dist/render-cleanup.d.ts.map +1 -0
  97. package/dist/render-cleanup.js +7 -0
  98. package/dist/render-cleanup.js.map +1 -0
  99. package/dist/root.d.ts +12 -0
  100. package/dist/root.d.ts.map +1 -0
  101. package/dist/root.js +26 -0
  102. package/dist/root.js.map +1 -0
  103. package/dist/route-tree.d.ts +56 -0
  104. package/dist/route-tree.d.ts.map +1 -0
  105. package/dist/route-tree.js +86 -0
  106. package/dist/route-tree.js.map +1 -0
  107. package/dist/router.d.ts +118 -0
  108. package/dist/router.d.ts.map +1 -0
  109. package/dist/router.js +938 -0
  110. package/dist/router.js.map +1 -0
  111. package/dist/schema.d.ts +35 -0
  112. package/dist/schema.d.ts.map +1 -0
  113. package/dist/schema.js +74 -0
  114. package/dist/schema.js.map +1 -0
  115. package/dist/script.d.ts +23 -0
  116. package/dist/script.d.ts.map +1 -0
  117. package/dist/script.js +89 -0
  118. package/dist/script.js.map +1 -0
  119. package/dist/server-entry.d.ts +2 -0
  120. package/dist/server-entry.d.ts.map +1 -0
  121. package/dist/server-entry.js +4 -0
  122. package/dist/server-entry.js.map +1 -0
  123. package/dist/server-render.d.ts +19 -0
  124. package/dist/server-render.d.ts.map +1 -0
  125. package/dist/server-render.js +193 -0
  126. package/dist/server-render.js.map +1 -0
  127. package/dist/testing-setup.d.ts +2 -0
  128. package/dist/testing-setup.d.ts.map +1 -0
  129. package/dist/testing-setup.js +8 -0
  130. package/dist/testing-setup.js.map +1 -0
  131. package/dist/testing.d.ts +76 -0
  132. package/dist/testing.d.ts.map +1 -0
  133. package/dist/testing.js +106 -0
  134. package/dist/testing.js.map +1 -0
  135. package/dist/vitals-config.d.ts +4 -0
  136. package/dist/vitals-config.d.ts.map +1 -0
  137. package/dist/vitals-config.js +5 -0
  138. package/dist/vitals-config.js.map +1 -0
  139. package/dist/vitals.d.ts +13 -0
  140. package/dist/vitals.d.ts.map +1 -0
  141. package/dist/vitals.js +60 -0
  142. package/dist/vitals.js.map +1 -0
  143. package/dist/zod.d.ts +19 -0
  144. package/dist/zod.d.ts.map +1 -0
  145. package/dist/zod.js +65 -0
  146. package/dist/zod.js.map +1 -0
  147. package/package.json +147 -4
  148. package/sidecar/server.mjs +325 -0
  149. package/skills/netjes/SKILL.md +93 -0
  150. package/skills/netjes/references/caching-and-streaming.md +68 -0
  151. package/skills/netjes/references/data-and-actions.md +98 -0
  152. package/skills/netjes/references/deployment.md +57 -0
  153. package/skills/netjes/references/routing.md +65 -0
  154. package/skills/netjes/references/testing.md +57 -0
  155. package/src/actions.tsx +241 -0
  156. package/src/client-entry.tsx +126 -0
  157. package/src/deferred.ts +134 -0
  158. package/src/define-page.tsx +41 -0
  159. package/src/document.tsx +49 -0
  160. package/src/draft-mode.ts +6 -0
  161. package/src/dynamic.tsx +64 -0
  162. package/src/form-data.ts +10 -0
  163. package/src/form.tsx +122 -0
  164. package/src/href.ts +79 -0
  165. package/src/image.tsx +91 -0
  166. package/src/index.ts +40 -0
  167. package/src/link.tsx +73 -0
  168. package/src/locale.ts +6 -0
  169. package/src/metadata.tsx +181 -0
  170. package/src/modules.ts +133 -0
  171. package/src/nonce.tsx +14 -0
  172. package/src/payload.ts +405 -0
  173. package/src/public-config.tsx +19 -0
  174. package/src/query.tsx +82 -0
  175. package/src/render-cleanup.ts +7 -0
  176. package/src/root.tsx +39 -0
  177. package/src/route-tree.tsx +139 -0
  178. package/src/router.tsx +1188 -0
  179. package/src/schema.ts +98 -0
  180. package/src/script.tsx +103 -0
  181. package/src/server-entry.tsx +4 -0
  182. package/src/server-render.tsx +223 -0
  183. package/src/testing-setup.ts +8 -0
  184. package/src/testing.tsx +177 -0
  185. package/src/virtual.d.ts +12 -0
  186. package/src/vitals-config.ts +6 -0
  187. package/src/vitals.tsx +68 -0
  188. package/src/zod.ts +72 -0
  189. package/template/.dockerignore +11 -0
  190. package/template/Dockerfile +58 -0
  191. package/template/Features/Home/HomePage.cs +32 -0
  192. package/template/Program.cs +28 -0
  193. package/template/Properties/launchSettings.json +13 -0
  194. package/template/README.md +24 -0
  195. package/template/SiteProps.cs +4 -0
  196. package/template/_AGENTS.md +64 -0
  197. package/template/_CLAUDE.md +1 -0
  198. package/template/__NAME__.csproj +11 -0
  199. package/template/_gitattributes +2 -0
  200. package/template/_gitignore +11 -0
  201. package/template/app/about/page.tsx +17 -0
  202. package/template/app/error.tsx +15 -0
  203. package/template/app/layout.tsx +33 -0
  204. package/template/app/not-found.tsx +14 -0
  205. package/template/app/page.tsx +14 -0
  206. package/template/appsettings.Development.json +3 -0
  207. package/template/appsettings.json +9 -0
  208. package/template/components/Greeting.test.tsx +25 -0
  209. package/template/components/Greeting.tsx +26 -0
  210. package/template/components/HelloForm.test.tsx +27 -0
  211. package/template/components/HelloForm.tsx +34 -0
  212. package/template/docker-compose.override.yml +15 -0
  213. package/template/docker-compose.prod.yml +26 -0
  214. package/template/docker-compose.yml +16 -0
  215. package/template/generated/netjes.ts +73 -0
  216. package/template/package.json +36 -0
  217. package/template/public/favicon.svg +6 -0
  218. package/template/styles/global.css +7 -0
  219. package/template/tsconfig.json +19 -0
  220. package/template/vite.config.ts +7 -0
  221. package/vite/plugin.d.ts +29 -0
  222. package/vite/plugin.mjs +291 -0
@@ -0,0 +1,171 @@
1
+ import type { Metadata } from './metadata.tsx';
2
+ export declare const DATA_HEADER = "X-Netjes-Data";
3
+ export declare const SERVER_TIME_HEADER = "X-Netjes-Now";
4
+ export declare const SEGMENTS_HEADER = "X-Netjes-Segments";
5
+ /** `invalid` on an action's 400 when the server refused the call's antiforgery token: the action did not run. */
6
+ export declare const ANTIFORGERY_HEADER = "X-Netjes-Antiforgery";
7
+ /**
8
+ * `changed` on the response to an action call or a form post that set or deleted a cookie (signing in or out): the
9
+ * pages the router keeps for back and forward show the app as it was before.
10
+ */
11
+ export declare const COOKIES_HEADER = "X-Netjes-Cookies";
12
+ export declare const DATA_ELEMENT_ID = "__NETJES_DATA__";
13
+ /** The id of the empty element that ends the body of every server-rendered document, and so the shell. */
14
+ export declare const SHELL_END_ID = "__NETJES_SHELL_END__";
15
+ /** The page's route values by parameter name: a string per single segment, an array per catch-all (empty for an optional one). A single parameter the request has no value for is `null`, as when a page is rendered with `Page.Render` from an endpoint whose route lacks it. */
16
+ export type Params = Record<string, string | string[] | null>;
17
+ export type DocumentAssets = {
18
+ stylesheets: string[];
19
+ modulePreloads: string[];
20
+ scripts: string[];
21
+ };
22
+ /**
23
+ * A folder's segment files, outermost first: the client wraps the page in each segment's layout, template,
24
+ * error boundary and loading (Suspense) fallback. `props` come from the folder's C# layout loader.
25
+ */
26
+ export type SegmentRef = {
27
+ id: string;
28
+ layout?: string | undefined;
29
+ template?: string | undefined;
30
+ loading?: string | undefined;
31
+ error?: string | undefined;
32
+ props?: Record<string, unknown> | undefined;
33
+ /** Identifies what the segment's loader saw; the client sends the keys it holds on navigations. */
34
+ key?: string | undefined;
35
+ /** The loader was skipped because the client holds this segment (same key); its props are the client's. */
36
+ reused?: boolean | undefined;
37
+ /** Parallel routes: the file each `@slot` renders for this page (its page, else its default), or null. */
38
+ slots?: Record<string, string | null> | undefined;
39
+ /** How many URL segments a layout's folder covers for this URL (a catch-all counts what it matched). */
40
+ depth?: number | undefined;
41
+ /** Each slot page's own route values (its parameter names can differ from the page's). */
42
+ slotParams?: Record<string, Params> | undefined;
43
+ };
44
+ export type SpecialPageRef = {
45
+ page: string;
46
+ segments: SegmentRef[];
47
+ };
48
+ /** An intercepting page that can show this URL in a slot, with its own route values. */
49
+ export type InterceptRef = {
50
+ segment: string;
51
+ slot: string;
52
+ page: string;
53
+ params?: Params | undefined;
54
+ };
55
+ /** Why the server rendered a boundary file instead of the route's page. */
56
+ export type PageKind = 'notFound' | 'error' | 'forbidden' | 'unauthorized';
57
+ /** CSS inlined by the dev sidecar so server-rendered pages are styled before the client script runs. */
58
+ export type DevStyle = {
59
+ id: string;
60
+ css: string;
61
+ };
62
+ export type AntiforgeryToken = {
63
+ formFieldName: string;
64
+ headerName: string | null;
65
+ requestToken: string | null;
66
+ };
67
+ /** A TanStack Query cache entry seeded by the C# loader (`PageResult.WithQuery`). `updatedAt` is Unix milliseconds. */
68
+ export type SeededQuery = {
69
+ key: readonly unknown[];
70
+ data: unknown;
71
+ updatedAt: number;
72
+ };
73
+ /** Left by a server action posted without JavaScript that failed validation; the form's page renders with it. */
74
+ export type ActionStateRef = {
75
+ action: string;
76
+ errors: Record<string, string[]>;
77
+ values: Record<string, string | string[]>;
78
+ };
79
+ /** What a server action call answers with (`ServerActionResult` in C#). */
80
+ export type ActionResponse = {
81
+ kind: 'action';
82
+ ok: boolean;
83
+ status: number;
84
+ result?: unknown;
85
+ errors?: Record<string, string[]>;
86
+ /** After a failed form call: the submitted fields the failure state may hand back (declared by the action, not private). */
87
+ fields?: string[];
88
+ redirect?: string;
89
+ revalidate: boolean;
90
+ invalidate?: unknown[][];
91
+ queries?: SeededQuery[];
92
+ message?: string;
93
+ };
94
+ export type PagePayload = {
95
+ kind: 'page';
96
+ /** The page's URL pattern, e.g. `/blog/[slug]`; null for the 404 and error pages. */
97
+ route: string | null;
98
+ /** Module path of the page, e.g. `app/blog/[slug]/page.tsx`; null renders the built-in 404/error page. */
99
+ page: string | null;
100
+ /** Set when `page` is a not-found, error, forbidden or unauthorized file rather than the route's page. */
101
+ pageKind?: PageKind;
102
+ segments: SegmentRef[];
103
+ props: Record<string, unknown>;
104
+ params: Params;
105
+ shared: unknown;
106
+ status: number;
107
+ url: string;
108
+ version: string;
109
+ /** The server's clock (Unix ms) when it built this payload. */
110
+ renderedAt?: number;
111
+ antiforgery?: AntiforgeryToken;
112
+ queries?: SeededQuery[];
113
+ actionState?: ActionStateRef;
114
+ /** Intercepting routes: slots that may show this page instead, on a client navigation from inside their segment. */
115
+ intercepts?: InterceptRef[];
116
+ /** From the C# loader (`.WithMetadata(...)`), merged over the files' `export const metadata`. */
117
+ metadata?: Metadata;
118
+ /** The page was rendered in draft mode. */
119
+ draftMode?: boolean;
120
+ /** `UsePathBase`'s base path, when the app is not mounted at the root; `url` includes it. */
121
+ basePath?: string;
122
+ /** The request culture, with `AddNetjesLocalization`. */
123
+ locale?: string;
124
+ /**
125
+ * Client only, never sent: how far the browser clock is ahead of the server's, measured when the payload arrived.
126
+ * Server timestamps plus this offset are browser timestamps.
127
+ */
128
+ clockOffset?: number;
129
+ };
130
+ /** The `<Image>` optimizer: its path and the widths it serves (Netjes:Images). */
131
+ export type ImageConfigInfo = {
132
+ path: string;
133
+ widths: number[];
134
+ qualities?: number[];
135
+ basePath?: string;
136
+ };
137
+ export type DocumentInfo = {
138
+ lang: string;
139
+ assets: DocumentAssets;
140
+ errorPage: SpecialPageRef | null;
141
+ devStyles?: DevStyle[];
142
+ images?: ImageConfigInfo;
143
+ /** The `Netjes:PublicConfig` configuration section. */
144
+ publicConfig?: Record<string, unknown>;
145
+ /** The Content-Security-Policy nonce for this document's scripts and styles. */
146
+ nonce?: string;
147
+ /** Where `<WebVitals />` reports to, when the server collects web vitals. */
148
+ vitalsEndpoint?: string;
149
+ /**
150
+ * No sidecar was ready to render this document, so the server sent it without the page: the client entry renders
151
+ * it instead of hydrating.
152
+ */
153
+ clientRender?: boolean;
154
+ };
155
+ export type InitialPayload = PagePayload & {
156
+ document: DocumentInfo;
157
+ };
158
+ export type RedirectPayload = {
159
+ kind: 'redirect';
160
+ location: string;
161
+ version: string;
162
+ };
163
+ export type NavigationPayload = PagePayload | RedirectPayload;
164
+ export declare class PayloadError extends Error {
165
+ name: string;
166
+ }
167
+ export declare function parseAntiforgery(value: unknown): AntiforgeryToken;
168
+ export declare function parseActionResponse(value: unknown): ActionResponse;
169
+ export declare function parseNavigationPayload(value: unknown): NavigationPayload;
170
+ export declare function parseInitialPayload(value: unknown): InitialPayload;
171
+ //# sourceMappingURL=payload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,273 @@
1
+ // The JSON contract with the .NET side (src/Netjes/Rendering/PagePayload.cs). Keep the two in sync.
2
+ export const DATA_HEADER = 'X-Netjes-Data';
3
+ export const SERVER_TIME_HEADER = 'X-Netjes-Now';
4
+ export const SEGMENTS_HEADER = 'X-Netjes-Segments';
5
+ /** `invalid` on an action's 400 when the server refused the call's antiforgery token: the action did not run. */
6
+ export const ANTIFORGERY_HEADER = 'X-Netjes-Antiforgery';
7
+ /**
8
+ * `changed` on the response to an action call or a form post that set or deleted a cookie (signing in or out): the
9
+ * pages the router keeps for back and forward show the app as it was before.
10
+ */
11
+ export const COOKIES_HEADER = 'X-Netjes-Cookies';
12
+ export const DATA_ELEMENT_ID = '__NETJES_DATA__';
13
+ /** The id of the empty element that ends the body of every server-rendered document, and so the shell. */
14
+ export const SHELL_END_ID = '__NETJES_SHELL_END__';
15
+ export class PayloadError extends Error {
16
+ name = 'PayloadError';
17
+ }
18
+ function fail(message) {
19
+ throw new PayloadError(`Invalid netjes payload: ${message}`);
20
+ }
21
+ function object(value, what) {
22
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
23
+ fail(`${what} must be an object`);
24
+ return value;
25
+ }
26
+ function string(value, what) {
27
+ if (typeof value !== 'string')
28
+ fail(`${what} must be a string`);
29
+ return value;
30
+ }
31
+ function nullableString(value, what) {
32
+ return value === null ? null : string(value, what);
33
+ }
34
+ function number(value, what) {
35
+ if (typeof value !== 'number' || !Number.isFinite(value))
36
+ fail(`${what} must be a number`);
37
+ return value;
38
+ }
39
+ function strings(value, what) {
40
+ if (!Array.isArray(value))
41
+ fail(`${what} must be an array`);
42
+ return value.map((item, i) => string(item, `${what}[${i}]`));
43
+ }
44
+ function params(value) {
45
+ const result = {};
46
+ for (const [key, item] of Object.entries(object(value, 'params'))) {
47
+ result[key] = Array.isArray(item) ? strings(item, `params.${key}`) : nullableString(item, `params.${key}`);
48
+ }
49
+ return result;
50
+ }
51
+ export function parseAntiforgery(value) {
52
+ return antiforgery(value);
53
+ }
54
+ function antiforgery(value) {
55
+ const json = object(value, 'antiforgery');
56
+ return {
57
+ formFieldName: string(json.formFieldName, 'antiforgery.formFieldName'),
58
+ headerName: nullableString(json.headerName ?? null, 'antiforgery.headerName'),
59
+ requestToken: nullableString(json.requestToken ?? null, 'antiforgery.requestToken'),
60
+ };
61
+ }
62
+ function optionalString(value, what) {
63
+ return value === undefined || value === null ? undefined : string(value, what);
64
+ }
65
+ function segments(value, what) {
66
+ if (!Array.isArray(value))
67
+ fail(`${what} must be an array`);
68
+ return value.map((item, i) => {
69
+ const json = object(item, `${what}[${i}]`);
70
+ const segment = { id: string(json.id, `${what}[${i}].id`) };
71
+ for (const key of ['layout', 'template', 'loading', 'error']) {
72
+ const file = optionalString(json[key], `${what}[${i}].${key}`);
73
+ if (file !== undefined)
74
+ segment[key] = file;
75
+ }
76
+ if (json.props !== undefined && json.props !== null)
77
+ segment.props = object(json.props, `${what}[${i}].props`);
78
+ const key = optionalString(json.key, `${what}[${i}].key`);
79
+ if (key !== undefined)
80
+ segment.key = key;
81
+ if (json.reused === true)
82
+ segment.reused = true;
83
+ if (json.depth !== undefined && json.depth !== null) {
84
+ if (typeof json.depth !== 'number' || !Number.isInteger(json.depth) || json.depth < 0) {
85
+ throw new PayloadError(`${what}[${i}].depth must be a whole number`);
86
+ }
87
+ segment.depth = json.depth;
88
+ }
89
+ if (json.slotParams !== undefined && json.slotParams !== null) {
90
+ segment.slotParams = Object.fromEntries(Object.entries(object(json.slotParams, `${what}[${i}].slotParams`)).map(([name, values]) => [name, params(values)]));
91
+ }
92
+ if (json.slots !== undefined && json.slots !== null) {
93
+ const slots = {};
94
+ for (const [name, file] of Object.entries(object(json.slots, `${what}[${i}].slots`))) {
95
+ slots[name] = nullableString(file, `${what}[${i}].slots.${name}`);
96
+ }
97
+ segment.slots = slots;
98
+ }
99
+ return segment;
100
+ });
101
+ }
102
+ function errorMap(value, what) {
103
+ const result = {};
104
+ for (const [key, messages] of Object.entries(object(value, what)))
105
+ result[key] = strings(messages, `${what}.${key}`);
106
+ return result;
107
+ }
108
+ function actionState(value) {
109
+ const json = object(value, 'actionState');
110
+ const values = {};
111
+ for (const [key, item] of Object.entries(object(json.values ?? {}, 'actionState.values'))) {
112
+ values[key] = Array.isArray(item) ? strings(item, `actionState.values.${key}`) : string(item, `actionState.values.${key}`);
113
+ }
114
+ return { action: string(json.action, 'actionState.action'), errors: errorMap(json.errors ?? {}, 'actionState.errors'), values };
115
+ }
116
+ export function parseActionResponse(value) {
117
+ const json = object(value, 'action response');
118
+ if (json.kind !== 'action')
119
+ fail(`expected an action response, got kind ${JSON.stringify(json.kind)}`);
120
+ const response = {
121
+ kind: 'action',
122
+ ok: json.ok === true,
123
+ status: number(json.status, 'status'),
124
+ revalidate: json.revalidate === true,
125
+ };
126
+ if ('result' in json)
127
+ response.result = json.result;
128
+ if (json.errors !== undefined && json.errors !== null)
129
+ response.errors = errorMap(json.errors, 'errors');
130
+ if (json.fields !== undefined && json.fields !== null)
131
+ response.fields = strings(json.fields, 'fields');
132
+ if (json.redirect !== undefined && json.redirect !== null)
133
+ response.redirect = string(json.redirect, 'redirect');
134
+ if (json.invalidate !== undefined && json.invalidate !== null) {
135
+ if (!Array.isArray(json.invalidate) || !json.invalidate.every(Array.isArray))
136
+ fail('invalidate must be an array of query keys');
137
+ response.invalidate = json.invalidate;
138
+ }
139
+ if (json.queries !== undefined && json.queries !== null)
140
+ response.queries = queries(json.queries);
141
+ if (typeof json.message === 'string')
142
+ response.message = json.message;
143
+ return response;
144
+ }
145
+ const PAGE_KINDS = ['notFound', 'error', 'forbidden', 'unauthorized'];
146
+ function queries(value) {
147
+ if (!Array.isArray(value))
148
+ fail('queries must be an array');
149
+ return value.map((item, i) => {
150
+ const query = object(item, `queries[${i}]`);
151
+ if (!Array.isArray(query.key) || query.key.length === 0)
152
+ fail(`queries[${i}].key must be a non-empty array`);
153
+ return { key: query.key, data: query.data ?? null, updatedAt: number(query.updatedAt, `queries[${i}].updatedAt`) };
154
+ });
155
+ }
156
+ function pagePayload(json) {
157
+ const payload = {
158
+ kind: 'page',
159
+ route: nullableString(json.route ?? null, 'route'),
160
+ page: nullableString(json.page ?? null, 'page'),
161
+ segments: segments(json.segments, 'segments'),
162
+ props: object(json.props, 'props'),
163
+ params: params(json.params),
164
+ shared: json.shared ?? null,
165
+ status: number(json.status, 'status'),
166
+ url: string(json.url, 'url'),
167
+ version: string(json.version, 'version'),
168
+ };
169
+ if (json.antiforgery !== undefined && json.antiforgery !== null)
170
+ payload.antiforgery = antiforgery(json.antiforgery);
171
+ if (json.queries !== undefined && json.queries !== null)
172
+ payload.queries = queries(json.queries);
173
+ if (json.actionState !== undefined && json.actionState !== null)
174
+ payload.actionState = actionState(json.actionState);
175
+ if (Array.isArray(json.intercepts)) {
176
+ payload.intercepts = json.intercepts.map((item, i) => {
177
+ const intercept = object(item, `intercepts[${i}]`);
178
+ return {
179
+ segment: string(intercept.segment, `intercepts[${i}].segment`),
180
+ slot: string(intercept.slot, `intercepts[${i}].slot`),
181
+ page: string(intercept.page, `intercepts[${i}].page`),
182
+ ...(intercept.params !== undefined && intercept.params !== null ? { params: params(intercept.params) } : {}),
183
+ };
184
+ });
185
+ }
186
+ if (json.metadata !== undefined && json.metadata !== null)
187
+ payload.metadata = object(json.metadata, 'metadata');
188
+ if (json.pageKind !== undefined && json.pageKind !== null) {
189
+ if (!PAGE_KINDS.includes(json.pageKind))
190
+ fail(`unknown pageKind ${JSON.stringify(json.pageKind)}`);
191
+ payload.pageKind = json.pageKind;
192
+ }
193
+ if (json.renderedAt !== undefined && json.renderedAt !== null)
194
+ payload.renderedAt = number(json.renderedAt, 'renderedAt');
195
+ if (json.basePath !== undefined && json.basePath !== null)
196
+ payload.basePath = string(json.basePath, 'basePath');
197
+ if (json.locale !== undefined && json.locale !== null)
198
+ payload.locale = string(json.locale, 'locale');
199
+ if (json.draftMode !== undefined && json.draftMode !== null) {
200
+ if (typeof json.draftMode !== 'boolean')
201
+ fail('draftMode must be a boolean');
202
+ payload.draftMode = json.draftMode;
203
+ }
204
+ return payload;
205
+ }
206
+ export function parseNavigationPayload(value) {
207
+ const json = object(value, 'payload');
208
+ switch (json.kind) {
209
+ case 'page':
210
+ return pagePayload(json);
211
+ case 'redirect':
212
+ return { kind: 'redirect', location: string(json.location, 'location'), version: string(json.version, 'version') };
213
+ default:
214
+ return fail(`unknown kind ${JSON.stringify(json.kind)}`);
215
+ }
216
+ }
217
+ export function parseInitialPayload(value) {
218
+ const json = object(value, 'payload');
219
+ if (json.kind !== 'page')
220
+ fail('the initial payload must be a page');
221
+ const document = object(json.document, 'document');
222
+ const assets = object(document.assets, 'document.assets');
223
+ const errorPage = document.errorPage === null || document.errorPage === undefined
224
+ ? null
225
+ : object(document.errorPage, 'document.errorPage');
226
+ const info = {
227
+ lang: string(document.lang, 'document.lang'),
228
+ assets: {
229
+ stylesheets: strings(assets.stylesheets, 'document.assets.stylesheets'),
230
+ modulePreloads: strings(assets.modulePreloads, 'document.assets.modulePreloads'),
231
+ scripts: strings(assets.scripts, 'document.assets.scripts'),
232
+ },
233
+ errorPage: errorPage && {
234
+ page: string(errorPage.page, 'document.errorPage.page'),
235
+ segments: segments(errorPage.segments, 'document.errorPage.segments'),
236
+ },
237
+ };
238
+ if (Array.isArray(document.devStyles)) {
239
+ info.devStyles = document.devStyles.map((style, i) => {
240
+ const item = object(style, `document.devStyles[${i}]`);
241
+ return { id: string(item.id, 'devStyles.id'), css: string(item.css, 'devStyles.css') };
242
+ });
243
+ }
244
+ if (document.images !== undefined && document.images !== null) {
245
+ const images = object(document.images, 'document.images');
246
+ if (!Array.isArray(images.widths))
247
+ fail('document.images.widths must be an array');
248
+ info.images = {
249
+ path: string(images.path, 'document.images.path'),
250
+ widths: images.widths.map((w, i) => number(w, `document.images.widths[${i}]`)),
251
+ ...(typeof images.basePath === 'string' && images.basePath ? { basePath: images.basePath } : {}),
252
+ ...(Array.isArray(images.qualities)
253
+ ? { qualities: images.qualities.map((q, i) => number(q, `document.images.qualities[${i}]`)) }
254
+ : {}),
255
+ };
256
+ }
257
+ if (document.nonce !== undefined && document.nonce !== null)
258
+ info.nonce = string(document.nonce, 'document.nonce');
259
+ if (document.vitalsEndpoint !== undefined && document.vitalsEndpoint !== null) {
260
+ info.vitalsEndpoint = string(document.vitalsEndpoint, 'document.vitalsEndpoint');
261
+ }
262
+ if (document.publicConfig !== undefined && document.publicConfig !== null) {
263
+ info.publicConfig = object(document.publicConfig, 'document.publicConfig');
264
+ }
265
+ if (document.clientRender !== undefined && document.clientRender !== null) {
266
+ if (typeof document.clientRender !== 'boolean')
267
+ fail('document.clientRender must be a boolean');
268
+ if (document.clientRender)
269
+ info.clientRender = true;
270
+ }
271
+ return { ...pagePayload(json), document: info };
272
+ }
273
+ //# sourceMappingURL=payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../src/payload.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type StandardSchemaV1 } from './schema.ts';
2
+ /** Provided by Netjes from the first document; tests can provide their own (or use `createTestApp({ publicConfig })`). */
3
+ export declare const PublicConfigProvider: import("react").Provider<Record<string, unknown>>;
4
+ /**
5
+ * The server's `Netjes:PublicConfig` configuration section, the runtime counterpart of Next.js's `NEXT_PUBLIC_`
6
+ * variables: change it per environment without rebuilding the client. Values arrive as strings (configuration has
7
+ * no other type), so use coercing schemas such as `z.coerce.number()` or `z.stringbool()`. Everything in it is public.
8
+ */
9
+ export declare function usePublicConfig(): unknown;
10
+ export declare function usePublicConfig<Schema extends StandardSchemaV1>(schema: Schema): StandardSchemaV1.InferOutput<Schema>;
11
+ //# sourceMappingURL=public-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-config.d.ts","sourceRoot":"","sources":["../src/public-config.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,aAAa,CAAC;AAI/D,0HAA0H;AAC1H,eAAO,MAAM,oBAAoB,mDAA+B,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAAC;AAC3C,wBAAgB,eAAe,CAAC,MAAM,SAAS,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { createContext, useContext, useMemo } from 'react';
2
+ import { parseWith } from './schema.js';
3
+ const PublicConfigContext = createContext({});
4
+ /** Provided by Netjes from the first document; tests can provide their own (or use `createTestApp({ publicConfig })`). */
5
+ export const PublicConfigProvider = PublicConfigContext.Provider;
6
+ export function usePublicConfig(schema) {
7
+ const config = useContext(PublicConfigContext);
8
+ return useMemo(() => (schema ? parseWith(schema, config, 'public config') : config), [config, schema]);
9
+ }
10
+ //# sourceMappingURL=public-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-config.js","sourceRoot":"","sources":["../src/public-config.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAyB,SAAS,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,mBAAmB,GAAG,aAAa,CAA0B,EAAE,CAAC,CAAC;AAEvE,0HAA0H;AAC1H,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,QAAQ,CAAC;AASjE,MAAM,UAAU,eAAe,CAAC,MAAyB;IACvD,MAAM,MAAM,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACzG,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type DefaultOptions, type DehydratedState } from '@tanstack/react-query';
2
+ import { type ReactNode } from 'react';
3
+ import type { SeededQuery } from './payload.ts';
4
+ export type QueryShellOptions = {
5
+ /** Merged over the Netjes defaults (`staleTime` of one minute, so seeded data is not refetched straight away). */
6
+ defaultOptions?: DefaultOptions;
7
+ };
8
+ /** The Netjes defaults with the app's options merged over them, as the built-in client and the test harness use. */
9
+ export declare function mergeOptions(options: DefaultOptions | undefined): DefaultOptions;
10
+ /**
11
+ * Turns the payload's seeded queries into TanStack's dehydrated state, using only public APIs. Server timestamps
12
+ * are moved onto the browser clock, so freshness and "newer data wins" compare like with like.
13
+ */
14
+ export declare function dehydratedStateOf(queries: readonly SeededQuery[] | undefined, clockOffset?: number): DehydratedState | undefined;
15
+ /**
16
+ * The app-wide QueryClient: one per request on the server, one per page load in the browser (it survives
17
+ * client navigations). Each page's seeded queries are hydrated into it; data the client fetched more recently wins.
18
+ */
19
+ export declare function createQueryShell(options?: QueryShellOptions): ({ children }: {
20
+ children: ReactNode;
21
+ }) => import("react").JSX.Element;
22
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAkE,MAAM,uBAAuB,CAAC;AAClJ,OAAO,EAAE,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAIhD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,kHAAkH;IAClH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC;AAIF,oHAAoH;AACpH,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,GAAG,cAAc,CAOhF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,EAAE,WAAW,SAAI,GAAG,eAAe,GAAG,SAAS,CAO3H;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,kBAGrB;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,iCA8BjE"}
package/dist/query.js ADDED
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { HydrationBoundary, QueryClient, QueryClientProvider, dehydrate } from '@tanstack/react-query';
3
+ import { useContext, useEffect, useMemo, useState } from 'react';
4
+ import { RenderCleanupContext } from './render-cleanup.js';
5
+ import { useInternalRouter, usePagePayload } from './router.js';
6
+ const DEFAULTS = { queries: { staleTime: 60_000 } };
7
+ /** The Netjes defaults with the app's options merged over them, as the built-in client and the test harness use. */
8
+ export function mergeOptions(options) {
9
+ return {
10
+ ...DEFAULTS,
11
+ ...options,
12
+ queries: { ...DEFAULTS.queries, ...options?.queries },
13
+ mutations: { ...DEFAULTS.mutations, ...options?.mutations },
14
+ };
15
+ }
16
+ /**
17
+ * Turns the payload's seeded queries into TanStack's dehydrated state, using only public APIs. Server timestamps
18
+ * are moved onto the browser clock, so freshness and "newer data wins" compare like with like.
19
+ */
20
+ export function dehydratedStateOf(queries, clockOffset = 0) {
21
+ if (!queries?.length)
22
+ return undefined;
23
+ const scratch = new QueryClient();
24
+ for (const query of queries)
25
+ scratch.setQueryData(query.key, query.data, { updatedAt: query.updatedAt + clockOffset });
26
+ const state = dehydrate(scratch);
27
+ scratch.clear();
28
+ return state;
29
+ }
30
+ /**
31
+ * The server keeps one QueryClient per render in a long-lived process: a finite gcTime would leave a timer (and the
32
+ * client's data) behind for every query of every request.
33
+ */
34
+ function onServer(options) {
35
+ return { ...options, queries: { ...options.queries, gcTime: Number.POSITIVE_INFINITY } };
36
+ }
37
+ /**
38
+ * The app-wide QueryClient: one per request on the server, one per page load in the browser (it survives
39
+ * client navigations). Each page's seeded queries are hydrated into it; data the client fetched more recently wins.
40
+ */
41
+ export function createQueryShell(options = {}) {
42
+ const defaultOptions = mergeOptions(options.defaultOptions);
43
+ return function QueryShell({ children }) {
44
+ const onRenderEnd = useContext(RenderCleanupContext);
45
+ const [client] = useState(() => {
46
+ const created = new QueryClient({ defaultOptions: typeof window === 'undefined' ? onServer(defaultOptions) : defaultOptions });
47
+ // A query's own gcTime still schedules a timer; the sidecar drops the client with its document.
48
+ onRenderEnd?.(() => created.clear());
49
+ return created;
50
+ });
51
+ const { queries, clockOffset } = usePagePayload();
52
+ const state = useMemo(() => dehydratedStateOf(queries, clockOffset), [queries, clockOffset]);
53
+ const router = useInternalRouter();
54
+ // Server actions can set entries (.WithQuery) and invalidate keys (.Invalidate) in C#.
55
+ useEffect(() => router.onActionResponse((response) => {
56
+ for (const query of response.queries ?? [])
57
+ client.setQueryData(query.key, query.data);
58
+ for (const queryKey of response.invalidate ?? [])
59
+ void client.invalidateQueries({ queryKey });
60
+ }), [router, client]);
61
+ // Signing in or out (a call or post that set or deleted a cookie): any query may hold the previous user's data,
62
+ // those seeded by earlier pages too, so all of them go. The page loads again, seeding its own; the action's own
63
+ // query entries are applied after this.
64
+ useEffect(() => router.onCookiesChanged(() => client.clear()), [router, client]);
65
+ return (_jsx(QueryClientProvider, { client: client, children: _jsx(HydrationBoundary, { state: state, children: children }) }));
66
+ };
67
+ }
68
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.tsx"],"names":[],"mappings":";AAAA,OAAO,EAA6C,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClJ,OAAO,EAAkB,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAc,CAAC;AAOjE,MAAM,QAAQ,GAAmB,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;AAEpE,oHAAoH;AACpH,MAAM,UAAU,YAAY,CAAC,OAAmC;IAC9D,OAAO;QACL,GAAG,QAAQ;QACX,GAAG,OAAO;QACV,OAAO,EAAE,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE;QACrD,SAAS,EAAE,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE;KAC5D,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA2C,EAAE,WAAW,GAAG,CAAC;IAC5F,IAAI,CAAC,OAAO,EAAE,MAAM;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,WAAW,EAAE,CAAC,CAAC;IACvH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,CAAC,KAAK,EAAE,CAAC;IAChB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,OAAuB;IACvC,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAAE,EAAE,CAAC;AAC3F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAO,GAAsB,EAAE;IAC9D,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5D,OAAO,SAAS,UAAU,CAAC,EAAE,QAAQ,EAA2B;QAC9D,MAAM,WAAW,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE;YAC7B,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,EAAE,cAAc,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;YAC/H,gGAAgG;YAChG,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YACrC,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAC7F,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;QACnC,uFAAuF;QACvF,SAAS,CACP,GAAG,EAAE,CACH,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,EAAE;YACnC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE;gBAAE,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACvF,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,UAAU,IAAI,EAAE;gBAAE,KAAK,MAAM,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAChG,CAAC,CAAC,EACJ,CAAC,MAAM,EAAE,MAAM,CAAC,CACjB,CAAC;QACF,gHAAgH;QAChH,gHAAgH;QAChH,wCAAwC;QACxC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACjF,OAAO,CACL,KAAC,mBAAmB,IAAC,MAAM,EAAE,MAAM,YACjC,KAAC,iBAAiB,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAqB,GAC3C,CACvB,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * During a server render: registers something to release once the document is done, such as the render's
3
+ * QueryClient (whose queries may have their own gcTime timers). Null in the browser.
4
+ */
5
+ export declare const RenderCleanupContext: import("react").Context<((cleanup: () => void) => void) | null>;
6
+ //# sourceMappingURL=render-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-cleanup.d.ts","sourceRoot":"","sources":["../src/render-cleanup.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,qCAA4B,MAAM,IAAI,KAAK,IAAI,SAAe,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { createContext } from 'react';
2
+ /**
3
+ * During a server render: registers something to release once the document is done, such as the render's
4
+ * QueryClient (whose queries may have their own gcTime timers). Null in the browser.
5
+ */
6
+ export const RenderCleanupContext = createContext(null);
7
+ //# sourceMappingURL=render-cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-cleanup.js","sourceRoot":"","sources":["../src/render-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAAyC,IAAI,CAAC,CAAC"}