@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,20 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as fsp from 'node:fs/promises';
3
3
  import * as path from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
4
5
  import { getTsconfig } from 'get-tsconfig';
5
6
  import MagicString from 'magic-string';
6
7
  import { minify } from 'oxc-minify';
7
8
  import { parseSync, visitorKeys } from 'oxc-parser';
8
9
  import { transform as oxcTransform } from 'oxc-transform';
9
10
  import { init as esModuleLexerInit, parse as esModuleLexer } from 'es-module-lexer';
10
- import { isCommonJS, mayContainCommonJSModuleGlobals } from "./cjs-check.js";
11
- import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
12
- import { generateFingerprint } from "../fingerprint.js";
13
- import { maskAuthoredInjectedPackageSpecifier, mayContainInjectedPackageSpecifier, restoreAuthoredInjectedPackageSpecifier, } from "../injected-packages.js";
14
- import { normalizeFilePath } from "../paths.js";
15
- import { composeSourceMaps, rewriteSourceMapSources, stringifySourceMap } from "../source-maps.js";
11
+ import { isCommonJS, mayContainCommonJSModuleGlobals } from './cjs-check.js';
12
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
13
+ import { generateFingerprint } from '../fingerprint.js';
14
+ import { maskAuthoredInjectedPackageSpecifier, mayContainInjectedPackageSpecifier, restoreAuthoredInjectedPackageSpecifier, } from '../injected-packages.js';
15
+ import { normalizeFilePath } from '../paths.js';
16
+ import { composeSourceMaps, rewriteSourceMapSources, stringifySourceMap } from '../source-maps.js';
17
+ import { scriptLoaderConditions } from './conditions.js';
16
18
  const scriptModuleTypes = [
17
19
  { extension: '.js', lang: 'js' },
18
20
  { extension: '.jsx', lang: 'jsx' },
@@ -105,9 +107,17 @@ export async function transformModule(record, args) {
105
107
  };
106
108
  }
107
109
  try {
110
+ let stableUrlPathname = args.routes.toUrlPathname(record.identityPath);
111
+ if (!stableUrlPathname) {
112
+ throw createAssetServerCompilationError(`File ${record.identityPath} is outside all configured fileMap entries.`, {
113
+ code: 'FILE_OUTSIDE_FILE_MAP',
114
+ });
115
+ }
108
116
  let analysis = await analyzeModuleSource(sourceText, resolvedPath, transformOptions, {
109
117
  define: args.define ?? undefined,
110
118
  minify: args.minify,
119
+ loaders: args.loaders,
120
+ moduleUrl: stableUrlPathname,
111
121
  sourceMaps: args.sourceMaps ?? undefined,
112
122
  target: args.target ?? undefined,
113
123
  });
@@ -119,12 +129,6 @@ export async function transformModule(record, args) {
119
129
  code: 'COMMONJS_NOT_SUPPORTED',
120
130
  });
121
131
  }
122
- let stableUrlPathname = args.routes.toUrlPathname(record.identityPath);
123
- if (!stableUrlPathname) {
124
- throw createAssetServerCompilationError(`File ${record.identityPath} is outside all configured fileMap entries.`, {
125
- code: 'FILE_OUTSIDE_FILE_MAP',
126
- });
127
- }
128
132
  let sourceMap = analysis.sourceMap
129
133
  ? rewriteSourceMapSources(analysis.sourceMap, resolvedPath, stableUrlPathname, args.sourceMapSourcePaths, sourceText)
130
134
  : null;
@@ -140,6 +144,7 @@ export async function transformModule(record, args) {
140
144
  buildId: args.buildId,
141
145
  content: sourceText,
142
146
  }),
147
+ hmr: getHmrAnalysis(analysis.rawCode),
143
148
  identityPath: record.identityPath,
144
149
  importerDir: path.dirname(resolvedPath),
145
150
  packageSpecifiers: analysis.unresolvedImports
@@ -164,6 +169,105 @@ export async function transformModule(record, args) {
164
169
  };
165
170
  }
166
171
  }
172
+ export function getHmrAnalysis(rawCode) {
173
+ let mayUseImportMetaHot = rawCode.includes('import.meta.hot');
174
+ let usesImportMetaHot = false;
175
+ let acceptedDeps = [];
176
+ let selfAccepting = false;
177
+ if (mayUseImportMetaHot) {
178
+ try {
179
+ let parseResult = parseSync('hmr-analysis.js', rawCode, {
180
+ lang: 'js',
181
+ sourceType: 'module',
182
+ });
183
+ if (parseResult.errors.length > 0) {
184
+ throw createAssetServerCompilationError(`Failed to analyze HMR usage in transformed script. ${parseResult.errors[0]?.message ?? 'Unknown parse error'}`, {
185
+ code: 'TRANSFORM_FAILED',
186
+ });
187
+ }
188
+ walkAst(parseResult.program, (node) => {
189
+ if (isImportMetaHotNode(node)) {
190
+ usesImportMetaHot = true;
191
+ }
192
+ if (node.type !== 'CallExpression')
193
+ return;
194
+ if (!isImportMetaHotAcceptCallee(node.callee))
195
+ return;
196
+ let [firstArgument] = node.arguments;
197
+ if (firstArgument === undefined || !isAcceptedDependencyArgument(firstArgument)) {
198
+ selfAccepting = true;
199
+ return;
200
+ }
201
+ acceptedDeps.push(...getAcceptedDependencies(firstArgument, rawCode));
202
+ });
203
+ }
204
+ catch (error) {
205
+ if (isAssetServerCompilationError(error))
206
+ throw error;
207
+ throw createAssetServerCompilationError(`Failed to analyze HMR usage in transformed script.`, {
208
+ cause: error,
209
+ code: 'TRANSFORM_FAILED',
210
+ });
211
+ }
212
+ }
213
+ return {
214
+ acceptedDeps,
215
+ selfAccepting,
216
+ usesImportMetaHot,
217
+ };
218
+ }
219
+ function isImportMetaHotAcceptCallee(node) {
220
+ let callee = unwrapChainExpression(node);
221
+ if (callee.type !== 'MemberExpression')
222
+ return false;
223
+ if (callee.computed || !isIdentifierNode(callee.property, 'accept'))
224
+ return false;
225
+ return isImportMetaHotNode(callee.object);
226
+ }
227
+ function isImportMetaHotNode(node) {
228
+ let hot = unwrapChainExpression(node);
229
+ if (hot.type !== 'MemberExpression')
230
+ return false;
231
+ if (hot.computed || !isIdentifierNode(hot.property, 'hot'))
232
+ return false;
233
+ let meta = unwrapChainExpression(hot.object);
234
+ return (meta.type === 'MetaProperty' &&
235
+ isIdentifierNode(meta.meta, 'import') &&
236
+ isIdentifierNode(meta.property, 'meta'));
237
+ }
238
+ function unwrapChainExpression(node) {
239
+ return node.type === 'ChainExpression' ? node.expression : node;
240
+ }
241
+ function isIdentifierNode(node, name) {
242
+ return node.type === 'Identifier' && node.name === name;
243
+ }
244
+ function isAcceptedDependencyArgument(node) {
245
+ return isStringLiteralNode(node) || node.type === 'ArrayExpression';
246
+ }
247
+ function getAcceptedDependencies(node, source) {
248
+ if (isStringLiteralNode(node)) {
249
+ return [
250
+ {
251
+ end: node.end - 1,
252
+ specifier: node.value,
253
+ start: node.start + 1,
254
+ },
255
+ ];
256
+ }
257
+ if (node.type !== 'ArrayExpression')
258
+ return [];
259
+ let deps = [];
260
+ for (let element of node.elements) {
261
+ if (!isStringLiteralNode(element))
262
+ continue;
263
+ deps.push({
264
+ end: element.end - 1,
265
+ specifier: element.value,
266
+ start: element.start + 1,
267
+ });
268
+ }
269
+ return deps;
270
+ }
167
271
  function findNearestTsconfigPath(directory) {
168
272
  let currentDirectory = directory;
169
273
  while (true) {
@@ -203,6 +307,38 @@ async function analyzeModuleSource(sourceText, resolvedPath, transformOptions, o
203
307
  }
204
308
  let rawCode = transformResult.code.trimEnd();
205
309
  let sourceMap = stringifySourceMap(transformResult.map);
310
+ if (options.loaders.length > 0) {
311
+ let loaderUrl = pathToFileURL(resolvedPath).href;
312
+ let loaderInputSource = sourceMap ? appendInlineSourceMap(rawCode, sourceMap) : rawCode;
313
+ let loaderOutputSource;
314
+ try {
315
+ let loaderResult = runModuleLoaders(loaderUrl, {
316
+ format: 'module',
317
+ loaders: options.loaders,
318
+ moduleUrl: options.moduleUrl,
319
+ source: loaderInputSource,
320
+ });
321
+ loaderOutputSource = moduleLoadSourceToString(getModuleLoadSource(loaderUrl, loaderResult));
322
+ }
323
+ catch (error) {
324
+ if (isAssetServerCompilationError(error))
325
+ throw error;
326
+ throw createAssetServerCompilationError(`Module loader failed for ${loaderUrl}. ${formatUnknownError(error)}`, {
327
+ cause: error,
328
+ code: 'LOADER_FAILED',
329
+ });
330
+ }
331
+ if (loaderOutputSource !== loaderInputSource) {
332
+ let loaderOutput = extractInlineSourceMap(loaderOutputSource);
333
+ rawCode = loaderOutput.code.trimEnd();
334
+ sourceMap =
335
+ loaderOutput.sourceMap && loaderOutput.sourceMap !== sourceMap
336
+ ? sourceMap
337
+ ? composeSourceMaps(loaderOutput.sourceMap, sourceMap)
338
+ : loaderOutput.sourceMap
339
+ : null;
340
+ }
341
+ }
206
342
  if (options.minify) {
207
343
  let minifyResult = await minifyModule(rawCode, resolvedPath, options.target, options.sourceMaps);
208
344
  rawCode = minifyResult.code.trimEnd();
@@ -220,6 +356,76 @@ async function analyzeModuleSource(sourceText, resolvedPath, transformOptions, o
220
356
  unresolvedImports: await getUnresolvedImportsFromLexer(rawCode),
221
357
  };
222
358
  }
359
+ function runModuleLoaders(url, options) {
360
+ let loadContext = {
361
+ conditions: [...scriptLoaderConditions],
362
+ format: options.format,
363
+ importAttributes: {},
364
+ moduleUrl: options.moduleUrl,
365
+ };
366
+ let load = (_url, context) => ({
367
+ format: context?.format ?? options.format,
368
+ source: options.source,
369
+ });
370
+ for (let loader of options.loaders) {
371
+ let nextLoad = load;
372
+ load = (nextUrl, nextContext) => {
373
+ let nextLoadCalled = false;
374
+ let wrappedNextLoad = (wrappedUrl, wrappedContext) => {
375
+ if (wrappedUrl !== nextUrl) {
376
+ throw createAssetServerCompilationError(`Module loader for ${nextUrl} attempted to change the module URL to ${wrappedUrl}. Loaders cannot change module URLs.`, {
377
+ code: 'LOADER_FAILED',
378
+ });
379
+ }
380
+ nextLoadCalled = true;
381
+ return nextLoad(wrappedUrl, wrappedContext);
382
+ };
383
+ let result = loader(nextUrl, {
384
+ conditions: nextContext?.conditions ?? loadContext.conditions,
385
+ format: nextContext?.format ?? loadContext.format,
386
+ importAttributes: nextContext?.importAttributes ?? loadContext.importAttributes,
387
+ moduleUrl: nextContext?.moduleUrl ?? loadContext.moduleUrl,
388
+ }, wrappedNextLoad);
389
+ if (!nextLoadCalled && result.shortCircuit !== true) {
390
+ throw createAssetServerCompilationError(`Module loader for ${nextUrl} returned without calling nextLoad or setting shortCircuit: true.`, {
391
+ code: 'LOADER_FAILED',
392
+ });
393
+ }
394
+ return result;
395
+ };
396
+ }
397
+ return load(url, loadContext);
398
+ }
399
+ function getModuleLoadSource(url, result) {
400
+ if (result.format !== 'module') {
401
+ throw createAssetServerCompilationError(`Module loader for ${url} returned unsupported format ${JSON.stringify(result.format)}. Only "module" is supported.`, {
402
+ code: 'LOADER_FAILED',
403
+ });
404
+ }
405
+ if (result.source !== undefined && result.source !== null)
406
+ return result.source;
407
+ throw createAssetServerCompilationError(`Module loader for ${url} did not return source.`, {
408
+ code: 'LOADER_FAILED',
409
+ });
410
+ }
411
+ function moduleLoadSourceToString(source) {
412
+ if (typeof source === 'string')
413
+ return source;
414
+ return new TextDecoder().decode(source);
415
+ }
416
+ function appendInlineSourceMap(source, sourceMap) {
417
+ let encoded = Buffer.from(sourceMap).toString('base64');
418
+ return `${source}\n//# sourceMappingURL=data:application/json;base64,${encoded}`;
419
+ }
420
+ function extractInlineSourceMap(source) {
421
+ let sourceMapPattern = /(?:\/\/# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)|\/\*# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+) \*\/)\s*$/g;
422
+ let sourceMap = null;
423
+ let code = source.replace(sourceMapPattern, (_match, lineComment, blockComment) => {
424
+ sourceMap = Buffer.from(lineComment ?? blockComment, 'base64').toString('utf-8');
425
+ return '';
426
+ });
427
+ return { code, sourceMap };
428
+ }
223
429
  async function minifyModule(rawCode, resolvedPath, target, sourceMaps) {
224
430
  try {
225
431
  let result = await minify(resolvedPath, rawCode, {
@@ -324,7 +530,7 @@ async function getUnresolvedImportsFromLexer(rawCode) {
324
530
  let unresolvedImports = [];
325
531
  for (let imported of imports) {
326
532
  let specifier = getStaticImportSpecifier(rawCode, imported);
327
- if (specifier == null || shouldSkipImportSpecifier(specifier))
533
+ if (specifier == null || isBrowserExternalModuleUrl(specifier))
328
534
  continue;
329
535
  unresolvedImports.push({
330
536
  specifier,
@@ -338,6 +544,9 @@ async function getUnresolvedImportsFromLexer(rawCode) {
338
544
  function getDisplayImportSpecifier(specifier) {
339
545
  return restoreAuthoredInjectedPackageSpecifier(specifier) ?? specifier;
340
546
  }
547
+ function isBrowserExternalModuleUrl(url) {
548
+ return url.startsWith('data:') || url.startsWith('http://') || url.startsWith('https://');
549
+ }
341
550
  function maskAuthoredInjectedPackageImports(sourceText, resolvedPath) {
342
551
  if (!mayContainInjectedPackageSpecifier(sourceText)) {
343
552
  return sourceText;
@@ -423,11 +632,6 @@ function getStaticImportSpecifier(source, imported) {
423
632
  function isStaticTemplateLiteral(specifier) {
424
633
  return specifier.startsWith('`') && specifier.endsWith('`') && !specifier.includes('${');
425
634
  }
426
- function shouldSkipImportSpecifier(specifier) {
427
- return (specifier.startsWith('data:') ||
428
- specifier.startsWith('http://') ||
429
- specifier.startsWith('https://'));
430
- }
431
635
  function getImportQuote(source, start) {
432
636
  let firstCharacter = source[start];
433
637
  if (firstCharacter === '"' || firstCharacter === "'" || firstCharacter === '`') {
@@ -1,5 +1,5 @@
1
1
  import { SourceMapConsumer, SourceMapGenerator } from 'source-map-js';
2
- import { normalizeFilePath } from "./paths.js";
2
+ import { normalizeFilePath } from './paths.js';
3
3
  export function composeSourceMaps(rewriteSourceMap, transformSourceMap) {
4
4
  let rewriteConsumer = new SourceMapConsumer(JSON.parse(rewriteSourceMap));
5
5
  let transformConsumer = new SourceMapConsumer(JSON.parse(transformSourceMap));
@@ -24,6 +24,9 @@ type StyleCompilerOptions = {
24
24
  getServedFileUrl?(identityPath: string, options: {
25
25
  transform: readonly string[] | null;
26
26
  }): Promise<string>;
27
+ hmr?: {
28
+ send(pathname: string, timestamp: number): void;
29
+ };
27
30
  isAllowed(absolutePath: string): boolean;
28
31
  isServedFilePath(filePath: string): boolean;
29
32
  minify: boolean;
@@ -31,6 +34,10 @@ type StyleCompilerOptions = {
31
34
  add: string[];
32
35
  remove: string[];
33
36
  }) => void;
37
+ onWatchFilesChange?: (delta: {
38
+ add: string[];
39
+ remove: string[];
40
+ }) => void;
34
41
  rootDir: string;
35
42
  routes: CompiledRoutes;
36
43
  sourceMapSourcePaths: 'absolute' | 'url';
@@ -42,7 +49,13 @@ type StyleCompiler = {
42
49
  getHref(filePath: string): Promise<string>;
43
50
  getPreloadLayers(filePath: string | readonly string[]): Promise<string[][]>;
44
51
  getStyle(filePath: string, options: StyleGetOptions): Promise<StyleGetResult>;
45
- handleFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): Promise<void>;
52
+ classifyHmrFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): Promise<StyleHmrUpdate[]>;
53
+ invalidateFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): void;
54
+ };
55
+ export type StyleHmrUpdate = {
56
+ filePath: string;
57
+ path: string;
58
+ timestamp: number;
46
59
  };
47
60
  export declare function createStyleCompiler(options: StyleCompilerOptions): StyleCompiler;
48
61
  export declare function isStyleFilePath(filePath: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,WAAW,CAAA;AAS3D,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,cAAc,GACf;IACE,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,CAAA;AAEL,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,oBAAoB,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,CACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;QACP,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;KACpC,GACA,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB,EAAE,UAAU,GAAG,KAAK,CAAA;IACxC,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;IAClC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrF,CAAA;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAmOhF;AAkED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACf,GACA,QAAQ,CA6BV"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"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"}
@@ -2,13 +2,13 @@ import * as os from 'node:os';
2
2
  import * as path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { IfNoneMatch } from '@remix-run/headers/if-none-match';
5
- import { createFileMatcher } from "../file-matcher.js";
6
- import { formatFingerprintedPathname } from "../fingerprint.js";
7
- import { createModuleStore } from "../module-store.js";
8
- import { normalizeFilePath, resolveFilePath } from "../paths.js";
9
- import { emitResolvedStyle } from "./emit.js";
10
- import { resolveServedStyleOrThrow, resolveStyle } from "./resolve.js";
11
- import { transformStyle } from "./transform.js";
5
+ import { createFileMatcher } from '../file-matcher.js';
6
+ import { formatFingerprintedPathname } from '../fingerprint.js';
7
+ import { createModuleStore } from '../module-store.js';
8
+ import { normalizeFilePath, resolveFilePath } from '../paths.js';
9
+ import { emitResolvedStyle } from './emit.js';
10
+ import { resolveServedStyleOrThrow, resolveStyle } from './resolve.js';
11
+ import { transformStyle } from './transform.js';
12
12
  const preloadConcurrency = Math.max(1, Math.min(8, os.availableParallelism() - 1));
13
13
  const styleExtension = '.css';
14
14
  export function createStyleCompiler(options) {
@@ -17,7 +17,11 @@ export function createStyleCompiler(options) {
17
17
  watchIgnoreMatchers: (options.watchIgnore ?? []).map((pattern) => createFileMatcher(pattern, options.rootDir)),
18
18
  };
19
19
  let styleStore = createModuleStore({
20
+ getDependencies(resolvedStyle) {
21
+ return resolvedStyle.deps;
22
+ },
20
23
  onWatchDirectoriesChange: options.onWatchDirectoriesChange,
24
+ onWatchFilesChange: options.onWatchFilesChange,
21
25
  });
22
26
  let resolveInFlightByCacheKey = new Map();
23
27
  let emitInFlightByCacheKey = new Map();
@@ -74,7 +78,7 @@ export function createStyleCompiler(options) {
74
78
  async getStyle(filePath, getOptions) {
75
79
  let resolvedStyle = resolveServedStyleOrThrow(resolveInputFilePath(filePath), resolveArgs);
76
80
  let record = styleStore.get(resolvedStyle.identityPath);
77
- let notModified = getNotModifiedStyle(record.emitted, getOptions);
81
+ let notModified = getNotModifiedStyle(record, styleStore, getOptions, hasHmrTimestampedDependency);
78
82
  if (notModified)
79
83
  return notModified;
80
84
  let emitted = await getOrCreateEmittedStyle(record);
@@ -83,7 +87,23 @@ export function createStyleCompiler(options) {
83
87
  type: 'style',
84
88
  };
85
89
  },
86
- async handleFileEvent(filePath, event) {
90
+ async classifyHmrFileEvent(filePath, event) {
91
+ let normalizedFilePath = normalizeFilePath(filePath);
92
+ if (isWatchIgnored(normalizedFilePath))
93
+ return [];
94
+ let timestamp = Date.now();
95
+ let updatePathnames = event === 'change' ? getHmrUpdatePathnames(normalizedFilePath, timestamp) : [];
96
+ styleStore.invalidateForFileEvent(normalizedFilePath, event);
97
+ for (let updatePathname of updatePathnames) {
98
+ resolvedOptions.hmr?.send(updatePathname, timestamp);
99
+ }
100
+ return updatePathnames.map((path) => ({
101
+ filePath: normalizedFilePath,
102
+ path,
103
+ timestamp,
104
+ }));
105
+ },
106
+ invalidateFileEvent(filePath, event) {
87
107
  let normalizedFilePath = normalizeFilePath(filePath);
88
108
  if (isWatchIgnored(normalizedFilePath))
89
109
  return;
@@ -103,7 +123,7 @@ export function createStyleCompiler(options) {
103
123
  return mapWithConcurrency(records, preloadConcurrency, (record) => getOrCreateResolvedStyle(record));
104
124
  }
105
125
  async function getOrCreateResolvedStyle(record) {
106
- if (record.resolved)
126
+ if (record.resolved && styleStore.isResolvedFresh(record))
107
127
  return record.resolved;
108
128
  let cacheKey = getRecordCacheKey(record);
109
129
  let existing = resolveInFlightByCacheKey.get(cacheKey);
@@ -137,7 +157,7 @@ export function createStyleCompiler(options) {
137
157
  }
138
158
  }
139
159
  async function getOrCreateTransformedStyle(record) {
140
- if (record.transformed)
160
+ if (record.transformed && styleStore.isTransformedFresh(record))
141
161
  return record.transformed;
142
162
  let startedVersion = record.invalidationVersion;
143
163
  let transformStyleResult = await transformStyle(record, transformArgs);
@@ -155,8 +175,11 @@ export function createStyleCompiler(options) {
155
175
  return transformStyleResult.value;
156
176
  }
157
177
  async function getOrCreateEmittedStyle(record) {
158
- if (record.emitted)
178
+ if (record.emitted &&
179
+ styleStore.isEmittedFresh(record) &&
180
+ !hasHmrTimestampedDependency(record.resolved)) {
159
181
  return record.emitted;
182
+ }
160
183
  let cacheKey = getRecordCacheKey(record);
161
184
  let existing = emitInFlightByCacheKey.get(cacheKey);
162
185
  if (existing)
@@ -191,7 +214,37 @@ export function createStyleCompiler(options) {
191
214
  return getServedUrlForResolvedStyle(await getOrCreateResolvedStyle(styleStore.get(identityPath)));
192
215
  }
193
216
  function getServedUrlForResolvedStyle(resolvedStyle) {
194
- return formatFingerprintedPathname(resolvedStyle.stableUrlPathname, resolvedOptions.fingerprintAssets ? resolvedStyle.fingerprint : null);
217
+ let pathname = formatFingerprintedPathname(resolvedStyle.stableUrlPathname, resolvedOptions.fingerprintAssets ? resolvedStyle.fingerprint : null);
218
+ let timestamp = styleStore.getHmrUpdateTimestamp(resolvedStyle.identityPath);
219
+ return timestamp ? appendTimestamp(pathname, timestamp) : pathname;
220
+ }
221
+ function getHmrUpdatePathnames(identityPath, timestamp) {
222
+ let resolvedStyles = findHmrUpdateStyles(identityPath, new Set());
223
+ // Mark update timestamps before invalidating so re-emitted importer stylesheets
224
+ // can rewrite imports to the changed dependency with this HMR timestamp.
225
+ for (let resolvedStyle of resolvedStyles) {
226
+ styleStore.setHmrUpdateTimestamp(resolvedStyle.identityPath, timestamp);
227
+ }
228
+ return dedupeHmrUpdatePathnames(resolvedStyles
229
+ .filter((resolvedStyle) => styleStore.getImporters(resolvedStyle.identityPath).size === 0)
230
+ .map((resolvedStyle) => resolvedStyle.stableUrlPathname));
231
+ }
232
+ function findHmrUpdateStyles(identityPath, traversed) {
233
+ if (traversed.has(identityPath))
234
+ return [];
235
+ traversed.add(identityPath);
236
+ let resolvedStyle = styleStore.getLastResolved(identityPath);
237
+ if (!resolvedStyle)
238
+ return [];
239
+ let resolvedStyles = [resolvedStyle];
240
+ for (let importerPath of styleStore.getImporters(identityPath)) {
241
+ resolvedStyles.push(...findHmrUpdateStyles(importerPath, traversed));
242
+ }
243
+ return resolvedStyles;
244
+ }
245
+ function hasHmrTimestampedDependency(resolvedStyle) {
246
+ return (resolvedStyle?.deps.some((depPath) => styleStore.getHmrUpdateTimestamp(depPath) != null) ===
247
+ true);
195
248
  }
196
249
  function isWatchIgnored(filePath) {
197
250
  return resolvedOptions.watchIgnoreMatchers.some((matcher) => matcher(filePath));
@@ -203,7 +256,12 @@ function getRecordCacheKey(record) {
203
256
  function isFresh(record, version) {
204
257
  return record.invalidationVersion === version;
205
258
  }
206
- function getNotModifiedStyle(emittedStyle, options) {
259
+ function getNotModifiedStyle(record, styleStore, options, hasHmrTimestampedDependency) {
260
+ if (hasHmrTimestampedDependency(record.resolved))
261
+ return null;
262
+ if (!styleStore.isEmittedFresh(record))
263
+ return null;
264
+ let emittedStyle = record.emitted;
207
265
  if (!emittedStyle || options.ifNoneMatch === null)
208
266
  return null;
209
267
  if (options.requestedFingerprint !== null &&
@@ -217,6 +275,12 @@ function getNotModifiedStyle(emittedStyle, options) {
217
275
  return null;
218
276
  return { etag: asset.etag, type: 'not-modified' };
219
277
  }
278
+ function appendTimestamp(pathname, timestamp) {
279
+ return `${pathname}${pathname.includes('?') ? '&' : '?'}t=${timestamp}`;
280
+ }
281
+ function dedupeHmrUpdatePathnames(pathnames) {
282
+ return [...new Set(pathnames)];
283
+ }
220
284
  function getEmittedAssetForRequest(emittedStyle, isSourceMapRequest) {
221
285
  return isSourceMapRequest ? emittedStyle.sourceMap : emittedStyle.code;
222
286
  }
@@ -1,7 +1,7 @@
1
1
  import MagicString from 'magic-string';
2
- import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
3
- import { hashContent } from "../fingerprint.js";
4
- import { composeSourceMaps } from "../source-maps.js";
2
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
3
+ import { hashContent } from '../fingerprint.js';
4
+ import { composeSourceMaps } from '../source-maps.js';
5
5
  export async function emitResolvedStyle(resolvedStyle, options) {
6
6
  try {
7
7
  let importUrls = await Promise.all(resolvedStyle.deps.map((depPath) => options.getServedUrl(depPath)));
@@ -47,7 +47,7 @@ async function rewriteDependencies(resolvedStyle, options) {
47
47
  let replacement = dependency.kind === 'external'
48
48
  ? dependency.replacement
49
49
  : dependency.kind === 'style'
50
- ? `${await options.getServedUrl(dependency.depPath)}${dependency.suffix}`
50
+ ? appendUrlSuffix(await options.getServedUrl(dependency.depPath), dependency.suffix)
51
51
  : appendUrlSuffix(await getServedFileUrl(options, resolvedStyle.identityPath, dependency.depPath, {
52
52
  transform: dependency.requestTransform,
53
53
  }), dependency.suffix);
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/resolve.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,KAAK,WAAW,GAAG,YAAY,CAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;AAE9E,KAAK,kBAAkB,GACnB;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;IAC1C,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAEL,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;CACzB,GAAG,CACA;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,aAAa,CAAA;CACrB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CACJ,CAAA;AAQD,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CA+DxB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,GAChB;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CA+BA"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/resolve.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,KAAK,WAAW,GAAG,YAAY,CAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;AAE9E,KAAK,kBAAkB,GACnB;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;IAC1C,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAEL,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;CACzB,GAAG,CACA;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,aAAa,CAAA;CACrB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CACJ,CAAA;AAQD,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CA+DxB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,GAChB;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAmCA"}
@@ -1,8 +1,8 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import { fileURLToPath, pathToFileURL } from 'node:url';
4
- import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
5
- import { normalizeFilePath } from "../paths.js";
4
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
5
+ import { normalizeFilePath } from '../paths.js';
6
6
  export async function resolveStyle(record, transformed, args) {
7
7
  let trackedFiles = new Set(transformed.trackedFiles);
8
8
  let dependencies = [];
@@ -63,7 +63,8 @@ export function resolveServedStyleOrThrow(filePath, args) {
63
63
  });
64
64
  }
65
65
  if (!args.isAllowed(identityPath)) {
66
- throw createAssetServerCompilationError(`File is not allowed: ${identityPath}`, {
66
+ throw createAssetServerCompilationError(`File "${identityPath}" is not allowed by the asset server access configuration. ` +
67
+ `Add a matching allowFiles or allowPackages rule, or remove a conflicting denyFiles rule.`, {
67
68
  code: 'FILE_NOT_ALLOWED',
68
69
  });
69
70
  }
@@ -100,8 +101,8 @@ function resolveImportDependency(url, importerPath, placeholder, args) {
100
101
  });
101
102
  }
102
103
  if (!args.isAllowed(identityPath)) {
103
- throw createAssetServerCompilationError(`Import "${url}" in ${importerPath}, resolved to "${identityPath}", is not allowed by the asset server allow/deny configuration. ` +
104
- `Add a matching allow rule for this file path, remove a conflicting deny rule for this file path, or mark this import as external.`, {
104
+ throw createAssetServerCompilationError(`Import "${url}" in ${importerPath}, resolved to "${identityPath}", is not allowed by the asset server access configuration. ` +
105
+ `Add a matching allowFiles or allowPackages rule, remove a conflicting denyFiles rule, or mark this import as external.`, {
105
106
  code: 'IMPORT_NOT_ALLOWED',
106
107
  });
107
108
  }
@@ -149,8 +150,8 @@ function resolveUrlDependency(url, importerPath, placeholder, args) {
149
150
  });
150
151
  }
151
152
  if (!args.isAllowed(identityPath)) {
152
- throw createAssetServerCompilationError(`URL "${url}" in ${importerPath}, resolved to "${identityPath}", is not allowed by the asset server allow/deny configuration. ` +
153
- `Add a matching allow rule for this file path or remove a conflicting deny rule for this file path.`, {
153
+ throw createAssetServerCompilationError(`URL "${url}" in ${importerPath}, resolved to "${identityPath}", is not allowed by the asset server access configuration. ` +
154
+ `Add a matching allowFiles or allowPackages rule, or remove a conflicting denyFiles rule.`, {
154
155
  code: 'URL_NOT_ALLOWED',
155
156
  });
156
157
  }
@@ -1,8 +1,8 @@
1
1
  import * as fs from 'node:fs/promises';
2
2
  import { transform } from 'lightningcss';
3
- import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
4
- import { generateFingerprint } from "../fingerprint.js";
5
- import { rewriteSourceMapSources, stringifySourceMap } from "../source-maps.js";
3
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from '../compilation-error.js';
4
+ import { generateFingerprint } from '../fingerprint.js';
5
+ import { rewriteSourceMapSources, stringifySourceMap } from '../source-maps.js';
6
6
  export async function transformStyle(record, args) {
7
7
  let resolvedPath = record.identityPath;
8
8
  let trackedFiles = args.isWatchIgnored(resolvedPath) ? [] : [resolvedPath];
@@ -1,5 +1,5 @@
1
1
  import type { Targets as LightningCssTargets } from 'lightningcss';
2
- declare const browserTargetNames: readonly ["chrome", "edge", "firefox", "ie", "ios", "opera", "safari", "samsung"];
2
+ declare const browserTargetNames: readonly ['chrome', 'edge', 'firefox', 'ie', 'ios', 'opera', 'safari', 'samsung'];
3
3
  export type AssetTargetVersion = `${number}` | `${number}.${number}` | `${number}.${number}.${number}`;
4
4
  export type BrowserTargetName = (typeof browserTargetNames)[number];
5
5
  export type ResolvedScriptTarget = string[];
@@ -1 +1 @@
1
- {"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/lib/target.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElE,QAAA,MAAM,kBAAkB,mFASd,CAAA;AAeV,MAAM,MAAM,kBAAkB,GAC1B,GAAG,MAAM,EAAE,GACX,GAAG,MAAM,IAAI,MAAM,EAAE,GACrB,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,CAAA;AACnC,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAA;AACnE,MAAM,MAAM,oBAAoB,GAAG,MAAM,EAAE,CAAA;AAC3C,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAA;AAErD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,EAAE,CAAC,EAAE,kBAAkB,CAAA;IACvB,GAAG,CAAC,EAAE,kBAAkB,CAAA;IACxB,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAMD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,oBAAoB,GAAG,SAAS,CAgBlC;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,mBAAmB,GAAG,SAAS,CAajC"}
1
+ {"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../src/lib/target.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAElE,QAAA,MAAM,kBAAkB,YACtB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,IAAI,EACJ,KAAK,EACL,OAAO,EACP,QAAQ,EACR,SAAS,CACD,CAAA;AAeV,MAAM,MAAM,kBAAkB,GAC1B,GAAG,MAAM,EAAE,GACX,GAAG,MAAM,IAAI,MAAM,EAAE,GACrB,GAAG,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,CAAA;AACnC,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAA;AACnE,MAAM,MAAM,oBAAoB,GAAG,MAAM,EAAE,CAAA;AAC3C,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,CAAA;AAErD,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,EAAE,CAAC,EAAE,kBAAkB,CAAA;IACvB,GAAG,CAAC,EAAE,kBAAkB,CAAA;IACxB,KAAK,CAAC,EAAE,kBAAkB,CAAA;IAC1B,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAMD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,oBAAoB,GAAG,SAAS,CAgBlC;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,mBAAmB,GAAG,SAAS,CAajC"}
package/dist/lib/watch.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import chokidar from 'chokidar';
2
- import { getFilePathDirectory, normalizeFilePath } from "./paths.js";
2
+ import { getFilePathDirectory, normalizeFilePath } from './paths.js';
3
3
  export function createAssetServerWatcher(options) {
4
4
  let watcher = chokidar.watch([], {
5
5
  ignoreInitial: true,