@remix-run/assets 0.1.0 → 0.2.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 (57) hide show
  1. package/README.md +53 -47
  2. package/dist/lib/asset-server.d.ts +45 -43
  3. package/dist/lib/asset-server.d.ts.map +1 -1
  4. package/dist/lib/asset-server.js +142 -46
  5. package/dist/lib/compilation-error.d.ts +2 -2
  6. package/dist/lib/compilation-error.d.ts.map +1 -1
  7. package/dist/lib/compilation-error.js +1 -1
  8. package/dist/lib/file-matcher.d.ts.map +1 -1
  9. package/dist/lib/file-matcher.js +3 -2
  10. package/dist/lib/module-store.d.ts +41 -0
  11. package/dist/lib/module-store.d.ts.map +1 -0
  12. package/dist/lib/{scripts/store.js → module-store.js} +43 -41
  13. package/dist/lib/scripts/compiler.d.ts +15 -15
  14. package/dist/lib/scripts/compiler.d.ts.map +1 -1
  15. package/dist/lib/scripts/compiler.js +50 -46
  16. package/dist/lib/scripts/emit.js +2 -2
  17. package/dist/lib/scripts/resolve.d.ts +7 -17
  18. package/dist/lib/scripts/resolve.d.ts.map +1 -1
  19. package/dist/lib/scripts/resolve.js +15 -9
  20. package/dist/lib/scripts/transform.d.ts +11 -9
  21. package/dist/lib/scripts/transform.d.ts.map +1 -1
  22. package/dist/lib/scripts/transform.js +32 -21
  23. package/dist/lib/source-maps.d.ts +1 -1
  24. package/dist/lib/source-maps.d.ts.map +1 -1
  25. package/dist/lib/source-maps.js +7 -1
  26. package/dist/lib/styles/compiler.d.ts +52 -0
  27. package/dist/lib/styles/compiler.d.ts.map +1 -0
  28. package/dist/lib/styles/compiler.js +272 -0
  29. package/dist/lib/styles/emit.d.ts +25 -0
  30. package/dist/lib/styles/emit.d.ts.map +1 -0
  31. package/dist/lib/styles/emit.js +78 -0
  32. package/dist/lib/styles/resolve.d.ts +48 -0
  33. package/dist/lib/styles/resolve.d.ts.map +1 -0
  34. package/dist/lib/styles/resolve.js +188 -0
  35. package/dist/lib/styles/transform.d.ts +47 -0
  36. package/dist/lib/styles/transform.d.ts.map +1 -0
  37. package/dist/lib/styles/transform.js +131 -0
  38. package/dist/lib/target.d.ts +21 -0
  39. package/dist/lib/target.d.ts.map +1 -0
  40. package/dist/lib/target.js +127 -0
  41. package/package.json +7 -2
  42. package/src/lib/asset-server.ts +218 -96
  43. package/src/lib/compilation-error.ts +7 -7
  44. package/src/lib/file-matcher.ts +3 -2
  45. package/src/lib/{scripts/store.ts → module-store.ts} +100 -87
  46. package/src/lib/scripts/compiler.ts +88 -70
  47. package/src/lib/scripts/emit.ts +2 -2
  48. package/src/lib/scripts/resolve.ts +34 -23
  49. package/src/lib/scripts/transform.ts +49 -34
  50. package/src/lib/source-maps.ts +8 -1
  51. package/src/lib/styles/compiler.ts +400 -0
  52. package/src/lib/styles/emit.ts +137 -0
  53. package/src/lib/styles/resolve.ts +316 -0
  54. package/src/lib/styles/transform.ts +226 -0
  55. package/src/lib/target.ts +196 -0
  56. package/dist/lib/scripts/store.d.ts +0 -40
  57. package/dist/lib/scripts/store.d.ts.map +0 -1
@@ -21,41 +21,50 @@ import {
21
21
  } from './resolve.ts'
22
22
  import type { ResolveArgs, ResolvedModule } from './resolve.ts'
23
23
  import type { CompiledRoutes } from '../routes.ts'
24
- import type { ScriptsTarget } from '../asset-server.ts'
25
- import { createModuleStore } from './store.ts'
26
- import type { FileSnapshot, ModuleRecord, ModuleSnapshot } from './store.ts'
24
+ import type { ResolvedScriptTarget } from '../target.ts'
25
+ import { createModuleStore } from '../module-store.ts'
26
+ import type {
27
+ FileSnapshot,
28
+ ModuleRecord,
29
+ ModuleSnapshot,
30
+ ModuleStore,
31
+ ModuleWatchEvent,
32
+ } from '../module-store.ts'
27
33
  import { createTsconfigTransformOptionsResolver, transformModule } from './transform.ts'
28
34
  import type { ResolveModuleResult, TransformArgs, TransformedModule } from './transform.ts'
29
35
  import { ResolverFactory } from 'oxc-resolver'
30
36
  import type { EmittedAsset, EmittedModule } from './emit.ts'
31
37
 
32
- type ModuleCompileResult = {
38
+ type ScriptRecord = ModuleRecord<TransformedModule, ResolvedModule, EmittedModule>
39
+ type ScriptStore = ModuleStore<TransformedModule, ResolvedModule, EmittedModule>
40
+
41
+ type ScriptCompileResult = {
33
42
  code: EmittedAsset
34
43
  fingerprint: string | null
35
44
  sourceMap: EmittedAsset | null
36
45
  }
37
46
 
38
- type ModuleGetResult =
47
+ type ScriptGetResult =
39
48
  | {
40
- type: 'module'
41
- module: ModuleCompileResult
49
+ script: ScriptCompileResult
50
+ type: 'script'
42
51
  }
43
52
  | {
44
53
  type: 'not-modified'
45
54
  etag: string
46
55
  }
47
56
 
48
- type ModuleGetOptions = {
57
+ type ScriptGetOptions = {
49
58
  ifNoneMatch: string | null
50
59
  isSourceMapRequest: boolean
51
60
  requestedFingerprint: string | null
52
61
  }
53
62
 
54
- type ModuleCompilerOptions = {
63
+ type ScriptCompilerOptions = {
55
64
  buildId?: string
56
65
  define?: Record<string, string>
57
66
  external: string[]
58
- fingerprintModules: boolean
67
+ fingerprintAssets: boolean
59
68
  isAllowed(absolutePath: string): boolean
60
69
  minify: boolean
61
70
  onWatchDirectoriesChange?: (delta: { add: string[]; remove: string[] }) => void
@@ -63,16 +72,14 @@ type ModuleCompilerOptions = {
63
72
  routes: CompiledRoutes
64
73
  sourceMapSourcePaths: 'absolute' | 'url'
65
74
  sourceMaps?: 'external' | 'inline'
66
- target?: ScriptsTarget
75
+ target?: ResolvedScriptTarget
67
76
  watchIgnore?: readonly string[]
68
77
  watchMode: boolean
69
78
  }
70
79
 
71
- type ModuleWatchEvent = 'add' | 'change' | 'unlink'
72
-
73
- type ModuleCompiler = {
74
- getModule(filePath: string, options: ModuleGetOptions): Promise<ModuleGetResult>
75
- getPreloadUrls(filePath: string | readonly string[]): Promise<string[]>
80
+ type ScriptCompiler = {
81
+ getScript(filePath: string, options: ScriptGetOptions): Promise<ScriptGetResult>
82
+ getPreloadLayers(filePath: string | readonly string[]): Promise<string[][]>
76
83
  getHref(filePath: string): Promise<string>
77
84
  handleFileEvent(filePath: string, event: ModuleWatchEvent): Promise<void>
78
85
  parseRequestPathname(pathname: string): ParsedRequestPathname | null
@@ -88,7 +95,7 @@ type ParsedRequestPathname = {
88
95
  const supportedScriptExtensionSet = new Set<string>(supportedScriptExtensions)
89
96
  const preloadConcurrency = Math.max(1, Math.min(8, os.availableParallelism() - 1))
90
97
 
91
- export function createModuleCompiler(options: ModuleCompilerOptions): ModuleCompiler {
98
+ export function createScriptCompiler(options: ScriptCompilerOptions): ScriptCompiler {
92
99
  let resolvedOptions = {
93
100
  ...options,
94
101
  externalSet: new Set(options.external),
@@ -96,7 +103,11 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
96
103
  createFileMatcher(pattern, options.rootDir),
97
104
  ),
98
105
  }
99
- let store = createModuleStore({
106
+ let scriptStore: ScriptStore = createModuleStore<
107
+ TransformedModule,
108
+ ResolvedModule,
109
+ EmittedModule
110
+ >({
100
111
  onWatchDirectoriesChange: options.onWatchDirectoriesChange,
101
112
  })
102
113
  let tsconfigTransformOptionsResolver = createTsconfigTransformOptionsResolver()
@@ -133,25 +144,25 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
133
144
  }
134
145
 
135
146
  return {
136
- async getModule(filePath, getOptions) {
137
- let resolvedModule = resolveServedModuleOrThrow(resolveInputFilePath(filePath))
138
- let record = store.get(resolvedModule.identityPath)
139
- let notModified = getNotModifiedModule(record, getOptions)
147
+ async getScript(filePath, getOptions) {
148
+ let resolvedModule = resolveServedScriptOrThrow(resolveInputFilePath(filePath))
149
+ let record = scriptStore.get(resolvedModule.identityPath)
150
+ let notModified = getNotModifiedScript(record, getOptions)
140
151
  if (notModified) return notModified
141
152
 
142
- let emitted = await getOrCreateEmittedModule(record)
153
+ let emitted = await getOrCreateEmittedScript(record)
143
154
  return {
144
- type: 'module',
145
- module: toModuleCompileResult(emitted),
155
+ script: toScriptCompileResult(emitted),
156
+ type: 'script',
146
157
  }
147
158
  },
148
159
 
149
- async getPreloadUrls(filePath) {
160
+ async getPreloadLayers(filePath) {
150
161
  let resolvedEntries: string[] = []
151
162
  let seen = new Set<string>()
152
163
 
153
164
  for (let resolvedModule of (Array.isArray(filePath) ? filePath : [filePath]).map((nextPath) =>
154
- resolveServedModuleOrThrow(resolveInputFilePath(nextPath)),
165
+ resolveServedScriptOrThrow(resolveInputFilePath(nextPath)),
155
166
  )) {
156
167
  if (seen.has(resolvedModule.identityPath)) continue
157
168
  seen.add(resolvedModule.identityPath)
@@ -160,17 +171,18 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
160
171
 
161
172
  let visited = new Set(resolvedEntries)
162
173
  let queue = [...resolvedEntries]
163
- let urls: string[] = []
174
+ let layers: string[][] = []
164
175
 
165
176
  while (queue.length > 0) {
166
177
  let frontier = queue
167
178
  queue = []
168
- let resolvedModules = await getOrCreateResolvedModules(
169
- frontier.map((identityPath) => store.get(identityPath)),
179
+ let resolvedModules = await getOrCreateResolvedScripts(
180
+ frontier.map((identityPath) => scriptStore.get(identityPath)),
170
181
  )
182
+ let layer: string[] = []
171
183
 
172
184
  for (let resolvedModule of resolvedModules) {
173
- urls.push(getServedUrlForResolvedModule(resolvedModule))
185
+ layer.push(getServedUrlForResolvedScript(resolvedModule))
174
186
 
175
187
  for (let dep of resolvedModule.deps) {
176
188
  if (visited.has(dep)) continue
@@ -178,13 +190,15 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
178
190
  queue.push(dep)
179
191
  }
180
192
  }
193
+
194
+ layers.push(layer)
181
195
  }
182
196
 
183
- return urls
197
+ return layers
184
198
  },
185
199
 
186
200
  async getHref(filePath) {
187
- let resolvedModule = resolveServedModuleOrThrow(resolveInputFilePath(filePath))
201
+ let resolvedModule = resolveServedScriptOrThrow(resolveInputFilePath(filePath))
188
202
  return getServedUrl(resolvedModule.identityPath)
189
203
  },
190
204
 
@@ -198,23 +212,23 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
198
212
 
199
213
  if (isTsconfigPath(normalizedFilePath)) {
200
214
  tsconfigTransformOptionsResolver.clear()
201
- store.invalidateAll()
215
+ scriptStore.invalidateAll()
202
216
  return
203
217
  }
204
218
 
205
219
  if (isPackageJsonPath(normalizedFilePath)) {
206
- store.invalidateAll()
220
+ scriptStore.invalidateAll()
207
221
  return
208
222
  }
209
223
 
210
- store.invalidateForFileEvent(normalizedFilePath, event)
224
+ scriptStore.invalidateForFileEvent(normalizedFilePath, event)
211
225
  },
212
226
 
213
227
  parseRequestPathname(pathname) {
214
228
  let parsedPathname = parseServedPathname(pathname)
215
229
  let filePath = resolvedOptions.routes.resolveUrlPathname(parsedPathname.stablePathname)
216
230
  if (!filePath) return null
217
- if (resolvedOptions.fingerprintModules && parsedPathname.requestedFingerprint === null)
231
+ if (resolvedOptions.fingerprintAssets && parsedPathname.requestedFingerprint === null)
218
232
  return null
219
233
 
220
234
  return {
@@ -238,19 +252,19 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
238
252
  return resolveFilePath(resolvedOptions.rootDir, filePath)
239
253
  }
240
254
 
241
- function resolveServedModuleOrThrow(absolutePath: string): ResolveModuleResult {
255
+ function resolveServedScriptOrThrow(absolutePath: string): ResolveModuleResult {
242
256
  let resolvedModule = resolveModulePath(absolutePath)
243
257
  if (!resolvedModule) {
244
- throw createAssetServerCompilationError(`Module not found: ${absolutePath}`, {
245
- code: 'MODULE_NOT_FOUND',
258
+ throw createAssetServerCompilationError(`File not found: ${absolutePath}`, {
259
+ code: 'FILE_NOT_FOUND',
246
260
  })
247
261
  }
248
262
 
249
263
  if (!resolvedOptions.isAllowed(resolvedModule.identityPath)) {
250
264
  throw createAssetServerCompilationError(
251
- `Module is not allowed: ${resolvedModule.identityPath}`,
265
+ `File is not allowed: ${resolvedModule.identityPath}`,
252
266
  {
253
- code: 'MODULE_NOT_ALLOWED',
267
+ code: 'FILE_NOT_ALLOWED',
254
268
  },
255
269
  )
256
270
  }
@@ -258,10 +272,10 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
258
272
  return resolvedModule
259
273
  }
260
274
 
261
- function getNotModifiedModule(
262
- record: ModuleRecord,
263
- options: ModuleGetOptions,
264
- ): ModuleGetResult | null {
275
+ function getNotModifiedScript(
276
+ record: ScriptRecord,
277
+ options: ScriptGetOptions,
278
+ ): ScriptGetResult | null {
265
279
  let current = getNotModifiedResult(record.emitted, options)
266
280
  if (current) return current
267
281
 
@@ -272,13 +286,13 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
272
286
  return getNotModifiedResult(record.staleEmitted, options)
273
287
  }
274
288
 
275
- async function getOrCreateResolvedModules(records: ModuleRecord[]): Promise<ResolvedModule[]> {
289
+ async function getOrCreateResolvedScripts(records: ScriptRecord[]): Promise<ResolvedModule[]> {
276
290
  return mapWithConcurrency(records, preloadConcurrency, (record) =>
277
- getOrCreateResolvedModule(record),
291
+ getOrCreateResolvedScript(record),
278
292
  )
279
293
  }
280
294
 
281
- async function getOrCreateResolvedModule(record: ModuleRecord): Promise<ResolvedModule> {
295
+ async function getOrCreateResolvedScript(record: ScriptRecord): Promise<ResolvedModule> {
282
296
  if (record.resolved) return record.resolved
283
297
 
284
298
  let cacheKey = getRecordCacheKey(record)
@@ -287,7 +301,7 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
287
301
 
288
302
  let promise = (async () => {
289
303
  let startedVersion = record.invalidationVersion
290
- let transformedModule = await getOrCreateTransformedModule(record)
304
+ let transformedModule = await getOrCreateTransformedScript(record)
291
305
  if (
292
306
  resolvedOptions.watchMode &&
293
307
  transformedModule.unresolvedImports.some((unresolved) =>
@@ -300,13 +314,15 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
300
314
 
301
315
  if (!resolveModuleResult.ok) {
302
316
  if (isFresh(record, startedVersion)) {
303
- store.setResolveFailure(record.identityPath, resolveModuleResult.tracking)
317
+ scriptStore.clearResolved(record.identityPath, [resolveModuleResult.tracking])
304
318
  }
305
319
  throw resolveModuleResult.error
306
320
  }
307
321
 
308
322
  if (isFresh(record, startedVersion)) {
309
- store.setResolved(record.identityPath, resolveModuleResult.value)
323
+ scriptStore.setResolved(record.identityPath, resolveModuleResult.value, [
324
+ resolveModuleResult.tracking,
325
+ ])
310
326
  }
311
327
 
312
328
  return resolveModuleResult.value
@@ -323,7 +339,7 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
323
339
  }
324
340
  }
325
341
 
326
- async function getOrCreateTransformedModule(record: ModuleRecord): Promise<TransformedModule> {
342
+ async function getOrCreateTransformedScript(record: ScriptRecord): Promise<TransformedModule> {
327
343
  if (record.transformed) return record.transformed
328
344
 
329
345
  let startedVersion = record.invalidationVersion
@@ -331,21 +347,21 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
331
347
 
332
348
  if (!transformModuleResult.ok) {
333
349
  if (isFresh(record, startedVersion)) {
334
- store.setTransformFailure(record.identityPath, {
335
- trackedFiles: transformModuleResult.trackedFiles,
336
- })
350
+ scriptStore.clearTransformed(record.identityPath, [transformModuleResult.tracking])
337
351
  }
338
352
  throw transformModuleResult.error
339
353
  }
340
354
 
341
355
  if (isFresh(record, startedVersion)) {
342
- store.setTransformed(record.identityPath, transformModuleResult.value)
356
+ scriptStore.setTransformed(record.identityPath, transformModuleResult.value, [
357
+ transformModuleResult.tracking,
358
+ ])
343
359
  }
344
360
 
345
361
  return transformModuleResult.value
346
362
  }
347
363
 
348
- async function getOrCreateEmittedModule(record: ModuleRecord): Promise<EmittedModule> {
364
+ async function getOrCreateEmittedScript(record: ScriptRecord): Promise<EmittedModule> {
349
365
  if (record.emitted) return record.emitted
350
366
 
351
367
  let cacheKey = getRecordCacheKey(record)
@@ -354,7 +370,7 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
354
370
 
355
371
  let promise = (async () => {
356
372
  let startedVersion = record.invalidationVersion
357
- let resolvedModule = await getOrCreateResolvedModule(record)
373
+ let resolvedModule = await getOrCreateResolvedScript(record)
358
374
  let emitResolvedModuleResult = await emitResolvedModule(resolvedModule, {
359
375
  getServedUrl,
360
376
  sourceMaps: resolvedOptions.sourceMaps,
@@ -365,7 +381,7 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
365
381
  }
366
382
 
367
383
  if (isFresh(record, startedVersion)) {
368
- store.setEmitted(
384
+ scriptStore.setEmitted(
369
385
  record.identityPath,
370
386
  emitResolvedModuleResult.value,
371
387
  createModuleSnapshot(resolvedModule.trackedFiles),
@@ -387,13 +403,15 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
387
403
  }
388
404
 
389
405
  async function getServedUrl(identityPath: string): Promise<string> {
390
- return getServedUrlForResolvedModule(await getOrCreateResolvedModule(store.get(identityPath)))
406
+ return getServedUrlForResolvedScript(
407
+ await getOrCreateResolvedScript(scriptStore.get(identityPath)),
408
+ )
391
409
  }
392
410
 
393
- function getServedUrlForResolvedModule(resolvedModule: ResolvedModule): string {
411
+ function getServedUrlForResolvedScript(resolvedModule: ResolvedModule): string {
394
412
  return formatFingerprintedPathname(
395
413
  resolvedModule.stableUrlPathname,
396
- resolvedOptions.fingerprintModules ? resolvedModule.fingerprint : null,
414
+ resolvedOptions.fingerprintAssets ? resolvedModule.fingerprint : null,
397
415
  )
398
416
  }
399
417
 
@@ -402,18 +420,18 @@ export function createModuleCompiler(options: ModuleCompilerOptions): ModuleComp
402
420
  }
403
421
  }
404
422
 
405
- function getRecordCacheKey(record: ModuleRecord): string {
423
+ function getRecordCacheKey(record: ScriptRecord): string {
406
424
  return `${record.identityPath}\0${record.invalidationVersion}`
407
425
  }
408
426
 
409
- function isFresh(record: ModuleRecord, version: number): boolean {
427
+ function isFresh(record: ScriptRecord, version: number): boolean {
410
428
  return record.invalidationVersion === version
411
429
  }
412
430
 
413
431
  function getNotModifiedResult(
414
432
  emittedModule: EmittedModule | undefined,
415
- options: ModuleGetOptions,
416
- ): ModuleGetResult | null {
433
+ options: ScriptGetOptions,
434
+ ): ScriptGetResult | null {
417
435
  if (!emittedModule || options.ifNoneMatch === null) return null
418
436
 
419
437
  if (
@@ -510,7 +528,7 @@ async function mapWithConcurrency<item, result>(
510
528
  return results
511
529
  }
512
530
 
513
- function toModuleCompileResult(emittedModule: EmittedModule): ModuleCompileResult {
531
+ function toScriptCompileResult(emittedModule: EmittedModule): ScriptCompileResult {
514
532
  return {
515
533
  code: emittedModule.code,
516
534
  fingerprint: emittedModule.fingerprint,
@@ -582,8 +600,8 @@ function isNoEntityError(
582
600
  )
583
601
  }
584
602
 
585
- export function createResponseForModule(
586
- result: ModuleCompileResult,
603
+ export function createResponseForScript(
604
+ result: ScriptCompileResult,
587
605
  options: {
588
606
  cacheControl: string
589
607
  ifNoneMatch: string | null
@@ -113,10 +113,10 @@ function toEmitError(error: unknown, identityPath: string): AssetServerCompilati
113
113
  if (isAssetServerCompilationError(error)) return error
114
114
 
115
115
  return createAssetServerCompilationError(
116
- `Failed to emit module ${identityPath}. ${error instanceof Error ? error.message : String(error)}`,
116
+ `Failed to emit script ${identityPath}. ${error instanceof Error ? error.message : String(error)}`,
117
117
  {
118
118
  cause: error,
119
- code: 'MODULE_EMIT_FAILED',
119
+ code: 'EMIT_FAILED',
120
120
  },
121
121
  )
122
122
  }
@@ -7,10 +7,13 @@ import {
7
7
  isAssetServerCompilationError,
8
8
  } from '../compilation-error.ts'
9
9
  import type { AssetServerCompilationError } from '../compilation-error.ts'
10
+ import type { ModuleRecord, ModuleTracking } from '../module-store.ts'
10
11
  import { normalizeFilePath } from '../paths.ts'
11
12
  import type { CompiledRoutes } from '../routes.ts'
12
- import type { ModuleRecord } from './store.ts'
13
13
  import type { ResolveModuleResult, TransformedModule } from './transform.ts'
14
+ import type { EmittedModule } from './emit.ts'
15
+
16
+ type ScriptRecord = ModuleRecord<TransformedModule, ResolvedModule, EmittedModule>
14
17
 
15
18
  export const resolverExtensionAlias = {
16
19
  '.js': ['.js', '.ts', '.tsx', '.jsx'],
@@ -35,7 +38,7 @@ type RelativeImportResolution = {
35
38
  specifier: string
36
39
  }
37
40
 
38
- export type TrackedResolution = RelativeImportResolution & {
41
+ type TrackedResolution = RelativeImportResolution & {
39
42
  resolvedIdentityPath: string | null
40
43
  }
41
44
 
@@ -45,19 +48,15 @@ export type ResolvedModule = {
45
48
  identityPath: string
46
49
  imports: ResolvedImport[]
47
50
  trackedFiles: string[]
48
- trackedResolutions: TrackedResolution[]
49
51
  rawCode: string
50
52
  resolvedPath: string
51
53
  sourceMap: string | null
52
54
  stableUrlPathname: string
53
55
  }
54
56
 
55
- export type ResolutionFailureState = {
56
- trackedFiles: readonly string[]
57
- trackedResolutions: readonly TrackedResolution[]
58
- }
59
-
60
- type ResolveResult =
57
+ type ResolveResult = {
58
+ tracking: ModuleTracking
59
+ } & (
61
60
  | {
62
61
  ok: true
63
62
  value: ResolvedModule
@@ -65,8 +64,8 @@ type ResolveResult =
65
64
  | {
66
65
  ok: false
67
66
  error: AssetServerCompilationError
68
- tracking: ResolutionFailureState
69
67
  }
68
+ )
70
69
 
71
70
  export type ResolveArgs = {
72
71
  isAllowed(absolutePath: string): boolean
@@ -83,7 +82,7 @@ type ResolvedSpec = {
83
82
  }
84
83
 
85
84
  export async function resolveModule(
86
- record: ModuleRecord,
85
+ record: ScriptRecord,
87
86
  transformed: TransformedModule,
88
87
  args: ResolveArgs,
89
88
  ): Promise<ResolveResult> {
@@ -137,7 +136,7 @@ export async function resolveModule(
137
136
  if (!resolvedImport) {
138
137
  return failResolve(
139
138
  createAssetServerCompilationError(
140
- `Resolved import "${unresolved.specifier}" in ${transformed.resolvedPath} is not a supported script module. ` +
139
+ `Import "${unresolved.specifier}" in ${transformed.resolvedPath}, resolved to "${resolvedSpec.absolutePath}", is not a supported script file. ` +
141
140
  `Supported extensions are ${supportedScriptExtensions.join(', ')}.`,
142
141
  {
143
142
  code: 'IMPORT_NOT_SUPPORTED',
@@ -153,8 +152,8 @@ export async function resolveModule(
153
152
  if (!args.isAllowed(resolvedImport.identityPath)) {
154
153
  return failResolve(
155
154
  createAssetServerCompilationError(
156
- `Resolved import "${unresolved.specifier}" in ${transformed.resolvedPath} is not allowed by the asset server allow/deny configuration. ` +
157
- `Add a matching allow rule, remove a conflicting deny rule, or mark this import as external.`,
155
+ `Import "${unresolved.specifier}" in ${transformed.resolvedPath}, resolved to "${resolvedImport.identityPath}", is not allowed by the asset server allow/deny configuration. ` +
156
+ `Add a matching allow rule for this file path, remove a conflicting deny rule for this file path, or mark this import as external.`,
158
157
  {
159
158
  code: 'IMPORT_NOT_ALLOWED',
160
159
  },
@@ -170,7 +169,7 @@ export async function resolveModule(
170
169
  if (!stableUrlPathname) {
171
170
  return failResolve(
172
171
  createAssetServerCompilationError(
173
- `Resolved import "${unresolved.specifier}" in ${transformed.resolvedPath} is outside all configured fileMap entries. ` +
172
+ `Import "${unresolved.specifier}" in ${transformed.resolvedPath}, resolved to "${resolvedImport.identityPath}", is outside all configured fileMap entries. ` +
174
173
  `Add a matching fileMap entry for this file path, or mark this import as external.`,
175
174
  {
176
175
  code: 'IMPORT_OUTSIDE_FILE_MAP',
@@ -210,13 +209,13 @@ export async function resolveModule(
210
209
 
211
210
  return {
212
211
  ok: true,
212
+ tracking: toResolveTracking(trackedFiles, trackedResolutions),
213
213
  value: {
214
214
  deps: [...deps],
215
215
  fingerprint: transformed.fingerprint,
216
216
  identityPath: record.identityPath,
217
217
  imports: importsWithPaths,
218
218
  trackedFiles: [...trackedFiles],
219
- trackedResolutions,
220
219
  rawCode: transformed.rawCode,
221
220
  resolvedPath: transformed.resolvedPath,
222
221
  sourceMap: transformed.sourceMap,
@@ -384,13 +383,25 @@ function failResolve(
384
383
  return {
385
384
  ok: false,
386
385
  error: toResolveError(error, importerPath),
387
- tracking: {
388
- trackedFiles: [...trackedFiles],
389
- trackedResolutions: appendFailedTrackedResolution(
390
- trackedResolutions,
391
- options.trackedResolution,
392
- ),
393
- },
386
+ tracking: toResolveTracking(
387
+ trackedFiles,
388
+ appendFailedTrackedResolution(trackedResolutions, options.trackedResolution),
389
+ ),
390
+ }
391
+ }
392
+
393
+ function toResolveTracking(
394
+ trackedFiles: ReadonlySet<string> | readonly string[],
395
+ trackedResolutions: readonly TrackedResolution[],
396
+ ): ModuleTracking {
397
+ return {
398
+ trackedFiles: [
399
+ ...trackedFiles,
400
+ ...trackedResolutions.flatMap((trackedResolution) => trackedResolution.candidatePaths),
401
+ ],
402
+ trackedDirectories: trackedResolutions.flatMap(
403
+ (trackedResolution) => trackedResolution.candidatePrefixes,
404
+ ),
394
405
  }
395
406
  }
396
407