@remix-run/assets 0.0.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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +325 -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 +139 -0
  10. package/dist/lib/asset-server.d.ts.map +1 -0
  11. package/dist/lib/asset-server.js +338 -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 +44 -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/module-store.d.ts +41 -0
  22. package/dist/lib/module-store.d.ts.map +1 -0
  23. package/dist/lib/module-store.js +230 -0
  24. package/dist/lib/paths.d.ts +8 -0
  25. package/dist/lib/paths.d.ts.map +1 -0
  26. package/dist/lib/paths.js +50 -0
  27. package/dist/lib/routes.d.ts +13 -0
  28. package/dist/lib/routes.d.ts.map +1 -0
  29. package/dist/lib/routes.js +94 -0
  30. package/dist/lib/scripts/cjs-check.d.ts +3 -0
  31. package/dist/lib/scripts/cjs-check.d.ts.map +1 -0
  32. package/dist/lib/scripts/cjs-check.js +398 -0
  33. package/dist/lib/scripts/compiler.d.ts +62 -0
  34. package/dist/lib/scripts/compiler.d.ts.map +1 -0
  35. package/dist/lib/scripts/compiler.js +439 -0
  36. package/dist/lib/scripts/emit.d.ts +25 -0
  37. package/dist/lib/scripts/emit.d.ts.map +1 -0
  38. package/dist/lib/scripts/emit.js +63 -0
  39. package/dist/lib/scripts/resolve.d.ts +50 -0
  40. package/dist/lib/scripts/resolve.d.ts.map +1 -0
  41. package/dist/lib/scripts/resolve.js +236 -0
  42. package/dist/lib/scripts/transform.d.ts +64 -0
  43. package/dist/lib/scripts/transform.d.ts.map +1 -0
  44. package/dist/lib/scripts/transform.js +373 -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 +62 -0
  48. package/dist/lib/styles/compiler.d.ts +52 -0
  49. package/dist/lib/styles/compiler.d.ts.map +1 -0
  50. package/dist/lib/styles/compiler.js +272 -0
  51. package/dist/lib/styles/emit.d.ts +25 -0
  52. package/dist/lib/styles/emit.d.ts.map +1 -0
  53. package/dist/lib/styles/emit.js +78 -0
  54. package/dist/lib/styles/resolve.d.ts +48 -0
  55. package/dist/lib/styles/resolve.d.ts.map +1 -0
  56. package/dist/lib/styles/resolve.js +188 -0
  57. package/dist/lib/styles/transform.d.ts +47 -0
  58. package/dist/lib/styles/transform.d.ts.map +1 -0
  59. package/dist/lib/styles/transform.js +131 -0
  60. package/dist/lib/target.d.ts +21 -0
  61. package/dist/lib/target.d.ts.map +1 -0
  62. package/dist/lib/target.js +127 -0
  63. package/dist/lib/watch.d.ts +22 -0
  64. package/dist/lib/watch.d.ts.map +1 -0
  65. package/dist/lib/watch.js +96 -0
  66. package/package.json +55 -12
  67. package/src/assets.ts +2 -0
  68. package/src/lib/access.ts +24 -0
  69. package/src/lib/asset-server.ts +537 -0
  70. package/src/lib/compilation-error.ts +61 -0
  71. package/src/lib/file-matcher.ts +63 -0
  72. package/src/lib/fingerprint.ts +65 -0
  73. package/src/lib/module-store.ts +340 -0
  74. package/src/lib/paths.ts +66 -0
  75. package/src/lib/routes.ts +164 -0
  76. package/src/lib/scripts/cjs-check.ts +476 -0
  77. package/src/lib/scripts/compiler.ts +640 -0
  78. package/src/lib/scripts/emit.ts +122 -0
  79. package/src/lib/scripts/resolve.ts +433 -0
  80. package/src/lib/scripts/transform.ts +609 -0
  81. package/src/lib/source-maps.ts +75 -0
  82. package/src/lib/styles/compiler.ts +400 -0
  83. package/src/lib/styles/emit.ts +137 -0
  84. package/src/lib/styles/resolve.ts +316 -0
  85. package/src/lib/styles/transform.ts +226 -0
  86. package/src/lib/target.ts +196 -0
  87. package/src/lib/watch.ts +136 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-maps.d.ts","sourceRoot":"","sources":["../../src/lib/source-maps.ts"],"names":[],"mappings":"AAIA,wBAAgB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,MAAM,CA2C9F;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,EACzB,oBAAoB,EAAE,UAAU,GAAG,KAAK,EACxC,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CASR;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ9D"}
@@ -0,0 +1,62 @@
1
+ import { SourceMapConsumer, SourceMapGenerator } from 'source-map-js';
2
+ import { normalizeFilePath } from "./paths.js";
3
+ export function composeSourceMaps(rewriteSourceMap, transformSourceMap) {
4
+ let rewriteConsumer = new SourceMapConsumer(JSON.parse(rewriteSourceMap));
5
+ let transformConsumer = new SourceMapConsumer(JSON.parse(transformSourceMap));
6
+ let generator = new SourceMapGenerator();
7
+ rewriteConsumer.eachMapping((mapping) => {
8
+ if (mapping.originalLine == null ||
9
+ mapping.originalColumn == null ||
10
+ mapping.generatedLine == null ||
11
+ mapping.generatedColumn == null) {
12
+ return;
13
+ }
14
+ let original = transformConsumer.originalPositionFor({
15
+ line: mapping.originalLine,
16
+ column: mapping.originalColumn,
17
+ });
18
+ if (original.line == null || original.column == null || original.source == null)
19
+ return;
20
+ generator.addMapping({
21
+ generated: {
22
+ line: mapping.generatedLine,
23
+ column: mapping.generatedColumn,
24
+ },
25
+ original: {
26
+ line: original.line,
27
+ column: original.column,
28
+ },
29
+ source: original.source,
30
+ name: original.name ?? mapping.name ?? undefined,
31
+ });
32
+ });
33
+ for (let source of transformConsumer.sources) {
34
+ let sourceContent = transformConsumer.sourceContentFor(source, true);
35
+ if (sourceContent !== null) {
36
+ generator.setSourceContent(source, sourceContent);
37
+ }
38
+ }
39
+ return JSON.stringify(generator.toJSON());
40
+ }
41
+ export function rewriteSourceMapSources(sourceMap, resolvedPath, stableUrlPathname, sourceMapSourcePaths, sourceContent) {
42
+ let json = JSON.parse(sourceMap);
43
+ json.sources = [
44
+ sourceMapSourcePaths === 'absolute' ? normalizeFilePath(resolvedPath) : stableUrlPathname,
45
+ ];
46
+ if (sourceContent !== undefined) {
47
+ json.sourcesContent = [sourceContent];
48
+ }
49
+ return JSON.stringify(json);
50
+ }
51
+ export function stringifySourceMap(map) {
52
+ if (!map)
53
+ return null;
54
+ if (typeof map === 'string')
55
+ return map;
56
+ if (map instanceof Uint8Array) {
57
+ return Buffer.from(map).toString('utf8');
58
+ }
59
+ if (typeof map === 'object' && map !== null)
60
+ return JSON.stringify(map);
61
+ return String(map);
62
+ }
@@ -0,0 +1,52 @@
1
+ import type { CompiledRoutes } from '../routes.ts';
2
+ import type { ResolvedStyleTarget } from '../target.ts';
3
+ import type { EmittedAsset } from './emit.ts';
4
+ type StyleCompileResult = {
5
+ code: EmittedAsset;
6
+ fingerprint: string | null;
7
+ sourceMap: EmittedAsset | null;
8
+ };
9
+ type StyleGetResult = {
10
+ style: StyleCompileResult;
11
+ type: 'style';
12
+ } | {
13
+ etag: string;
14
+ type: 'not-modified';
15
+ };
16
+ type StyleGetOptions = {
17
+ ifNoneMatch: string | null;
18
+ isSourceMapRequest: boolean;
19
+ requestedFingerprint: string | null;
20
+ };
21
+ type StyleCompilerOptions = {
22
+ buildId?: string;
23
+ fingerprintAssets: boolean;
24
+ isAllowed(absolutePath: string): boolean;
25
+ minify: boolean;
26
+ onWatchDirectoriesChange?: (delta: {
27
+ add: string[];
28
+ remove: string[];
29
+ }) => void;
30
+ rootDir: string;
31
+ routes: CompiledRoutes;
32
+ sourceMapSourcePaths: 'absolute' | 'url';
33
+ sourceMaps?: 'external' | 'inline';
34
+ targets?: ResolvedStyleTarget;
35
+ watchIgnore?: readonly string[];
36
+ };
37
+ type StyleCompiler = {
38
+ getHref(filePath: string): Promise<string>;
39
+ getPreloadLayers(filePath: string | readonly string[]): Promise<string[][]>;
40
+ getStyle(filePath: string, options: StyleGetOptions): Promise<StyleGetResult>;
41
+ handleFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): Promise<void>;
42
+ };
43
+ export declare function createStyleCompiler(options: StyleCompilerOptions): StyleCompiler;
44
+ export declare function isStyleFilePath(filePath: string): boolean;
45
+ export declare function createResponseForStyle(result: StyleCompileResult, options: {
46
+ cacheControl: string;
47
+ ifNoneMatch: string | null;
48
+ isSourceMapRequest: boolean;
49
+ method: string;
50
+ }): Response;
51
+ export {};
52
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,WAAW,CAAA;AAS3D,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,cAAc,GACf;IACE,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,CAAA;AAEL,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,oBAAoB,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,MAAM,EAAE,OAAO,CAAA;IACf,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB,EAAE,UAAU,GAAG,KAAK,CAAA;IACxC,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;IAClC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrF,CAAA;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAiOhF;AAkED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACf,GACA,QAAQ,CA6BV"}
@@ -0,0 +1,272 @@
1
+ import * as os from 'node:os';
2
+ import * as path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { IfNoneMatch } from '@remix-run/headers';
5
+ import { createFileMatcher } from "../file-matcher.js";
6
+ import { formatFingerprintedPathname } from "../fingerprint.js";
7
+ import { createModuleStore } from "../module-store.js";
8
+ import { normalizeFilePath, resolveFilePath } from "../paths.js";
9
+ import { emitResolvedStyle } from "./emit.js";
10
+ import { resolveServedStyleOrThrow, resolveStyle } from "./resolve.js";
11
+ import { transformStyle } from "./transform.js";
12
+ const preloadConcurrency = Math.max(1, Math.min(8, os.availableParallelism() - 1));
13
+ const styleExtension = '.css';
14
+ export function createStyleCompiler(options) {
15
+ let resolvedOptions = {
16
+ ...options,
17
+ watchIgnoreMatchers: (options.watchIgnore ?? []).map((pattern) => createFileMatcher(pattern, options.rootDir)),
18
+ };
19
+ let styleStore = createModuleStore({
20
+ onWatchDirectoriesChange: options.onWatchDirectoriesChange,
21
+ });
22
+ let resolveInFlightByCacheKey = new Map();
23
+ let emitInFlightByCacheKey = new Map();
24
+ let resolveArgs = {
25
+ isAllowed: resolvedOptions.isAllowed,
26
+ isWatchIgnored,
27
+ routes: resolvedOptions.routes,
28
+ };
29
+ let transformArgs = {
30
+ buildId: resolvedOptions.buildId ?? null,
31
+ isWatchIgnored,
32
+ minify: resolvedOptions.minify,
33
+ routes: resolvedOptions.routes,
34
+ sourceMapSourcePaths: resolvedOptions.sourceMapSourcePaths,
35
+ sourceMaps: resolvedOptions.sourceMaps ?? null,
36
+ targets: resolvedOptions.targets ?? null,
37
+ };
38
+ return {
39
+ async getHref(filePath) {
40
+ let resolvedStyle = resolveServedStyleOrThrow(resolveInputFilePath(filePath), resolveArgs);
41
+ return getServedUrl(resolvedStyle.identityPath);
42
+ },
43
+ async getPreloadLayers(filePath) {
44
+ let resolvedEntries = [];
45
+ let seen = new Set();
46
+ for (let resolvedStyle of (Array.isArray(filePath) ? filePath : [filePath]).map((nextPath) => resolveServedStyleOrThrow(resolveInputFilePath(nextPath), resolveArgs))) {
47
+ if (seen.has(resolvedStyle.identityPath))
48
+ continue;
49
+ seen.add(resolvedStyle.identityPath);
50
+ resolvedEntries.push(resolvedStyle.identityPath);
51
+ }
52
+ let visited = new Set(resolvedEntries);
53
+ let queue = [...resolvedEntries];
54
+ let layers = [];
55
+ while (queue.length > 0) {
56
+ let frontier = queue;
57
+ queue = [];
58
+ let resolvedStyles = await getOrCreateResolvedStyles(frontier.map((identityPath) => styleStore.get(identityPath)));
59
+ let layer = [];
60
+ for (let resolvedStyle of resolvedStyles) {
61
+ layer.push(getServedUrlForResolvedStyle(resolvedStyle));
62
+ for (let dep of resolvedStyle.deps) {
63
+ if (visited.has(dep))
64
+ continue;
65
+ visited.add(dep);
66
+ queue.push(dep);
67
+ }
68
+ }
69
+ layers.push(layer);
70
+ }
71
+ return layers;
72
+ },
73
+ async getStyle(filePath, getOptions) {
74
+ let resolvedStyle = resolveServedStyleOrThrow(resolveInputFilePath(filePath), resolveArgs);
75
+ let record = styleStore.get(resolvedStyle.identityPath);
76
+ let notModified = getNotModifiedStyle(record.emitted, getOptions);
77
+ if (notModified)
78
+ return notModified;
79
+ let emitted = await getOrCreateEmittedStyle(record);
80
+ return {
81
+ style: toStyleCompileResult(emitted),
82
+ type: 'style',
83
+ };
84
+ },
85
+ async handleFileEvent(filePath, event) {
86
+ let normalizedFilePath = normalizeFilePath(filePath);
87
+ if (isWatchIgnored(normalizedFilePath))
88
+ return;
89
+ styleStore.invalidateForFileEvent(normalizedFilePath, event);
90
+ },
91
+ };
92
+ function resolveInputFilePath(filePath) {
93
+ if (filePath.startsWith('file://')) {
94
+ return normalizeFilePath(fileURLToPath(new URL(filePath)));
95
+ }
96
+ if (filePath.includes('://')) {
97
+ throw new TypeError(`Expected a file path or file:// URL, received "${filePath}"`);
98
+ }
99
+ return resolveFilePath(resolvedOptions.rootDir, filePath);
100
+ }
101
+ async function getOrCreateResolvedStyles(records) {
102
+ return mapWithConcurrency(records, preloadConcurrency, (record) => getOrCreateResolvedStyle(record));
103
+ }
104
+ async function getOrCreateResolvedStyle(record) {
105
+ if (record.resolved)
106
+ return record.resolved;
107
+ let cacheKey = getRecordCacheKey(record);
108
+ let existing = resolveInFlightByCacheKey.get(cacheKey);
109
+ if (existing)
110
+ return existing;
111
+ let promise = (async () => {
112
+ let startedVersion = record.invalidationVersion;
113
+ let transformedStyle = await getOrCreateTransformedStyle(record);
114
+ let resolvedStyleResult = await resolveStyle(record, transformedStyle, resolveArgs);
115
+ if (!resolvedStyleResult.ok) {
116
+ if (isFresh(record, startedVersion)) {
117
+ styleStore.clearResolved(record.identityPath, [resolvedStyleResult.tracking]);
118
+ }
119
+ throw resolvedStyleResult.error;
120
+ }
121
+ if (isFresh(record, startedVersion)) {
122
+ styleStore.setResolved(record.identityPath, resolvedStyleResult.value, [
123
+ resolvedStyleResult.tracking,
124
+ ]);
125
+ }
126
+ return resolvedStyleResult.value;
127
+ })();
128
+ resolveInFlightByCacheKey.set(cacheKey, promise);
129
+ try {
130
+ return await promise;
131
+ }
132
+ finally {
133
+ if (resolveInFlightByCacheKey.get(cacheKey) === promise) {
134
+ resolveInFlightByCacheKey.delete(cacheKey);
135
+ }
136
+ }
137
+ }
138
+ async function getOrCreateTransformedStyle(record) {
139
+ if (record.transformed)
140
+ return record.transformed;
141
+ let startedVersion = record.invalidationVersion;
142
+ let transformStyleResult = await transformStyle(record, transformArgs);
143
+ if (!transformStyleResult.ok) {
144
+ if (isFresh(record, startedVersion)) {
145
+ styleStore.clearTransformed(record.identityPath, [transformStyleResult.tracking]);
146
+ }
147
+ throw transformStyleResult.error;
148
+ }
149
+ if (isFresh(record, startedVersion)) {
150
+ styleStore.setTransformed(record.identityPath, transformStyleResult.value, [
151
+ transformStyleResult.tracking,
152
+ ]);
153
+ }
154
+ return transformStyleResult.value;
155
+ }
156
+ async function getOrCreateEmittedStyle(record) {
157
+ if (record.emitted)
158
+ return record.emitted;
159
+ let cacheKey = getRecordCacheKey(record);
160
+ let existing = emitInFlightByCacheKey.get(cacheKey);
161
+ if (existing)
162
+ return existing;
163
+ let promise = (async () => {
164
+ let startedVersion = record.invalidationVersion;
165
+ let resolvedStyle = await getOrCreateResolvedStyle(record);
166
+ let emitResolvedStyleResult = await emitResolvedStyle(resolvedStyle, {
167
+ getServedUrl,
168
+ sourceMaps: resolvedOptions.sourceMaps,
169
+ });
170
+ if (!emitResolvedStyleResult.ok) {
171
+ throw emitResolvedStyleResult.error;
172
+ }
173
+ if (isFresh(record, startedVersion)) {
174
+ styleStore.setEmitted(record.identityPath, emitResolvedStyleResult.value, null);
175
+ }
176
+ return emitResolvedStyleResult.value;
177
+ })();
178
+ emitInFlightByCacheKey.set(cacheKey, promise);
179
+ try {
180
+ return await promise;
181
+ }
182
+ finally {
183
+ if (emitInFlightByCacheKey.get(cacheKey) === promise) {
184
+ emitInFlightByCacheKey.delete(cacheKey);
185
+ }
186
+ }
187
+ }
188
+ async function getServedUrl(identityPath) {
189
+ return getServedUrlForResolvedStyle(await getOrCreateResolvedStyle(styleStore.get(identityPath)));
190
+ }
191
+ function getServedUrlForResolvedStyle(resolvedStyle) {
192
+ return formatFingerprintedPathname(resolvedStyle.stableUrlPathname, resolvedOptions.fingerprintAssets ? resolvedStyle.fingerprint : null);
193
+ }
194
+ function isWatchIgnored(filePath) {
195
+ return resolvedOptions.watchIgnoreMatchers.some((matcher) => matcher(filePath));
196
+ }
197
+ }
198
+ function getRecordCacheKey(record) {
199
+ return `${record.identityPath}\0${record.invalidationVersion}`;
200
+ }
201
+ function isFresh(record, version) {
202
+ return record.invalidationVersion === version;
203
+ }
204
+ function getNotModifiedStyle(emittedStyle, options) {
205
+ if (!emittedStyle || options.ifNoneMatch === null)
206
+ return null;
207
+ if (options.requestedFingerprint !== null &&
208
+ emittedStyle.fingerprint !== options.requestedFingerprint) {
209
+ return null;
210
+ }
211
+ let asset = getEmittedAssetForRequest(emittedStyle, options.isSourceMapRequest);
212
+ if (!asset)
213
+ return null;
214
+ if (!IfNoneMatch.from(options.ifNoneMatch).matches(asset.etag))
215
+ return null;
216
+ return { etag: asset.etag, type: 'not-modified' };
217
+ }
218
+ function getEmittedAssetForRequest(emittedStyle, isSourceMapRequest) {
219
+ return isSourceMapRequest ? emittedStyle.sourceMap : emittedStyle.code;
220
+ }
221
+ async function mapWithConcurrency(items, concurrency, mapper) {
222
+ if (items.length === 0)
223
+ return [];
224
+ let results = new Array(items.length);
225
+ let nextIndex = 0;
226
+ async function worker() {
227
+ while (nextIndex < items.length) {
228
+ let index = nextIndex++;
229
+ results[index] = await mapper(items[index], index);
230
+ }
231
+ }
232
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
233
+ return results;
234
+ }
235
+ function toStyleCompileResult(emittedStyle) {
236
+ return {
237
+ code: emittedStyle.code,
238
+ fingerprint: emittedStyle.fingerprint,
239
+ sourceMap: emittedStyle.sourceMap,
240
+ };
241
+ }
242
+ export function isStyleFilePath(filePath) {
243
+ return path.extname(filePath).toLowerCase() === styleExtension;
244
+ }
245
+ export function createResponseForStyle(result, options) {
246
+ let body;
247
+ let etag;
248
+ let contentType;
249
+ if (options.isSourceMapRequest) {
250
+ if (!result.sourceMap) {
251
+ return new Response('Not found', { status: 404 });
252
+ }
253
+ body = options.method === 'HEAD' ? null : result.sourceMap.content;
254
+ etag = result.sourceMap.etag;
255
+ contentType = 'application/json; charset=utf-8';
256
+ }
257
+ else {
258
+ body = options.method === 'HEAD' ? null : result.code.content;
259
+ etag = result.code.etag;
260
+ contentType = 'text/css; charset=utf-8';
261
+ }
262
+ if (IfNoneMatch.from(options.ifNoneMatch).matches(etag)) {
263
+ return new Response(null, { status: 304, headers: { ETag: etag } });
264
+ }
265
+ return new Response(body, {
266
+ headers: {
267
+ 'Cache-Control': options.cacheControl,
268
+ 'Content-Type': contentType,
269
+ ETag: etag,
270
+ },
271
+ });
272
+ }
@@ -0,0 +1,25 @@
1
+ import type { AssetServerCompilationError } from '../compilation-error.ts';
2
+ import type { ResolvedStyle } from './resolve.ts';
3
+ export type EmittedAsset = {
4
+ content: string;
5
+ etag: string;
6
+ };
7
+ export type EmittedStyle = {
8
+ code: EmittedAsset;
9
+ fingerprint: string | null;
10
+ importUrls: string[];
11
+ sourceMap: EmittedAsset | null;
12
+ };
13
+ type EmitResult = {
14
+ ok: true;
15
+ value: EmittedStyle;
16
+ } | {
17
+ error: AssetServerCompilationError;
18
+ ok: false;
19
+ };
20
+ export declare function emitResolvedStyle(resolvedStyle: ResolvedStyle, options: {
21
+ getServedUrl(identityPath: string): Promise<string>;
22
+ sourceMaps?: 'external' | 'inline';
23
+ }): Promise<EmitResult>;
24
+ export {};
25
+ //# sourceMappingURL=emit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/emit.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,UAAU,GACX;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,YAAY,CAAA;CACpB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CAAA;AAEL,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE;IACP,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,GACA,OAAO,CAAC,UAAU,CAAC,CAkCrB"}
@@ -0,0 +1,78 @@
1
+ import MagicString from 'magic-string';
2
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
3
+ import { hashContent } from "../fingerprint.js";
4
+ import { composeSourceMaps } from "../source-maps.js";
5
+ export async function emitResolvedStyle(resolvedStyle, options) {
6
+ try {
7
+ let importUrls = await Promise.all(resolvedStyle.deps.map((depPath) => options.getServedUrl(depPath)));
8
+ let rewriteResult = await rewriteDependencies(resolvedStyle, options);
9
+ let finalCode = rewriteResult.code;
10
+ if (rewriteResult.sourceMap) {
11
+ if (options.sourceMaps === 'inline') {
12
+ let encoded = Buffer.from(rewriteResult.sourceMap).toString('base64');
13
+ finalCode += `\n/*# sourceMappingURL=data:application/json;base64,${encoded} */`;
14
+ }
15
+ else if (options.sourceMaps === 'external') {
16
+ finalCode += `\n/*# sourceMappingURL=${await options.getServedUrl(resolvedStyle.identityPath)}.map */`;
17
+ }
18
+ }
19
+ return {
20
+ ok: true,
21
+ value: {
22
+ code: await createEmittedAsset(finalCode),
23
+ fingerprint: resolvedStyle.fingerprint,
24
+ importUrls,
25
+ sourceMap: rewriteResult.sourceMap
26
+ ? await createEmittedAsset(rewriteResult.sourceMap)
27
+ : null,
28
+ },
29
+ };
30
+ }
31
+ catch (error) {
32
+ return {
33
+ error: toEmitError(error, resolvedStyle.identityPath),
34
+ ok: false,
35
+ };
36
+ }
37
+ }
38
+ async function rewriteDependencies(resolvedStyle, options) {
39
+ if (resolvedStyle.dependencies.length === 0) {
40
+ return {
41
+ code: resolvedStyle.rawCode,
42
+ sourceMap: resolvedStyle.sourceMap,
43
+ };
44
+ }
45
+ let rewrittenSource = new MagicString(resolvedStyle.rawCode);
46
+ for (let dependency of resolvedStyle.dependencies) {
47
+ let replacement = dependency.kind === 'external'
48
+ ? dependency.replacement
49
+ : `${await options.getServedUrl(dependency.depPath)}${dependency.suffix}`;
50
+ let start = resolvedStyle.rawCode.indexOf(dependency.placeholder);
51
+ if (start < 0) {
52
+ throw createAssetServerCompilationError(`Missing dependency placeholder "${dependency.placeholder}" while emitting style ${resolvedStyle.identityPath}.`, {
53
+ code: 'EMIT_FAILED',
54
+ });
55
+ }
56
+ rewrittenSource.overwrite(start, start + dependency.placeholder.length, replacement);
57
+ }
58
+ return {
59
+ code: rewrittenSource.toString(),
60
+ sourceMap: resolvedStyle.sourceMap
61
+ ? composeSourceMaps(rewrittenSource.generateMap({ hires: true }).toString(), resolvedStyle.sourceMap)
62
+ : null,
63
+ };
64
+ }
65
+ async function createEmittedAsset(content) {
66
+ return {
67
+ content,
68
+ etag: `W/"${await hashContent(content)}"`,
69
+ };
70
+ }
71
+ function toEmitError(error, identityPath) {
72
+ if (isAssetServerCompilationError(error))
73
+ return error;
74
+ return createAssetServerCompilationError(`Failed to emit style ${identityPath}. ${error instanceof Error ? error.message : String(error)}`, {
75
+ cause: error,
76
+ code: 'EMIT_FAILED',
77
+ });
78
+ }
@@ -0,0 +1,48 @@
1
+ import type { AssetServerCompilationError } from '../compilation-error.ts';
2
+ import type { ModuleRecord, ModuleTracking } from '../module-store.ts';
3
+ import type { CompiledRoutes } from '../routes.ts';
4
+ import type { EmittedStyle } from './emit.ts';
5
+ import type { TransformedStyle } from './transform.ts';
6
+ type StyleRecord = ModuleRecord<TransformedStyle, ResolvedStyle, EmittedStyle>;
7
+ type ResolvedDependency = {
8
+ kind: 'external';
9
+ placeholder: string;
10
+ replacement: string;
11
+ } | {
12
+ depPath: string;
13
+ kind: 'local';
14
+ placeholder: string;
15
+ suffix: string;
16
+ };
17
+ export type ResolvedStyle = {
18
+ dependencies: ResolvedDependency[];
19
+ deps: string[];
20
+ fingerprint: string | null;
21
+ identityPath: string;
22
+ rawCode: string;
23
+ resolvedPath: string;
24
+ sourceMap: string | null;
25
+ stableUrlPathname: string;
26
+ trackedFiles: string[];
27
+ };
28
+ export type ResolveArgs = {
29
+ isAllowed(absolutePath: string): boolean;
30
+ isWatchIgnored(filePath: string): boolean;
31
+ routes: CompiledRoutes;
32
+ };
33
+ type ResolveResult = {
34
+ tracking: ModuleTracking;
35
+ } & ({
36
+ ok: true;
37
+ value: ResolvedStyle;
38
+ } | {
39
+ error: AssetServerCompilationError;
40
+ ok: false;
41
+ });
42
+ export declare function resolveStyle(record: StyleRecord, transformed: TransformedStyle, args: ResolveArgs): Promise<ResolveResult>;
43
+ export declare function resolveServedStyleOrThrow(filePath: string, args: ResolveArgs): {
44
+ identityPath: string;
45
+ stableUrlPathname: string;
46
+ };
47
+ export {};
48
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/resolve.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,KAAK,WAAW,GAAG,YAAY,CAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;AAE9E,KAAK,kBAAkB,GACnB;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAEL,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;CACzB,GAAG,CACA;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,aAAa,CAAA;CACrB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CACJ,CAAA;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CAuDxB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,GAChB;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CA+BA"}