tachyon-dom 0.1.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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +339 -0
  3. package/dist/adapters/lambda.d.ts +65 -0
  4. package/dist/adapters/lambda.js +211 -0
  5. package/dist/adapters/node.d.ts +25 -0
  6. package/dist/adapters/node.js +360 -0
  7. package/dist/adapters/workers.d.ts +149 -0
  8. package/dist/adapters/workers.js +272 -0
  9. package/dist/adapters.d.ts +3 -0
  10. package/dist/adapters.js +3 -0
  11. package/dist/app.d.ts +98 -0
  12. package/dist/app.js +306 -0
  13. package/dist/cli.d.ts +55 -0
  14. package/dist/cli.js +711 -0
  15. package/dist/compiler/expression.d.ts +55 -0
  16. package/dist/compiler/expression.js +858 -0
  17. package/dist/compiler/index.d.ts +8 -0
  18. package/dist/compiler/index.js +50 -0
  19. package/dist/compiler/ir.d.ts +4 -0
  20. package/dist/compiler/ir.js +255 -0
  21. package/dist/compiler/parser.d.ts +3 -0
  22. package/dist/compiler/parser.js +236 -0
  23. package/dist/compiler/sfc.d.ts +33 -0
  24. package/dist/compiler/sfc.js +439 -0
  25. package/dist/compiler/targets/client.d.ts +3 -0
  26. package/dist/compiler/targets/client.js +568 -0
  27. package/dist/compiler/targets/server.d.ts +7 -0
  28. package/dist/compiler/targets/server.js +396 -0
  29. package/dist/compiler/targets/stream.d.ts +2 -0
  30. package/dist/compiler/targets/stream.js +204 -0
  31. package/dist/compiler/types.d.ts +185 -0
  32. package/dist/compiler/types.js +1 -0
  33. package/dist/compiler/utils.d.ts +40 -0
  34. package/dist/compiler/utils.js +185 -0
  35. package/dist/compiler/whitespace.d.ts +2 -0
  36. package/dist/compiler/whitespace.js +66 -0
  37. package/dist/compiler.d.ts +1 -0
  38. package/dist/compiler.js +1 -0
  39. package/dist/constant-time.d.ts +1 -0
  40. package/dist/constant-time.js +26 -0
  41. package/dist/cookies.d.ts +44 -0
  42. package/dist/cookies.js +199 -0
  43. package/dist/diagnostics.d.ts +22 -0
  44. package/dist/diagnostics.js +45 -0
  45. package/dist/env.d.ts +27 -0
  46. package/dist/env.js +37 -0
  47. package/dist/html-escape.d.ts +2 -0
  48. package/dist/html-escape.js +20 -0
  49. package/dist/html-whitespace.d.ts +6 -0
  50. package/dist/html-whitespace.js +83 -0
  51. package/dist/i18n.d.ts +19 -0
  52. package/dist/i18n.js +93 -0
  53. package/dist/index.d.ts +20 -0
  54. package/dist/index.js +18 -0
  55. package/dist/language-server.d.ts +17 -0
  56. package/dist/language-server.js +79 -0
  57. package/dist/package-integrity.d.ts +9 -0
  58. package/dist/package-integrity.js +64 -0
  59. package/dist/result.d.ts +13 -0
  60. package/dist/result.js +4 -0
  61. package/dist/router-node.d.ts +2 -0
  62. package/dist/router-node.js +12 -0
  63. package/dist/router.d.ts +324 -0
  64. package/dist/router.js +1024 -0
  65. package/dist/runtime/attr.d.ts +3 -0
  66. package/dist/runtime/attr.js +66 -0
  67. package/dist/runtime/class.d.ts +2 -0
  68. package/dist/runtime/class.js +10 -0
  69. package/dist/runtime/conditional.d.ts +78 -0
  70. package/dist/runtime/conditional.js +140 -0
  71. package/dist/runtime/enhancement.d.ts +11 -0
  72. package/dist/runtime/enhancement.js +70 -0
  73. package/dist/runtime/error-boundary.d.ts +8 -0
  74. package/dist/runtime/error-boundary.js +27 -0
  75. package/dist/runtime/event.d.ts +1 -0
  76. package/dist/runtime/event.js +11 -0
  77. package/dist/runtime/form.d.ts +41 -0
  78. package/dist/runtime/form.js +167 -0
  79. package/dist/runtime/fragment.d.ts +6 -0
  80. package/dist/runtime/fragment.js +18 -0
  81. package/dist/runtime/html.d.ts +8 -0
  82. package/dist/runtime/html.js +6 -0
  83. package/dist/runtime/hydrate.d.ts +68 -0
  84. package/dist/runtime/hydrate.js +205 -0
  85. package/dist/runtime/keyed-rows.d.ts +61 -0
  86. package/dist/runtime/keyed-rows.js +192 -0
  87. package/dist/runtime/list.d.ts +84 -0
  88. package/dist/runtime/list.js +424 -0
  89. package/dist/runtime/portal.d.ts +6 -0
  90. package/dist/runtime/portal.js +12 -0
  91. package/dist/runtime/router.d.ts +102 -0
  92. package/dist/runtime/router.js +649 -0
  93. package/dist/runtime/signal.d.ts +30 -0
  94. package/dist/runtime/signal.js +275 -0
  95. package/dist/runtime/store.d.ts +1 -0
  96. package/dist/runtime/store.js +1 -0
  97. package/dist/runtime/stream-client.d.ts +8 -0
  98. package/dist/runtime/stream-client.js +33 -0
  99. package/dist/runtime/text.d.ts +2 -0
  100. package/dist/runtime/text.js +10 -0
  101. package/dist/runtime/virtual-list.d.ts +15 -0
  102. package/dist/runtime/virtual-list.js +89 -0
  103. package/dist/security.d.ts +27 -0
  104. package/dist/security.js +173 -0
  105. package/dist/server/form-action.d.ts +52 -0
  106. package/dist/server/form-action.js +102 -0
  107. package/dist/server/html.d.ts +19 -0
  108. package/dist/server/html.js +101 -0
  109. package/dist/server/stream.d.ts +4 -0
  110. package/dist/server/stream.js +72 -0
  111. package/dist/source-map.d.ts +17 -0
  112. package/dist/source-map.js +18 -0
  113. package/dist/tachyon-html.d.ts +110 -0
  114. package/dist/testing.d.ts +14 -0
  115. package/dist/testing.js +36 -0
  116. package/dist/typed.d.ts +9 -0
  117. package/dist/typed.js +4 -0
  118. package/dist/vite.d.ts +84 -0
  119. package/dist/vite.js +426 -0
  120. package/package.json +604 -0
@@ -0,0 +1,79 @@
1
+ import { createConnection, DiagnosticSeverity, ProposedFeatures, TextDocumentSyncKind, TextDocuments, } from "vscode-languageserver/node";
2
+ import { TextDocument } from "vscode-languageserver-textdocument";
3
+ import { diagnoseTachyonSfc } from "./diagnostics.js";
4
+ const source = "tachyon-dom";
5
+ export const diagnosticsForTachyonDocument = (text) => {
6
+ const result = diagnoseTachyonSfc(text);
7
+ if (result.ok) {
8
+ return [];
9
+ }
10
+ const diagnostic = result.error;
11
+ const line = Math.max(0, diagnostic.line - 1);
12
+ const character = Math.max(0, diagnostic.column - 1);
13
+ const endLine = Math.max(line, diagnostic.endLine - 1);
14
+ const endCharacter = Math.max(0, diagnostic.endColumn - 1);
15
+ return [
16
+ {
17
+ message: diagnostic.message,
18
+ range: {
19
+ start: { line, character },
20
+ end: { line: endLine, character: endCharacter },
21
+ },
22
+ severity: DiagnosticSeverity.Error,
23
+ source,
24
+ },
25
+ ];
26
+ };
27
+ export const createDiagnosticsScheduler = (sendDiagnostics, delayMs = 80) => {
28
+ const pending = new Map();
29
+ const clear = (uri) => {
30
+ const timer = pending.get(uri);
31
+ if (timer !== undefined) {
32
+ clearTimeout(timer);
33
+ pending.delete(uri);
34
+ }
35
+ };
36
+ return {
37
+ schedule: (document) => {
38
+ clear(document.uri);
39
+ pending.set(document.uri, setTimeout(() => {
40
+ pending.delete(document.uri);
41
+ sendDiagnostics({
42
+ uri: document.uri,
43
+ diagnostics: diagnosticsForTachyonDocument(document.getText()),
44
+ });
45
+ }, delayMs));
46
+ },
47
+ clear,
48
+ dispose: () => {
49
+ for (const timer of pending.values()) {
50
+ clearTimeout(timer);
51
+ }
52
+ pending.clear();
53
+ },
54
+ };
55
+ };
56
+ export const startLanguageServer = (connection = createConnection(ProposedFeatures.all)) => {
57
+ const documents = new TextDocuments(TextDocument);
58
+ const diagnostics = createDiagnosticsScheduler((payload) => connection.sendDiagnostics(payload));
59
+ connection.onInitialize(() => ({
60
+ capabilities: {
61
+ textDocumentSync: TextDocumentSyncKind.Incremental,
62
+ },
63
+ }));
64
+ documents.onDidOpen((event) => {
65
+ connection.sendDiagnostics({
66
+ uri: event.document.uri,
67
+ diagnostics: diagnosticsForTachyonDocument(event.document.getText()),
68
+ });
69
+ });
70
+ documents.onDidChangeContent((event) => {
71
+ diagnostics.schedule(event.document);
72
+ });
73
+ documents.onDidClose((event) => {
74
+ diagnostics.clear(event.document.uri);
75
+ connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
76
+ });
77
+ documents.listen(connection);
78
+ connection.listen();
79
+ };
@@ -0,0 +1,9 @@
1
+ import { type Result } from "./result.js";
2
+ export type PackageArtifactCheckOptions = {
3
+ packageDir: string;
4
+ checkPack?: boolean;
5
+ };
6
+ export type PackageArtifactCheck = {
7
+ checkedFiles: string[];
8
+ };
9
+ export declare const verifyPackageArtifacts: (options: PackageArtifactCheckOptions) => Promise<Result<PackageArtifactCheck, string>>;
@@ -0,0 +1,64 @@
1
+ import { execFile } from "node:child_process";
2
+ import { access, readFile } from "node:fs/promises";
3
+ import { promisify } from "node:util";
4
+ import { err, ok } from "./result.js";
5
+ const execFileAsync = promisify(execFile);
6
+ const isDistReference = (value) => value.startsWith("./dist/");
7
+ const normalizePackagePath = (value) => value.replace(/^\.\//, "");
8
+ const collectExportReferences = (value, label, references) => {
9
+ if (typeof value === "string") {
10
+ if (isDistReference(value)) {
11
+ references.push({ label, path: value });
12
+ }
13
+ return;
14
+ }
15
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
16
+ return;
17
+ }
18
+ for (const [key, nested] of Object.entries(value)) {
19
+ collectExportReferences(nested, `${label}.${key}`, references);
20
+ }
21
+ };
22
+ const collectArtifactReferences = (packageJson) => {
23
+ const references = [];
24
+ if (typeof packageJson.bin === "string") {
25
+ references.push({ label: "bin", path: packageJson.bin });
26
+ }
27
+ else if (packageJson.bin) {
28
+ for (const [name, value] of Object.entries(packageJson.bin)) {
29
+ references.push({ label: `bin.${name}`, path: value });
30
+ }
31
+ }
32
+ collectExportReferences(packageJson.exports, "exports", references);
33
+ return references.filter((reference) => isDistReference(reference.path));
34
+ };
35
+ const packedFilesFor = async (packageDir) => {
36
+ const { stdout } = await execFileAsync("npm", ["pack", "--dry-run", "--json"], { cwd: packageDir });
37
+ const [pack] = JSON.parse(stdout);
38
+ return new Set((pack?.files ?? []).flatMap((file) => (file.path ? [file.path] : [])));
39
+ };
40
+ export const verifyPackageArtifacts = async (options) => {
41
+ const packageJson = JSON.parse(await readFile(`${options.packageDir}/package.json`, "utf8"));
42
+ const references = collectArtifactReferences(packageJson);
43
+ const missing = [];
44
+ for (const reference of references) {
45
+ try {
46
+ await access(`${options.packageDir}/${normalizePackagePath(reference.path)}`);
47
+ }
48
+ catch {
49
+ missing.push(`${reference.label} -> ${reference.path}`);
50
+ }
51
+ }
52
+ if (options.checkPack !== false) {
53
+ const packedFiles = await packedFilesFor(options.packageDir);
54
+ for (const reference of references) {
55
+ if (!packedFiles.has(normalizePackagePath(reference.path))) {
56
+ missing.push(`${reference.label} -> ${reference.path} is not included in npm pack output`);
57
+ }
58
+ }
59
+ }
60
+ if (missing.length > 0) {
61
+ return err(`Package artifact verification failed:\n${missing.map((item) => `- ${item}`).join("\n")}`);
62
+ }
63
+ return ok({ checkedFiles: references.map((reference) => normalizePackagePath(reference.path)).sort() });
64
+ };
@@ -0,0 +1,13 @@
1
+ export type Ok<T> = {
2
+ readonly ok: true;
3
+ readonly value: T;
4
+ };
5
+ export type Err<E> = {
6
+ readonly ok: false;
7
+ readonly error: E;
8
+ };
9
+ export type Result<T, E> = Ok<T> | Err<E>;
10
+ export declare const ok: <T>(value: T) => Ok<T>;
11
+ export declare const err: <E>(error: E) => Err<E>;
12
+ export declare const isOk: <T, E>(result: Result<T, E>) => result is Ok<T>;
13
+ export declare const isErr: <T, E>(result: Result<T, E>) => result is Err<E>;
package/dist/result.js ADDED
@@ -0,0 +1,4 @@
1
+ export const ok = (value) => ({ ok: true, value });
2
+ export const err = (error) => ({ ok: false, error });
3
+ export const isOk = (result) => result.ok;
4
+ export const isErr = (result) => !result.ok;
@@ -0,0 +1,2 @@
1
+ import { type FileRouteManifestEntry } from "./router.js";
2
+ export declare const scanFileRoutes: (rootDir: string) => Promise<FileRouteManifestEntry[]>;
@@ -0,0 +1,12 @@
1
+ import { readdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { createFileRouteManifest } from "./router.js";
4
+ const collectFiles = async (directory) => {
5
+ const entries = await readdir(directory, { withFileTypes: true });
6
+ const files = await Promise.all(entries.map(async (entry) => {
7
+ const absolute = path.join(directory, entry.name);
8
+ return entry.isDirectory() ? await collectFiles(absolute) : [absolute];
9
+ }));
10
+ return files.flat();
11
+ };
12
+ export const scanFileRoutes = async (rootDir) => createFileRouteManifest(await collectFiles(rootDir), { rootDir });
@@ -0,0 +1,324 @@
1
+ import { type Result } from "./result.js";
2
+ import { type HtmlWhitespacePolicy } from "./html-whitespace.js";
3
+ export type RouteParams = Record<string, string>;
4
+ export type ParamsForPath<Path extends string> = Path extends `${string}:${infer Param}/${infer Rest}` ? {
5
+ [Key in Param | keyof ParamsForPath<`/${Rest}`>]: string;
6
+ } : Path extends `${string}:${infer Param}` ? {
7
+ [Key in Param]: string;
8
+ } : Path extends `${string}*${infer Param}/${infer Rest}` ? {
9
+ [Key in Param | keyof ParamsForPath<`/${Rest}`>]: string;
10
+ } : Path extends `${string}*${infer Param}` ? {
11
+ [Key in Param]: string;
12
+ } : {};
13
+ export type RouteResource = {
14
+ rel: "stylesheet" | "modulepreload" | "preload" | "prefetch";
15
+ href: string;
16
+ as?: string;
17
+ type?: string;
18
+ crossorigin?: string;
19
+ fetchpriority?: "high" | "low" | "auto";
20
+ };
21
+ export type RouteHeadDescriptor = {
22
+ title?: string;
23
+ metas?: Array<Record<string, string>>;
24
+ links?: Array<Record<string, string>>;
25
+ scripts?: Array<Record<string, string>>;
26
+ };
27
+ export type TrustedHtml = {
28
+ __tachyonTrustedHtml: true;
29
+ value: string;
30
+ };
31
+ export type RouteContext<Data = unknown, ActionResult = unknown> = {
32
+ request: Request;
33
+ url: URL;
34
+ params: RouteParams;
35
+ route: RouteDefinition;
36
+ env: RouteEnvironment;
37
+ data: Data;
38
+ loaderData: Record<string, unknown>;
39
+ actionResult: ActionResult;
40
+ outlet: string;
41
+ };
42
+ export type RouteEnvironment = Record<string, string | undefined>;
43
+ export type RouteCachePolicy = {
44
+ mode?: "public" | "private" | "no-store";
45
+ maxAge?: number;
46
+ sharedMaxAge?: number;
47
+ staleWhileRevalidate?: number;
48
+ staleIfError?: number;
49
+ immutable?: boolean;
50
+ tags?: readonly string[];
51
+ };
52
+ export type RouteDefinition<Data = unknown, ActionResult = unknown> = {
53
+ id?: string;
54
+ path: string;
55
+ loader?: (context: Omit<RouteContext<Data, ActionResult>, "data" | "outlet">) => Data | Promise<Data>;
56
+ action?: (context: Omit<RouteContext<Data, ActionResult>, "data" | "outlet">) => ActionResult | Promise<ActionResult>;
57
+ head?: (descriptor: RouteContext<Data, ActionResult>) => RouteHeadDescriptor | Promise<RouteHeadDescriptor> | RouteHeadDescriptor;
58
+ resources?: readonly RouteResource[] | ((context: RouteContext<Data, ActionResult>) => readonly RouteResource[]);
59
+ headers?: HeadersInit | ((context: RouteContext<Data, ActionResult>) => HeadersInit | Promise<HeadersInit>);
60
+ cache?: RouteCachePolicy | ((context: RouteContext<Data, ActionResult>) => RouteCachePolicy | Promise<RouteCachePolicy>);
61
+ fallback?: string;
62
+ error?: (context: {
63
+ request: Request;
64
+ url: URL;
65
+ error: unknown;
66
+ }) => string | Promise<string>;
67
+ notFound?: (context: {
68
+ request: Request;
69
+ url: URL;
70
+ }) => string | Promise<string>;
71
+ /**
72
+ * Streams the deepest matched route after loaders and authoritative metadata resolve.
73
+ * Every string is trusted raw HTML: adapters do not escape or sanitize chunks. Use
74
+ * trustedHtmlChunk(escapeToHtml(value)) for untrusted text and a vetted sanitizer
75
+ * followed by trustedHtmlChunk() for intentionally accepted markup.
76
+ */
77
+ stream?: (context: RouteContext<Data, ActionResult>) => AsyncIterable<string>;
78
+ render: (context: RouteContext<Data, ActionResult>) => string | Promise<string>;
79
+ children?: RouteDefinition[];
80
+ };
81
+ export type RouteManifestEntry = {
82
+ id: string;
83
+ path: string;
84
+ parentId?: string;
85
+ };
86
+ export type FileRouteManifestEntry = {
87
+ id: string;
88
+ path: string;
89
+ file: string;
90
+ kind: "template" | "module" | "layout";
91
+ };
92
+ export type MatchedRoute = {
93
+ route: RouteDefinition;
94
+ branch: Array<{
95
+ route: RouteDefinition;
96
+ path: string;
97
+ params: RouteParams;
98
+ }>;
99
+ params: RouteParams;
100
+ pathname: string;
101
+ };
102
+ export type RouteRenderResult = {
103
+ status: number;
104
+ html: string;
105
+ headHtml: string;
106
+ resourceHints: string;
107
+ stateScript: string;
108
+ loaderData: Record<string, unknown>;
109
+ actionResult: unknown;
110
+ match: MatchedRoute;
111
+ headers: Headers;
112
+ responseBody?: string;
113
+ responseChunks?: AsyncIterable<string>;
114
+ };
115
+ type RouteRenderOptionsBase = {
116
+ notFound?: (context: {
117
+ request: Request;
118
+ url: URL;
119
+ }) => string | Promise<string>;
120
+ error?: (context: {
121
+ request: Request;
122
+ url: URL;
123
+ error: unknown;
124
+ }) => string | Promise<string>;
125
+ allowedMethods?: readonly string[];
126
+ maxActionBodyBytes?: number;
127
+ cspNonce?: string;
128
+ csrf?: {
129
+ verify: (context: {
130
+ request: Request;
131
+ url: URL;
132
+ env: RouteEnvironment;
133
+ }) => boolean | Promise<boolean>;
134
+ };
135
+ middleware?: readonly RouteMiddleware[];
136
+ hooks?: RouteHooks;
137
+ env?: RouteEnvironment;
138
+ };
139
+ export type RouteRenderOptions = RouteRenderOptionsBase & {
140
+ /** Applied only after buffered rendering. Streaming chunks are always preserved. */
141
+ htmlWhitespace?: HtmlWhitespacePolicy;
142
+ };
143
+ export type RouteError = {
144
+ message: string;
145
+ status: number;
146
+ };
147
+ export type RouteModule<Data = unknown, ActionResult = unknown> = {
148
+ path?: string;
149
+ loader?: RouteDefinition<Data, ActionResult>["loader"];
150
+ action?: RouteDefinition<Data, ActionResult>["action"];
151
+ head?: RouteDefinition<Data, ActionResult>["head"];
152
+ resources?: RouteDefinition<Data, ActionResult>["resources"];
153
+ headers?: RouteDefinition<Data, ActionResult>["headers"];
154
+ cache?: RouteDefinition<Data, ActionResult>["cache"];
155
+ fallback?: string;
156
+ stream?: RouteDefinition<Data, ActionResult>["stream"];
157
+ template?: RouteDefinition<Data, ActionResult>["render"];
158
+ render?: RouteDefinition<Data, ActionResult>["render"];
159
+ ErrorBoundary?: (context: {
160
+ request: Request;
161
+ url: URL;
162
+ error: unknown;
163
+ }) => string | Promise<string>;
164
+ NotFound?: (context: {
165
+ request: Request;
166
+ url: URL;
167
+ }) => string | Promise<string>;
168
+ children?: RouteDefinition[];
169
+ };
170
+ export type RouteResponse = {
171
+ __tachyonRouteResponse: true;
172
+ status: number;
173
+ headers: Headers;
174
+ body: string;
175
+ };
176
+ export type RouteMiddlewareResult = Request | Response | RouteResponse | void;
177
+ export type RouteMiddleware = (context: {
178
+ request: Request;
179
+ url: URL;
180
+ env: RouteEnvironment;
181
+ }) => RouteMiddlewareResult | Promise<RouteMiddlewareResult>;
182
+ export type RouteHooks = {
183
+ onRequest?: (context: {
184
+ request: Request;
185
+ url: URL;
186
+ }) => void | Promise<void>;
187
+ onMatch?: (context: {
188
+ request: Request;
189
+ url: URL;
190
+ match: MatchedRoute;
191
+ }) => void | Promise<void>;
192
+ onLoader?: (context: {
193
+ request: Request;
194
+ url: URL;
195
+ route: RouteDefinition;
196
+ data: unknown;
197
+ }) => void | Promise<void>;
198
+ onAction?: (context: {
199
+ request: Request;
200
+ url: URL;
201
+ route: RouteDefinition;
202
+ result: unknown;
203
+ }) => void | Promise<void>;
204
+ onRender?: (context: {
205
+ request: Request;
206
+ url: URL;
207
+ html: string;
208
+ match: MatchedRoute;
209
+ }) => void | Promise<void>;
210
+ onError?: (context: {
211
+ request: Request;
212
+ url: URL;
213
+ error: unknown;
214
+ match?: MatchedRoute;
215
+ }) => void | Promise<void>;
216
+ };
217
+ export type DeferredData<T extends Record<string, unknown> = Record<string, unknown>> = {
218
+ __tachyonDeferredData: true;
219
+ immediate: Partial<T>;
220
+ pending: Partial<{
221
+ [Key in keyof T]: Promise<Awaited<T[Key]>>;
222
+ }>;
223
+ };
224
+ export type RouteBuildManifest = {
225
+ buildId: string;
226
+ routes: RouteManifestEntry[];
227
+ assets: Record<string, string[]>;
228
+ types: string;
229
+ };
230
+ export type RoutePreloadEntry = {
231
+ href: string;
232
+ rel: "modulepreload" | "preload" | "prefetch";
233
+ as?: string;
234
+ };
235
+ export type UserGuardOptions<User> = {
236
+ redirectTo?: string;
237
+ forbidden?: (context: {
238
+ request: Request;
239
+ url: URL;
240
+ }) => RouteResponse | Response;
241
+ getRedirect?: (context: {
242
+ request: Request;
243
+ url: URL;
244
+ }) => string;
245
+ onUser?: (context: {
246
+ request: Request;
247
+ url: URL;
248
+ user: User;
249
+ }) => void | Promise<void>;
250
+ };
251
+ export declare const isDeferredData: (value: unknown) => value is DeferredData;
252
+ export type RedirectOptions = ResponseInit & {
253
+ allowExternal?: boolean;
254
+ allowedOrigins?: readonly string[];
255
+ };
256
+ export declare const redirect: (location: string, init?: RedirectOptions) => RouteResponse;
257
+ export declare const json: (data: unknown, init?: ResponseInit) => RouteResponse;
258
+ export declare const unsafeHtml: (value: string) => TrustedHtml;
259
+ export declare const escapeToHtml: (value: unknown) => TrustedHtml;
260
+ /**
261
+ * Converts a factory-created TrustedHtml value into a raw progressive response chunk.
262
+ * Route stream chunks are inserted as HTML without adapter escaping. Escape untrusted
263
+ * text with escapeToHtml(), or sanitize intentional markup with a vetted sanitizer,
264
+ * before calling this helper.
265
+ */
266
+ export declare const trustedHtmlChunk: (value: TrustedHtml) => string;
267
+ export declare const html: (body: TrustedHtml, init?: ResponseInit) => RouteResponse;
268
+ export declare const cacheControl: (policy: RouteCachePolicy) => Headers;
269
+ export declare const withCacheHeaders: (response: Response, policy: RouteCachePolicy) => Response;
270
+ export declare const defer: <T extends Record<string, unknown>>(values: T) => DeferredData<T>;
271
+ export declare const resolveDeferredData: <T extends Record<string, unknown>>(data: DeferredData<T>) => Promise<T>;
272
+ export declare const renderDeferredDataScript: <T extends Record<string, unknown>>(id: string, data: DeferredData<T>, options?: {
273
+ nonce?: string;
274
+ }) => Promise<string>;
275
+ export declare const createSecurityHeaders: (options?: {
276
+ nonce?: string;
277
+ csp?: boolean;
278
+ hsts?: boolean;
279
+ frameAncestors?: string;
280
+ }) => Headers;
281
+ export declare const applySecurityHeaders: (response: Response, headers: Headers) => Response;
282
+ export declare const requireUser: <User>(getUser: (context: {
283
+ request: Request;
284
+ url: URL;
285
+ }) => User | undefined | null | Promise<User | undefined | null>, options?: UserGuardOptions<User>) => RouteMiddleware;
286
+ export declare const defineRouteModule: <Data = unknown, ActionResult = unknown>(module: RouteModule<Data, ActionResult>) => RouteModule<Data, ActionResult>;
287
+ export declare const routeFromModule: <Data = unknown, ActionResult = unknown>(id: string, module: RouteModule<Data, ActionResult>) => RouteDefinition<Data, ActionResult>;
288
+ export declare const createFileRouteManifest: (files: readonly string[], options: {
289
+ rootDir: string;
290
+ }) => FileRouteManifestEntry[];
291
+ export declare const createRouteManifest: (routes: readonly RouteDefinition[], parentPath?: string, parentId?: string) => RouteManifestEntry[];
292
+ export declare const generateRouteTypes: (manifest: readonly Pick<RouteManifestEntry, "id" | "path">[]) => string;
293
+ export declare const createRouteBuildManifest: (routes: readonly RouteDefinition[], options: {
294
+ buildId: string;
295
+ assets?: readonly {
296
+ routeId: string;
297
+ files: readonly string[];
298
+ }[];
299
+ }) => RouteBuildManifest;
300
+ export declare const hrefForRoute: (manifest: readonly Pick<RouteManifestEntry, "id" | "path">[], id: string, params?: RouteParams) => string;
301
+ export declare const createHrefBuilder: <Manifest extends readonly Pick<RouteManifestEntry, "id" | "path">[]>(manifest: Manifest) => <Id extends Manifest[number]["id"]>(id: Id, params?: RouteParams) => string;
302
+ export declare const createRoutePreloadPlan: (manifest: RouteBuildManifest, routeId: string) => RoutePreloadEntry[];
303
+ export declare const matchRoute: (routes: readonly RouteDefinition[], input: string | URL) => Result<MatchedRoute, RouteError>;
304
+ export declare const renderHead: (descriptor: RouteHeadDescriptor, options?: {
305
+ nonce?: string;
306
+ }) => string;
307
+ export declare const renderResourceHints: (resources: readonly RouteResource[]) => string;
308
+ export declare const collectRouteResources: (branch: readonly {
309
+ route: RouteDefinition;
310
+ path: string;
311
+ params: RouteParams;
312
+ }[], context?: Partial<RouteContext>) => RouteResource[];
313
+ export declare const renderRoute: (routes: readonly RouteDefinition[], input: Request | URL | string, options?: RouteRenderOptions) => Promise<Result<RouteRenderResult, RouteError>>;
314
+ export type RouteStreamResult = {
315
+ status: number;
316
+ chunks: AsyncIterable<string>;
317
+ headHtml: string;
318
+ resourceHints: string;
319
+ stateScript: string;
320
+ headers: Headers;
321
+ final: Promise<Pick<RouteRenderResult, "headHtml" | "resourceHints" | "stateScript" | "headers" | "status">>;
322
+ };
323
+ export declare const renderRouteStream: (routes: readonly RouteDefinition[], input: Request | URL | string, options?: RouteRenderOptions) => Promise<Result<RouteStreamResult, RouteError>>;
324
+ export {};