@bleedingdev/modern-js-renderer-core 0.0.0-bootstrap → 3.9.3-ultramodern.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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/abort.js +65 -0
  3. package/dist/cjs/adapter.js +62 -0
  4. package/dist/cjs/data/body.js +78 -0
  5. package/dist/cjs/data/client.js +409 -0
  6. package/dist/cjs/data/codec.js +168 -0
  7. package/dist/cjs/data/index.js +125 -0
  8. package/dist/cjs/data/private.js +77 -0
  9. package/dist/cjs/data/routes.js +149 -0
  10. package/dist/cjs/data/server.js +791 -0
  11. package/dist/cjs/data/static.js +110 -0
  12. package/dist/cjs/data/tree.js +231 -0
  13. package/dist/cjs/data/types.js +56 -0
  14. package/dist/cjs/document.js +184 -0
  15. package/dist/cjs/entry-client.js +142 -0
  16. package/dist/cjs/entry-server.js +253 -0
  17. package/dist/cjs/federation.js +80 -0
  18. package/dist/cjs/identity.js +120 -0
  19. package/dist/cjs/index.js +46 -0
  20. package/dist/cjs/localization.js +48 -0
  21. package/dist/cjs/router.js +293 -0
  22. package/dist/cjs/server/assets.js +56 -0
  23. package/dist/cjs/server/dispatch.js +351 -0
  24. package/dist/cjs/server/index.js +57 -0
  25. package/dist/cjs/server/types.js +18 -0
  26. package/dist/cjs/server/worker.js +73 -0
  27. package/dist/cjs/session/cache.js +172 -0
  28. package/dist/cjs/session/index.js +63 -0
  29. package/dist/cjs/session/request.js +269 -0
  30. package/dist/cjs/session/types.js +18 -0
  31. package/dist/esm/abort.mjs +27 -0
  32. package/dist/esm/adapter.mjs +21 -0
  33. package/dist/esm/data/body.mjs +40 -0
  34. package/dist/esm/data/client.mjs +368 -0
  35. package/dist/esm/data/codec.mjs +112 -0
  36. package/dist/esm/data/index.mjs +7 -0
  37. package/dist/esm/data/private.mjs +39 -0
  38. package/dist/esm/data/routes.mjs +108 -0
  39. package/dist/esm/data/server.mjs +723 -0
  40. package/dist/esm/data/static.mjs +51 -0
  41. package/dist/esm/data/tree.mjs +193 -0
  42. package/dist/esm/data/types.mjs +6 -0
  43. package/dist/esm/document.mjs +131 -0
  44. package/dist/esm/entry-client.mjs +104 -0
  45. package/dist/esm/entry-server.mjs +215 -0
  46. package/dist/esm/federation.mjs +36 -0
  47. package/dist/esm/identity.mjs +63 -0
  48. package/dist/esm/index.mjs +1 -0
  49. package/dist/esm/localization.mjs +10 -0
  50. package/dist/esm/router.mjs +225 -0
  51. package/dist/esm/server/assets.mjs +15 -0
  52. package/dist/esm/server/dispatch.mjs +307 -0
  53. package/dist/esm/server/index.mjs +3 -0
  54. package/dist/esm/server/types.mjs +0 -0
  55. package/dist/esm/server/worker.mjs +35 -0
  56. package/dist/esm/session/cache.mjs +116 -0
  57. package/dist/esm/session/index.mjs +3 -0
  58. package/dist/esm/session/request.mjs +231 -0
  59. package/dist/esm/session/types.mjs +0 -0
  60. package/dist/esm-node/abort.mjs +28 -0
  61. package/dist/esm-node/adapter.mjs +22 -0
  62. package/dist/esm-node/data/body.mjs +41 -0
  63. package/dist/esm-node/data/client.mjs +369 -0
  64. package/dist/esm-node/data/codec.mjs +113 -0
  65. package/dist/esm-node/data/index.mjs +8 -0
  66. package/dist/esm-node/data/private.mjs +40 -0
  67. package/dist/esm-node/data/routes.mjs +109 -0
  68. package/dist/esm-node/data/server.mjs +724 -0
  69. package/dist/esm-node/data/static.mjs +52 -0
  70. package/dist/esm-node/data/tree.mjs +194 -0
  71. package/dist/esm-node/data/types.mjs +7 -0
  72. package/dist/esm-node/document.mjs +132 -0
  73. package/dist/esm-node/entry-client.mjs +105 -0
  74. package/dist/esm-node/entry-server.mjs +216 -0
  75. package/dist/esm-node/federation.mjs +37 -0
  76. package/dist/esm-node/identity.mjs +64 -0
  77. package/dist/esm-node/index.mjs +2 -0
  78. package/dist/esm-node/localization.mjs +11 -0
  79. package/dist/esm-node/router.mjs +226 -0
  80. package/dist/esm-node/server/assets.mjs +16 -0
  81. package/dist/esm-node/server/dispatch.mjs +308 -0
  82. package/dist/esm-node/server/index.mjs +4 -0
  83. package/dist/esm-node/server/types.mjs +1 -0
  84. package/dist/esm-node/server/worker.mjs +36 -0
  85. package/dist/esm-node/session/cache.mjs +117 -0
  86. package/dist/esm-node/session/index.mjs +4 -0
  87. package/dist/esm-node/session/request.mjs +232 -0
  88. package/dist/esm-node/session/types.mjs +1 -0
  89. package/dist/types/abort.d.ts +6 -0
  90. package/dist/types/adapter.d.ts +195 -0
  91. package/dist/types/data/body.d.ts +2 -0
  92. package/dist/types/data/client.d.ts +17 -0
  93. package/dist/types/data/codec.d.ts +14 -0
  94. package/dist/types/data/index.d.ts +8 -0
  95. package/dist/types/data/private.d.ts +6 -0
  96. package/dist/types/data/routes.d.ts +28 -0
  97. package/dist/types/data/server.d.ts +59 -0
  98. package/dist/types/data/static.d.ts +31 -0
  99. package/dist/types/data/tree.d.ts +3 -0
  100. package/dist/types/data/types.d.ts +104 -0
  101. package/dist/types/document.d.ts +76 -0
  102. package/dist/types/entry-client.d.ts +53 -0
  103. package/dist/types/entry-server.d.ts +63 -0
  104. package/dist/types/federation.d.ts +56 -0
  105. package/dist/types/identity.d.ts +27 -0
  106. package/dist/types/index.d.ts +1 -0
  107. package/dist/types/localization.d.ts +58 -0
  108. package/dist/types/router.d.ts +201 -0
  109. package/dist/types/server/assets.d.ts +14 -0
  110. package/dist/types/server/dispatch.d.ts +11 -0
  111. package/dist/types/server/index.d.ts +4 -0
  112. package/dist/types/server/types.d.ts +64 -0
  113. package/dist/types/server/worker.d.ts +25 -0
  114. package/dist/types/session/cache.d.ts +25 -0
  115. package/dist/types/session/index.d.ts +4 -0
  116. package/dist/types/session/request.d.ts +8 -0
  117. package/dist/types/session/types.d.ts +48 -0
  118. package/package.json +159 -4
  119. package/src/abort.ts +40 -0
  120. package/src/adapter.ts +255 -0
  121. package/src/data/body.ts +43 -0
  122. package/src/data/client.ts +501 -0
  123. package/src/data/codec.ts +247 -0
  124. package/src/data/index.ts +8 -0
  125. package/src/data/private.ts +68 -0
  126. package/src/data/routes.ts +201 -0
  127. package/src/data/server.ts +977 -0
  128. package/src/data/static.ts +105 -0
  129. package/src/data/tree.ts +244 -0
  130. package/src/data/types.ts +98 -0
  131. package/src/document.ts +338 -0
  132. package/src/entry-client.ts +236 -0
  133. package/src/entry-server.ts +393 -0
  134. package/src/federation.ts +111 -0
  135. package/src/identity.ts +128 -0
  136. package/src/index.ts +7 -0
  137. package/src/localization.ts +77 -0
  138. package/src/router.ts +475 -0
  139. package/src/server/assets.ts +60 -0
  140. package/src/server/dispatch.ts +523 -0
  141. package/src/server/index.ts +16 -0
  142. package/src/server/types.ts +94 -0
  143. package/src/server/worker.ts +94 -0
  144. package/src/session/cache.ts +177 -0
  145. package/src/session/index.ts +11 -0
  146. package/src/session/request.ts +324 -0
  147. package/src/session/types.ts +60 -0
@@ -0,0 +1,232 @@
1
+ import "node:module";
2
+ import { identityCacheKey } from "../identity.mjs";
3
+ import { permitsDocumentCache, policyHeaders } from "./cache.mjs";
4
+ function freezeResponsePolicy(policy) {
5
+ if (!Number.isInteger(policy.status) || policy.status < 200 || policy.status > 599) throw new TypeError('A renderer response status must be an integer from 200 to 599.');
6
+ if ('document' !== policy.kind && 'terminal' !== policy.kind) throw new TypeError('A renderer response must identify its document or terminal outcome.');
7
+ const statusText = policy.statusText;
8
+ if (void 0 !== statusText && 'string' != typeof statusText) throw new TypeError('A renderer response status text must be a string.');
9
+ new Response(null, {
10
+ status: policy.status,
11
+ ...void 0 === statusText ? {} : {
12
+ statusText
13
+ }
14
+ });
15
+ if (![
16
+ 'no-store',
17
+ 'private',
18
+ 'public'
19
+ ].includes(policy.cache.mode)) throw new TypeError('A renderer response has an unknown cache policy.');
20
+ if ('public' === policy.cache.mode && (!Number.isInteger(policy.cache.maxAgeSeconds) || policy.cache.maxAgeSeconds < 0)) throw new TypeError('A public document cache lifetime must be a nonnegative integer.');
21
+ const headers = policy.headers.map(([name, value])=>{
22
+ new Headers([
23
+ [
24
+ name,
25
+ value
26
+ ]
27
+ ]);
28
+ return Object.freeze([
29
+ name,
30
+ value
31
+ ]);
32
+ });
33
+ return Object.freeze({
34
+ kind: policy.kind,
35
+ status: policy.status,
36
+ ...void 0 === statusText ? {} : {
37
+ statusText
38
+ },
39
+ headers: Object.freeze(headers),
40
+ cache: Object.freeze({
41
+ ...policy.cache
42
+ })
43
+ });
44
+ }
45
+ function createRequestSession(input) {
46
+ identityCacheKey(input.identity);
47
+ if ('node' !== input.platform.kind && 'worker' !== input.platform.kind) throw new TypeError('A renderer request requires an explicit Node or worker binding.');
48
+ const identity = Object.freeze({
49
+ ...input.identity
50
+ });
51
+ const platform = Object.freeze({
52
+ ...input.platform
53
+ });
54
+ const abortController = new AbortController();
55
+ const disposers = new Set();
56
+ let state = 'matching';
57
+ let policy;
58
+ let committedPolicy;
59
+ let fallback = false;
60
+ let responseCreated = false;
61
+ let hasDocumentBody = false;
62
+ let deliveredResponse;
63
+ let deliveredHeaders;
64
+ let reader;
65
+ let bodyController;
66
+ let cancelPromise;
67
+ let finishPromise;
68
+ let resolveCompletion;
69
+ const completion = new Promise((resolve)=>{
70
+ resolveCompletion = resolve;
71
+ });
72
+ const cancelSource = (reason)=>{
73
+ cancelPromise ??= reader ? reader.cancel(reason).finally(()=>reader?.releaseLock()) : Promise.resolve();
74
+ return cancelPromise;
75
+ };
76
+ const finish = (terminalState, error)=>{
77
+ if (finishPromise) return finishPromise;
78
+ state = terminalState;
79
+ input.request.signal.removeEventListener('abort', onRequestAbort);
80
+ const ownedDisposers = [
81
+ ...disposers
82
+ ].reverse();
83
+ disposers.clear();
84
+ finishPromise = Promise.resolve().then(async ()=>{
85
+ const cleanupErrors = [];
86
+ let recorded = false;
87
+ if ('completed' !== terminalState) cancelSource(error).catch((cancelError)=>{
88
+ if (!recorded) cleanupErrors.push(cancelError);
89
+ });
90
+ for (const dispose of ownedDisposers)try {
91
+ await dispose();
92
+ } catch (cleanupError) {
93
+ cleanupErrors.push(cleanupError);
94
+ }
95
+ await Promise.resolve();
96
+ recorded = true;
97
+ if ('completed' === terminalState && cleanupErrors.length > 0) state = 'failed';
98
+ const result = Object.freeze({
99
+ state: state,
100
+ fallback,
101
+ ...void 0 !== error ? {
102
+ error
103
+ } : {},
104
+ cleanupErrors: Object.freeze(cleanupErrors),
105
+ cacheEligible: 'completed' === state && hasDocumentBody && !fallback && void 0 !== committedPolicy && permitsDocumentCache({
106
+ ...committedPolicy,
107
+ headers: deliveredHeaders ? [
108
+ ...deliveredHeaders.entries()
109
+ ] : committedPolicy.headers
110
+ })
111
+ });
112
+ resolveCompletion(result);
113
+ return result;
114
+ });
115
+ if ('completed' !== terminalState) {
116
+ abortController.abort(error);
117
+ bodyController?.error(error);
118
+ }
119
+ return finishPromise;
120
+ };
121
+ const abort = (reason = new DOMException('The renderer request was aborted.', 'AbortError'))=>{
122
+ finish('aborted', reason);
123
+ };
124
+ function onRequestAbort() {
125
+ abort(input.request.signal.reason);
126
+ }
127
+ const session = {
128
+ request: input.request,
129
+ identity,
130
+ platform,
131
+ signal: abortController.signal,
132
+ get state () {
133
+ return state;
134
+ },
135
+ get responsePolicy () {
136
+ return policy;
137
+ },
138
+ get committedPolicy () {
139
+ return committedPolicy;
140
+ },
141
+ completion,
142
+ resolveResponse (nextPolicy) {
143
+ if (committedPolicy || finishPromise) throw new Error('Renderer response status and headers are already committed or terminated.');
144
+ policy = freezeResponsePolicy(nextPolicy);
145
+ if ('matching' === state) state = 'ready';
146
+ },
147
+ startRendering () {
148
+ if ('ready' !== state) throw new Error('Resolve the blocking HTTP outcome before starting the renderer.');
149
+ state = 'rendering';
150
+ },
151
+ registerCleanup (dispose) {
152
+ if (finishPromise) throw new Error('Cannot register cleanup after a renderer request terminates.');
153
+ disposers.add(dispose);
154
+ return ()=>{
155
+ disposers.delete(dispose);
156
+ };
157
+ },
158
+ markFallback () {
159
+ if (finishPromise) throw new Error('Cannot change fallback disposition after a renderer request terminates.');
160
+ fallback = true;
161
+ },
162
+ respond (body) {
163
+ if (responseCreated || committedPolicy || finishPromise) throw new Error('A renderer request has exactly one response body consumer.');
164
+ if (!policy || 'ready' !== state && 'rendering' !== state) throw new Error('Resolve the blocking HTTP outcome before committing a response.');
165
+ if (null !== body && [
166
+ 204,
167
+ 205,
168
+ 304
169
+ ].includes(policy.status)) throw new TypeError(`HTTP ${policy.status} cannot contain a renderer response body.`);
170
+ reader = body?.getReader();
171
+ hasDocumentBody = null !== body;
172
+ responseCreated = true;
173
+ committedPolicy = policy;
174
+ state = 'committed';
175
+ const headers = policyHeaders(committedPolicy.headers);
176
+ let wrappedBody = null;
177
+ if (reader) {
178
+ const sourceReader = reader;
179
+ wrappedBody = new ReadableStream({
180
+ start (controller) {
181
+ bodyController = controller;
182
+ },
183
+ async pull (controller) {
184
+ try {
185
+ const next = await sourceReader.read();
186
+ if (finishPromise) return;
187
+ if (!next.done) return void controller.enqueue(next.value);
188
+ sourceReader.releaseLock();
189
+ const result = await finish('completed');
190
+ if (result.cleanupErrors.length > 0) controller.error(new AggregateError(result.cleanupErrors, 'Renderer request cleanup failed.'));
191
+ else controller.close();
192
+ } catch (error) {
193
+ if (!finishPromise) {
194
+ await finish('failed', error);
195
+ controller.error(error);
196
+ }
197
+ }
198
+ },
199
+ cancel (reason) {
200
+ abort(reason);
201
+ return completion.then(()=>{});
202
+ }
203
+ }, {
204
+ highWaterMark: 0
205
+ });
206
+ } else finish('completed');
207
+ const response = new Response(wrappedBody, {
208
+ status: committedPolicy.status,
209
+ ...void 0 === committedPolicy.statusText ? {} : {
210
+ statusText: committedPolicy.statusText
211
+ },
212
+ headers
213
+ });
214
+ deliveredResponse = response;
215
+ deliveredHeaders = response.headers;
216
+ return response;
217
+ },
218
+ ownsResponseBody (response) {
219
+ return void 0 !== deliveredResponse && (response === deliveredResponse || null !== deliveredResponse.body && response.body === deliveredResponse.body);
220
+ },
221
+ fail (error) {
222
+ finish('failed', error);
223
+ },
224
+ abort
225
+ };
226
+ if (input.request.signal.aborted) onRequestAbort();
227
+ else input.request.signal.addEventListener('abort', onRequestAbort, {
228
+ once: true
229
+ });
230
+ return session;
231
+ }
232
+ export { createRequestSession };
@@ -0,0 +1 @@
1
+ import "node:module";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Settle with the work, or reject once the signal aborts: work that ignores
3
+ * cancellation must not keep its caller alive. A late Response body is
4
+ * cancelled and a late failure observed.
5
+ */
6
+ export declare function untilAborted<T>(handled: T | Promise<T>, signal: AbortSignal): Promise<T>;
@@ -0,0 +1,195 @@
1
+ import type { RsbuildPlugin } from '@rsbuild/core';
2
+ import type { Renderer, RendererIdentity } from './identity.js';
3
+ /**
4
+ * Renderer adapters are build-side descriptors. A renderer package exports one
5
+ * from its `./plugin` entry; UltraModern loads only the selected adapter and
6
+ * drives native entries, compilation, artifacts, deployment and scaffolding
7
+ * from its data. Nothing here is imported by application runtime code.
8
+ */
9
+ export interface RendererBuildProfile<TRenderer extends Renderer = Renderer> {
10
+ renderer: TRenderer;
11
+ status: 'stable' | 'preview';
12
+ protocolVersion: 1;
13
+ minimumNode: '26.10.0';
14
+ hmr: {
15
+ editedBoundary: 'may-reset';
16
+ unaffectedComponents: 'preserved';
17
+ document: 'preserved';
18
+ roots: 'single';
19
+ cleanup: 'exactly-once';
20
+ };
21
+ compiler: {
22
+ name: string;
23
+ version: string;
24
+ };
25
+ hydration: {
26
+ name: string;
27
+ version: string;
28
+ };
29
+ router: {
30
+ name: string;
31
+ version: string;
32
+ coreName: string;
33
+ coreVersion: string;
34
+ };
35
+ sourceExtensions: readonly string[];
36
+ jsxImportSource: string;
37
+ dependencies: Readonly<Record<string, string>>;
38
+ capabilities: {
39
+ worker: boolean;
40
+ /**
41
+ * `true`: Module Federation with SSR. React federates through the React
42
+ * MF plugin; native renderers server-render same-renderer federated
43
+ * components from a native module-federation.config.
44
+ * `'client'`: native same-renderer federated components rendered on the
45
+ * client only.
46
+ */
47
+ moduleFederation: boolean | 'client';
48
+ rsc: boolean;
49
+ ssg: boolean;
50
+ i18n: boolean;
51
+ svgComponent: boolean;
52
+ };
53
+ }
54
+ export interface NativeRendererCompilerOptions {
55
+ /** The selected native infrastructure owns these source-build identities. */
56
+ rendererIdentities(): Readonly<Record<string, RendererIdentity>>;
57
+ /** Rsbuild environment that renders server documents inside a web worker. */
58
+ readonly workerEnvironmentName: string;
59
+ }
60
+ export interface NativeCompilerArtifactContext {
61
+ /** Hash from the completed client compiler, when validating emitted output. */
62
+ readonly compilationHash?: string;
63
+ /** Hydration identity retained with a development snapshot. */
64
+ readonly hydrationBuildId?: string;
65
+ readonly development?: boolean;
66
+ }
67
+ export interface ValidatedNativeCompilerArtifact {
68
+ readonly nativeManifest: unknown;
69
+ /** Optional compiler-owned hydration and document cache identity. */
70
+ readonly hydrationBuildId?: string;
71
+ }
72
+ /** The selected compiler owns its artifact ABI; lifecycle consumers keep it opaque. */
73
+ export interface NativeCompilerArtifacts {
74
+ clientManifestFile(entryName: string): string;
75
+ validateClientManifest(value: unknown, identity: RendererIdentity, context: NativeCompilerArtifactContext): Promise<ValidatedNativeCompilerArtifact>;
76
+ isMutableDevelopmentAsset(filename: string, entryNames: readonly string[]): boolean;
77
+ }
78
+ /** Public modules the generated native entries and the host import. */
79
+ export interface NativeRendererRuntime {
80
+ /** The renderer's own reactive runtime package, e.g. `solid-js`. */
81
+ readonly package: string;
82
+ /** The renderer package that owns this adapter and its runtime modules. */
83
+ readonly bootstrap: string;
84
+ readonly entryClient: string;
85
+ readonly entryServer: string;
86
+ readonly router: string;
87
+ readonly i18n?: string;
88
+ /**
89
+ * Exports the renderer's `compilerArtifacts`, which the production server
90
+ * loads to validate compiler module manifests; also proves the installed
91
+ * owner.
92
+ */
93
+ readonly manifest: string;
94
+ }
95
+ export interface NativeRendererFederation {
96
+ /** Runtime singletons a host and every remote share (`pkg/` for subpaths). */
97
+ readonly shared: readonly string[];
98
+ /** Required providers, with the native import each compilation owns. */
99
+ readonly sharedByEnvironment?: Readonly<Record<'client' | 'server', Readonly<Record<string, string>>>>;
100
+ /** Browser container format, matching the renderer's client chunks. */
101
+ readonly library: 'module';
102
+ /** Whether federated components also render on the server. */
103
+ readonly ssr: boolean;
104
+ }
105
+ export interface RendererWorkerSupport {
106
+ /** Worker documents come from the renderer's native server handler. */
107
+ readonly nativeDocuments: boolean;
108
+ readonly rsc: boolean;
109
+ }
110
+ export interface NativeEntryClientStub {
111
+ /** Ambient declarations the generated client entry needs. */
112
+ readonly declarations: string;
113
+ /** Extra `startNativeClient` fields, as source expressions. */
114
+ readonly fields: Readonly<Record<string, string>>;
115
+ }
116
+ export interface RendererAppSourceOptions {
117
+ appId: string;
118
+ title: string;
119
+ entryName: string;
120
+ sourceExtension: '.tsx' | '.tsrx';
121
+ jsxImportSource: string;
122
+ capabilities: {
123
+ ssr: boolean;
124
+ federation: boolean;
125
+ };
126
+ }
127
+ export interface RendererAppSources {
128
+ sourceExtension: '.tsx' | '.tsrx';
129
+ jsxImportSource: string;
130
+ artifacts: {
131
+ path: string;
132
+ content: string;
133
+ }[];
134
+ }
135
+ export interface RendererCreatePackages {
136
+ /** Framework packages the generated application depends on directly. */
137
+ frameworkDependencies: readonly string[];
138
+ dependencies: Record<string, string>;
139
+ devDependencies: Record<string, string>;
140
+ typecheckCommand?: string;
141
+ tsconfig?: Record<string, unknown>;
142
+ }
143
+ export interface RendererCreateSupport {
144
+ /** Deployment templates the adapter admits in generated workspaces. */
145
+ readonly templates?: {
146
+ readonly federation: boolean;
147
+ readonly workers: boolean;
148
+ };
149
+ dependencies(profile: RendererBuildProfile, context: {
150
+ readonly typescriptVersion: string;
151
+ }): RendererCreatePackages;
152
+ generateAppSources(options: RendererAppSourceOptions): RendererAppSources;
153
+ }
154
+ interface RendererAdapterDescriptor<TRenderer extends Renderer> {
155
+ readonly name: TRenderer;
156
+ readonly profile: RendererBuildProfile<TRenderer>;
157
+ readonly routerFrameworks: readonly string[];
158
+ readonly worker: RendererWorkerSupport;
159
+ readonly create?: RendererCreateSupport;
160
+ }
161
+ export interface NativeRendererAdapter<TRenderer extends Renderer = Renderer> extends RendererAdapterDescriptor<TRenderer> {
162
+ readonly kind: 'native';
163
+ readonly runtime: NativeRendererRuntime;
164
+ readonly federation?: NativeRendererFederation;
165
+ readonly entryClient?: NativeEntryClientStub;
166
+ /**
167
+ * Who links the stylesheets of lazy components in a server document.
168
+ * `'renderer'`: the server render links each one beside the markup it
169
+ * renders. `'document'`: the render cannot report which lazy modules it
170
+ * rendered, so the document links every lazy stylesheet up front.
171
+ */
172
+ readonly lazyStyles: 'renderer' | 'document';
173
+ /** Path of a CommonJS module exporting `(parts) => source` for `?component` SVGs. */
174
+ svgComponentTemplate?(): string;
175
+ /** The renderer compiler; UltraModern applies SVG and ownership policy. */
176
+ compiler(options: NativeRendererCompilerOptions): RsbuildPlugin;
177
+ readonly artifacts: NativeCompilerArtifacts;
178
+ assertSupportedSource?(source: string | false | undefined): Promise<void>;
179
+ }
180
+ /** A renderer composed from an existing plugin stack (React only). */
181
+ export interface ComposedRendererAdapter<TRenderer extends Renderer = Renderer, TPlugin = unknown, TPolicy = unknown> extends RendererAdapterDescriptor<TRenderer> {
182
+ readonly kind: 'composed';
183
+ /** Public modules whose installed owners pin the profile versions. */
184
+ readonly frameworkModules: readonly {
185
+ readonly specifier: string;
186
+ readonly request: string;
187
+ }[];
188
+ compose(consumerPlugins: readonly TPlugin[], policy?: TPolicy): TPlugin;
189
+ }
190
+ export type RendererAdapter<TRenderer extends Renderer = Renderer> = NativeRendererAdapter<TRenderer> | ComposedRendererAdapter<TRenderer>;
191
+ /** Validate an adapter's internal consistency and freeze its descriptor data. */
192
+ export declare function defineRendererAdapter<T extends RendererAdapter>(adapter: T): T;
193
+ /** Third-party runtime packages a generated native application installs. */
194
+ export declare function nativeRendererDependencies(profile: RendererBuildProfile): Record<string, string>;
195
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Bound actual bytes while reading, rather than buffering an arbitrary body. */
2
+ export declare function readBoundedDataText(response: Response, signal?: AbortSignal, maxBytes?: number): Promise<string>;
@@ -0,0 +1,17 @@
1
+ import { type RendererIdentity } from '../identity.js';
2
+ import { type DataOperation, type DecodedDataOutcome } from './types.js';
3
+ export declare function readDataResponse(response: Response, expected: {
4
+ identity: RendererIdentity;
5
+ routeId: string;
6
+ operation: DataOperation;
7
+ }, signal?: AbortSignal): Promise<DecodedDataOutcome>;
8
+ export declare function createDataClient(routeId: string, identity: RendererIdentity, options?: {
9
+ fetch?: typeof globalThis.fetch;
10
+ }): {
11
+ loader(input: {
12
+ request: Request;
13
+ }): Promise<DecodedDataOutcome>;
14
+ action(input: {
15
+ request: Request;
16
+ }): Promise<DecodedDataOutcome>;
17
+ };
@@ -0,0 +1,14 @@
1
+ export declare const DATA_CODEC: 'seroval-json@1.6.8';
2
+ export declare const MAX_DATA_BYTES: number;
3
+ export declare class DataProtocolError extends Error {
4
+ constructor(message: string);
5
+ }
6
+ /** Only explicit loader/action results are public. Request context is not data. */
7
+ export declare function assertPublicData(value: unknown, options?: {
8
+ privateReferences?: WeakSet<object>;
9
+ }): void;
10
+ /** JSON text stays inert when it is placed in a script element. */
11
+ export declare function escapeInlineDataJSON(text: string): string;
12
+ /** JSON text. `serializeInlineData` escapes it when it goes into a document. */
13
+ export declare function serializePublicData(value: unknown): string;
14
+ export declare function parsePublicData(text: string): unknown;
@@ -0,0 +1,8 @@
1
+ export * from './client.js';
2
+ export * from './codec.js';
3
+ export type { RequestDataPolicy } from './private.js';
4
+ export { createRequestDataPolicy } from './private.js';
5
+ export * from './routes.js';
6
+ export * from './server.js';
7
+ export * from './static.js';
8
+ export * from './types.js';
@@ -0,0 +1,6 @@
1
+ export interface RequestDataPolicy {
2
+ assertRoot(value: unknown): void;
3
+ assertValue(value: unknown): void;
4
+ }
5
+ /** Capture aliases before callbacks, and retain them as request context changes. */
6
+ export declare function createRequestDataPolicy(roots: readonly unknown[]): RequestDataPolicy;
@@ -0,0 +1,28 @@
1
+ /** Module references remain build-time strings; adapters import their own views. */
2
+ export interface RouteModuleReferences {
3
+ data?: string;
4
+ clientData?: string;
5
+ loading?: string;
6
+ error?: string;
7
+ search?: string;
8
+ head?: string;
9
+ notFound?: string;
10
+ }
11
+ /** Filesystem structure only. Matching and scheduling belong to native routers. */
12
+ export interface FileSystemRouteIR {
13
+ id: string;
14
+ file?: string;
15
+ path?: string;
16
+ index?: boolean;
17
+ isRoot?: boolean;
18
+ modules?: RouteModuleReferences;
19
+ children: FileSystemRouteIR[];
20
+ }
21
+ /**
22
+ * Project the structural CLI route shape without retaining source objects,
23
+ * executable handlers, component values, or arbitrary configuration.
24
+ * Input order and conventional path syntax survive the projection unchanged.
25
+ */
26
+ export declare function projectFileSystemRoutes(routes: unknown): FileSystemRouteIR[];
27
+ /** Convert conventional parameter spelling for TanStack without matching it. */
28
+ export declare function toTanstackPath(pathname: string): string;
@@ -0,0 +1,59 @@
1
+ import { type RendererIdentity } from '../identity.js';
2
+ import { responseHeaders as collectDataHeaders } from '../session/cache.js';
3
+ import type { ResponsePolicy } from '../session/types.js';
4
+ import { type DataHandler, type DataHandlerInput, type DataOperation, type DataOutcome, type DataResponseMetadata, type PublicDataError, type SelectedDataRoute } from './types.js';
5
+ export { collectDataHeaders };
6
+ declare const DEFERRED: unique symbol;
7
+ /**
8
+ * Combine header fields from two sources for one document: list fields
9
+ * (cookies, `Vary`, `Link`, `Server-Timing`, CSP) keep both sources' values,
10
+ * while a singleton field from `primary` replaces the `secondary` one.
11
+ */
12
+ export declare function mergeHeaderFields(primary: readonly (readonly [string, string])[], secondary: readonly (readonly [string, string])[]): [string, string][];
13
+ /**
14
+ * Opaque result of {@link deferData}. Exported so loaders returning it keep a
15
+ * nameable type under declaration emit (composite/declaration projects).
16
+ */
17
+ export interface DeferredDataResult {
18
+ [DEFERRED]: true;
19
+ critical: Record<string, unknown>;
20
+ deferred: Record<string, Promise<unknown>>;
21
+ init?: ResponseInit;
22
+ }
23
+ export declare function deferData(critical: Record<string, unknown>, deferred: Record<string, Promise<unknown>>, init?: ResponseInit): DeferredDataResult;
24
+ /** The native router supplies status after resolving its own route outcomes. */
25
+ export declare function mergeDataResponseMetadata(outcomes: readonly DataOutcome[], nativeResponse: {
26
+ status: number;
27
+ statusText?: string;
28
+ }): DataResponseMetadata;
29
+ /** Loader representation headers cannot describe the native HTML document. */
30
+ export declare function dataMetadataToDocumentPolicy(metadata: DataResponseMetadata): ResponsePolicy;
31
+ /** Preserve a native terminal response while adding all matched loader cookies. */
32
+ export declare function mergeDataResponseIntoResponse(response: Response, metadata: DataResponseMetadata): Response;
33
+ export declare function publicDataError(error: unknown, production?: boolean): PublicDataError;
34
+ /** Resolve every status/redirect/header outcome before the document commits headers. */
35
+ export declare function normalizeDataResult(value: unknown, options?: {
36
+ thrown?: boolean;
37
+ production?: boolean;
38
+ signal?: AbortSignal;
39
+ }): Promise<DataOutcome>;
40
+ export declare function invokeRouteData<Context>(handler: DataHandler<Context>, input: DataHandlerInput<Context>, options?: {
41
+ production?: boolean;
42
+ privateValues?: readonly unknown[];
43
+ }): Promise<DataOutcome>;
44
+ export declare function createDataResponse(outcome: DataOutcome, identity: RendererIdentity, options: {
45
+ routeId: string;
46
+ operation: DataOperation;
47
+ signal?: AbortSignal;
48
+ production?: boolean;
49
+ onCancel?: (reason: unknown) => void | Promise<void>;
50
+ }): Response;
51
+ export declare function handleDataRequest<Context>(options: {
52
+ request: Request;
53
+ identity: RendererIdentity;
54
+ context: Context;
55
+ selectRoute: (request: Request, requestedRouteId: string, operation: DataOperation) => SelectedDataRoute<Context> | undefined | Promise<SelectedDataRoute<Context> | undefined>;
56
+ production?: boolean;
57
+ /** Additional dispatcher-owned request identities, never public payload. */
58
+ privateValues?: readonly unknown[];
59
+ }): Promise<Response | undefined>;
@@ -0,0 +1,31 @@
1
+ import { DATA_CONTENT_TYPE, DATA_STREAM_CONTENT_TYPE } from './types.js';
2
+ /** Head marker written into documents produced by static prerendering. */
3
+ export declare const PRERENDERED_DOCUMENT_META = "ultramodern-prerendered";
4
+ /** Directory beside a prerendered document that holds its loader payloads. */
5
+ export declare const STATIC_DATA_DIRECTORY = "__ultramodern-data";
6
+ /** A loader response captured at build time, replayed by the data client. */
7
+ export interface StaticDataPayload {
8
+ status: number;
9
+ contentType: typeof DATA_CONTENT_TYPE | typeof DATA_STREAM_CONTENT_TYPE;
10
+ body: string;
11
+ }
12
+ /** URL path of one route's loader payload for a search-free document path. */
13
+ export declare function staticDataPayloadPath(pathname: string, routeId: string): string;
14
+ /**
15
+ * The client reads a payload file whole before replaying it. One response
16
+ * wrapped as a JSON string can grow up to six times through escaping; a
17
+ * deferred stream's frames are bounded only one by one, so prerendering
18
+ * checks the whole file against the same limit.
19
+ */
20
+ export declare const STATIC_DATA_PAYLOAD_MAX_BYTES: number;
21
+ /**
22
+ * Read a captured loader response with a running byte bound. Encoding only
23
+ * grows the body, so a body over the limit fails as soon as it crosses it,
24
+ * before an unbounded deferred stream is buffered.
25
+ */
26
+ export declare function readStaticDataPayloadBody(response: Response): Promise<string>;
27
+ /** The payload file's text, or an error when the client could not read it. */
28
+ export declare function encodeStaticDataPayload(payload: StaticDataPayload): string;
29
+ export declare function isStaticDataPayload(value: unknown): value is StaticDataPayload;
30
+ /** Whether the current browser document was emitted by static prerendering. */
31
+ export declare function isPrerenderedDocument(): boolean;
@@ -0,0 +1,3 @@
1
+ import type { SerovalJSON } from 'seroval';
2
+ /** Validate inert, pure-data Seroval JSON before the decoder can coerce it. */
3
+ export declare function validateSerializedData(value: unknown): asserts value is SerovalJSON;