@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,230 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
4
+ import { normalizeFilePath } from "../paths.js";
5
+ export const resolverExtensionAlias = {
6
+ '.js': ['.js', '.ts', '.tsx', '.jsx'],
7
+ '.jsx': ['.jsx', '.tsx'],
8
+ '.mjs': ['.mjs', '.mts'],
9
+ };
10
+ export const resolverExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs'];
11
+ export const supportedScriptExtensions = ['.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs'];
12
+ const supportedScriptExtensionSet = new Set(supportedScriptExtensions);
13
+ export async function resolveModule(record, transformed, args) {
14
+ let trackedFiles = new Set(transformed.trackedFiles);
15
+ let trackedResolutions = [];
16
+ let resolvedImports;
17
+ try {
18
+ resolvedImports =
19
+ transformed.unresolvedImports.length > 0
20
+ ? await batchResolveSpecifiers(getUniqueSpecifiers(transformed.unresolvedImports), transformed.resolvedPath, args.resolverFactory)
21
+ : new Map();
22
+ }
23
+ catch (error) {
24
+ return failResolve(error, trackedFiles, trackedResolutions, transformed.resolvedPath, {
25
+ isWatchIgnored: args.isWatchIgnored,
26
+ });
27
+ }
28
+ let importsWithPaths = [];
29
+ let deps = new Set();
30
+ for (let unresolved of transformed.unresolvedImports) {
31
+ let trackedResolution = getTrackedRelativeImportResolution(transformed.importerDir, unresolved.specifier, args.isWatchIgnored);
32
+ let resolvedSpec = resolvedImports.get(unresolved.specifier);
33
+ if (!resolvedSpec?.absolutePath) {
34
+ return failResolve(createAssetServerCompilationError(`Failed to resolve import "${unresolved.specifier}" in ${transformed.resolvedPath}. ` +
35
+ `Ensure it resolves to a file within the configured asset server fileMap, or mark it as external.`, {
36
+ code: 'IMPORT_RESOLUTION_FAILED',
37
+ }), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
38
+ }
39
+ let resolvedImport = args.resolveModulePath(resolvedSpec.absolutePath);
40
+ if (!resolvedImport) {
41
+ return failResolve(createAssetServerCompilationError(`Resolved import "${unresolved.specifier}" in ${transformed.resolvedPath} is not a supported script module. ` +
42
+ `Supported extensions are ${supportedScriptExtensions.join(', ')}.`, {
43
+ code: 'IMPORT_NOT_SUPPORTED',
44
+ }), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
45
+ }
46
+ if (!args.isAllowed(resolvedImport.identityPath)) {
47
+ return failResolve(createAssetServerCompilationError(`Resolved import "${unresolved.specifier}" in ${transformed.resolvedPath} is not allowed by the asset server allow/deny configuration. ` +
48
+ `Add a matching allow rule, remove a conflicting deny rule, or mark this import as external.`, {
49
+ code: 'IMPORT_NOT_ALLOWED',
50
+ }), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
51
+ }
52
+ let stableUrlPathname = args.routes.toUrlPathname(resolvedImport.identityPath);
53
+ if (!stableUrlPathname) {
54
+ return failResolve(createAssetServerCompilationError(`Resolved import "${unresolved.specifier}" in ${transformed.resolvedPath} is outside all configured fileMap entries. ` +
55
+ `Add a matching fileMap entry for this file path, or mark this import as external.`, {
56
+ code: 'IMPORT_OUTSIDE_FILE_MAP',
57
+ }), trackedFiles, trackedResolutions, transformed.resolvedPath, { isWatchIgnored: args.isWatchIgnored, trackedResolution });
58
+ }
59
+ deps.add(resolvedImport.identityPath);
60
+ if (transformed.packageSpecifiers.includes(unresolved.specifier)) {
61
+ let packageJsonPath = resolvedSpec.packageJsonPath ?? findNearestPackageJsonPath(resolvedImport.resolvedPath);
62
+ if (packageJsonPath && !args.isWatchIgnored(packageJsonPath)) {
63
+ trackedFiles.add(packageJsonPath);
64
+ }
65
+ }
66
+ if (trackedResolution) {
67
+ trackedResolutions.push({
68
+ ...trackedResolution,
69
+ resolvedIdentityPath: resolvedImport.identityPath,
70
+ });
71
+ }
72
+ importsWithPaths.push({
73
+ depPath: resolvedImport.identityPath,
74
+ end: unresolved.end,
75
+ quote: unresolved.quote,
76
+ start: unresolved.start,
77
+ });
78
+ }
79
+ return {
80
+ ok: true,
81
+ value: {
82
+ deps: [...deps],
83
+ fingerprint: transformed.fingerprint,
84
+ identityPath: record.identityPath,
85
+ imports: importsWithPaths,
86
+ trackedFiles: [...trackedFiles],
87
+ trackedResolutions,
88
+ rawCode: transformed.rawCode,
89
+ resolvedPath: transformed.resolvedPath,
90
+ sourceMap: transformed.sourceMap,
91
+ stableUrlPathname: transformed.stableUrlPathname,
92
+ },
93
+ };
94
+ }
95
+ function findNearestPackageJsonPath(filePath) {
96
+ let directory = path.dirname(filePath);
97
+ while (true) {
98
+ let packageJsonPath = path.join(directory, 'package.json');
99
+ if (fs.existsSync(packageJsonPath)) {
100
+ return normalizeFilePath(packageJsonPath);
101
+ }
102
+ let parentDirectory = path.dirname(directory);
103
+ if (parentDirectory === directory)
104
+ return null;
105
+ directory = parentDirectory;
106
+ }
107
+ }
108
+ function isRelativeImportSpecifier(specifier) {
109
+ return specifier.startsWith('./') || specifier.startsWith('../');
110
+ }
111
+ function getTrackedRelativeImportResolution(importerDir, specifier, isWatchIgnored) {
112
+ if (!isRelativeImportSpecifier(specifier))
113
+ return null;
114
+ let candidatePath = resolveCandidateBasePath(importerDir, specifier);
115
+ let candidatePrefixes = [`${candidatePath}/`].filter((candidatePrefix) => !isWatchIgnored(candidatePrefix.replace(/\/+$/, '') || '/'));
116
+ let extension = path.extname(specifier);
117
+ if (extension === '') {
118
+ let candidatePaths = [
119
+ candidatePath,
120
+ ...supportedScriptExtensions.map((candidateExtension) => `${candidatePath}${candidateExtension}`),
121
+ ].filter((candidatePath) => !isWatchIgnored(candidatePath));
122
+ return candidatePaths.length === 0 && candidatePrefixes.length === 0
123
+ ? null
124
+ : {
125
+ candidatePaths,
126
+ candidatePrefixes,
127
+ specifier,
128
+ };
129
+ }
130
+ let candidateExtensions = resolverExtensionAlias[extension];
131
+ if (!candidateExtensions && !supportedScriptExtensionSet.has(extension)) {
132
+ let candidatePaths = [
133
+ candidatePath,
134
+ ...supportedScriptExtensions.map((candidateExtension) => `${candidatePath}${candidateExtension}`),
135
+ ].filter((candidatePath) => !isWatchIgnored(candidatePath));
136
+ return candidatePaths.length === 0 && candidatePrefixes.length === 0
137
+ ? null
138
+ : {
139
+ candidatePaths,
140
+ candidatePrefixes,
141
+ specifier,
142
+ };
143
+ }
144
+ if (!candidateExtensions)
145
+ return null;
146
+ let candidatePaths = [
147
+ candidatePath,
148
+ ...candidateExtensions.map((candidateExtension) => `${candidatePath.slice(0, candidatePath.length - extension.length)}${candidateExtension}`),
149
+ ].filter((candidatePath) => !isWatchIgnored(candidatePath));
150
+ return candidatePaths.length === 0 && candidatePrefixes.length === 0
151
+ ? null
152
+ : {
153
+ candidatePaths,
154
+ candidatePrefixes,
155
+ specifier,
156
+ };
157
+ }
158
+ function resolveCandidateBasePath(importerDir, specifier) {
159
+ return normalizeFilePath(path.resolve(importerDir, specifier));
160
+ }
161
+ async function batchResolveSpecifiers(specifiers, importerPath, resolverFactory) {
162
+ let resolvedBySpecifier = new Map();
163
+ if (specifiers.length === 0)
164
+ return resolvedBySpecifier;
165
+ try {
166
+ for (let specifier of specifiers) {
167
+ let resolutionResult = await resolverFactory.resolveFileAsync(importerPath, specifier);
168
+ if (resolutionResult.error) {
169
+ throw createAssetServerCompilationError(`Failed to resolve import "${specifier}" in ${importerPath}. ` +
170
+ `Ensure it resolves to a file within the configured asset server fileMap, or mark it as external.`, {
171
+ code: 'IMPORT_RESOLUTION_FAILED',
172
+ });
173
+ }
174
+ resolvedBySpecifier.set(specifier, {
175
+ absolutePath: resolutionResult.path && path.isAbsolute(resolutionResult.path)
176
+ ? normalizeFilePath(resolutionResult.path)
177
+ : null,
178
+ packageJsonPath: resolutionResult.packageJsonPath
179
+ ? normalizeFilePath(resolutionResult.packageJsonPath)
180
+ : null,
181
+ specifier,
182
+ });
183
+ }
184
+ }
185
+ catch (error) {
186
+ if (isAssetServerCompilationError(error) && error.code === 'IMPORT_RESOLUTION_FAILED') {
187
+ throw error;
188
+ }
189
+ throw createAssetServerCompilationError(`Failed to resolve imports in ${importerPath}. ${formatUnknownError(error)}`, {
190
+ cause: error,
191
+ code: 'IMPORT_RESOLUTION_FAILED',
192
+ });
193
+ }
194
+ return resolvedBySpecifier;
195
+ }
196
+ function getUniqueSpecifiers(unresolvedImports) {
197
+ return [...new Set(unresolvedImports.map((unresolved) => unresolved.specifier))];
198
+ }
199
+ function formatUnknownError(error) {
200
+ return error instanceof Error ? error.message : String(error);
201
+ }
202
+ function failResolve(error, trackedFiles, trackedResolutions, importerPath, options = {}) {
203
+ return {
204
+ ok: false,
205
+ error: toResolveError(error, importerPath),
206
+ tracking: {
207
+ trackedFiles: [...trackedFiles],
208
+ trackedResolutions: appendFailedTrackedResolution(trackedResolutions, options.trackedResolution),
209
+ },
210
+ };
211
+ }
212
+ function appendFailedTrackedResolution(trackedResolutions, trackedResolution) {
213
+ if (trackedResolution == null)
214
+ return [...trackedResolutions];
215
+ return [
216
+ ...trackedResolutions,
217
+ {
218
+ ...trackedResolution,
219
+ resolvedIdentityPath: null,
220
+ },
221
+ ];
222
+ }
223
+ function toResolveError(error, importerPath) {
224
+ if (isAssetServerCompilationError(error))
225
+ return error;
226
+ return createAssetServerCompilationError(`Failed to resolve imports in ${importerPath}. ${formatUnknownError(error)}`, {
227
+ cause: error,
228
+ code: 'IMPORT_RESOLUTION_FAILED',
229
+ });
230
+ }
@@ -0,0 +1,40 @@
1
+ import type { EmittedModule } from './emit.ts';
2
+ import type { ResolutionFailureState, ResolvedModule, TrackedResolution } from './resolve.ts';
3
+ import type { TransformFailureState, TransformedModule } from './transform.ts';
4
+ export type ModuleWatchEvent = 'change' | 'add' | 'unlink';
5
+ export type FileSnapshot = {
6
+ mtimeNs: bigint;
7
+ size: bigint;
8
+ };
9
+ export type ModuleSnapshot = ReadonlyMap<string, FileSnapshot>;
10
+ type ModuleRecordState = {
11
+ identityPath: string;
12
+ invalidationVersion: number;
13
+ transformed?: TransformedModule;
14
+ resolved?: ResolvedModule;
15
+ emitted?: EmittedModule;
16
+ emittedSnapshot?: ModuleSnapshot;
17
+ staleEmitted?: EmittedModule;
18
+ staleEmittedSnapshot?: ModuleSnapshot;
19
+ trackedFiles: ReadonlySet<string>;
20
+ trackedResolutions: readonly TrackedResolution[];
21
+ };
22
+ export type ModuleRecord = Readonly<ModuleRecordState>;
23
+ type ModuleStore = {
24
+ get(identityPath: string): ModuleRecord;
25
+ setTransformFailure(identityPath: string, failure: TransformFailureState): void;
26
+ setTransformed(identityPath: string, transformed: TransformedModule): void;
27
+ setResolved(identityPath: string, resolved: ResolvedModule): void;
28
+ setResolveFailure(identityPath: string, failure: ResolutionFailureState): void;
29
+ setEmitted(identityPath: string, emitted: EmittedModule, snapshot: ModuleSnapshot | null): void;
30
+ invalidateForFileEvent(filePath: string, event: ModuleWatchEvent): void;
31
+ invalidateAll(): void;
32
+ };
33
+ export declare function createModuleStore(options?: {
34
+ onWatchDirectoriesChange?: (delta: {
35
+ add: string[];
36
+ remove: string[];
37
+ }) => void;
38
+ }): ModuleStore;
39
+ export {};
40
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAE9E,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,CAAA;AAE1D,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;AAE9D,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,YAAY,CAAC,EAAE,aAAa,CAAA;IAC5B,oBAAoB,CAAC,EAAE,cAAc,CAAA;IACrC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,kBAAkB,EAAE,SAAS,iBAAiB,EAAE,CAAA;CACjD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,iBAAiB,CAAC,CAAA;AAetD,KAAK,WAAW,GAAG;IACjB,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAAA;IACvC,mBAAmB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAA;IAC/E,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1E,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAA;IACjE,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAA;IAC9E,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAAA;IAC/F,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACvE,aAAa,IAAI,IAAI,CAAA;CACtB,CAAA;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE;IACP,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAA;CAC3E,GACL,WAAW,CA4Nb"}
@@ -0,0 +1,228 @@
1
+ import { getFilePathDirectory } from "../paths.js";
2
+ export function createModuleStore(options = {}) {
3
+ let recordsByIdentityPath = new Map();
4
+ let recordsByTrackedFile = new Map();
5
+ let watchDirectoryRefCountByPath = new Map();
6
+ return {
7
+ get(identityPath) {
8
+ let existing = recordsByIdentityPath.get(identityPath);
9
+ if (existing)
10
+ return existing;
11
+ let record = {
12
+ identityPath,
13
+ invalidationVersion: 0,
14
+ trackedFiles: new Set(),
15
+ trackedResolutions: [],
16
+ };
17
+ recordsByIdentityPath.set(identityPath, record);
18
+ return record;
19
+ },
20
+ setTransformFailure(identityPath, failure) {
21
+ let record = getOrCreateMutableRecord(identityPath);
22
+ record.transformed = undefined;
23
+ record.resolved = undefined;
24
+ record.emitted = undefined;
25
+ record.emittedSnapshot = undefined;
26
+ record.staleEmitted = undefined;
27
+ record.staleEmittedSnapshot = undefined;
28
+ setTracking(record, {
29
+ trackedFiles: failure.trackedFiles,
30
+ trackedResolutions: [],
31
+ });
32
+ },
33
+ setTransformed(identityPath, transformed) {
34
+ let record = getOrCreateMutableRecord(identityPath);
35
+ record.transformed = transformed;
36
+ record.resolved = undefined;
37
+ record.emitted = undefined;
38
+ record.emittedSnapshot = undefined;
39
+ record.staleEmitted = undefined;
40
+ record.staleEmittedSnapshot = undefined;
41
+ setTracking(record, {
42
+ trackedFiles: transformed.trackedFiles,
43
+ trackedResolutions: [],
44
+ });
45
+ },
46
+ setResolved(identityPath, resolved) {
47
+ let record = getOrCreateMutableRecord(identityPath);
48
+ record.resolved = resolved;
49
+ record.emitted = undefined;
50
+ record.emittedSnapshot = undefined;
51
+ record.staleEmitted = undefined;
52
+ record.staleEmittedSnapshot = undefined;
53
+ setTracking(record, {
54
+ trackedFiles: resolved.trackedFiles,
55
+ trackedResolutions: resolved.trackedResolutions,
56
+ });
57
+ },
58
+ setResolveFailure(identityPath, failure) {
59
+ let record = getOrCreateMutableRecord(identityPath);
60
+ record.resolved = undefined;
61
+ record.emitted = undefined;
62
+ record.emittedSnapshot = undefined;
63
+ record.staleEmitted = undefined;
64
+ record.staleEmittedSnapshot = undefined;
65
+ setTracking(record, {
66
+ trackedFiles: failure.trackedFiles,
67
+ trackedResolutions: failure.trackedResolutions,
68
+ });
69
+ },
70
+ setEmitted(identityPath, emitted, snapshot) {
71
+ let record = getOrCreateMutableRecord(identityPath);
72
+ record.emitted = emitted;
73
+ record.emittedSnapshot = snapshot ?? undefined;
74
+ record.staleEmitted = undefined;
75
+ record.staleEmittedSnapshot = undefined;
76
+ },
77
+ invalidateForFileEvent(filePath, event) {
78
+ let affected = new Set(recordsByTrackedFile.get(filePath) ?? []);
79
+ if (event !== 'change') {
80
+ for (let record of recordsByIdentityPath.values()) {
81
+ if (record.trackedResolutions.some((tracked) => mayAffectTrackedResolution(tracked, filePath))) {
82
+ affected.add(record.identityPath);
83
+ }
84
+ }
85
+ }
86
+ for (let identityPath of affected) {
87
+ let record = recordsByIdentityPath.get(identityPath);
88
+ if (record)
89
+ invalidateRecord(record, { retainStale: event === 'change' });
90
+ }
91
+ if (event === 'unlink') {
92
+ let deletedRecord = recordsByIdentityPath.get(filePath);
93
+ if (deletedRecord) {
94
+ clearTracking(deletedRecord);
95
+ }
96
+ }
97
+ },
98
+ invalidateAll() {
99
+ for (let record of recordsByIdentityPath.values()) {
100
+ invalidateRecord(record, { retainStale: false });
101
+ }
102
+ },
103
+ };
104
+ function getOrCreateMutableRecord(identityPath) {
105
+ let existing = recordsByIdentityPath.get(identityPath);
106
+ if (existing)
107
+ return existing;
108
+ let record = {
109
+ identityPath,
110
+ invalidationVersion: 0,
111
+ trackedFiles: new Set(),
112
+ trackedResolutions: [],
113
+ };
114
+ recordsByIdentityPath.set(identityPath, record);
115
+ return record;
116
+ }
117
+ function invalidateRecord(record, options) {
118
+ if (!options.retainStale) {
119
+ record.staleEmitted = undefined;
120
+ record.staleEmittedSnapshot = undefined;
121
+ }
122
+ else if (record.emitted && record.emittedSnapshot) {
123
+ record.staleEmitted = record.emitted;
124
+ record.staleEmittedSnapshot = record.emittedSnapshot;
125
+ }
126
+ else if (!record.staleEmitted || !record.staleEmittedSnapshot) {
127
+ record.staleEmitted = undefined;
128
+ record.staleEmittedSnapshot = undefined;
129
+ }
130
+ record.emitted = undefined;
131
+ record.emittedSnapshot = undefined;
132
+ record.resolved = undefined;
133
+ record.transformed = undefined;
134
+ record.invalidationVersion += 1;
135
+ }
136
+ function setTracking(record, tracking) {
137
+ let previousWatchedDirectories = getWatchedDirectories(record);
138
+ removeIndexes(record);
139
+ record.trackedFiles = new Set(tracking.trackedFiles);
140
+ record.trackedResolutions = [...tracking.trackedResolutions];
141
+ for (let trackedFile of record.trackedFiles) {
142
+ addToIndexedSet(recordsByTrackedFile, trackedFile, record.identityPath);
143
+ }
144
+ let nextWatchedDirectories = getWatchedDirectories(record);
145
+ let delta = updateWatchDirectoryRefCounts(previousWatchedDirectories, nextWatchedDirectories);
146
+ emitWatchDirectoryDelta(delta);
147
+ }
148
+ function clearTracking(record) {
149
+ setTracking(record, {
150
+ trackedFiles: [],
151
+ trackedResolutions: [],
152
+ });
153
+ }
154
+ function removeIndexes(record) {
155
+ for (let trackedFile of record.trackedFiles) {
156
+ removeFromIndexedSet(recordsByTrackedFile, trackedFile, record.identityPath);
157
+ }
158
+ }
159
+ function updateWatchDirectoryRefCounts(previousWatchedDirectories, nextWatchedDirectories) {
160
+ let add = [];
161
+ let remove = [];
162
+ for (let directory of previousWatchedDirectories) {
163
+ if (nextWatchedDirectories.has(directory))
164
+ continue;
165
+ let previousCount = watchDirectoryRefCountByPath.get(directory);
166
+ if (!previousCount)
167
+ continue;
168
+ if (previousCount === 1) {
169
+ watchDirectoryRefCountByPath.delete(directory);
170
+ remove.push(directory);
171
+ }
172
+ else {
173
+ watchDirectoryRefCountByPath.set(directory, previousCount - 1);
174
+ }
175
+ }
176
+ for (let directory of nextWatchedDirectories) {
177
+ if (previousWatchedDirectories.has(directory))
178
+ continue;
179
+ let previousCount = watchDirectoryRefCountByPath.get(directory) ?? 0;
180
+ watchDirectoryRefCountByPath.set(directory, previousCount + 1);
181
+ if (previousCount === 0) {
182
+ add.push(directory);
183
+ }
184
+ }
185
+ return { add, remove };
186
+ }
187
+ function emitWatchDirectoryDelta(delta) {
188
+ if (!options.onWatchDirectoriesChange)
189
+ return;
190
+ if (delta.add.length === 0 && delta.remove.length === 0)
191
+ return;
192
+ options.onWatchDirectoriesChange(delta);
193
+ }
194
+ }
195
+ function addToIndexedSet(map, key, value) {
196
+ let existing = map.get(key) ?? new Set();
197
+ existing.add(value);
198
+ map.set(key, existing);
199
+ }
200
+ function removeFromIndexedSet(map, key, value) {
201
+ let existing = map.get(key);
202
+ if (!existing)
203
+ return;
204
+ existing.delete(value);
205
+ if (existing.size === 0) {
206
+ map.delete(key);
207
+ }
208
+ }
209
+ function mayAffectTrackedResolution(trackedResolution, filePath) {
210
+ return (trackedResolution.candidatePaths.includes(filePath) ||
211
+ trackedResolution.candidatePrefixes.some((prefix) => filePath.startsWith(prefix)));
212
+ }
213
+ function getWatchedDirectories(record) {
214
+ let watchedDirectories = new Set();
215
+ for (let trackedFile of record.trackedFiles) {
216
+ watchedDirectories.add(getFilePathDirectory(trackedFile));
217
+ }
218
+ for (let trackedResolution of record.trackedResolutions) {
219
+ for (let candidatePath of trackedResolution.candidatePaths) {
220
+ watchedDirectories.add(getFilePathDirectory(candidatePath));
221
+ }
222
+ for (let candidatePrefix of trackedResolution.candidatePrefixes) {
223
+ let directoryPath = candidatePrefix.replace(/\/+$/, '') || '/';
224
+ watchedDirectories.add(directoryPath);
225
+ }
226
+ }
227
+ return watchedDirectories;
228
+ }
@@ -0,0 +1,62 @@
1
+ import type { TsConfigJsonResolved } from 'get-tsconfig';
2
+ import type { AssetServerCompilationError } from '../compilation-error.ts';
3
+ import type { CompiledRoutes } from '../routes.ts';
4
+ import type { ScriptsTarget } from '../asset-server.ts';
5
+ import type { ModuleRecord } from './store.ts';
6
+ export type ResolveModuleResult = {
7
+ identityPath: string;
8
+ resolvedPath: string;
9
+ };
10
+ type UnresolvedImport = {
11
+ end: number;
12
+ quote?: '"' | "'" | '`';
13
+ specifier: string;
14
+ start: number;
15
+ };
16
+ export type TransformedModule = {
17
+ fingerprint: string | null;
18
+ identityPath: string;
19
+ importerDir: string;
20
+ packageSpecifiers: string[];
21
+ rawCode: string;
22
+ resolvedPath: string;
23
+ sourceMap: string | null;
24
+ stableUrlPathname: string;
25
+ trackedFiles: string[];
26
+ unresolvedImports: UnresolvedImport[];
27
+ };
28
+ export type TransformFailureState = {
29
+ trackedFiles: readonly string[];
30
+ };
31
+ type TransformResult = {
32
+ ok: true;
33
+ value: TransformedModule;
34
+ } | ({
35
+ ok: false;
36
+ error: AssetServerCompilationError;
37
+ } & TransformFailureState);
38
+ type TsconfigTransformOptions = {
39
+ trackedFiles: string[];
40
+ tsconfigRaw?: TsConfigJsonResolved;
41
+ };
42
+ type TsconfigTransformOptionsResolver = ReturnType<typeof createTsconfigTransformOptionsResolver>;
43
+ export type TransformArgs = {
44
+ buildId: string | null;
45
+ define: Record<string, string> | null;
46
+ externalSet: ReadonlySet<string>;
47
+ isWatchIgnored(filePath: string): boolean;
48
+ minify: boolean;
49
+ resolveActualPath(identityPath: string): string | null;
50
+ routes: CompiledRoutes;
51
+ sourceMapSourcePaths: 'absolute' | 'url';
52
+ sourceMaps: 'external' | 'inline' | null;
53
+ target: ScriptsTarget | null;
54
+ tsconfigTransformOptionsResolver: TsconfigTransformOptionsResolver;
55
+ };
56
+ export declare function createTsconfigTransformOptionsResolver(): {
57
+ clear(): void;
58
+ getTransformOptions(filePath: string, isWatchIgnored: (filePath: string) => boolean): TsconfigTransformOptions;
59
+ };
60
+ export declare function transformModule(record: ModuleRecord, args: TransformArgs): Promise<TransformResult>;
61
+ export {};
62
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/lib/scripts/transform.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAS,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAQ/D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAG1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA6B9C,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,KAAK,gBAAgB,GAAG;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,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;IACtB,iBAAiB,EAAE,gBAAgB,EAAE,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,KAAK,eAAe,GAChB;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,iBAAiB,CAAA;CACzB,GACD,CAAC;IACC,EAAE,EAAE,KAAK,CAAA;IACT,KAAK,EAAE,2BAA2B,CAAA;CACnC,GAAG,qBAAqB,CAAC,CAAA;AAE9B,KAAK,wBAAwB,GAAG;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,WAAW,CAAC,EAAE,oBAAoB,CAAA;CACnC,CAAA;AAED,KAAK,gCAAgC,GAAG,UAAU,CAAC,OAAO,sCAAsC,CAAC,CAAA;AAEjG,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IACrC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAChC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,MAAM,EAAE,OAAO,CAAA;IACf,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACtD,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB,EAAE,UAAU,GAAG,KAAK,CAAA;IACxC,UAAU,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAAA;IACxC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,gCAAgC,EAAE,gCAAgC,CAAA;CACnE,CAAA;AAED,wBAAgB,sCAAsC;;;EAkCrD;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,eAAe,CAAC,CAiH1B"}