@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.
- package/README.md +322 -56
- package/dist/assets.d.ts +2 -1
- package/dist/assets.d.ts.map +1 -1
- package/dist/assets.js +2 -2
- package/dist/lib/access.d.ts +6 -2
- package/dist/lib/access.d.ts.map +1 -1
- package/dist/lib/access.js +300 -5
- package/dist/lib/asset-server.d.ts +118 -5
- package/dist/lib/asset-server.d.ts.map +1 -1
- package/dist/lib/asset-server.js +260 -24
- package/dist/lib/compilation-error.d.ts +1 -1
- package/dist/lib/compilation-error.d.ts.map +1 -1
- package/dist/lib/file-matcher.js +1 -1
- package/dist/lib/files/compiler.d.ts.map +1 -1
- package/dist/lib/files/compiler.js +7 -6
- package/dist/lib/files/config.js +1 -1
- package/dist/lib/hmr.d.ts +37 -0
- package/dist/lib/hmr.d.ts.map +1 -0
- package/dist/lib/hmr.js +357 -0
- package/dist/lib/injected-packages.d.ts.map +1 -1
- package/dist/lib/injected-packages.js +36 -13
- package/dist/lib/loaders.d.ts +57 -0
- package/dist/lib/loaders.d.ts.map +1 -0
- package/dist/lib/loaders.js +1 -0
- package/dist/lib/module-store.d.ts +24 -0
- package/dist/lib/module-store.d.ts.map +1 -1
- package/dist/lib/module-store.js +136 -11
- package/dist/lib/routes.d.ts.map +1 -1
- package/dist/lib/routes.js +13 -13
- package/dist/lib/scripts/compiler.d.ts +24 -1
- package/dist/lib/scripts/compiler.d.ts.map +1 -1
- package/dist/lib/scripts/compiler.js +183 -29
- package/dist/lib/scripts/conditions.d.ts +2 -0
- package/dist/lib/scripts/conditions.d.ts.map +1 -0
- package/dist/lib/scripts/conditions.js +1 -0
- package/dist/lib/scripts/emit.d.ts +3 -0
- package/dist/lib/scripts/emit.d.ts.map +1 -1
- package/dist/lib/scripts/emit.js +24 -5
- package/dist/lib/scripts/resolve.d.ts +4 -0
- package/dist/lib/scripts/resolve.d.ts.map +1 -1
- package/dist/lib/scripts/resolve.js +70 -5
- package/dist/lib/scripts/transform.d.ts +9 -0
- package/dist/lib/scripts/transform.d.ts.map +1 -1
- package/dist/lib/scripts/transform.js +222 -18
- package/dist/lib/source-maps.js +1 -1
- package/dist/lib/styles/compiler.d.ts +14 -1
- package/dist/lib/styles/compiler.d.ts.map +1 -1
- package/dist/lib/styles/compiler.js +78 -14
- package/dist/lib/styles/emit.js +4 -4
- package/dist/lib/styles/resolve.d.ts.map +1 -1
- package/dist/lib/styles/resolve.js +8 -7
- package/dist/lib/styles/transform.js +3 -3
- package/dist/lib/target.d.ts +1 -1
- package/dist/lib/target.d.ts.map +1 -1
- package/dist/lib/watch.js +1 -1
- package/dist/types/hmr.d.ts +36 -0
- package/package.json +17 -11
- package/src/assets.ts +2 -1
- package/src/lib/access.ts +386 -5
- package/src/lib/asset-server.ts +429 -18
- package/src/lib/compilation-error.ts +1 -0
- package/src/lib/files/compiler.ts +7 -3
- package/src/lib/hmr.ts +397 -0
- package/src/lib/injected-packages.ts +41 -11
- package/src/lib/loaders.ts +80 -0
- package/src/lib/module-store.ts +190 -9
- package/src/lib/routes.ts +24 -14
- package/src/lib/scripts/compiler.ts +248 -24
- package/src/lib/scripts/conditions.ts +1 -0
- package/src/lib/scripts/emit.ts +50 -5
- package/src/lib/scripts/resolve.ts +124 -2
- package/src/lib/scripts/transform.ts +290 -19
- package/src/lib/styles/compiler.ts +108 -8
- package/src/lib/styles/emit.ts +1 -1
- package/src/lib/styles/resolve.ts +11 -7
- package/src/types/hmr.d.ts +36 -0
package/src/lib/module-store.ts
CHANGED
|
@@ -14,11 +14,27 @@ export type FileSnapshot = {
|
|
|
14
14
|
|
|
15
15
|
export type ModuleSnapshot = ReadonlyMap<string, FileSnapshot>
|
|
16
16
|
|
|
17
|
+
type ModuleLinksState = {
|
|
18
|
+
acceptedDependencies: ReadonlySet<string>
|
|
19
|
+
dependencies: ReadonlySet<string>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type MutableModuleLinks = {
|
|
23
|
+
acceptedDependencies: Set<string>
|
|
24
|
+
dependencies: Set<string>
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
type ModuleRecordState<transformed, resolved, emitted> = {
|
|
28
|
+
emittedVersion?: number
|
|
29
|
+
hmrUpdateTimestamp?: number
|
|
18
30
|
identityPath: string
|
|
19
31
|
invalidationVersion: number
|
|
20
32
|
transformed?: transformed
|
|
33
|
+
transformedVersion?: number
|
|
21
34
|
resolved?: resolved
|
|
35
|
+
resolvedVersion?: number
|
|
36
|
+
lastResolved?: resolved
|
|
37
|
+
links: ModuleLinksState
|
|
22
38
|
emitted?: emitted
|
|
23
39
|
emittedSnapshot?: ModuleSnapshot
|
|
24
40
|
staleEmitted?: emitted
|
|
@@ -32,10 +48,16 @@ export type ModuleRecord<transformed, resolved, emitted> = Readonly<
|
|
|
32
48
|
>
|
|
33
49
|
|
|
34
50
|
type MutableModuleRecord<transformed, resolved, emitted> = {
|
|
51
|
+
emittedVersion?: number
|
|
52
|
+
hmrUpdateTimestamp?: number
|
|
35
53
|
identityPath: string
|
|
36
54
|
invalidationVersion: number
|
|
37
55
|
transformed?: transformed
|
|
56
|
+
transformedVersion?: number
|
|
38
57
|
resolved?: resolved
|
|
58
|
+
resolvedVersion?: number
|
|
59
|
+
lastResolved?: resolved
|
|
60
|
+
links: MutableModuleLinks
|
|
39
61
|
emitted?: emitted
|
|
40
62
|
emittedSnapshot?: ModuleSnapshot
|
|
41
63
|
staleEmitted?: emitted
|
|
@@ -46,6 +68,14 @@ type MutableModuleRecord<transformed, resolved, emitted> = {
|
|
|
46
68
|
|
|
47
69
|
export type ModuleStore<transformed, resolved, emitted> = {
|
|
48
70
|
get(identityPath: string): ModuleRecord<transformed, resolved, emitted>
|
|
71
|
+
getAcceptedImporters(identityPath: string): ReadonlySet<string>
|
|
72
|
+
getHmrUpdateTimestamp(identityPath: string): number | undefined
|
|
73
|
+
getImporters(identityPath: string): ReadonlySet<string>
|
|
74
|
+
getLastResolved(identityPath: string): resolved | undefined
|
|
75
|
+
isEmittedFresh(record: ModuleRecord<transformed, resolved, emitted>): boolean
|
|
76
|
+
isResolvedFresh(record: ModuleRecord<transformed, resolved, emitted>): boolean
|
|
77
|
+
isTransformedFresh(record: ModuleRecord<transformed, resolved, emitted>): boolean
|
|
78
|
+
setHmrUpdateTimestamp(identityPath: string, timestamp: number): void
|
|
49
79
|
clearTransformed(identityPath: string, tracking: readonly ModuleTracking[]): void
|
|
50
80
|
setTransformed(
|
|
51
81
|
identityPath: string,
|
|
@@ -61,12 +91,19 @@ export type ModuleStore<transformed, resolved, emitted> = {
|
|
|
61
91
|
|
|
62
92
|
export function createModuleStore<transformed, resolved, emitted>(
|
|
63
93
|
options: {
|
|
94
|
+
getAcceptedDependencies?: (resolved: resolved) => readonly string[]
|
|
95
|
+
getDependencies?: (resolved: resolved) => readonly string[]
|
|
64
96
|
onWatchDirectoriesChange?: (delta: { add: string[]; remove: string[] }) => void
|
|
97
|
+
onWatchFilesChange?: (delta: { add: string[]; remove: string[] }) => void
|
|
65
98
|
} = {},
|
|
66
99
|
): ModuleStore<transformed, resolved, emitted> {
|
|
67
100
|
let recordsByIdentityPath = new Map<string, MutableModuleRecord<transformed, resolved, emitted>>()
|
|
101
|
+
let importersByDepPath = new Map<string, Set<string>>()
|
|
102
|
+
let acceptedImportersByDepPath = new Map<string, Set<string>>()
|
|
68
103
|
let recordsByTrackedFile = new Map<string, Set<string>>()
|
|
69
104
|
let watchDirectoryRefCountByPath = new Map<string, number>()
|
|
105
|
+
let watchFileRefCountByPath = new Map<string, number>()
|
|
106
|
+
let emptyImporters = new Set<string>()
|
|
70
107
|
|
|
71
108
|
return {
|
|
72
109
|
get(identityPath) {
|
|
@@ -76,17 +113,55 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
76
113
|
let record: MutableModuleRecord<transformed, resolved, emitted> = {
|
|
77
114
|
identityPath,
|
|
78
115
|
invalidationVersion: 0,
|
|
116
|
+
links: createEmptyLinks(),
|
|
79
117
|
trackedFiles: new Set(),
|
|
80
118
|
trackedDirectories: new Set(),
|
|
81
119
|
}
|
|
82
120
|
recordsByIdentityPath.set(identityPath, record)
|
|
83
121
|
return record
|
|
84
122
|
},
|
|
123
|
+
|
|
124
|
+
getAcceptedImporters(identityPath) {
|
|
125
|
+
return acceptedImportersByDepPath.get(identityPath) ?? emptyImporters
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
getHmrUpdateTimestamp(identityPath) {
|
|
129
|
+
return recordsByIdentityPath.get(identityPath)?.hmrUpdateTimestamp
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
getImporters(identityPath) {
|
|
133
|
+
return importersByDepPath.get(identityPath) ?? emptyImporters
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
getLastResolved(identityPath) {
|
|
137
|
+
return recordsByIdentityPath.get(identityPath)?.lastResolved
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
isEmittedFresh(record) {
|
|
141
|
+
return record.emittedVersion === record.invalidationVersion
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
isResolvedFresh(record) {
|
|
145
|
+
return record.resolvedVersion === record.invalidationVersion
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
isTransformedFresh(record) {
|
|
149
|
+
return record.transformedVersion === record.invalidationVersion
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
setHmrUpdateTimestamp(identityPath, timestamp) {
|
|
153
|
+
let record = getOrCreateMutableRecord(identityPath)
|
|
154
|
+
record.hmrUpdateTimestamp = timestamp
|
|
155
|
+
},
|
|
156
|
+
|
|
85
157
|
clearTransformed(identityPath, tracking) {
|
|
86
158
|
let record = getOrCreateMutableRecord(identityPath)
|
|
87
159
|
record.transformed = undefined
|
|
160
|
+
record.transformedVersion = undefined
|
|
88
161
|
record.resolved = undefined
|
|
162
|
+
record.resolvedVersion = undefined
|
|
89
163
|
record.emitted = undefined
|
|
164
|
+
record.emittedVersion = undefined
|
|
90
165
|
record.emittedSnapshot = undefined
|
|
91
166
|
record.staleEmitted = undefined
|
|
92
167
|
record.staleEmittedSnapshot = undefined
|
|
@@ -96,8 +171,11 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
96
171
|
setTransformed(identityPath, transformed, tracking) {
|
|
97
172
|
let record = getOrCreateMutableRecord(identityPath)
|
|
98
173
|
record.transformed = transformed
|
|
174
|
+
record.transformedVersion = record.invalidationVersion
|
|
99
175
|
record.resolved = undefined
|
|
176
|
+
record.resolvedVersion = undefined
|
|
100
177
|
record.emitted = undefined
|
|
178
|
+
record.emittedVersion = undefined
|
|
101
179
|
record.emittedSnapshot = undefined
|
|
102
180
|
record.staleEmitted = undefined
|
|
103
181
|
record.staleEmittedSnapshot = undefined
|
|
@@ -106,18 +184,26 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
106
184
|
|
|
107
185
|
setResolved(identityPath, resolved, tracking) {
|
|
108
186
|
let record = getOrCreateMutableRecord(identityPath)
|
|
187
|
+
removeResolvedIndexes(record)
|
|
109
188
|
record.resolved = resolved
|
|
189
|
+
record.resolvedVersion = record.invalidationVersion
|
|
190
|
+
record.lastResolved = resolved
|
|
191
|
+
record.links = createLinks(resolved)
|
|
110
192
|
record.emitted = undefined
|
|
193
|
+
record.emittedVersion = undefined
|
|
111
194
|
record.emittedSnapshot = undefined
|
|
112
195
|
record.staleEmitted = undefined
|
|
113
196
|
record.staleEmittedSnapshot = undefined
|
|
114
197
|
setTracking(record, tracking)
|
|
198
|
+
addResolvedIndexes(record)
|
|
115
199
|
},
|
|
116
200
|
|
|
117
201
|
clearResolved(identityPath, tracking) {
|
|
118
202
|
let record = getOrCreateMutableRecord(identityPath)
|
|
119
203
|
record.resolved = undefined
|
|
204
|
+
record.resolvedVersion = undefined
|
|
120
205
|
record.emitted = undefined
|
|
206
|
+
record.emittedVersion = undefined
|
|
121
207
|
record.emittedSnapshot = undefined
|
|
122
208
|
record.staleEmitted = undefined
|
|
123
209
|
record.staleEmittedSnapshot = undefined
|
|
@@ -127,6 +213,7 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
127
213
|
setEmitted(identityPath, emitted, snapshot) {
|
|
128
214
|
let record = getOrCreateMutableRecord(identityPath)
|
|
129
215
|
record.emitted = emitted
|
|
216
|
+
record.emittedVersion = record.invalidationVersion
|
|
130
217
|
record.emittedSnapshot = snapshot ?? undefined
|
|
131
218
|
record.staleEmitted = undefined
|
|
132
219
|
record.staleEmittedSnapshot = undefined
|
|
@@ -145,12 +232,21 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
145
232
|
|
|
146
233
|
for (let identityPath of affected) {
|
|
147
234
|
let record = recordsByIdentityPath.get(identityPath)
|
|
148
|
-
if (record)
|
|
235
|
+
if (record) {
|
|
236
|
+
if (event === 'change') {
|
|
237
|
+
invalidateContent(record, { retainStale: true })
|
|
238
|
+
} else {
|
|
239
|
+
invalidateGraph(record)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
149
242
|
}
|
|
150
243
|
|
|
151
244
|
if (event === 'unlink') {
|
|
152
245
|
let deletedRecord = recordsByIdentityPath.get(filePath)
|
|
153
246
|
if (deletedRecord) {
|
|
247
|
+
if (!affected.has(filePath)) {
|
|
248
|
+
invalidateGraph(deletedRecord)
|
|
249
|
+
}
|
|
154
250
|
clearTracking(deletedRecord)
|
|
155
251
|
}
|
|
156
252
|
}
|
|
@@ -158,7 +254,7 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
158
254
|
|
|
159
255
|
invalidateAll() {
|
|
160
256
|
for (let record of recordsByIdentityPath.values()) {
|
|
161
|
-
|
|
257
|
+
invalidateGraph(record)
|
|
162
258
|
}
|
|
163
259
|
},
|
|
164
260
|
}
|
|
@@ -172,6 +268,7 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
172
268
|
let record: MutableModuleRecord<transformed, resolved, emitted> = {
|
|
173
269
|
identityPath,
|
|
174
270
|
invalidationVersion: 0,
|
|
271
|
+
links: createEmptyLinks(),
|
|
175
272
|
trackedFiles: new Set(),
|
|
176
273
|
trackedDirectories: new Set(),
|
|
177
274
|
}
|
|
@@ -179,7 +276,7 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
179
276
|
return record
|
|
180
277
|
}
|
|
181
278
|
|
|
182
|
-
function
|
|
279
|
+
function invalidateContent(
|
|
183
280
|
record: MutableModuleRecord<transformed, resolved, emitted>,
|
|
184
281
|
options: { retainStale: boolean },
|
|
185
282
|
) {
|
|
@@ -194,18 +291,51 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
194
291
|
record.staleEmittedSnapshot = undefined
|
|
195
292
|
}
|
|
196
293
|
|
|
197
|
-
record.emitted = undefined
|
|
198
|
-
record.emittedSnapshot = undefined
|
|
199
|
-
record.resolved = undefined
|
|
200
|
-
record.transformed = undefined
|
|
201
294
|
record.invalidationVersion += 1
|
|
202
295
|
}
|
|
203
296
|
|
|
297
|
+
function invalidateGraph(record: MutableModuleRecord<transformed, resolved, emitted>) {
|
|
298
|
+
record.hmrUpdateTimestamp = undefined
|
|
299
|
+
invalidateContent(record, { retainStale: false })
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function createLinks(resolved: resolved): MutableModuleLinks {
|
|
303
|
+
return {
|
|
304
|
+
acceptedDependencies: new Set(options.getAcceptedDependencies?.(resolved) ?? []),
|
|
305
|
+
dependencies: new Set(options.getDependencies?.(resolved) ?? []),
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function createEmptyLinks(): MutableModuleLinks {
|
|
310
|
+
return {
|
|
311
|
+
acceptedDependencies: new Set(),
|
|
312
|
+
dependencies: new Set(),
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function addResolvedIndexes(record: MutableModuleRecord<transformed, resolved, emitted>): void {
|
|
317
|
+
for (let depPath of record.links.dependencies) {
|
|
318
|
+
addToIndexedSet(importersByDepPath, depPath, record.identityPath)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
for (let depPath of record.links.acceptedDependencies) {
|
|
322
|
+
addToIndexedSet(acceptedImportersByDepPath, depPath, record.identityPath)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function removeResolvedIndexes(
|
|
327
|
+
record: MutableModuleRecord<transformed, resolved, emitted>,
|
|
328
|
+
): void {
|
|
329
|
+
removeFromIndexedSets(importersByDepPath, record.identityPath)
|
|
330
|
+
removeFromIndexedSets(acceptedImportersByDepPath, record.identityPath)
|
|
331
|
+
}
|
|
332
|
+
|
|
204
333
|
function setTracking(
|
|
205
334
|
record: MutableModuleRecord<transformed, resolved, emitted>,
|
|
206
335
|
tracking: readonly ModuleTracking[],
|
|
207
336
|
) {
|
|
208
337
|
let previousWatchedDirectories = getWatchedDirectories(record)
|
|
338
|
+
let previousWatchedFiles = new Set(record.trackedFiles)
|
|
209
339
|
removeIndexes(record)
|
|
210
340
|
|
|
211
341
|
let normalizedTracking = mergeTracking(tracking)
|
|
@@ -217,8 +347,13 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
217
347
|
}
|
|
218
348
|
|
|
219
349
|
let nextWatchedDirectories = getWatchedDirectories(record)
|
|
220
|
-
let
|
|
221
|
-
|
|
350
|
+
let directoryDelta = updateWatchDirectoryRefCounts(
|
|
351
|
+
previousWatchedDirectories,
|
|
352
|
+
nextWatchedDirectories,
|
|
353
|
+
)
|
|
354
|
+
let fileDelta = updateWatchFileRefCounts(previousWatchedFiles, record.trackedFiles)
|
|
355
|
+
emitWatchDirectoryDelta(directoryDelta)
|
|
356
|
+
emitWatchFileDelta(fileDelta)
|
|
222
357
|
}
|
|
223
358
|
|
|
224
359
|
function clearTracking(record: MutableModuleRecord<transformed, resolved, emitted>) {
|
|
@@ -262,11 +397,48 @@ export function createModuleStore<transformed, resolved, emitted>(
|
|
|
262
397
|
return { add, remove }
|
|
263
398
|
}
|
|
264
399
|
|
|
400
|
+
function updateWatchFileRefCounts(
|
|
401
|
+
previousWatchedFiles: ReadonlySet<string>,
|
|
402
|
+
nextWatchedFiles: ReadonlySet<string>,
|
|
403
|
+
): { add: string[]; remove: string[] } {
|
|
404
|
+
let add: string[] = []
|
|
405
|
+
let remove: string[] = []
|
|
406
|
+
|
|
407
|
+
for (let file of previousWatchedFiles) {
|
|
408
|
+
if (nextWatchedFiles.has(file)) continue
|
|
409
|
+
let previousCount = watchFileRefCountByPath.get(file)
|
|
410
|
+
if (!previousCount) continue
|
|
411
|
+
if (previousCount === 1) {
|
|
412
|
+
watchFileRefCountByPath.delete(file)
|
|
413
|
+
remove.push(file)
|
|
414
|
+
} else {
|
|
415
|
+
watchFileRefCountByPath.set(file, previousCount - 1)
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
for (let file of nextWatchedFiles) {
|
|
420
|
+
if (previousWatchedFiles.has(file)) continue
|
|
421
|
+
let previousCount = watchFileRefCountByPath.get(file) ?? 0
|
|
422
|
+
watchFileRefCountByPath.set(file, previousCount + 1)
|
|
423
|
+
if (previousCount === 0) {
|
|
424
|
+
add.push(file)
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return { add, remove }
|
|
429
|
+
}
|
|
430
|
+
|
|
265
431
|
function emitWatchDirectoryDelta(delta: { add: string[]; remove: string[] }): void {
|
|
266
432
|
if (!options.onWatchDirectoriesChange) return
|
|
267
433
|
if (delta.add.length === 0 && delta.remove.length === 0) return
|
|
268
434
|
options.onWatchDirectoriesChange(delta)
|
|
269
435
|
}
|
|
436
|
+
|
|
437
|
+
function emitWatchFileDelta(delta: { add: string[]; remove: string[] }): void {
|
|
438
|
+
if (!options.onWatchFilesChange) return
|
|
439
|
+
if (delta.add.length === 0 && delta.remove.length === 0) return
|
|
440
|
+
options.onWatchFilesChange(delta)
|
|
441
|
+
}
|
|
270
442
|
}
|
|
271
443
|
|
|
272
444
|
function addToIndexedSet(map: Map<string, Set<string>>, key: string, value: string) {
|
|
@@ -284,6 +456,15 @@ function removeFromIndexedSet(map: Map<string, Set<string>>, key: string, value:
|
|
|
284
456
|
}
|
|
285
457
|
}
|
|
286
458
|
|
|
459
|
+
function removeFromIndexedSets(map: Map<string, Set<string>>, value: string): void {
|
|
460
|
+
for (let [key, values] of map) {
|
|
461
|
+
values.delete(value)
|
|
462
|
+
if (values.size === 0) {
|
|
463
|
+
map.delete(key)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
287
468
|
function matchesTrackedDirectory(
|
|
288
469
|
trackedDirectories: ReadonlySet<string>,
|
|
289
470
|
filePath: string,
|
package/src/lib/routes.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getRoutePatternCaptures,
|
|
3
|
+
RoutePattern,
|
|
4
|
+
type RoutePatternCapture,
|
|
5
|
+
} from '@remix-run/route-pattern'
|
|
2
6
|
import { createHref } from '@remix-run/route-pattern/href'
|
|
3
7
|
import { createMatcher, type Matcher } from '@remix-run/route-pattern/match'
|
|
4
8
|
|
|
@@ -73,7 +77,9 @@ export function compileRoutes(
|
|
|
73
77
|
for (let route of compiledRoutes) {
|
|
74
78
|
let match = route.urlMatcher.match(`http://remix.run${normalizedPathname}`)
|
|
75
79
|
if (!match) continue
|
|
76
|
-
let relativeFilePath =
|
|
80
|
+
let relativeFilePath = decodeURIComponent(
|
|
81
|
+
createHref(route.filePattern, match.params),
|
|
82
|
+
).replace(/^\/+/, '')
|
|
77
83
|
return resolveFilePath(route.rootDir, relativeFilePath)
|
|
78
84
|
}
|
|
79
85
|
|
|
@@ -140,18 +146,18 @@ function stripDotSegments(pattern: string): string {
|
|
|
140
146
|
}
|
|
141
147
|
|
|
142
148
|
function validateRoutePatterns(urlPattern: RoutePattern, filePattern: RoutePattern): void {
|
|
143
|
-
let
|
|
144
|
-
let
|
|
145
|
-
if (
|
|
149
|
+
let urlCaptures = getPathnameCaptures(urlPattern)
|
|
150
|
+
let fileCaptures = getPathnameCaptures(filePattern)
|
|
151
|
+
if (urlCaptures.length !== fileCaptures.length) {
|
|
146
152
|
throw new Error(
|
|
147
153
|
`Route patterns must have matching capture structure.\nURL: ${urlPattern}\nFile: ${filePattern}`,
|
|
148
154
|
)
|
|
149
155
|
}
|
|
150
156
|
|
|
151
|
-
for (let i = 0; i <
|
|
152
|
-
let
|
|
153
|
-
let
|
|
154
|
-
if (
|
|
157
|
+
for (let i = 0; i < urlCaptures.length; i++) {
|
|
158
|
+
let urlCapture = urlCaptures[i]
|
|
159
|
+
let fileCapture = fileCaptures[i]
|
|
160
|
+
if (urlCapture.type !== fileCapture.type || urlCapture.name !== fileCapture.name) {
|
|
155
161
|
throw new Error(
|
|
156
162
|
`Route patterns must have matching capture structure.\nURL: ${urlPattern}\nFile: ${filePattern}`,
|
|
157
163
|
)
|
|
@@ -160,17 +166,21 @@ function validateRoutePatterns(urlPattern: RoutePattern, filePattern: RoutePatte
|
|
|
160
166
|
}
|
|
161
167
|
|
|
162
168
|
function validateNoUnnamedWildcards(pattern: RoutePattern, label: string): void {
|
|
163
|
-
if (
|
|
169
|
+
if (
|
|
170
|
+
getRoutePatternCaptures(pattern).some(
|
|
171
|
+
(capture) => capture.part === 'pathname' && capture.type === '*' && capture.name === '*',
|
|
172
|
+
)
|
|
173
|
+
) {
|
|
164
174
|
throw new Error(
|
|
165
175
|
`${label} route patterns must use named wildcards for reversible mapping.\nPattern: ${pattern}`,
|
|
166
176
|
)
|
|
167
177
|
}
|
|
168
178
|
}
|
|
169
179
|
|
|
170
|
-
type
|
|
180
|
+
type PathnameCapture = RoutePatternCapture & { readonly part: 'pathname' }
|
|
171
181
|
|
|
172
|
-
function
|
|
173
|
-
return pattern.
|
|
174
|
-
(
|
|
182
|
+
function getPathnameCaptures(pattern: RoutePattern): Array<PathnameCapture> {
|
|
183
|
+
return getRoutePatternCaptures(pattern).filter(
|
|
184
|
+
(capture): capture is PathnameCapture => capture.part === 'pathname',
|
|
175
185
|
)
|
|
176
186
|
}
|