@remix-run/assets 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +319 -2
  3. package/dist/assets.d.ts +3 -0
  4. package/dist/assets.d.ts.map +1 -0
  5. package/dist/assets.js +1 -0
  6. package/dist/lib/access.d.ts +10 -0
  7. package/dist/lib/access.d.ts.map +1 -0
  8. package/dist/lib/access.js +14 -0
  9. package/dist/lib/asset-server.d.ts +137 -0
  10. package/dist/lib/asset-server.d.ts.map +1 -0
  11. package/dist/lib/asset-server.js +242 -0
  12. package/dist/lib/compilation-error.d.ts +33 -0
  13. package/dist/lib/compilation-error.d.ts.map +1 -0
  14. package/dist/lib/compilation-error.js +32 -0
  15. package/dist/lib/file-matcher.d.ts +6 -0
  16. package/dist/lib/file-matcher.d.ts.map +1 -0
  17. package/dist/lib/file-matcher.js +43 -0
  18. package/dist/lib/fingerprint.d.ts +12 -0
  19. package/dist/lib/fingerprint.d.ts.map +1 -0
  20. package/dist/lib/fingerprint.js +49 -0
  21. package/dist/lib/paths.d.ts +8 -0
  22. package/dist/lib/paths.d.ts.map +1 -0
  23. package/dist/lib/paths.js +50 -0
  24. package/dist/lib/routes.d.ts +13 -0
  25. package/dist/lib/routes.d.ts.map +1 -0
  26. package/dist/lib/routes.js +94 -0
  27. package/dist/lib/scripts/cjs-check.d.ts +3 -0
  28. package/dist/lib/scripts/cjs-check.d.ts.map +1 -0
  29. package/dist/lib/scripts/cjs-check.js +398 -0
  30. package/dist/lib/scripts/compiler.d.ts +62 -0
  31. package/dist/lib/scripts/compiler.d.ts.map +1 -0
  32. package/dist/lib/scripts/compiler.js +435 -0
  33. package/dist/lib/scripts/emit.d.ts +25 -0
  34. package/dist/lib/scripts/emit.d.ts.map +1 -0
  35. package/dist/lib/scripts/emit.js +63 -0
  36. package/dist/lib/scripts/resolve.d.ts +60 -0
  37. package/dist/lib/scripts/resolve.d.ts.map +1 -0
  38. package/dist/lib/scripts/resolve.js +230 -0
  39. package/dist/lib/scripts/store.d.ts +40 -0
  40. package/dist/lib/scripts/store.d.ts.map +1 -0
  41. package/dist/lib/scripts/store.js +228 -0
  42. package/dist/lib/scripts/transform.d.ts +62 -0
  43. package/dist/lib/scripts/transform.d.ts.map +1 -0
  44. package/dist/lib/scripts/transform.js +362 -0
  45. package/dist/lib/source-maps.d.ts +4 -0
  46. package/dist/lib/source-maps.d.ts.map +1 -0
  47. package/dist/lib/source-maps.js +56 -0
  48. package/dist/lib/watch.d.ts +22 -0
  49. package/dist/lib/watch.d.ts.map +1 -0
  50. package/dist/lib/watch.js +96 -0
  51. package/package.json +50 -12
  52. package/src/assets.ts +2 -0
  53. package/src/lib/access.ts +24 -0
  54. package/src/lib/asset-server.ts +415 -0
  55. package/src/lib/compilation-error.ts +61 -0
  56. package/src/lib/file-matcher.ts +62 -0
  57. package/src/lib/fingerprint.ts +65 -0
  58. package/src/lib/paths.ts +66 -0
  59. package/src/lib/routes.ts +164 -0
  60. package/src/lib/scripts/cjs-check.ts +476 -0
  61. package/src/lib/scripts/compiler.ts +622 -0
  62. package/src/lib/scripts/emit.ts +122 -0
  63. package/src/lib/scripts/resolve.ts +422 -0
  64. package/src/lib/scripts/store.ts +327 -0
  65. package/src/lib/scripts/transform.ts +594 -0
  66. package/src/lib/source-maps.ts +68 -0
  67. package/src/lib/watch.ts +136 -0
@@ -0,0 +1,327 @@
1
+ import type { EmittedModule } from './emit.ts'
2
+ import { getFilePathDirectory } from '../paths.ts'
3
+ import type { ResolutionFailureState, ResolvedModule, TrackedResolution } from './resolve.ts'
4
+ import type { TransformFailureState, TransformedModule } from './transform.ts'
5
+
6
+ export type ModuleWatchEvent = 'change' | 'add' | 'unlink'
7
+
8
+ export type FileSnapshot = {
9
+ mtimeNs: bigint
10
+ size: bigint
11
+ }
12
+
13
+ export type ModuleSnapshot = ReadonlyMap<string, FileSnapshot>
14
+
15
+ type ModuleRecordState = {
16
+ identityPath: string
17
+ invalidationVersion: number
18
+ transformed?: TransformedModule
19
+ resolved?: ResolvedModule
20
+ emitted?: EmittedModule
21
+ emittedSnapshot?: ModuleSnapshot
22
+ staleEmitted?: EmittedModule
23
+ staleEmittedSnapshot?: ModuleSnapshot
24
+ trackedFiles: ReadonlySet<string>
25
+ trackedResolutions: readonly TrackedResolution[]
26
+ }
27
+
28
+ export type ModuleRecord = Readonly<ModuleRecordState>
29
+
30
+ type MutableModuleRecord = {
31
+ identityPath: string
32
+ invalidationVersion: number
33
+ transformed?: TransformedModule
34
+ resolved?: ResolvedModule
35
+ emitted?: EmittedModule
36
+ emittedSnapshot?: ModuleSnapshot
37
+ staleEmitted?: EmittedModule
38
+ staleEmittedSnapshot?: ModuleSnapshot
39
+ trackedFiles: Set<string>
40
+ trackedResolutions: TrackedResolution[]
41
+ }
42
+
43
+ type ModuleStore = {
44
+ get(identityPath: string): ModuleRecord
45
+ setTransformFailure(identityPath: string, failure: TransformFailureState): void
46
+ setTransformed(identityPath: string, transformed: TransformedModule): void
47
+ setResolved(identityPath: string, resolved: ResolvedModule): void
48
+ setResolveFailure(identityPath: string, failure: ResolutionFailureState): void
49
+ setEmitted(identityPath: string, emitted: EmittedModule, snapshot: ModuleSnapshot | null): void
50
+ invalidateForFileEvent(filePath: string, event: ModuleWatchEvent): void
51
+ invalidateAll(): void
52
+ }
53
+
54
+ export function createModuleStore(
55
+ options: {
56
+ onWatchDirectoriesChange?: (delta: { add: string[]; remove: string[] }) => void
57
+ } = {},
58
+ ): ModuleStore {
59
+ let recordsByIdentityPath = new Map<string, MutableModuleRecord>()
60
+ let recordsByTrackedFile = new Map<string, Set<string>>()
61
+ let watchDirectoryRefCountByPath = new Map<string, number>()
62
+
63
+ return {
64
+ get(identityPath) {
65
+ let existing = recordsByIdentityPath.get(identityPath)
66
+ if (existing) return existing
67
+
68
+ let record: MutableModuleRecord = {
69
+ identityPath,
70
+ invalidationVersion: 0,
71
+ trackedFiles: new Set(),
72
+ trackedResolutions: [],
73
+ }
74
+ recordsByIdentityPath.set(identityPath, record)
75
+ return record
76
+ },
77
+ setTransformFailure(identityPath, failure) {
78
+ let record = getOrCreateMutableRecord(identityPath)
79
+ record.transformed = undefined
80
+ record.resolved = undefined
81
+ record.emitted = undefined
82
+ record.emittedSnapshot = undefined
83
+ record.staleEmitted = undefined
84
+ record.staleEmittedSnapshot = undefined
85
+ setTracking(record, {
86
+ trackedFiles: failure.trackedFiles,
87
+ trackedResolutions: [],
88
+ })
89
+ },
90
+
91
+ setTransformed(identityPath, transformed) {
92
+ let record = getOrCreateMutableRecord(identityPath)
93
+ record.transformed = transformed
94
+ record.resolved = undefined
95
+ record.emitted = undefined
96
+ record.emittedSnapshot = undefined
97
+ record.staleEmitted = undefined
98
+ record.staleEmittedSnapshot = undefined
99
+ setTracking(record, {
100
+ trackedFiles: transformed.trackedFiles,
101
+ trackedResolutions: [],
102
+ })
103
+ },
104
+
105
+ setResolved(identityPath, resolved) {
106
+ let record = getOrCreateMutableRecord(identityPath)
107
+ record.resolved = resolved
108
+ record.emitted = undefined
109
+ record.emittedSnapshot = undefined
110
+ record.staleEmitted = undefined
111
+ record.staleEmittedSnapshot = undefined
112
+ setTracking(record, {
113
+ trackedFiles: resolved.trackedFiles,
114
+ trackedResolutions: resolved.trackedResolutions,
115
+ })
116
+ },
117
+
118
+ setResolveFailure(identityPath, failure) {
119
+ let record = getOrCreateMutableRecord(identityPath)
120
+ record.resolved = undefined
121
+ record.emitted = undefined
122
+ record.emittedSnapshot = undefined
123
+ record.staleEmitted = undefined
124
+ record.staleEmittedSnapshot = undefined
125
+ setTracking(record, {
126
+ trackedFiles: failure.trackedFiles,
127
+ trackedResolutions: failure.trackedResolutions,
128
+ })
129
+ },
130
+
131
+ setEmitted(identityPath, emitted, snapshot) {
132
+ let record = getOrCreateMutableRecord(identityPath)
133
+ record.emitted = emitted
134
+ record.emittedSnapshot = snapshot ?? undefined
135
+ record.staleEmitted = undefined
136
+ record.staleEmittedSnapshot = undefined
137
+ },
138
+
139
+ invalidateForFileEvent(filePath, event) {
140
+ let affected = new Set<string>(recordsByTrackedFile.get(filePath) ?? [])
141
+
142
+ if (event !== 'change') {
143
+ for (let record of recordsByIdentityPath.values()) {
144
+ if (
145
+ record.trackedResolutions.some((tracked) =>
146
+ mayAffectTrackedResolution(tracked, filePath),
147
+ )
148
+ ) {
149
+ affected.add(record.identityPath)
150
+ }
151
+ }
152
+ }
153
+
154
+ for (let identityPath of affected) {
155
+ let record = recordsByIdentityPath.get(identityPath)
156
+ if (record) invalidateRecord(record, { retainStale: event === 'change' })
157
+ }
158
+
159
+ if (event === 'unlink') {
160
+ let deletedRecord = recordsByIdentityPath.get(filePath)
161
+ if (deletedRecord) {
162
+ clearTracking(deletedRecord)
163
+ }
164
+ }
165
+ },
166
+
167
+ invalidateAll() {
168
+ for (let record of recordsByIdentityPath.values()) {
169
+ invalidateRecord(record, { retainStale: false })
170
+ }
171
+ },
172
+ }
173
+
174
+ function getOrCreateMutableRecord(identityPath: string): MutableModuleRecord {
175
+ let existing = recordsByIdentityPath.get(identityPath)
176
+ if (existing) return existing
177
+
178
+ let record: MutableModuleRecord = {
179
+ identityPath,
180
+ invalidationVersion: 0,
181
+ trackedFiles: new Set(),
182
+ trackedResolutions: [],
183
+ }
184
+ recordsByIdentityPath.set(identityPath, record)
185
+ return record
186
+ }
187
+
188
+ function invalidateRecord(record: MutableModuleRecord, options: { retainStale: boolean }) {
189
+ if (!options.retainStale) {
190
+ record.staleEmitted = undefined
191
+ record.staleEmittedSnapshot = undefined
192
+ } else if (record.emitted && record.emittedSnapshot) {
193
+ record.staleEmitted = record.emitted
194
+ record.staleEmittedSnapshot = record.emittedSnapshot
195
+ } else if (!record.staleEmitted || !record.staleEmittedSnapshot) {
196
+ record.staleEmitted = undefined
197
+ record.staleEmittedSnapshot = undefined
198
+ }
199
+
200
+ record.emitted = undefined
201
+ record.emittedSnapshot = undefined
202
+ record.resolved = undefined
203
+ record.transformed = undefined
204
+ record.invalidationVersion += 1
205
+ }
206
+
207
+ function setTracking(
208
+ record: MutableModuleRecord,
209
+ tracking: {
210
+ trackedFiles: readonly string[]
211
+ trackedResolutions: readonly TrackedResolution[]
212
+ },
213
+ ) {
214
+ let previousWatchedDirectories = getWatchedDirectories(record)
215
+ removeIndexes(record)
216
+
217
+ record.trackedFiles = new Set(tracking.trackedFiles)
218
+ record.trackedResolutions = [...tracking.trackedResolutions]
219
+
220
+ for (let trackedFile of record.trackedFiles) {
221
+ addToIndexedSet(recordsByTrackedFile, trackedFile, record.identityPath)
222
+ }
223
+
224
+ let nextWatchedDirectories = getWatchedDirectories(record)
225
+ let delta = updateWatchDirectoryRefCounts(previousWatchedDirectories, nextWatchedDirectories)
226
+ emitWatchDirectoryDelta(delta)
227
+ }
228
+
229
+ function clearTracking(record: MutableModuleRecord) {
230
+ setTracking(record, {
231
+ trackedFiles: [],
232
+ trackedResolutions: [],
233
+ })
234
+ }
235
+
236
+ function removeIndexes(record: MutableModuleRecord) {
237
+ for (let trackedFile of record.trackedFiles) {
238
+ removeFromIndexedSet(recordsByTrackedFile, trackedFile, record.identityPath)
239
+ }
240
+ }
241
+
242
+ function updateWatchDirectoryRefCounts(
243
+ previousWatchedDirectories: ReadonlySet<string>,
244
+ nextWatchedDirectories: ReadonlySet<string>,
245
+ ): { add: string[]; remove: string[] } {
246
+ let add: string[] = []
247
+ let remove: string[] = []
248
+
249
+ for (let directory of previousWatchedDirectories) {
250
+ if (nextWatchedDirectories.has(directory)) continue
251
+ let previousCount = watchDirectoryRefCountByPath.get(directory)
252
+ if (!previousCount) continue
253
+ if (previousCount === 1) {
254
+ watchDirectoryRefCountByPath.delete(directory)
255
+ remove.push(directory)
256
+ } else {
257
+ watchDirectoryRefCountByPath.set(directory, previousCount - 1)
258
+ }
259
+ }
260
+
261
+ for (let directory of nextWatchedDirectories) {
262
+ if (previousWatchedDirectories.has(directory)) continue
263
+ let previousCount = watchDirectoryRefCountByPath.get(directory) ?? 0
264
+ watchDirectoryRefCountByPath.set(directory, previousCount + 1)
265
+ if (previousCount === 0) {
266
+ add.push(directory)
267
+ }
268
+ }
269
+
270
+ return { add, remove }
271
+ }
272
+
273
+ function emitWatchDirectoryDelta(delta: { add: string[]; remove: string[] }): void {
274
+ if (!options.onWatchDirectoriesChange) return
275
+ if (delta.add.length === 0 && delta.remove.length === 0) return
276
+ options.onWatchDirectoriesChange(delta)
277
+ }
278
+ }
279
+
280
+ function addToIndexedSet(map: Map<string, Set<string>>, key: string, value: string) {
281
+ let existing = map.get(key) ?? new Set<string>()
282
+ existing.add(value)
283
+ map.set(key, existing)
284
+ }
285
+
286
+ function removeFromIndexedSet(map: Map<string, Set<string>>, key: string, value: string) {
287
+ let existing = map.get(key)
288
+ if (!existing) return
289
+ existing.delete(value)
290
+ if (existing.size === 0) {
291
+ map.delete(key)
292
+ }
293
+ }
294
+
295
+ function mayAffectTrackedResolution(
296
+ trackedResolution: TrackedResolution,
297
+ filePath: string,
298
+ ): boolean {
299
+ return (
300
+ trackedResolution.candidatePaths.includes(filePath) ||
301
+ trackedResolution.candidatePrefixes.some((prefix) => filePath.startsWith(prefix))
302
+ )
303
+ }
304
+
305
+ function getWatchedDirectories(record: {
306
+ trackedFiles: ReadonlySet<string>
307
+ trackedResolutions: readonly TrackedResolution[]
308
+ }): Set<string> {
309
+ let watchedDirectories = new Set<string>()
310
+
311
+ for (let trackedFile of record.trackedFiles) {
312
+ watchedDirectories.add(getFilePathDirectory(trackedFile))
313
+ }
314
+
315
+ for (let trackedResolution of record.trackedResolutions) {
316
+ for (let candidatePath of trackedResolution.candidatePaths) {
317
+ watchedDirectories.add(getFilePathDirectory(candidatePath))
318
+ }
319
+
320
+ for (let candidatePrefix of trackedResolution.candidatePrefixes) {
321
+ let directoryPath = candidatePrefix.replace(/\/+$/, '') || '/'
322
+ watchedDirectories.add(directoryPath)
323
+ }
324
+ }
325
+
326
+ return watchedDirectories
327
+ }