@remix-run/assets 0.4.3 → 0.5.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 (76) hide show
  1. package/README.md +322 -56
  2. package/dist/assets.d.ts +2 -1
  3. package/dist/assets.d.ts.map +1 -1
  4. package/dist/assets.js +2 -2
  5. package/dist/lib/access.d.ts +6 -2
  6. package/dist/lib/access.d.ts.map +1 -1
  7. package/dist/lib/access.js +300 -5
  8. package/dist/lib/asset-server.d.ts +118 -5
  9. package/dist/lib/asset-server.d.ts.map +1 -1
  10. package/dist/lib/asset-server.js +260 -24
  11. package/dist/lib/compilation-error.d.ts +1 -1
  12. package/dist/lib/compilation-error.d.ts.map +1 -1
  13. package/dist/lib/file-matcher.js +1 -1
  14. package/dist/lib/files/compiler.d.ts.map +1 -1
  15. package/dist/lib/files/compiler.js +7 -6
  16. package/dist/lib/files/config.js +1 -1
  17. package/dist/lib/hmr.d.ts +37 -0
  18. package/dist/lib/hmr.d.ts.map +1 -0
  19. package/dist/lib/hmr.js +357 -0
  20. package/dist/lib/injected-packages.d.ts.map +1 -1
  21. package/dist/lib/injected-packages.js +36 -13
  22. package/dist/lib/loaders.d.ts +57 -0
  23. package/dist/lib/loaders.d.ts.map +1 -0
  24. package/dist/lib/loaders.js +1 -0
  25. package/dist/lib/module-store.d.ts +24 -0
  26. package/dist/lib/module-store.d.ts.map +1 -1
  27. package/dist/lib/module-store.js +136 -11
  28. package/dist/lib/routes.d.ts.map +1 -1
  29. package/dist/lib/routes.js +13 -13
  30. package/dist/lib/scripts/compiler.d.ts +24 -1
  31. package/dist/lib/scripts/compiler.d.ts.map +1 -1
  32. package/dist/lib/scripts/compiler.js +183 -29
  33. package/dist/lib/scripts/conditions.d.ts +2 -0
  34. package/dist/lib/scripts/conditions.d.ts.map +1 -0
  35. package/dist/lib/scripts/conditions.js +1 -0
  36. package/dist/lib/scripts/emit.d.ts +3 -0
  37. package/dist/lib/scripts/emit.d.ts.map +1 -1
  38. package/dist/lib/scripts/emit.js +24 -5
  39. package/dist/lib/scripts/resolve.d.ts +4 -0
  40. package/dist/lib/scripts/resolve.d.ts.map +1 -1
  41. package/dist/lib/scripts/resolve.js +70 -5
  42. package/dist/lib/scripts/transform.d.ts +9 -0
  43. package/dist/lib/scripts/transform.d.ts.map +1 -1
  44. package/dist/lib/scripts/transform.js +222 -18
  45. package/dist/lib/source-maps.js +1 -1
  46. package/dist/lib/styles/compiler.d.ts +14 -1
  47. package/dist/lib/styles/compiler.d.ts.map +1 -1
  48. package/dist/lib/styles/compiler.js +78 -14
  49. package/dist/lib/styles/emit.js +4 -4
  50. package/dist/lib/styles/resolve.d.ts.map +1 -1
  51. package/dist/lib/styles/resolve.js +8 -7
  52. package/dist/lib/styles/transform.js +3 -3
  53. package/dist/lib/target.d.ts +1 -1
  54. package/dist/lib/target.d.ts.map +1 -1
  55. package/dist/lib/watch.js +1 -1
  56. package/dist/types/hmr.d.ts +36 -0
  57. package/package.json +17 -11
  58. package/src/assets.ts +2 -1
  59. package/src/lib/access.ts +386 -5
  60. package/src/lib/asset-server.ts +429 -18
  61. package/src/lib/compilation-error.ts +1 -0
  62. package/src/lib/files/compiler.ts +7 -3
  63. package/src/lib/hmr.ts +397 -0
  64. package/src/lib/injected-packages.ts +41 -11
  65. package/src/lib/loaders.ts +80 -0
  66. package/src/lib/module-store.ts +190 -9
  67. package/src/lib/routes.ts +24 -14
  68. package/src/lib/scripts/compiler.ts +248 -24
  69. package/src/lib/scripts/conditions.ts +1 -0
  70. package/src/lib/scripts/emit.ts +50 -5
  71. package/src/lib/scripts/resolve.ts +124 -2
  72. package/src/lib/scripts/transform.ts +290 -19
  73. package/src/lib/styles/compiler.ts +108 -8
  74. package/src/lib/styles/emit.ts +1 -1
  75. package/src/lib/styles/resolve.ts +11 -7
  76. package/src/types/hmr.d.ts +36 -0
@@ -1,18 +1,19 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs';
3
- import { createAccessPolicy } from "./access.js";
4
- import { createAssetServerCompilationError, isAssetServerCompilationError, } from "./compilation-error.js";
5
- import { createFileCompiler, createResponseForFile } from "./files/compiler.js";
6
- import { normalizeFilesOptions, serializeAssetTransformInvocations } from "./files/config.js";
7
- import { getFingerprintRequestCacheControl, parseFingerprintSuffix } from "./fingerprint.js";
8
- import { getInjectedPackageRouteConfigs } from "./injected-packages.js";
9
- import { normalizeFilePath, normalizePathname } from "./paths.js";
10
- import { compileRoutes } from "./routes.js";
11
- import { createResponseForScript, createScriptCompiler } from "./scripts/compiler.js";
12
- import { supportedScriptExtensions } from "./scripts/resolve.js";
13
- import { createResponseForStyle, createStyleCompiler, isStyleFilePath } from "./styles/compiler.js";
14
- import { resolveScriptTarget, resolveStyleTarget } from "./target.js";
15
- import { createAssetServerWatcher } from "./watch.js";
3
+ import { createAccessPolicy } from './access.js';
4
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from './compilation-error.js';
5
+ import { createFileCompiler, createResponseForFile } from './files/compiler.js';
6
+ import { normalizeFilesOptions, serializeAssetTransformInvocations } from './files/config.js';
7
+ import { getFingerprintRequestCacheControl, parseFingerprintSuffix } from './fingerprint.js';
8
+ import { createHmrClientSource } from './hmr.js';
9
+ import { getInjectedPackageRouteConfigs } from './injected-packages.js';
10
+ import { normalizeFilePath, normalizePathname } from './paths.js';
11
+ import { compileRoutes } from './routes.js';
12
+ import { createResponseForScript, createScriptCompiler } from './scripts/compiler.js';
13
+ import { supportedScriptExtensions } from './scripts/resolve.js';
14
+ import { createResponseForStyle, createStyleCompiler, isStyleFilePath } from './styles/compiler.js';
15
+ import { resolveScriptTarget, resolveStyleTarget } from './target.js';
16
+ import { createAssetServerWatcher } from './watch.js';
16
17
  const scriptExtensionSet = new Set(supportedScriptExtensions);
17
18
  const chokidarWatcherByAssetServer = new WeakMap();
18
19
  const watcherByAssetServer = new WeakMap();
@@ -38,7 +39,9 @@ export function getInternalWatchTargets(assetServer) {
38
39
  * fileMap: {
39
40
  * '/app/*path': 'app/*path',
40
41
  * },
41
- * allow: ['app/**'],
42
+ * allowFiles: ['app/routes.ts', 'app/**\/public/**'],
43
+ * allowPackages: ['remix'],
44
+ * denyFiles: ['app/**\/*.test.*'],
42
45
  * })
43
46
  *
44
47
  * route('/assets/*path', ({ request }) => assetServer.fetch(request))
@@ -47,18 +50,45 @@ export function getInternalWatchTargets(assetServer) {
47
50
  export function createAssetServer(options) {
48
51
  let resolvedOptions = resolveAssetServerOptions(options);
49
52
  let accessPolicy = createAccessPolicy({
50
- allow: resolvedOptions.allow,
51
- deny: resolvedOptions.deny,
53
+ allowFiles: resolvedOptions.allowFiles,
54
+ allowPackages: resolvedOptions.allowPackages,
55
+ denyFiles: resolvedOptions.denyFiles,
56
+ packageSearchRoots: hasPackages(resolvedOptions.allowPackages)
57
+ ? getPackageSearchRoots(options.fileMap, resolvedOptions.rootDir)
58
+ : undefined,
52
59
  rootDir: resolvedOptions.rootDir,
53
60
  });
54
61
  let watcher = null;
55
62
  let chokidarWatcher = null;
56
63
  let fileCompiler = null;
64
+ let closed = false;
65
+ let unsubscribeBrowserHmrFileEvents;
66
+ let browserHmrChannelPromise = createBrowserHmrChannel(resolvedOptions.hmr, handleBrowserHmrFileEvents, () => closed, (unsubscribe) => {
67
+ unsubscribeBrowserHmrFileEvents = unsubscribe;
68
+ });
69
+ void browserHmrChannelPromise.catch(() => {
70
+ // The HMR client request and close() both await this promise. Attach a
71
+ // rejection handler now so async factory failures do not surface first as
72
+ // unhandled rejections.
73
+ });
74
+ let sendHmrPayload = resolvedOptions.hmr ? createHmrPayloadSender() : null;
75
+ let hmrPathnames = getHmrPathnames(resolvedOptions.basePath);
57
76
  let scriptCompiler = createScriptCompiler({
58
77
  buildId: resolvedOptions.buildId,
59
78
  define: resolvedOptions.define,
60
79
  external: resolvedOptions.external,
61
80
  fingerprintAssets: resolvedOptions.fingerprintAssets,
81
+ loaders: resolvedOptions.loaders,
82
+ hmr: sendHmrPayload
83
+ ? {
84
+ clientPathname: hmrPathnames.client,
85
+ send(updates) {
86
+ let payload = createScriptHmrPayload(updates);
87
+ if (payload)
88
+ sendHmrPayload(payload);
89
+ },
90
+ }
91
+ : undefined,
62
92
  isAllowed: accessPolicy.isAllowed,
63
93
  minify: resolvedOptions.minify,
64
94
  onWatchDirectoriesChange: (delta) => {
@@ -66,6 +96,9 @@ export function createAssetServer(options) {
66
96
  return;
67
97
  watcher.updateWatchedDirectories(delta);
68
98
  },
99
+ onWatchFilesChange: (delta) => {
100
+ updateBrowserHmrWatchedFiles(delta);
101
+ },
69
102
  rootDir: resolvedOptions.rootDir,
70
103
  routes: resolvedOptions.routes,
71
104
  sourceMapSourcePaths: resolvedOptions.sourceMapSourcePaths,
@@ -88,6 +121,22 @@ export function createAssetServer(options) {
88
121
  }
89
122
  return fileCompiler.getHref(identityPath, { transform: options.transform });
90
123
  },
124
+ hmr: sendHmrPayload
125
+ ? {
126
+ send(pathname, timestamp) {
127
+ sendHmrPayload({
128
+ timestamp,
129
+ type: 'browser:update',
130
+ updates: [
131
+ {
132
+ path: pathname,
133
+ type: 'css',
134
+ },
135
+ ],
136
+ });
137
+ },
138
+ }
139
+ : undefined,
91
140
  isAllowed: accessPolicy.isAllowed,
92
141
  isServedFilePath(filePath) {
93
142
  return fileCompiler?.isServedFilePath(filePath) ?? false;
@@ -98,6 +147,9 @@ export function createAssetServer(options) {
98
147
  return;
99
148
  watcher.updateWatchedDirectories(delta, { includeAncestors: false });
100
149
  },
150
+ onWatchFilesChange: (delta) => {
151
+ updateBrowserHmrWatchedFiles(delta);
152
+ },
101
153
  rootDir: resolvedOptions.rootDir,
102
154
  routes: resolvedOptions.routes,
103
155
  sourceMapSourcePaths: resolvedOptions.sourceMapSourcePaths,
@@ -128,6 +180,7 @@ export function createAssetServer(options) {
128
180
  onFileEvent: handleWatchEvent,
129
181
  rootDir: resolvedOptions.rootDir,
130
182
  });
183
+ watcher.updateWatchedDirectories({ add: accessPolicy.getPackageWatchDirectories(), remove: [] }, { includeAncestors: false });
131
184
  }
132
185
  async function responseForError(error) {
133
186
  try {
@@ -141,21 +194,65 @@ export function createAssetServer(options) {
141
194
  async function handleWatchEvent(filePath, event) {
142
195
  try {
143
196
  let normalizedFilePath = normalizeFilePath(filePath);
144
- await scriptCompiler.handleFileEvent(normalizedFilePath, event);
145
- await styleCompiler.handleFileEvent(normalizedFilePath, event);
197
+ accessPolicy.handleFileEvent(normalizedFilePath);
198
+ scriptCompiler.invalidateFileEvent(normalizedFilePath, event);
199
+ styleCompiler.invalidateFileEvent(normalizedFilePath, event);
146
200
  await fileCompiler?.handleFileEvent(normalizedFilePath, event);
147
201
  }
148
202
  catch (error) {
149
203
  console.error(`There was an error invalidating the asset server cache: ${error}`);
150
204
  }
151
205
  }
206
+ async function handleBrowserHmrFileEvents(events) {
207
+ let browserHmrEvents = [];
208
+ for (let event of events) {
209
+ let normalizedFilePath = normalizeFilePath(event.filePath);
210
+ let scriptUpdates = await scriptCompiler.classifyHmrFileEvent(normalizedFilePath, event.event);
211
+ let scriptPayload = createScriptHmrPayload(scriptUpdates);
212
+ if (scriptPayload) {
213
+ browserHmrEvents.push(createBrowserHmrEvent(scriptPayload, getScriptHmrUpdateFiles(scriptUpdates)));
214
+ }
215
+ let styleUpdates = await styleCompiler.classifyHmrFileEvent(normalizedFilePath, event.event);
216
+ for (let styleUpdate of styleUpdates) {
217
+ browserHmrEvents.push(createBrowserHmrEvent({
218
+ timestamp: styleUpdate.timestamp,
219
+ type: 'browser:update',
220
+ updates: [
221
+ {
222
+ path: styleUpdate.path,
223
+ type: 'css',
224
+ },
225
+ ],
226
+ }, [styleUpdate.filePath]));
227
+ }
228
+ await fileCompiler?.handleFileEvent(normalizedFilePath, event.event);
229
+ }
230
+ return browserHmrEvents;
231
+ }
232
+ function updateBrowserHmrWatchedFiles(delta) {
233
+ browserHmrChannelPromise
234
+ .then((channel) => {
235
+ channel?.updateWatchedFiles(delta);
236
+ })
237
+ .catch((error) => {
238
+ console.error(`There was an error updating browser HMR watched files: ${error}`);
239
+ });
240
+ }
152
241
  let assetServer = {
153
242
  async fetch(request) {
154
243
  if (request.method !== 'GET' && request.method !== 'HEAD')
155
244
  return null;
245
+ let requestPathname = new URL(request.url).pathname;
246
+ if (resolvedOptions.hmr) {
247
+ if (requestPathname === hmrPathnames.client) {
248
+ let browserHmrChannel = await browserHmrChannelPromise;
249
+ assertBrowserEventUrl(browserHmrChannel?.url);
250
+ return createHmrClientResponse(browserHmrChannel.url, request.method);
251
+ }
252
+ }
156
253
  let requestUrl = new URL(request.url);
157
254
  let requestedTransform = normalizeRequestedTransformQuery(requestUrl.searchParams);
158
- let parsedRequestPathname = parseAssetRequestPathname(requestUrl.pathname, {
255
+ let parsedRequestPathname = parseAssetRequestPathname(requestPathname, {
159
256
  fingerprintAssets: resolvedOptions.fingerprintAssets,
160
257
  routes: resolvedOptions.routes,
161
258
  });
@@ -246,7 +343,7 @@ export function createAssetServer(options) {
246
343
  });
247
344
  }
248
345
  catch (error) {
249
- // A direct request can race with the filesystem or fail a deeper allow check while
346
+ // A direct request can race with the filesystem or fail a deeper allowFiles check while
250
347
  // compiling imports. In this fetch context, both cases should fall through as "not
251
348
  // handled here" so the outer router can continue to its own 404 behavior.
252
349
  if (isAssetServerCompilationError(error) &&
@@ -341,7 +438,19 @@ export function createAssetServer(options) {
341
438
  return mergePreloadLayers(await Promise.all(preloadLayerGroupPromises));
342
439
  },
343
440
  async close() {
344
- await watcher?.close();
441
+ if (closed)
442
+ return;
443
+ closed = true;
444
+ let unsubscribe = unsubscribeBrowserHmrFileEvents;
445
+ unsubscribeBrowserHmrFileEvents = undefined;
446
+ unsubscribe?.();
447
+ try {
448
+ let channel = await browserHmrChannelPromise;
449
+ channel?.close();
450
+ }
451
+ finally {
452
+ await watcher?.close();
453
+ }
345
454
  },
346
455
  };
347
456
  if (chokidarWatcher) {
@@ -377,6 +486,67 @@ function badRequest(message) {
377
486
  headers: { 'Content-Type': 'text/plain; charset=utf-8' },
378
487
  });
379
488
  }
489
+ function getHmrPathnames(basePath) {
490
+ let hmrBase = `${basePath}/__remix_hmr`;
491
+ return {
492
+ client: `${hmrBase}/client.js`,
493
+ events: `${hmrBase}/events`,
494
+ };
495
+ }
496
+ function createHmrClientResponse(eventPathname, method) {
497
+ return new Response(method === 'HEAD' ? null : createHmrClientSource({ eventPathname }), {
498
+ headers: {
499
+ 'Cache-Control': 'no-cache',
500
+ 'Content-Type': 'application/javascript; charset=utf-8',
501
+ },
502
+ });
503
+ }
504
+ function assertBrowserEventUrl(url) {
505
+ if (url === undefined) {
506
+ throw new TypeError('hmr must be provided');
507
+ }
508
+ }
509
+ function createHmrPayloadSender() {
510
+ return () => { };
511
+ }
512
+ function createBrowserHmrEvent(payload, files) {
513
+ if (payload.type === 'browser:reload') {
514
+ return {
515
+ ...(files.length === 0 ? {} : { files: [...files] }),
516
+ type: 'reload',
517
+ };
518
+ }
519
+ return {
520
+ ...(files.length === 0 ? {} : { files: [...files] }),
521
+ timestamp: payload.timestamp,
522
+ type: 'update',
523
+ updates: payload.updates,
524
+ };
525
+ }
526
+ function getScriptHmrUpdateFiles(updates) {
527
+ return [...new Set(updates.map((update) => update.filePath))];
528
+ }
529
+ export function createScriptHmrPayload(updates) {
530
+ let timestamp = updates[0]?.timestamp ?? Date.now();
531
+ let rejectedUpdate = updates.find((update) => !update.accepted);
532
+ if (rejectedUpdate) {
533
+ return {
534
+ type: 'browser:reload',
535
+ };
536
+ }
537
+ let acceptedUpdates = updates.filter((update) => update.accepted);
538
+ if (acceptedUpdates.length === 0)
539
+ return null;
540
+ return {
541
+ timestamp,
542
+ type: 'browser:update',
543
+ updates: acceptedUpdates.map((update) => ({
544
+ ...(update.acceptedPath === update.path ? {} : { acceptedPath: update.acceptedPath }),
545
+ path: update.path,
546
+ type: 'js',
547
+ })),
548
+ };
549
+ }
380
550
  function mergePreloadLayers(preloadLayersByRoot) {
381
551
  let urls = [];
382
552
  let seen = new Set();
@@ -422,16 +592,24 @@ function resolveAssetServerOptions(options) {
422
592
  fingerprint: options.fingerprint,
423
593
  watch: options.watch,
424
594
  });
595
+ let watchOptions = normalizeWatchOptions(options.watch);
596
+ let hmrFactory = normalizeHmrFactory(options.hmr);
597
+ if (hmrFactory && watchOptions === null) {
598
+ throw new TypeError('hmr requires watch mode');
599
+ }
425
600
  return {
426
- allow: options.allow,
601
+ allowFiles: options.allowFiles,
602
+ allowPackages: options.allowPackages,
427
603
  basePath,
428
604
  buildId: fingerprintOptions.buildId,
429
605
  define: scriptOptions.define,
430
- deny: options.deny,
606
+ denyFiles: options.denyFiles,
431
607
  external: scriptOptions.external ?? [],
432
608
  files: normalizeFilesOptions(options.files),
433
609
  fingerprintAssets: fingerprintOptions.enabled,
610
+ hmr: hmrFactory,
434
611
  minify: options.minify ?? false,
612
+ loaders: scriptOptions.loaders ?? [],
435
613
  onError: options.onError ?? defaultErrorHandler,
436
614
  rootDir,
437
615
  routes: compileRoutes(basePath, [
@@ -445,9 +623,56 @@ function resolveAssetServerOptions(options) {
445
623
  sourceMaps: options.sourceMaps,
446
624
  scriptsTarget: resolveScriptTarget(options.target),
447
625
  stylesTarget: resolveStyleTarget(options.target),
448
- watchOptions: normalizeWatchOptions(options.watch),
626
+ watchOptions,
449
627
  };
450
628
  }
629
+ function normalizeHmrFactory(factory) {
630
+ if (factory === undefined)
631
+ return null;
632
+ if (typeof factory !== 'function') {
633
+ throw new TypeError('hmr must be a function');
634
+ }
635
+ return factory;
636
+ }
637
+ function createBrowserHmrChannel(createChannel, handleFileEvents, isClosed, setUnsubscribe) {
638
+ if (!createChannel)
639
+ return Promise.resolve(null);
640
+ let channelOrPromise;
641
+ try {
642
+ channelOrPromise = createChannel();
643
+ }
644
+ catch (error) {
645
+ return Promise.reject(error);
646
+ }
647
+ return Promise.resolve(channelOrPromise).then((channel) => {
648
+ if (channel === undefined)
649
+ return null;
650
+ validateBrowserHmrChannel(channel);
651
+ if (isClosed()) {
652
+ channel.close();
653
+ return null;
654
+ }
655
+ setUnsubscribe(channel.onFileEvents(handleFileEvents));
656
+ return channel;
657
+ });
658
+ }
659
+ function validateBrowserHmrChannel(channel) {
660
+ if (channel === null || typeof channel !== 'object') {
661
+ throw new TypeError('hmr must create an object');
662
+ }
663
+ if (!('url' in channel) || typeof channel.url !== 'string') {
664
+ throw new TypeError('hmr must create a channel with a string url');
665
+ }
666
+ if (!('close' in channel) || typeof channel.close !== 'function') {
667
+ throw new TypeError('hmr must create a channel with a close function');
668
+ }
669
+ if (!('onFileEvents' in channel) || typeof channel.onFileEvents !== 'function') {
670
+ throw new TypeError('hmr must create a channel with an onFileEvents function');
671
+ }
672
+ if (!('updateWatchedFiles' in channel) || typeof channel.updateWatchedFiles !== 'function') {
673
+ throw new TypeError('hmr must create a channel with an updateWatchedFiles function');
674
+ }
675
+ }
451
676
  function normalizeBasePath(basePath) {
452
677
  if (typeof basePath !== 'string') {
453
678
  throw new TypeError('basePath must be a string');
@@ -481,6 +706,17 @@ function normalizeWatchOptions(options) {
481
706
  return {};
482
707
  return options;
483
708
  }
709
+ function hasPackages(packages) {
710
+ return packages !== undefined && packages.length > 0;
711
+ }
712
+ function getPackageSearchRoots(fileMap, rootDir) {
713
+ return Object.values(fileMap).map((filePattern) => path.resolve(rootDir, getStaticFilePatternPrefix(filePattern)));
714
+ }
715
+ function getStaticFilePatternPrefix(filePattern) {
716
+ let firstDynamicIndex = filePattern.search(/[*:]/);
717
+ let staticPrefix = firstDynamicIndex === -1 ? filePattern : filePattern.slice(0, firstDynamicIndex);
718
+ return staticPrefix.replace(/[/\\]*$/, '');
719
+ }
484
720
  function parseAssetRequestPathname(pathname, options) {
485
721
  let isSourceMapRequest = pathname.endsWith('.map');
486
722
  let pathWithoutMap = isSourceMapRequest ? pathname.slice(0, -4) : pathname;
@@ -1,4 +1,4 @@
1
- type AssetServerCompilationErrorCode = 'FILE_NOT_FOUND' | 'FILE_NOT_ALLOWED' | 'FILE_NOT_SUPPORTED' | 'FILE_OUTSIDE_FILE_MAP' | 'FILE_TRANSFORM_QUERY_INVALID' | 'FILE_TRANSFORM_NOT_SUPPORTED' | 'FILE_TRANSFORM_RESULT_INVALID' | 'FILE_TRANSFORM_FAILED' | 'COMMONJS_NOT_SUPPORTED' | 'TRANSFORM_FAILED' | 'EMIT_FAILED' | 'IMPORT_RESOLUTION_FAILED' | 'IMPORT_NOT_SUPPORTED' | 'IMPORT_NOT_ALLOWED' | 'IMPORT_OUTSIDE_FILE_MAP' | 'URL_RESOLUTION_FAILED' | 'URL_NOT_SUPPORTED' | 'URL_NOT_ALLOWED' | 'URL_OUTSIDE_FILE_MAP';
1
+ type AssetServerCompilationErrorCode = 'FILE_NOT_FOUND' | 'FILE_NOT_ALLOWED' | 'FILE_NOT_SUPPORTED' | 'FILE_OUTSIDE_FILE_MAP' | 'FILE_TRANSFORM_QUERY_INVALID' | 'FILE_TRANSFORM_NOT_SUPPORTED' | 'FILE_TRANSFORM_RESULT_INVALID' | 'FILE_TRANSFORM_FAILED' | 'COMMONJS_NOT_SUPPORTED' | 'TRANSFORM_FAILED' | 'LOADER_FAILED' | 'EMIT_FAILED' | 'IMPORT_RESOLUTION_FAILED' | 'IMPORT_NOT_SUPPORTED' | 'IMPORT_NOT_ALLOWED' | 'IMPORT_OUTSIDE_FILE_MAP' | 'URL_RESOLUTION_FAILED' | 'URL_NOT_SUPPORTED' | 'URL_NOT_ALLOWED' | 'URL_OUTSIDE_FILE_MAP';
2
2
  /**
3
3
  * Internal error used by the request-time asset compilation pipeline.
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"compilation-error.d.ts","sourceRoot":"","sources":["../../src/lib/compilation-error.ts"],"names":[],"mappings":"AAAA,KAAK,+BAA+B,GAChC,gBAAgB,GAChB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,8BAA8B,GAC9B,8BAA8B,GAC9B,+BAA+B,GAC/B,uBAAuB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,aAAa,GACb,0BAA0B,GAC1B,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,GACzB,uBAAuB,GACvB,mBAAmB,GACnB,iBAAiB,GACjB,sBAAsB,CAAA;AAE1B;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,IAAI,EAAE,+BAA+B,CAAA;IAErC,YACE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,+BAA+B,CAAA;KACtC,EAKF;CACF;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,2BAA2B,CAEtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,+BAA+B,CAAA;CACtC,GACA,2BAA2B,CAE7B"}
1
+ {"version":3,"file":"compilation-error.d.ts","sourceRoot":"","sources":["../../src/lib/compilation-error.ts"],"names":[],"mappings":"AAAA,KAAK,+BAA+B,GAChC,gBAAgB,GAChB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,8BAA8B,GAC9B,8BAA8B,GAC9B,+BAA+B,GAC/B,uBAAuB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,eAAe,GACf,aAAa,GACb,0BAA0B,GAC1B,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,GACzB,uBAAuB,GACvB,mBAAmB,GACnB,iBAAiB,GACjB,sBAAsB,CAAA;AAE1B;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,IAAI,EAAE,+BAA+B,CAAA;IAErC,YACE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,+BAA+B,CAAA;KACtC,EAKF;CACF;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,2BAA2B,CAEtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,+BAA+B,CAAA;CACtC,GACA,2BAA2B,CAE7B"}
@@ -1,6 +1,6 @@
1
1
  import * as fs from 'node:fs';
2
2
  import picomatch from 'picomatch';
3
- import { normalizeFilePath, resolveFilePath } from "./paths.js";
3
+ import { normalizeFilePath, resolveFilePath } from './paths.js';
4
4
  export function createFileMatcher(pattern, rootDir, options = {}) {
5
5
  let resolvedPatternPath = resolveFilePath(rootDir, pattern);
6
6
  let allowDirectories = options.allowDirectories ?? true;
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/files/compiler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAU1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAA;AAU7F,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAID,KAAK,iBAAiB,GAAG,WAAW,CAAA;AAEpC,KAAK,aAAa,GACd;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAEL,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,EAAE,SAAS;QACzB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CACP,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE;YACP,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,EAAE,MAAM,CAAA;SACjB,GAEC,MAAM,GACN,UAAU,GACV,wBAAwB,GACxB,IAAI,GACJ,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,wBAAwB,GAAG,IAAI,CAAC,CAAA;KACnE,EAAE,CAAA;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,UAAU,EAAE,gCAAgC,CAAA;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1E,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,sBAAsB,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAChE,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC/B,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAkBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAma7E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,YAAY,CAkC1F;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf,GACA,QAAQ,CAYV;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAE3F"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/files/compiler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAU1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAA;AAU7F,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAID,KAAK,iBAAiB,GAAG,WAAW,CAAA;AAEpC,KAAK,aAAa,GACd;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAEL,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,EAAE,SAAS;QACzB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CACP,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE;YACP,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,EAAE,MAAM,CAAA;SACjB,GAEC,MAAM,GACN,UAAU,GACV,wBAAwB,GACxB,IAAI,GACJ,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,wBAAwB,GAAG,IAAI,CAAC,CAAA;KACnE,EAAE,CAAA;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,UAAU,EAAE,gCAAgC,CAAA;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1E,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,sBAAsB,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAChE,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC/B,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAkBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAma7E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,YAAY,CAsC1F;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf,GACA,QAAQ,CAYV;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAE3F"}
@@ -4,11 +4,11 @@ import * as path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { IfNoneMatch } from '@remix-run/headers/if-none-match';
6
6
  import { detectContentType } from '@remix-run/mime';
7
- import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
8
- import { formatFingerprintedPathname, generateFingerprint, hashContent } from "../fingerprint.js";
9
- import { normalizeFilePath, resolveFilePath } from "../paths.js";
10
- import { parseAssetTransformInvocations } from "./config.js";
11
- import { createSourceFileStore } from "./store.js";
7
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
8
+ import { formatFingerprintedPathname, generateFingerprint, hashContent } from '../fingerprint.js';
9
+ import { normalizeFilePath, resolveFilePath } from '../paths.js';
10
+ import { parseAssetTransformInvocations } from './config.js';
11
+ import { createSourceFileStore } from './store.js';
12
12
  export function createFileCompiler(options) {
13
13
  let resolvedOptions = {
14
14
  ...options,
@@ -327,7 +327,8 @@ export function resolveServedFileOrThrow(filePath, args) {
327
327
  });
328
328
  }
329
329
  if (!args.isAllowed(identityPath)) {
330
- throw createAssetServerCompilationError(`File is not allowed: ${identityPath}`, {
330
+ throw createAssetServerCompilationError(`File "${identityPath}" is not allowed by the asset server access configuration. ` +
331
+ `Add a matching allowFiles or allowPackages rule, or remove a conflicting denyFiles rule.`, {
331
332
  code: 'FILE_NOT_ALLOWED',
332
333
  });
333
334
  }
@@ -1,4 +1,4 @@
1
- import { supportedScriptExtensions } from "../scripts/resolve.js";
1
+ import { supportedScriptExtensions } from '../scripts/resolve.js';
2
2
  export function defineFileTransform(transform) {
3
3
  return transform;
4
4
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Messages consumed by the browser HMR client.
3
+ *
4
+ * Server runtimes use `server:update` to request reconciliation with freshly rendered server
5
+ * output. Asset tooling uses `browser:update` for updates accepted by JavaScript or CSS boundaries,
6
+ * and falls back to `browser:reload` when the page must reload.
7
+ */
8
+ export type HmrPayload = {
9
+ /** Indicates that server-rendered output may have changed. */
10
+ type: 'server:update';
11
+ } | {
12
+ /** JavaScript and CSS modules that the browser should update. */
13
+ updates: Array<{
14
+ /** Importing module whose dependency-accept handler accepts this update. */
15
+ acceptedPath?: string;
16
+ /** Public URL of the changed JavaScript module. */
17
+ path: string;
18
+ /** Identifies a JavaScript module update. */
19
+ type: 'js';
20
+ } | {
21
+ /** Public URL of the changed stylesheet. */
22
+ path: string;
23
+ /** Identifies a stylesheet update. */
24
+ type: 'css';
25
+ }>;
26
+ /** Update time used to bypass browser module and stylesheet caches. */
27
+ timestamp: number;
28
+ /** Indicates that the listed browser modules should update in place. */
29
+ type: 'browser:update';
30
+ } | {
31
+ /** Indicates that no HMR boundary accepted the change and the page must reload. */
32
+ type: 'browser:reload';
33
+ };
34
+ export declare function createHmrClientSource(options: {
35
+ eventPathname: string;
36
+ }): string;
37
+ //# sourceMappingURL=hmr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../src/lib/hmr.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAClB;IACE,8DAA8D;IAC9D,IAAI,EAAE,eAAe,CAAA;CACtB,GACD;IACE,iEAAiE;IACjE,OAAO,EAAE,KAAK,CACV;QACE,4EAA4E;QAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,mDAAmD;QACnD,IAAI,EAAE,MAAM,CAAA;QACZ,6CAA6C;QAC7C,IAAI,EAAE,IAAI,CAAA;KACX,GACD;QACE,4CAA4C;QAC5C,IAAI,EAAE,MAAM,CAAA;QACZ,sCAAsC;QACtC,IAAI,EAAE,KAAK,CAAA;KACZ,CACJ,CAAA;IACD,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB,wEAAwE;IACxE,IAAI,EAAE,gBAAgB,CAAA;CACvB,GACD;IACE,mFAAmF;IACnF,IAAI,EAAE,gBAAgB,CAAA;CACvB,CAAA;AAEL,wBAAgB,qBAAqB,CAAC,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAoWhF"}