@remix-run/assets 0.0.0 → 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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +319 -2
  3. package/dist/assets.d.ts +3 -0
  4. package/dist/assets.d.ts.map +1 -0
  5. package/dist/assets.js +1 -0
  6. package/dist/lib/access.d.ts +10 -0
  7. package/dist/lib/access.d.ts.map +1 -0
  8. package/dist/lib/access.js +14 -0
  9. package/dist/lib/asset-server.d.ts +137 -0
  10. package/dist/lib/asset-server.d.ts.map +1 -0
  11. package/dist/lib/asset-server.js +242 -0
  12. package/dist/lib/compilation-error.d.ts +33 -0
  13. package/dist/lib/compilation-error.d.ts.map +1 -0
  14. package/dist/lib/compilation-error.js +32 -0
  15. package/dist/lib/file-matcher.d.ts +6 -0
  16. package/dist/lib/file-matcher.d.ts.map +1 -0
  17. package/dist/lib/file-matcher.js +43 -0
  18. package/dist/lib/fingerprint.d.ts +12 -0
  19. package/dist/lib/fingerprint.d.ts.map +1 -0
  20. package/dist/lib/fingerprint.js +49 -0
  21. package/dist/lib/paths.d.ts +8 -0
  22. package/dist/lib/paths.d.ts.map +1 -0
  23. package/dist/lib/paths.js +50 -0
  24. package/dist/lib/routes.d.ts +13 -0
  25. package/dist/lib/routes.d.ts.map +1 -0
  26. package/dist/lib/routes.js +94 -0
  27. package/dist/lib/scripts/cjs-check.d.ts +3 -0
  28. package/dist/lib/scripts/cjs-check.d.ts.map +1 -0
  29. package/dist/lib/scripts/cjs-check.js +398 -0
  30. package/dist/lib/scripts/compiler.d.ts +62 -0
  31. package/dist/lib/scripts/compiler.d.ts.map +1 -0
  32. package/dist/lib/scripts/compiler.js +435 -0
  33. package/dist/lib/scripts/emit.d.ts +25 -0
  34. package/dist/lib/scripts/emit.d.ts.map +1 -0
  35. package/dist/lib/scripts/emit.js +63 -0
  36. package/dist/lib/scripts/resolve.d.ts +60 -0
  37. package/dist/lib/scripts/resolve.d.ts.map +1 -0
  38. package/dist/lib/scripts/resolve.js +230 -0
  39. package/dist/lib/scripts/store.d.ts +40 -0
  40. package/dist/lib/scripts/store.d.ts.map +1 -0
  41. package/dist/lib/scripts/store.js +228 -0
  42. package/dist/lib/scripts/transform.d.ts +62 -0
  43. package/dist/lib/scripts/transform.d.ts.map +1 -0
  44. package/dist/lib/scripts/transform.js +362 -0
  45. package/dist/lib/source-maps.d.ts +4 -0
  46. package/dist/lib/source-maps.d.ts.map +1 -0
  47. package/dist/lib/source-maps.js +56 -0
  48. package/dist/lib/watch.d.ts +22 -0
  49. package/dist/lib/watch.d.ts.map +1 -0
  50. package/dist/lib/watch.js +96 -0
  51. package/package.json +50 -12
  52. package/src/assets.ts +2 -0
  53. package/src/lib/access.ts +24 -0
  54. package/src/lib/asset-server.ts +415 -0
  55. package/src/lib/compilation-error.ts +61 -0
  56. package/src/lib/file-matcher.ts +62 -0
  57. package/src/lib/fingerprint.ts +65 -0
  58. package/src/lib/paths.ts +66 -0
  59. package/src/lib/routes.ts +164 -0
  60. package/src/lib/scripts/cjs-check.ts +476 -0
  61. package/src/lib/scripts/compiler.ts +622 -0
  62. package/src/lib/scripts/emit.ts +122 -0
  63. package/src/lib/scripts/resolve.ts +422 -0
  64. package/src/lib/scripts/store.ts +327 -0
  65. package/src/lib/scripts/transform.ts +594 -0
  66. package/src/lib/source-maps.ts +68 -0
  67. package/src/lib/watch.ts +136 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Shopify Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,320 @@
1
- # Placeholder Package
1
+ # assets
2
2
 
3
- This package is a placeholder published at `0.0.0` to reserve the npm name and configure CI publish permissions.
3
+ Fetch-based server for compiling browser JS/TS assets on demand.
4
+
5
+ ## Features
6
+
7
+ - **On-Demand Compilation** - Compile browser assets on demand
8
+ - **Custom File Mapping** - Define patterns for mapping public URLs to file paths on disk
9
+ - **Access Control** - Control exactly which files can be served with allow and deny rules
10
+ - **Preloads** - Generate modulepreload URLs for `<link>` tags or `Link` headers
11
+ - **Caching** - Conservative caching by default with stable URLs, ETags, and revalidation
12
+ - **Optional Fingerprinting** - Source-based fingerprinted URLs for long-lived browser caching
13
+ - **Source Maps** - Serve inline or external sourcemaps
14
+
15
+ ## Installation
16
+
17
+ ```sh
18
+ npm i remix
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ Use `createAssetServer` to serve browser modules from a URL namespace in your app.
24
+
25
+ ```ts
26
+ import { createRouter } from 'remix/fetch-router'
27
+ import { createAssetServer } from 'remix/assets'
28
+
29
+ let assetServer = createAssetServer({
30
+ fileMap: {
31
+ '/assets/app/*path': 'app/*path',
32
+ '/assets/npm/*path': 'node_modules/*path',
33
+ },
34
+ allow: ['app/assets/**', 'node_modules/**'],
35
+ })
36
+
37
+ let router = createRouter()
38
+
39
+ router.get('/assets/*', ({ request }) => {
40
+ return assetServer.fetch(request)
41
+ })
42
+ ```
43
+
44
+ This example gives you an `/assets/*` endpoint that serves compiled browser JS modules from `app/assets` and `node_modules`.
45
+
46
+ ## Root Directory
47
+
48
+ Use `rootDir` to specify the root directory of the asset server, which is used to resolve relative file paths. Defaults to `process.cwd()`.
49
+
50
+ ```ts
51
+ import * as path from 'node:path'
52
+ import { createAssetServer } from 'remix/assets'
53
+
54
+ let assetServer = createAssetServer({
55
+ rootDir: path.resolve(import.meta.dirname, '..'),
56
+ fileMap: {
57
+ '/assets/app/*path': 'app/*path',
58
+ '/assets/npm/*path': 'node_modules/*path',
59
+ },
60
+ allow: ['app/assets/**', 'node_modules/**'],
61
+ })
62
+ ```
63
+
64
+ ## Access Control
65
+
66
+ You must provide an `allow` list to specify which files are allowed to be served. `deny` is optional and takes precedence over `allow`.
67
+
68
+ ```ts
69
+ import { createAssetServer } from 'remix/assets'
70
+
71
+ let assetServer = createAssetServer({
72
+ fileMap: { '/assets/app/*path': 'app/*path' },
73
+ allow: ['app/assets/**'],
74
+ deny: ['app/**/*.server.*'],
75
+ })
76
+ ```
77
+
78
+ Rules for `allow` and `deny` are file paths or globs. Relative values are resolved from `rootDir`. Absolute file paths match exactly, and absolute directory paths also match their descendants.
79
+
80
+ ## File Map
81
+
82
+ Use `fileMap` to map public URLs to file paths on disk. The keys are public URL patterns, and the values are root-relative file path patterns.
83
+
84
+ ```ts
85
+ import { createAssetServer } from 'remix/assets'
86
+
87
+ let assetServer = createAssetServer({
88
+ fileMap: {
89
+ '/assets/app/*path': 'app/*path',
90
+ '/assets/packages/*path': '../packages/*path',
91
+ },
92
+ allow: ['app/assets/**', '../packages/**'],
93
+ })
94
+ ```
95
+
96
+ `fileMap` entries use [`route-pattern`](https://github.com/remix-run/remix/tree/main/packages/route-pattern) syntax for both URL and file patterns. Wildcards must be named, and the same params must appear in both patterns so imports can be rewritten back to public URLs.
97
+
98
+ ### File watching
99
+
100
+ The file system is watched by default so source changes are picked up without requiring a server restart.
101
+
102
+ ```ts
103
+ import { createAssetServer } from 'remix/assets'
104
+
105
+ let assetServer = createAssetServer({
106
+ fileMap: { '/assets/app/*path': 'app/*path' },
107
+ allow: ['app/assets/**', 'app/node_modules/**'],
108
+ })
109
+ ```
110
+
111
+ When finished with the asset server, call `await assetServer.close()` to clean up the file watcher.
112
+
113
+ ```ts
114
+ await assetServer.close()
115
+ ```
116
+
117
+ You can disable file watching if the files on disk won't change, or if watching is managed at a higher level (e.g. Node's `--watch` flag).
118
+
119
+ ```ts
120
+ import { createAssetServer } from 'remix/assets'
121
+
122
+ let assetServer = createAssetServer({
123
+ fileMap: { '/assets/app/*path': 'app/*path' },
124
+ allow: ['app/assets/**', 'app/node_modules/**'],
125
+ watch: false,
126
+ })
127
+ ```
128
+
129
+ You can optionally provide an array of glob patterns to the `watch.ignore` option:
130
+
131
+ ```ts
132
+ import { createAssetServer } from 'remix/assets'
133
+
134
+ let assetServer = createAssetServer({
135
+ fileMap: { '/assets/app/*path': 'app/*path' },
136
+ allow: ['app/assets/**', 'app/node_modules/**'],
137
+ watch: {
138
+ ignore: ['**/node_modules/**'],
139
+ },
140
+ })
141
+ ```
142
+
143
+ ## Hrefs
144
+
145
+ Use `assetServer.getHref()` when you need the public URL for a served asset. You can provide a root-relative or absolute file path, or a `file://` URL.
146
+
147
+ ```ts
148
+ let src = await assetServer.getHref('app/assets/entry.tsx')
149
+ // '/assets/app/assets/entry.tsx'
150
+ ```
151
+
152
+ ## Preloads
153
+
154
+ Use `assetServer.getPreloads()` when rendering HTML so you can turn the returned URLs into `<link rel="modulepreload">` tags or `Link` headers for one or more assets and their dependencies. You can provide root-relative or absolute file paths, or `file://` URLs.
155
+
156
+ ```ts
157
+ let preloads = await assetServer.getPreloads(['app/assets/entry.tsx', 'app/assets/search.tsx'])
158
+ // [
159
+ // '/assets/app/assets/entry.tsx',
160
+ // '/assets/app/assets/search.tsx',
161
+ // '/assets/app/assets/utils.ts',
162
+ // '/assets/npm/@remix-run/component/index.js',
163
+ // ...etc
164
+ // ]
165
+ ```
166
+
167
+ ## Fingerprinting
168
+
169
+ By default, scripts are served at stable URLs with ETags and `Cache-Control: no-cache`. Responses are cached for the lifetime of the asset server instance.
170
+
171
+ If you want clients to cache scripts aggressively without revalidation, you can opt into source-based fingerprinting.
172
+
173
+ ```ts
174
+ import { createAssetServer } from 'remix/assets'
175
+
176
+ let assetServer = createAssetServer({
177
+ fileMap: { '/assets/app/*path': 'app/*path' },
178
+ allow: ['app/assets/**'],
179
+ watch: false,
180
+ fingerprint: {
181
+ buildId: process.env.GITHUB_SHA,
182
+ },
183
+ })
184
+ ```
185
+
186
+ When fingerprinting is enabled, scripts use a `.@<fingerprint>` segment before the file extension and are served with `Cache-Control: public, max-age=31536000, immutable`.
187
+
188
+ Source fingerprints are based on the original file contents and the build ID. The build ID must change for each deployment so that fingerprinted modules are invalidated together. This fingerprinting strategy assumes that files on disk won't change, so fingerprinting requires `watch: false`.
189
+
190
+ ## Script Options
191
+
192
+ ### Minification
193
+
194
+ Enable minification with `scripts.minify`:
195
+
196
+ ```ts
197
+ import { createAssetServer } from 'remix/assets'
198
+
199
+ let assetServer = createAssetServer({
200
+ fileMap: { '/assets/app/*path': 'app/*path' },
201
+ allow: ['app/assets/**'],
202
+ scripts: {
203
+ minify: true,
204
+ },
205
+ })
206
+ ```
207
+
208
+ ### Target
209
+
210
+ Use `scripts.target` to lower emitted syntax to a specific ECMAScript version.
211
+
212
+ ```ts
213
+ import { createAssetServer } from 'remix/assets'
214
+
215
+ let assetServer = createAssetServer({
216
+ fileMap: { '/assets/app/*path': 'app/*path' },
217
+ allow: ['app/assets/**'],
218
+ scripts: {
219
+ target: 'es2019',
220
+ },
221
+ })
222
+ ```
223
+
224
+ The default target is `esnext`, which means all syntax is preserved.
225
+
226
+ ### Define
227
+
228
+ Use `scripts.define` to replace global identifiers with constant expressions.
229
+
230
+ ```ts
231
+ import { createAssetServer } from 'remix/assets'
232
+
233
+ let assetServer = createAssetServer({
234
+ fileMap: { '/assets/app/*path': 'app/*path' },
235
+ allow: ['app/assets/**', 'app/node_modules/**'],
236
+ scripts: {
237
+ define: {
238
+ 'process.env.NODE_ENV': '"production"',
239
+ },
240
+ minify: true,
241
+ },
242
+ })
243
+ ```
244
+
245
+ Values are injected exactly as defined, so string literals must include their own quotes, e.g. `process.env.NODE_ENV` must be `"production"` rather than `production`.
246
+
247
+ ### Source Maps
248
+
249
+ Enable sourcemaps with either `'external'` or `'inline'` using `scripts.sourceMaps`:
250
+
251
+ ```ts
252
+ import { createAssetServer } from 'remix/assets'
253
+
254
+ let assetServer = createAssetServer({
255
+ fileMap: { '/assets/app/*path': 'app/*path' },
256
+ allow: ['app/assets/**'],
257
+ scripts: {
258
+ sourceMaps: 'external',
259
+ },
260
+ })
261
+ ```
262
+
263
+ By default, sourcemap `sources` use URLs so they're presented alongside the compiled output in your browser's developer tools. You can also use file system paths instead with `scripts.sourceMapSourcePaths`:
264
+
265
+ ```ts
266
+ import { createAssetServer } from 'remix/assets'
267
+
268
+ let assetServer = createAssetServer({
269
+ fileMap: { '/assets/app/*path': 'app/*path' },
270
+ allow: ['app/assets/**'],
271
+ scripts: {
272
+ sourceMaps: 'inline',
273
+ sourceMapSourcePaths: 'absolute',
274
+ },
275
+ })
276
+ ```
277
+
278
+ ### External Imports
279
+
280
+ Use `scripts.external` to leave specific import specifiers unchanged by providing an array of specifiers.
281
+
282
+ ```ts
283
+ import { createAssetServer } from 'remix/assets'
284
+
285
+ let assetServer = createAssetServer({
286
+ fileMap: { '/assets/app/*path': 'app/*path' },
287
+ allow: ['app/assets/**'],
288
+ scripts: {
289
+ external: ['my-external-import'],
290
+ },
291
+ })
292
+ ```
293
+
294
+ ## Error Handling
295
+
296
+ Use `onError` to report unexpected compilation failures and/or return a custom response.
297
+
298
+ ```ts
299
+ import { createAssetServer } from 'remix/assets'
300
+
301
+ let assetServer = createAssetServer({
302
+ fileMap: { '/assets/app/*path': 'app/*path' },
303
+ allow: ['app/assets/**'],
304
+ onError(error) {
305
+ console.error('Failed to build client module', error)
306
+ return new Response('Client module build failed', { status: 500 })
307
+ },
308
+ })
309
+ ```
310
+
311
+ If `onError` returns nothing, the asset server responds with the default `500 Internal Server Error` response.
312
+
313
+ ## Related Packages
314
+
315
+ - [`fetch-router`](https://github.com/remix-run/remix/tree/main/packages/fetch-router) - A Fetch-based router that pairs naturally with `assets`
316
+ - [`route-pattern`](https://github.com/remix-run/remix/tree/main/packages/route-pattern) - Route-pattern syntax for URL and route file matching
317
+
318
+ ## License
319
+
320
+ See [LICENSE](https://github.com/remix-run/remix/blob/main/LICENSE)
@@ -0,0 +1,3 @@
1
+ export { createAssetServer } from './lib/asset-server.ts';
2
+ export type { AssetServer, AssetServerOptions } from './lib/asset-server.ts';
3
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA"}
package/dist/assets.js ADDED
@@ -0,0 +1 @@
1
+ export { createAssetServer } from "./lib/asset-server.js";
@@ -0,0 +1,10 @@
1
+ type AccessPolicy = {
2
+ isAllowed(filePath: string): boolean;
3
+ };
4
+ export declare function createAccessPolicy(options: {
5
+ allow: readonly string[];
6
+ deny?: readonly string[];
7
+ rootDir: string;
8
+ }): AccessPolicy;
9
+ export {};
10
+ //# sourceMappingURL=access.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/lib/access.ts"],"names":[],"mappings":"AAEA,KAAK,YAAY,GAAG;IAClB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CACrC,CAAA;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,YAAY,CAaf"}
@@ -0,0 +1,14 @@
1
+ import { createFileMatcher } from "./file-matcher.js";
2
+ export function createAccessPolicy(options) {
3
+ let allowMatchers = options.allow.map((pattern) => createFileMatcher(pattern, options.rootDir));
4
+ let denyMatchers = (options.deny ?? []).map((pattern) => createFileMatcher(pattern, options.rootDir));
5
+ return {
6
+ isAllowed(filePath) {
7
+ if (!allowMatchers.some((matcher) => matcher(filePath)))
8
+ return false;
9
+ if (denyMatchers.length > 0 && denyMatchers.some((matcher) => matcher(filePath)))
10
+ return false;
11
+ return true;
12
+ },
13
+ };
14
+ }
@@ -0,0 +1,137 @@
1
+ import type { ChokidarWatcher } from './watch.ts';
2
+ interface AssetServerWatchOptions {
3
+ /**
4
+ * Ignore matching glob patterns or file paths. Relative values are resolved
5
+ * from `rootDir`.
6
+ */
7
+ ignore?: readonly string[];
8
+ /**
9
+ * Use polling instead of native filesystem events. Defaults to `false`.
10
+ */
11
+ poll?: boolean;
12
+ /**
13
+ * Polling interval in milliseconds when `poll` is enabled. Defaults to `100`.
14
+ */
15
+ pollInterval?: number;
16
+ }
17
+ interface FingerprintOptions {
18
+ /**
19
+ * Per-build invalidation token that must change whenever fingerprinted module URLs
20
+ * should be invalidated together.
21
+ */
22
+ buildId: string;
23
+ }
24
+ declare const scriptTargets: readonly ["es2015", "es2016", "es2017", "es2018", "es2019", "es2020", "es2021", "es2022", "es2023", "es2024", "es2025", "es2026", "esnext"];
25
+ export type ScriptsTarget = (typeof scriptTargets)[number];
26
+ export interface AssetServerOptions {
27
+ /** File patterns keyed by public URL patterns. */
28
+ fileMap: Readonly<Record<string, string>>;
29
+ /**
30
+ * Root directory used to resolve relative file paths. Defaults to `process.cwd()`.
31
+ */
32
+ rootDir?: string;
33
+ /**
34
+ * Glob patterns or file paths that are allowed to be served. Relative values are resolved from `rootDir`.
35
+ */
36
+ allow: readonly string[];
37
+ /**
38
+ * Glob patterns or file paths that are denied from being served. Relative values are resolved from `rootDir`.
39
+ */
40
+ deny?: readonly string[];
41
+ /**
42
+ * Controls optional source-based URL fingerprinting for rewritten import URLs.
43
+ *
44
+ * When omitted, all served modules use stable non-fingerprinted URLs with `Cache-Control: no-cache`.
45
+ * Cannot be used together with active watch mode. Set `watch: false` when fingerprinting.
46
+ */
47
+ fingerprint?: FingerprintOptions;
48
+ /**
49
+ * Script pipeline configuration. Omit to use defaults.
50
+ */
51
+ scripts?: {
52
+ /**
53
+ * Source map mode (disabled when omitted).
54
+ * - `'external'`: serve source maps as separate `.map` files; adds `//# sourceMappingURL=` comment
55
+ * - `'inline'`: embed source maps as a base64 data URL directly in the JS; no separate `.map` file
56
+ */
57
+ sourceMaps?: 'inline' | 'external';
58
+ /**
59
+ * Controls the source paths written into source map `sources`.
60
+ * - `'url'` (default): use the stable server path (e.g. `'/assets/app/entry.ts'`)
61
+ * - `'absolute'`: use the original filesystem path on disk
62
+ */
63
+ sourceMapSourcePaths?: 'url' | 'absolute';
64
+ /**
65
+ * Minify emitted modules.
66
+ */
67
+ minify?: boolean;
68
+ /**
69
+ * Replace global expressions with constant values during transform, e.g.
70
+ * `{ 'process.env.NODE_ENV': '"production"' }`
71
+ */
72
+ define?: Record<string, string>;
73
+ /**
74
+ * Lower emitted syntax to a specific ECMAScript target. Omit this option to preserve
75
+ * modern syntax unless project configuration already requests a lower target.
76
+ */
77
+ target?: ScriptsTarget;
78
+ /** Import specifiers to leave unrewritten (CDN URLs, import map entries, etc.) */
79
+ external?: string[];
80
+ };
81
+ /**
82
+ * Enable filesystem-backed cache invalidation for long-lived server instances.
83
+ * Enabled by default. Pass `true` to use the default watcher options, an options
84
+ * object to customize watcher behavior, or `false` to disable watching.
85
+ */
86
+ watch?: boolean | AssetServerWatchOptions;
87
+ /**
88
+ * Handles unexpected request-time compilation errors. Return a `Response` to override the
89
+ * default `500 Internal Server Error` response, or return nothing to use the default.
90
+ */
91
+ onError?: (error: unknown) => void | Response | Promise<void | Response>;
92
+ }
93
+ export interface AssetServer {
94
+ /**
95
+ * Serves a script request. Returns `Response | null` — null means the request was not
96
+ * handled by this server, letting the router fall through to a 404.
97
+ */
98
+ fetch(request: Request): Promise<Response | null>;
99
+ /**
100
+ * Returns the request href for a served module file.
101
+ */
102
+ getHref(filePath: string): Promise<string>;
103
+ /**
104
+ * Returns preload URLs for one or more served module files, ordered shallowest-first.
105
+ */
106
+ getPreloads(filePath: string | readonly string[]): Promise<string[]>;
107
+ /**
108
+ * Closes any watcher resources owned by this server instance.
109
+ */
110
+ close(): Promise<void>;
111
+ }
112
+ export declare function getInternalChokidarWatcher(assetServer: AssetServer): ChokidarWatcher | undefined;
113
+ export declare function getInternalWatchTargets(assetServer: AssetServer): readonly string[];
114
+ /**
115
+ * Create an asset server instance
116
+ *
117
+ * Compiles TypeScript/JavaScript modules on demand with optional source-based URL
118
+ * fingerprinting, caching, and configurable file mapping.
119
+ *
120
+ * @param options Server configuration
121
+ * @returns A {@link AssetServer} with `fetch()`, `getHref()`, and `getPreloads()` methods
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * let assetServer = createAssetServer({
126
+ * fileMap: {
127
+ * '/assets/app/*path': 'app/*path',
128
+ * },
129
+ * allow: ['app/**'],
130
+ * })
131
+ *
132
+ * route('/assets/*path', ({ request }) => assetServer.fetch(request))
133
+ * ```
134
+ */
135
+ export declare function createAssetServer(options: AssetServerOptions): AssetServer;
136
+ export {};
137
+ //# sourceMappingURL=asset-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-server.d.ts","sourceRoot":"","sources":["../../src/lib/asset-server.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAGjD,UAAU,uBAAuB;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IACd;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,UAAU,kBAAkB;IAC1B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,QAAA,MAAM,aAAa,6IAcT,CAAA;AAGV,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1D,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACzC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC;;OAEG;IACH,OAAO,CAAC,EAAE;QACR;;;;WAIG;QACH,UAAU,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;QAClC;;;;WAIG;QACH,oBAAoB,CAAC,EAAE,KAAK,GAAG,UAAU,CAAA;QACzC;;WAEG;QACH,MAAM,CAAC,EAAE,OAAO,CAAA;QAChB;;;WAGG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC/B;;;WAGG;QACH,MAAM,CAAC,EAAE,aAAa,CAAA;QACtB,kFAAkF;QAClF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KACpB,CAAA;IACD;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,GAAG,uBAAuB,CAAA;IACzC;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAA;CACzE;AAED,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAA;IACjD;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IACpE;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAsBD,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,WAAW,GAAG,eAAe,GAAG,SAAS,CAEhG;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAEnF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CA4H1E"}