@askrjs/vite 0.2.0 → 0.2.2
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/dist/image-node.js +1 -1
- package/dist/index.js +378 -126
- package/dist/index.js.map +1 -1
- package/dist/server.js +5 -2
- package/dist/server.js.map +1 -1
- package/package.json +13 -13
package/dist/image-node.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import { r as IMAGE_METADATA_PATH, t as normalizeDeclarationOptions } from "./image-options-B-QnEqPc.js";
|
|
3
3
|
import { Image } from "./image.js";
|
|
4
|
-
import path from "node:path";
|
|
5
4
|
import { createHash } from "node:crypto";
|
|
5
|
+
import path from "node:path";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
//#region src/image-node.ts
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,213 @@
|
|
|
2
2
|
import { n as normalizeImageOptions, r as IMAGE_METADATA_PATH, t as normalizeDeclarationOptions } from "./image-options-B-QnEqPc.js";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { Visitor, parseSync } from "oxc-parser";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
import fs from "node:fs/promises";
|
|
6
7
|
import path from "node:path";
|
|
7
|
-
|
|
8
|
+
//#region src/source-map-rewrites.ts
|
|
9
|
+
const BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
10
|
+
const BASE64_VALUES = new Map([...BASE64].map((character, index) => [character, index]));
|
|
11
|
+
function decodeVlq(value, cursor) {
|
|
12
|
+
let result = 0;
|
|
13
|
+
let shift = 0;
|
|
14
|
+
for (;;) {
|
|
15
|
+
const digit = BASE64_VALUES.get(value[cursor.value++]);
|
|
16
|
+
if (digit === void 0) throw new Error("Invalid sourcemap VLQ segment.");
|
|
17
|
+
result += (digit & 31) << shift;
|
|
18
|
+
if ((digit & 32) === 0) break;
|
|
19
|
+
shift += 5;
|
|
20
|
+
}
|
|
21
|
+
const negative = (result & 1) === 1;
|
|
22
|
+
result >>= 1;
|
|
23
|
+
return negative ? -result : result;
|
|
24
|
+
}
|
|
25
|
+
function encodeVlq(value) {
|
|
26
|
+
let remaining = Math.abs(value) << 1 | (value < 0 ? 1 : 0);
|
|
27
|
+
let output = "";
|
|
28
|
+
do {
|
|
29
|
+
let digit = remaining & 31;
|
|
30
|
+
remaining >>>= 5;
|
|
31
|
+
if (remaining > 0) digit |= 32;
|
|
32
|
+
output += BASE64[digit];
|
|
33
|
+
} while (remaining > 0);
|
|
34
|
+
return output;
|
|
35
|
+
}
|
|
36
|
+
function decodeMappings(value) {
|
|
37
|
+
const lines = [];
|
|
38
|
+
let source = 0;
|
|
39
|
+
let originalLine = 0;
|
|
40
|
+
let originalColumn = 0;
|
|
41
|
+
let name = 0;
|
|
42
|
+
for (const encodedLine of value.split(";")) {
|
|
43
|
+
const segments = [];
|
|
44
|
+
let generatedColumn = 0;
|
|
45
|
+
for (const encoded of encodedLine.split(",")) {
|
|
46
|
+
if (!encoded) continue;
|
|
47
|
+
const cursor = { value: 0 };
|
|
48
|
+
generatedColumn += decodeVlq(encoded, cursor);
|
|
49
|
+
const segment = [generatedColumn];
|
|
50
|
+
if (cursor.value < encoded.length) {
|
|
51
|
+
source += decodeVlq(encoded, cursor);
|
|
52
|
+
originalLine += decodeVlq(encoded, cursor);
|
|
53
|
+
originalColumn += decodeVlq(encoded, cursor);
|
|
54
|
+
segment.push(source, originalLine, originalColumn);
|
|
55
|
+
if (cursor.value < encoded.length) {
|
|
56
|
+
name += decodeVlq(encoded, cursor);
|
|
57
|
+
segment.push(name);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
segments.push(segment);
|
|
61
|
+
}
|
|
62
|
+
lines.push(segments);
|
|
63
|
+
}
|
|
64
|
+
return lines;
|
|
65
|
+
}
|
|
66
|
+
function encodeMappings(lines) {
|
|
67
|
+
let previousSource = 0;
|
|
68
|
+
let previousOriginalLine = 0;
|
|
69
|
+
let previousOriginalColumn = 0;
|
|
70
|
+
let previousName = 0;
|
|
71
|
+
return lines.map((segments) => {
|
|
72
|
+
let previousGeneratedColumn = 0;
|
|
73
|
+
return segments.map((segment) => {
|
|
74
|
+
let encoded = encodeVlq(segment[0] - previousGeneratedColumn);
|
|
75
|
+
previousGeneratedColumn = segment[0];
|
|
76
|
+
if (segment.length >= 4) {
|
|
77
|
+
encoded += encodeVlq(segment[1] - previousSource);
|
|
78
|
+
encoded += encodeVlq(segment[2] - previousOriginalLine);
|
|
79
|
+
encoded += encodeVlq(segment[3] - previousOriginalColumn);
|
|
80
|
+
previousSource = segment[1];
|
|
81
|
+
previousOriginalLine = segment[2];
|
|
82
|
+
previousOriginalColumn = segment[3];
|
|
83
|
+
if (segment.length === 5) {
|
|
84
|
+
encoded += encodeVlq(segment[4] - previousName);
|
|
85
|
+
previousName = segment[4];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return encoded;
|
|
89
|
+
}).join(",");
|
|
90
|
+
}).join(";");
|
|
91
|
+
}
|
|
92
|
+
function lineStarts(code) {
|
|
93
|
+
const starts = [0];
|
|
94
|
+
for (let index = 0; index < code.length; index += 1) if (code[index] === "\n") starts.push(index + 1);
|
|
95
|
+
return starts;
|
|
96
|
+
}
|
|
97
|
+
function offsetAt(starts, line, column) {
|
|
98
|
+
return (starts[line] ?? starts[starts.length - 1]) + column;
|
|
99
|
+
}
|
|
100
|
+
function positionAt(starts, offset) {
|
|
101
|
+
let low = 0;
|
|
102
|
+
let high = starts.length;
|
|
103
|
+
while (low + 1 < high) {
|
|
104
|
+
const middle = low + high >>> 1;
|
|
105
|
+
if (starts[middle] <= offset) low = middle;
|
|
106
|
+
else high = middle;
|
|
107
|
+
}
|
|
108
|
+
return [low, offset - starts[low]];
|
|
109
|
+
}
|
|
110
|
+
function forwardOffset(offset, edits) {
|
|
111
|
+
let delta = 0;
|
|
112
|
+
for (const edit of edits) {
|
|
113
|
+
if (offset < edit.start) break;
|
|
114
|
+
if (offset < edit.end) return edit.start + delta;
|
|
115
|
+
delta += edit.replacement.length - (edit.end - edit.start);
|
|
116
|
+
}
|
|
117
|
+
return offset + delta;
|
|
118
|
+
}
|
|
119
|
+
function reverseOffset(offset, edits) {
|
|
120
|
+
let delta = 0;
|
|
121
|
+
for (const edit of edits) {
|
|
122
|
+
const generatedStart = edit.start + delta;
|
|
123
|
+
const generatedEnd = generatedStart + edit.replacement.length;
|
|
124
|
+
if (offset < generatedStart) break;
|
|
125
|
+
if (offset < generatedEnd) return edit.start;
|
|
126
|
+
delta += edit.replacement.length - (edit.end - edit.start);
|
|
127
|
+
}
|
|
128
|
+
return offset - delta;
|
|
129
|
+
}
|
|
130
|
+
function normalize(lines) {
|
|
131
|
+
return lines.map((segments) => {
|
|
132
|
+
const sorted = segments.sort((left, right) => left[0] - right[0]);
|
|
133
|
+
return sorted.filter((segment, index) => index === 0 || segment[0] !== sorted[index - 1][0]);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function mappingAt(lines, starts, offset) {
|
|
137
|
+
const [line, column] = positionAt(starts, offset);
|
|
138
|
+
let match;
|
|
139
|
+
for (const segment of lines[line] ?? []) {
|
|
140
|
+
if (segment[0] > column) break;
|
|
141
|
+
if (segment.length >= 4) match = segment;
|
|
142
|
+
}
|
|
143
|
+
return match;
|
|
144
|
+
}
|
|
145
|
+
/** Move generated coordinates after deterministic text edits. */
|
|
146
|
+
function remapGenerated(map, before, after, edits) {
|
|
147
|
+
const beforeStarts = lineStarts(before);
|
|
148
|
+
const afterStarts = lineStarts(after);
|
|
149
|
+
const decoded = decodeMappings(map.mappings);
|
|
150
|
+
const output = Array.from({ length: afterStarts.length }, () => []);
|
|
151
|
+
for (const [line, segments] of decoded.entries()) for (const segment of segments) {
|
|
152
|
+
const [nextLine, nextColumn] = positionAt(afterStarts, forwardOffset(offsetAt(beforeStarts, line, segment[0]), edits));
|
|
153
|
+
output[nextLine].push([nextColumn, ...segment.slice(1)]);
|
|
154
|
+
}
|
|
155
|
+
let delta = 0;
|
|
156
|
+
for (const edit of edits) {
|
|
157
|
+
if (edit.mapTo !== void 0) {
|
|
158
|
+
const mapped = mappingAt(decoded, beforeStarts, edit.mapTo);
|
|
159
|
+
if (mapped) {
|
|
160
|
+
const [line, column] = positionAt(afterStarts, edit.start + delta);
|
|
161
|
+
output[line].push([column, ...mapped.slice(1)]);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
delta += edit.replacement.length - (edit.end - edit.start);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
...map,
|
|
168
|
+
mappings: encodeMappings(normalize(output))
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** Move original coordinates back through deterministic text edits. */
|
|
172
|
+
function remapOriginal(map, original, rewritten, edits) {
|
|
173
|
+
const originalStarts = lineStarts(original);
|
|
174
|
+
const rewrittenStarts = lineStarts(rewritten);
|
|
175
|
+
const lines = decodeMappings(map.mappings);
|
|
176
|
+
for (const segments of lines) for (const segment of segments) {
|
|
177
|
+
if (segment.length < 4 || segment[1] !== 0) continue;
|
|
178
|
+
const [line, column] = positionAt(originalStarts, reverseOffset(offsetAt(rewrittenStarts, segment[2], segment[3]), edits));
|
|
179
|
+
segment[2] = line;
|
|
180
|
+
segment[3] = column;
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
...map,
|
|
184
|
+
mappings: encodeMappings(lines),
|
|
185
|
+
sourcesContent: map.sources?.map((_source, index) => index === 0 ? original : map.sourcesContent?.[index] ?? null)
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/** Build a complete map for a rewritten source when no downstream map exists. */
|
|
189
|
+
function sourceMapForRewrite(original, rewritten, edits, id) {
|
|
190
|
+
const originalStarts = lineStarts(original);
|
|
191
|
+
const rewrittenStarts = lineStarts(rewritten);
|
|
192
|
+
const lines = Array.from({ length: rewrittenStarts.length }, () => []);
|
|
193
|
+
for (let offset = 0; offset < rewritten.length; offset += 1) {
|
|
194
|
+
const [generatedLine, generatedColumn] = positionAt(rewrittenStarts, offset);
|
|
195
|
+
const [originalLine, originalColumn] = positionAt(originalStarts, reverseOffset(offset, edits));
|
|
196
|
+
lines[generatedLine].push([
|
|
197
|
+
generatedColumn,
|
|
198
|
+
0,
|
|
199
|
+
originalLine,
|
|
200
|
+
originalColumn
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
version: 3,
|
|
205
|
+
names: [],
|
|
206
|
+
sources: [id],
|
|
207
|
+
sourcesContent: [original],
|
|
208
|
+
mappings: encodeMappings(lines)
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
8
212
|
//#region src/template-optimizer.ts
|
|
9
213
|
const OPTIMIZED_PROPS = /* @__PURE__ */ new Set([
|
|
10
214
|
"class",
|
|
@@ -40,14 +244,20 @@ function collectCandidate(property, code, candidates) {
|
|
|
40
244
|
});
|
|
41
245
|
candidates.set(cacheKey, group);
|
|
42
246
|
}
|
|
43
|
-
function
|
|
247
|
+
function optimizeTemplateOutputWithEdits(code) {
|
|
44
248
|
const parsed = parseSync("askr-compiled.js", code, {
|
|
45
249
|
lang: "js",
|
|
46
250
|
sourceType: "module"
|
|
47
251
|
});
|
|
48
|
-
if (parsed.errors.length > 0) return
|
|
252
|
+
if (parsed.errors.length > 0) return {
|
|
253
|
+
code,
|
|
254
|
+
edits: []
|
|
255
|
+
};
|
|
49
256
|
const runtimeFactories = collectRuntimeFactories(parsed.program);
|
|
50
|
-
if (runtimeFactories.size === 0) return
|
|
257
|
+
if (runtimeFactories.size === 0) return {
|
|
258
|
+
code,
|
|
259
|
+
edits: []
|
|
260
|
+
};
|
|
51
261
|
const candidates = /* @__PURE__ */ new Map();
|
|
52
262
|
const identifiers = /* @__PURE__ */ new Set();
|
|
53
263
|
new Visitor({
|
|
@@ -76,10 +286,27 @@ function optimizeTemplateOutput(code) {
|
|
|
76
286
|
identifier
|
|
77
287
|
});
|
|
78
288
|
}
|
|
79
|
-
if (declarations.length === 0) return
|
|
289
|
+
if (declarations.length === 0) return {
|
|
290
|
+
code,
|
|
291
|
+
edits: []
|
|
292
|
+
};
|
|
293
|
+
const prefix = `${declarations.join("\n")}\n`;
|
|
294
|
+
const edits = [{
|
|
295
|
+
start: 0,
|
|
296
|
+
end: 0,
|
|
297
|
+
replacement: prefix,
|
|
298
|
+
mapTo: replacements[0].start
|
|
299
|
+
}, ...replacements.map(({ start, end, identifier }) => ({
|
|
300
|
+
start,
|
|
301
|
+
end,
|
|
302
|
+
replacement: identifier
|
|
303
|
+
})).sort((left, right) => left.start - right.start)];
|
|
80
304
|
let optimized = code;
|
|
81
305
|
for (const replacement of replacements.sort((left, right) => right.start - left.start)) optimized = optimized.slice(0, replacement.start) + replacement.identifier + optimized.slice(replacement.end);
|
|
82
|
-
return
|
|
306
|
+
return {
|
|
307
|
+
code: `${prefix}${optimized}`,
|
|
308
|
+
edits
|
|
309
|
+
};
|
|
83
310
|
}
|
|
84
311
|
//#endregion
|
|
85
312
|
//#region src/image-lexical.ts
|
|
@@ -130,6 +357,119 @@ function imageDeclarationMask(code) {
|
|
|
130
357
|
for (let match = IMAGE_IMPORT.exec(code); match; match = IMAGE_IMPORT.exec(code)) if (mask[match.index]) return mask;
|
|
131
358
|
}
|
|
132
359
|
//#endregion
|
|
360
|
+
//#region src/image-declarations.ts
|
|
361
|
+
const IMAGE_CALL = /\bimage\s*\(\s*new\s+URL\s*\(\s*(["'])([^"']+)\1\s*,\s*import\.meta\.url\s*\)/g;
|
|
362
|
+
function staticJson(source, id) {
|
|
363
|
+
let output = "";
|
|
364
|
+
for (let index = 0; index < source.length;) {
|
|
365
|
+
const character = source[index];
|
|
366
|
+
if (/\s/.test(character) || "{}[]:".includes(character)) {
|
|
367
|
+
output += character;
|
|
368
|
+
index += 1;
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
if (character === ",") {
|
|
372
|
+
let next = index + 1;
|
|
373
|
+
while (/\s/.test(source[next] ?? "")) next += 1;
|
|
374
|
+
if (source[next] !== "}" && source[next] !== "]") output += character;
|
|
375
|
+
index += 1;
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
if (character === "\"" || character === "'") {
|
|
379
|
+
let end = index + 1;
|
|
380
|
+
while (end < source.length && source[end] !== character) {
|
|
381
|
+
if (source[end] === "\\") throw new Error(`@askrjs/vite image() option strings in ${id} cannot contain escape sequences.`);
|
|
382
|
+
end += 1;
|
|
383
|
+
}
|
|
384
|
+
if (end >= source.length) throw new Error(`@askrjs/vite found an unterminated image option in ${id}.`);
|
|
385
|
+
output += JSON.stringify(source.slice(index + 1, end));
|
|
386
|
+
index = end + 1;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
const number = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:e[+-]?\d+)?/i.exec(source.slice(index));
|
|
390
|
+
if (number) {
|
|
391
|
+
output += number[0];
|
|
392
|
+
index += number[0].length;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const identifier = /^[A-Za-z_]\w*/.exec(source.slice(index));
|
|
396
|
+
if (identifier) {
|
|
397
|
+
let next = index + identifier[0].length;
|
|
398
|
+
while (/\s/.test(source[next] ?? "")) next += 1;
|
|
399
|
+
if (source[next] === ":") output += JSON.stringify(identifier[0]);
|
|
400
|
+
else if ([
|
|
401
|
+
"true",
|
|
402
|
+
"false",
|
|
403
|
+
"null"
|
|
404
|
+
].includes(identifier[0])) output += identifier[0];
|
|
405
|
+
else throw new Error(`@askrjs/vite image() options in ${id} must not reference ${identifier[0]}; use a static object literal.`);
|
|
406
|
+
index += identifier[0].length;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
throw new Error(`@askrjs/vite image() options in ${id} must be a static object literal so builds and direct SSG imports agree.`);
|
|
410
|
+
}
|
|
411
|
+
return output;
|
|
412
|
+
}
|
|
413
|
+
function staticOptions(source, id) {
|
|
414
|
+
const trimmed = source.trim();
|
|
415
|
+
if (!trimmed) return {};
|
|
416
|
+
let value;
|
|
417
|
+
try {
|
|
418
|
+
value = JSON.parse(staticJson(trimmed, id));
|
|
419
|
+
} catch (error) {
|
|
420
|
+
if (error instanceof Error && error.message.startsWith("@askrjs/vite")) throw error;
|
|
421
|
+
throw new Error(`@askrjs/vite could not parse image() options in ${id}.`, { cause: error });
|
|
422
|
+
}
|
|
423
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`@askrjs/vite image() options in ${id} must be an object literal.`);
|
|
424
|
+
return value;
|
|
425
|
+
}
|
|
426
|
+
function findCallEnd(code, start) {
|
|
427
|
+
let depth = 1;
|
|
428
|
+
let quote = "";
|
|
429
|
+
let escaped = false;
|
|
430
|
+
for (let index = start; index < code.length; index += 1) {
|
|
431
|
+
const character = code[index];
|
|
432
|
+
if (quote) {
|
|
433
|
+
if (escaped) escaped = false;
|
|
434
|
+
else if (character === "\\") escaped = true;
|
|
435
|
+
else if (character === quote) quote = "";
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (character === "\"" || character === "'") {
|
|
439
|
+
quote = character;
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
if (character === "(") depth += 1;
|
|
443
|
+
if (character === ")") {
|
|
444
|
+
depth -= 1;
|
|
445
|
+
if (depth === 0) return index;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return -1;
|
|
449
|
+
}
|
|
450
|
+
function imageDeclarations(code, id) {
|
|
451
|
+
const mask = imageDeclarationMask(code);
|
|
452
|
+
if (!mask) return [];
|
|
453
|
+
const output = [];
|
|
454
|
+
IMAGE_CALL.lastIndex = 0;
|
|
455
|
+
for (let match = IMAGE_CALL.exec(code); match; match = IMAGE_CALL.exec(code)) {
|
|
456
|
+
if (!mask[match.index]) continue;
|
|
457
|
+
const afterUrl = IMAGE_CALL.lastIndex;
|
|
458
|
+
const end = findCallEnd(code, afterUrl);
|
|
459
|
+
if (end < 0) throw new Error(`@askrjs/vite found an unterminated image() call in ${id}.`);
|
|
460
|
+
const remainder = code.slice(afterUrl, end).trim();
|
|
461
|
+
if (remainder && !remainder.startsWith(",")) throw new Error(`@askrjs/vite could not parse image() declaration in ${id}.`);
|
|
462
|
+
output.push({
|
|
463
|
+
start: match.index,
|
|
464
|
+
end: end + 1,
|
|
465
|
+
source: match[2],
|
|
466
|
+
options: staticOptions(remainder.replace(/^,/, ""), id)
|
|
467
|
+
});
|
|
468
|
+
IMAGE_CALL.lastIndex = end + 1;
|
|
469
|
+
}
|
|
470
|
+
return output;
|
|
471
|
+
}
|
|
472
|
+
//#endregion
|
|
133
473
|
//#region src/image-inspection.ts
|
|
134
474
|
function positiveDimensions(width, height, format, transformable, animated = false) {
|
|
135
475
|
return width > 0 && height > 0 ? {
|
|
@@ -421,117 +761,6 @@ async function processImage(context, sourcePath, declarationOptions, globalOptio
|
|
|
421
761
|
}
|
|
422
762
|
//#endregion
|
|
423
763
|
//#region src/image-pipeline.ts
|
|
424
|
-
const IMAGE_CALL = /\bimage\s*\(\s*new\s+URL\s*\(\s*(["'])([^"']+)\1\s*,\s*import\.meta\.url\s*\)/g;
|
|
425
|
-
function staticJson(source, id) {
|
|
426
|
-
let output = "";
|
|
427
|
-
for (let index = 0; index < source.length;) {
|
|
428
|
-
const character = source[index];
|
|
429
|
-
if (/\s/.test(character) || "{}[]:".includes(character)) {
|
|
430
|
-
output += character;
|
|
431
|
-
index += 1;
|
|
432
|
-
continue;
|
|
433
|
-
}
|
|
434
|
-
if (character === ",") {
|
|
435
|
-
let next = index + 1;
|
|
436
|
-
while (/\s/.test(source[next] ?? "")) next += 1;
|
|
437
|
-
if (source[next] !== "}" && source[next] !== "]") output += character;
|
|
438
|
-
index += 1;
|
|
439
|
-
continue;
|
|
440
|
-
}
|
|
441
|
-
if (character === "\"" || character === "'") {
|
|
442
|
-
let end = index + 1;
|
|
443
|
-
while (end < source.length && source[end] !== character) {
|
|
444
|
-
if (source[end] === "\\") throw new Error(`@askrjs/vite image() option strings in ${id} cannot contain escape sequences.`);
|
|
445
|
-
end += 1;
|
|
446
|
-
}
|
|
447
|
-
if (end >= source.length) throw new Error(`@askrjs/vite found an unterminated image option in ${id}.`);
|
|
448
|
-
output += JSON.stringify(source.slice(index + 1, end));
|
|
449
|
-
index = end + 1;
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
452
|
-
const number = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:e[+-]?\d+)?/i.exec(source.slice(index));
|
|
453
|
-
if (number) {
|
|
454
|
-
output += number[0];
|
|
455
|
-
index += number[0].length;
|
|
456
|
-
continue;
|
|
457
|
-
}
|
|
458
|
-
const identifier = /^[A-Za-z_]\w*/.exec(source.slice(index));
|
|
459
|
-
if (identifier) {
|
|
460
|
-
let next = index + identifier[0].length;
|
|
461
|
-
while (/\s/.test(source[next] ?? "")) next += 1;
|
|
462
|
-
if (source[next] === ":") output += JSON.stringify(identifier[0]);
|
|
463
|
-
else if ([
|
|
464
|
-
"true",
|
|
465
|
-
"false",
|
|
466
|
-
"null"
|
|
467
|
-
].includes(identifier[0])) output += identifier[0];
|
|
468
|
-
else throw new Error(`@askrjs/vite image() options in ${id} must not reference ${identifier[0]}; use a static object literal.`);
|
|
469
|
-
index += identifier[0].length;
|
|
470
|
-
continue;
|
|
471
|
-
}
|
|
472
|
-
throw new Error(`@askrjs/vite image() options in ${id} must be a static object literal so builds and direct SSG imports agree.`);
|
|
473
|
-
}
|
|
474
|
-
return output;
|
|
475
|
-
}
|
|
476
|
-
function staticOptions(source, id) {
|
|
477
|
-
const trimmed = source.trim();
|
|
478
|
-
if (!trimmed) return {};
|
|
479
|
-
let value;
|
|
480
|
-
try {
|
|
481
|
-
value = JSON.parse(staticJson(trimmed, id));
|
|
482
|
-
} catch (error) {
|
|
483
|
-
if (error instanceof Error && error.message.startsWith("@askrjs/vite")) throw error;
|
|
484
|
-
throw new Error(`@askrjs/vite could not parse image() options in ${id}.`, { cause: error });
|
|
485
|
-
}
|
|
486
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`@askrjs/vite image() options in ${id} must be an object literal.`);
|
|
487
|
-
return value;
|
|
488
|
-
}
|
|
489
|
-
function findCallEnd(code, start) {
|
|
490
|
-
let depth = 1;
|
|
491
|
-
let quote = "";
|
|
492
|
-
let escaped = false;
|
|
493
|
-
for (let index = start; index < code.length; index += 1) {
|
|
494
|
-
const character = code[index];
|
|
495
|
-
if (quote) {
|
|
496
|
-
if (escaped) escaped = false;
|
|
497
|
-
else if (character === "\\") escaped = true;
|
|
498
|
-
else if (character === quote) quote = "";
|
|
499
|
-
continue;
|
|
500
|
-
}
|
|
501
|
-
if (character === "\"" || character === "'") {
|
|
502
|
-
quote = character;
|
|
503
|
-
continue;
|
|
504
|
-
}
|
|
505
|
-
if (character === "(") depth += 1;
|
|
506
|
-
if (character === ")") {
|
|
507
|
-
depth -= 1;
|
|
508
|
-
if (depth === 0) return index;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
return -1;
|
|
512
|
-
}
|
|
513
|
-
function declarations(code, id) {
|
|
514
|
-
const mask = imageDeclarationMask(code);
|
|
515
|
-
if (!mask) return [];
|
|
516
|
-
const output = [];
|
|
517
|
-
IMAGE_CALL.lastIndex = 0;
|
|
518
|
-
for (let match = IMAGE_CALL.exec(code); match; match = IMAGE_CALL.exec(code)) {
|
|
519
|
-
if (!mask[match.index]) continue;
|
|
520
|
-
const afterUrl = IMAGE_CALL.lastIndex;
|
|
521
|
-
const end = findCallEnd(code, afterUrl);
|
|
522
|
-
if (end < 0) throw new Error(`@askrjs/vite found an unterminated image() call in ${id}.`);
|
|
523
|
-
const remainder = code.slice(afterUrl, end).trim();
|
|
524
|
-
if (remainder && !remainder.startsWith(",")) throw new Error(`@askrjs/vite could not parse image() declaration in ${id}.`);
|
|
525
|
-
output.push({
|
|
526
|
-
start: match.index,
|
|
527
|
-
end: end + 1,
|
|
528
|
-
source: match[2],
|
|
529
|
-
options: staticOptions(remainder.replace(/^,/, ""), id)
|
|
530
|
-
});
|
|
531
|
-
IMAGE_CALL.lastIndex = end + 1;
|
|
532
|
-
}
|
|
533
|
-
return output;
|
|
534
|
-
}
|
|
535
764
|
function urlExpression(referenceId) {
|
|
536
765
|
return `import.meta.ROLLUP_FILE_URL_${referenceId}`;
|
|
537
766
|
}
|
|
@@ -586,23 +815,39 @@ var ImagePipeline = class {
|
|
|
586
815
|
this.#config = config;
|
|
587
816
|
}
|
|
588
817
|
async transform(context, code, id) {
|
|
589
|
-
|
|
818
|
+
return (await this.transformWithEdits(context, code, id))?.code;
|
|
819
|
+
}
|
|
820
|
+
async transformWithEdits(context, code, id) {
|
|
821
|
+
const found = imageDeclarations(code, id);
|
|
590
822
|
if (found.length === 0) return void 0;
|
|
591
823
|
if (!this.#config) throw new Error("@askrjs/vite image pipeline was not configured.");
|
|
592
824
|
if (this.#config.command !== "build") throw new Error("@askrjs/vite responsive image declarations currently require a Vite build.");
|
|
593
825
|
const cacheDir = path.join(this.#config.root, "node_modules/.cache/@askrjs/vite/images");
|
|
594
826
|
let transformed = code;
|
|
827
|
+
const edits = [];
|
|
595
828
|
for (const declaration of [...found].reverse()) {
|
|
596
829
|
const sourcePath = path.resolve(path.dirname(id.split("?", 1)[0]), declaration.source);
|
|
597
830
|
const key = declarationKey(sourcePath, declaration.options);
|
|
598
831
|
let processed = this.#processed.get(key);
|
|
832
|
+
if (processed) {
|
|
833
|
+
if (createHash("sha256").update(await fs.readFile(sourcePath)).digest("hex") !== processed.sourceHash) processed = void 0;
|
|
834
|
+
}
|
|
599
835
|
if (!processed) {
|
|
600
836
|
processed = await processImage(context, sourcePath, declaration.options, this.#options, cacheDir, this.#sharpLoader);
|
|
601
837
|
this.#processed.set(key, processed);
|
|
602
838
|
}
|
|
603
|
-
|
|
839
|
+
const replacement = imageExpression(processed);
|
|
840
|
+
edits.push({
|
|
841
|
+
start: declaration.start,
|
|
842
|
+
end: declaration.end,
|
|
843
|
+
replacement
|
|
844
|
+
});
|
|
845
|
+
transformed = `${transformed.slice(0, declaration.start)}${replacement}${transformed.slice(declaration.end)}`;
|
|
604
846
|
}
|
|
605
|
-
return
|
|
847
|
+
return {
|
|
848
|
+
code: transformed,
|
|
849
|
+
edits: edits.sort((left, right) => left.start - right.start)
|
|
850
|
+
};
|
|
606
851
|
}
|
|
607
852
|
async writeMetadata(context) {
|
|
608
853
|
if (!this.#config || this.#processed.size === 0) return;
|
|
@@ -704,11 +949,11 @@ function askrVitePlugin(options = {}) {
|
|
|
704
949
|
},
|
|
705
950
|
async transform(code, id) {
|
|
706
951
|
if (id.includes("node_modules")) return null;
|
|
707
|
-
const imageTransformed = imagePipeline ? await imagePipeline.
|
|
708
|
-
const input = imageTransformed ?? code;
|
|
952
|
+
const imageTransformed = imagePipeline ? await imagePipeline.transformWithEdits(this, code, id) : void 0;
|
|
953
|
+
const input = imageTransformed?.code ?? code;
|
|
709
954
|
if (!shouldTransform || !/\.(jsx|tsx)$/.test(id)) return imageTransformed ? {
|
|
710
|
-
code: imageTransformed,
|
|
711
|
-
map:
|
|
955
|
+
code: imageTransformed.code,
|
|
956
|
+
map: sourceMapForRewrite(code, imageTransformed.code, imageTransformed.edits, id)
|
|
712
957
|
} : null;
|
|
713
958
|
try {
|
|
714
959
|
const result = await (await loadTransformWithOxc())(input, id, {
|
|
@@ -720,9 +965,16 @@ function askrVitePlugin(options = {}) {
|
|
|
720
965
|
sourcemap: true
|
|
721
966
|
});
|
|
722
967
|
if (!result?.code) return null;
|
|
968
|
+
let map = result.map;
|
|
969
|
+
if (imageTransformed) map = remapOriginal(map, code, input, imageTransformed.edits);
|
|
970
|
+
if (!shouldOptimizeTemplates) return {
|
|
971
|
+
code: result.code,
|
|
972
|
+
map
|
|
973
|
+
};
|
|
974
|
+
const optimized = optimizeTemplateOutputWithEdits(result.code);
|
|
723
975
|
return {
|
|
724
|
-
code:
|
|
725
|
-
map: result.
|
|
976
|
+
code: optimized.code,
|
|
977
|
+
map: remapGenerated(map, result.code, optimized.code, optimized.edits)
|
|
726
978
|
};
|
|
727
979
|
} catch (error) {
|
|
728
980
|
const detail = error instanceof Error ? error.message : String(error);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["mime","#options","#processed","#sharpLoader","#config"],"sources":["../src/template-optimizer.ts","../src/image-lexical.ts","../src/image-inspection.ts","../src/image-transform.ts","../src/image-pipeline.ts","../src/jsx-plugin.ts"],"sourcesContent":["import { parseSync, Visitor, type ObjectProperty } from \"oxc-parser\";\n\nconst OPTIMIZED_PROPS = new Set([\"class\", \"className\", \"style\"]);\nconst JSX_RUNTIME_SOURCE = \"@askrjs/askr/jsx-runtime\";\nconst JSX_FACTORIES = new Set([\"jsx\", \"jsxs\", \"jsxDEV\"]);\n\ntype Candidate = {\n literal: string;\n start: number;\n end: number;\n};\n\nfunction importedName(specifier: { imported: { type: string; name?: string; value?: unknown } }) {\n return specifier.imported.type === \"Identifier\"\n ? specifier.imported.name\n : specifier.imported.value;\n}\n\nfunction collectRuntimeFactories(program: ReturnType<typeof parseSync>[\"program\"]): Set<string> {\n const factories = new Set<string>();\n\n for (const statement of program.body) {\n if (statement.type !== \"ImportDeclaration\" || statement.source.value !== JSX_RUNTIME_SOURCE) {\n continue;\n }\n\n for (const specifier of statement.specifiers) {\n if (\n specifier.type === \"ImportSpecifier\" &&\n JSX_FACTORIES.has(String(importedName(specifier)))\n ) {\n factories.add(specifier.local.name);\n }\n }\n }\n\n return factories;\n}\n\nfunction collectCandidate(\n property: ObjectProperty,\n code: string,\n candidates: Map<string, Candidate[]>,\n) {\n if (\n property.kind !== \"init\" ||\n property.computed ||\n property.method ||\n property.key.type !== \"Identifier\" ||\n !OPTIMIZED_PROPS.has(property.key.name) ||\n property.value.type !== \"Literal\" ||\n typeof property.value.value !== \"string\"\n ) {\n return;\n }\n\n const literal = code.slice(property.value.start, property.value.end);\n const cacheKey = `${property.key.name}:${literal}`;\n const group = candidates.get(cacheKey) ?? [];\n group.push({\n literal,\n start: property.value.start,\n end: property.value.end,\n });\n candidates.set(cacheKey, group);\n}\n\nexport function optimizeTemplateOutput(code: string): string {\n const parsed = parseSync(\"askr-compiled.js\", code, {\n lang: \"js\",\n sourceType: \"module\",\n });\n if (parsed.errors.length > 0) return code;\n\n const runtimeFactories = collectRuntimeFactories(parsed.program);\n if (runtimeFactories.size === 0) return code;\n\n const candidates = new Map<string, Candidate[]>();\n const identifiers = new Set<string>();\n new Visitor({\n Identifier(identifier) {\n identifiers.add(identifier.name);\n },\n CallExpression(call) {\n if (\n call.callee.type !== \"Identifier\" ||\n !runtimeFactories.has(call.callee.name) ||\n call.arguments[1]?.type !== \"ObjectExpression\"\n ) {\n return;\n }\n\n for (const property of call.arguments[1].properties) {\n if (property.type === \"Property\") {\n collectCandidate(property, code, candidates);\n }\n }\n },\n }).visit(parsed.program);\n\n const declarations: string[] = [];\n const replacements: Array<{ start: number; end: number; identifier: string }> = [];\n let hoistIndex = 0;\n for (const group of candidates.values()) {\n if (group.length < 2) continue;\n\n let identifier: string;\n do {\n identifier = `__askrStaticLiteral${hoistIndex++}`;\n } while (identifiers.has(identifier));\n identifiers.add(identifier);\n declarations.push(`const ${identifier} = ${group[0].literal};`);\n for (const candidate of group) {\n replacements.push({ start: candidate.start, end: candidate.end, identifier });\n }\n }\n\n if (declarations.length === 0) return code;\n\n let optimized = code;\n for (const replacement of replacements.sort((left, right) => right.start - left.start)) {\n optimized =\n optimized.slice(0, replacement.start) +\n replacement.identifier +\n optimized.slice(replacement.end);\n }\n return `${declarations.join(\"\\n\")}\\n${optimized}`;\n}\n","const IMAGE_IMPORT = /from\\s+[\"']@askrjs\\/vite\\/image[\"']/g;\n\nfunction lexicalCodeMask(source: string): Uint8Array {\n const mask = new Uint8Array(source.length);\n let state: \"code\" | \"single\" | \"double\" | \"template\" | \"line-comment\" | \"block-comment\" = \"code\";\n let escaped = false;\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index]!;\n const next = source[index + 1];\n if (state === \"code\") {\n if (character === \"/\" && next === \"/\") {\n state = \"line-comment\";\n index += 1;\n } else if (character === \"/\" && next === \"*\") {\n state = \"block-comment\";\n index += 1;\n } else if (character === \"'\") state = \"single\";\n else if (character === '\"') state = \"double\";\n else if (character === \"`\") state = \"template\";\n else mask[index] = 1;\n continue;\n }\n if (state === \"line-comment\") {\n if (character === \"\\n\" || character === \"\\r\") {\n state = \"code\";\n mask[index] = 1;\n }\n continue;\n }\n if (state === \"block-comment\") {\n if (character === \"*\" && next === \"/\") {\n state = \"code\";\n index += 1;\n }\n continue;\n }\n if (escaped) escaped = false;\n else if (character === \"\\\\\") escaped = true;\n else if (\n (state === \"single\" && character === \"'\") ||\n (state === \"double\" && character === '\"') ||\n (state === \"template\" && character === \"`\")\n ) {\n state = \"code\";\n }\n }\n return mask;\n}\n\nexport function imageDeclarationMask(code: string): Uint8Array | undefined {\n const mask = lexicalCodeMask(code);\n IMAGE_IMPORT.lastIndex = 0;\n for (let match = IMAGE_IMPORT.exec(code); match; match = IMAGE_IMPORT.exec(code)) {\n if (mask[match.index]) return mask;\n }\n return undefined;\n}\n","export type AssetFormat = \"avif\" | \"webp\" | \"jpeg\" | \"png\" | \"gif\" | \"svg\";\n\nexport interface SourceInspection {\n width: number;\n height: number;\n format: AssetFormat;\n transformable: boolean;\n animated: boolean;\n}\n\nfunction positiveDimensions(\n width: number,\n height: number,\n format: AssetFormat,\n transformable: boolean,\n animated = false,\n): SourceInspection | undefined {\n return width > 0 && height > 0 ? { width, height, format, transformable, animated } : undefined;\n}\n\nfunction inspectPng(source: Buffer): SourceInspection | undefined {\n if (\n source.length < 24 ||\n !source.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))\n ) {\n return undefined;\n }\n return positiveDimensions(\n source.readUInt32BE(16),\n source.readUInt32BE(20),\n \"png\",\n true,\n source.includes(Buffer.from(\"acTL\")),\n );\n}\n\nfunction inspectGif(source: Buffer): SourceInspection | undefined {\n if (source.length < 10 || !/^GIF8[79]a$/.test(source.subarray(0, 6).toString(\"ascii\"))) {\n return undefined;\n }\n return positiveDimensions(source.readUInt16LE(6), source.readUInt16LE(8), \"gif\", false, true);\n}\n\nfunction exifOrientation(segment: Buffer): number | undefined {\n if (segment.length < 14 || segment.subarray(0, 6).toString(\"binary\") !== \"Exif\\0\\0\") {\n return undefined;\n }\n const tiff = 6;\n const byteOrder = segment.subarray(tiff, tiff + 2).toString(\"ascii\");\n const littleEndian = byteOrder === \"II\";\n if (!littleEndian && byteOrder !== \"MM\") return undefined;\n const read16 = (offset: number): number | undefined => {\n const absolute = tiff + offset;\n if (absolute < tiff || absolute + 2 > segment.length) return undefined;\n return littleEndian ? segment.readUInt16LE(absolute) : segment.readUInt16BE(absolute);\n };\n const read32 = (offset: number): number | undefined => {\n const absolute = tiff + offset;\n if (absolute < tiff || absolute + 4 > segment.length) return undefined;\n return littleEndian ? segment.readUInt32LE(absolute) : segment.readUInt32BE(absolute);\n };\n if (read16(2) !== 42) return undefined;\n const directoryOffset = read32(4);\n if (directoryOffset === undefined) return undefined;\n const entries = read16(directoryOffset);\n if (entries === undefined) return undefined;\n for (let index = 0; index < entries; index += 1) {\n const entry = directoryOffset + 2 + index * 12;\n if (read16(entry) !== 0x0112 || read16(entry + 2) !== 3 || read32(entry + 4) !== 1) {\n continue;\n }\n const orientation = read16(entry + 8);\n return orientation && orientation >= 1 && orientation <= 8 ? orientation : undefined;\n }\n return undefined;\n}\n\nfunction inspectJpeg(source: Buffer): SourceInspection | undefined {\n if (source.length < 4 || source[0] !== 0xff || source[1] !== 0xd8) return undefined;\n const startOfFrame = new Set([\n 0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf,\n ]);\n let orientation: number | undefined;\n let offset = 2;\n while (offset + 8 < source.length) {\n if (source[offset] !== 0xff) {\n offset += 1;\n continue;\n }\n while (source[offset] === 0xff) offset += 1;\n const marker = source[offset++]!;\n if (marker === 0xd8 || marker === 0xd9 || marker === 0x01) continue;\n if (marker >= 0xd0 && marker <= 0xd7) continue;\n if (offset + 2 > source.length) break;\n const length = source.readUInt16BE(offset);\n if (length < 2 || offset + length > source.length) break;\n if (marker === 0xe1) {\n orientation = exifOrientation(source.subarray(offset + 2, offset + length)) ?? orientation;\n }\n if (startOfFrame.has(marker) && length >= 7) {\n const width = source.readUInt16BE(offset + 5);\n const height = source.readUInt16BE(offset + 3);\n return positiveDimensions(\n orientation !== undefined && orientation >= 5 ? height : width,\n orientation !== undefined && orientation >= 5 ? width : height,\n \"jpeg\",\n true,\n );\n }\n offset += length;\n }\n return undefined;\n}\n\nfunction inspectSvg(source: Buffer): SourceInspection | undefined {\n const openingTag = source\n .subarray(0, 16_384)\n .toString(\"utf8\")\n .match(/<svg\\b[^>]*>/i)?.[0];\n if (!openingTag) return undefined;\n const numberAttribute = (name: string): number | undefined => {\n const value = openingTag.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']\\\\s*([0-9.]+)`, \"i\"))?.[1];\n const parsed = value ? Number(value) : Number.NaN;\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n };\n let width = numberAttribute(\"width\");\n let height = numberAttribute(\"height\");\n const viewBox = openingTag\n .match(/\\bviewBox\\s*=\\s*[\"']\\s*[-+0-9.e]+[ ,]+[-+0-9.e]+[ ,]+([-+0-9.e]+)[ ,]+([-+0-9.e]+)/i)\n ?.slice(1)\n .map(Number);\n if (!width && viewBox?.[0] && viewBox[0] > 0) width = viewBox[0];\n if (!height && viewBox?.[1] && viewBox[1] > 0) height = viewBox[1];\n if (!width && height && viewBox?.[0] && viewBox?.[1]) width = height * (viewBox[0] / viewBox[1]);\n if (!height && width && viewBox?.[0] && viewBox?.[1]) height = width / (viewBox[0] / viewBox[1]);\n return width && height ? positiveDimensions(width, height, \"svg\", false) : undefined;\n}\n\nfunction inspectWebp(source: Buffer): SourceInspection | undefined {\n if (\n source.length < 30 ||\n source.subarray(0, 4).toString(\"ascii\") !== \"RIFF\" ||\n source.subarray(8, 12).toString(\"ascii\") !== \"WEBP\"\n ) {\n return undefined;\n }\n const chunk = source.subarray(12, 16).toString(\"ascii\");\n if (chunk === \"VP8X\") {\n const width = 1 + source.readUIntLE(24, 3);\n const height = 1 + source.readUIntLE(27, 3);\n return positiveDimensions(width, height, \"webp\", false, Boolean(source[20]! & 0x02));\n }\n if (chunk === \"VP8 \") {\n return positiveDimensions(\n source.readUInt16LE(26) & 0x3fff,\n source.readUInt16LE(28) & 0x3fff,\n \"webp\",\n false,\n );\n }\n if (chunk === \"VP8L\" && source[20] === 0x2f) {\n const bits = source.readUInt32LE(21);\n return positiveDimensions(1 + (bits & 0x3fff), 1 + ((bits >>> 14) & 0x3fff), \"webp\", false);\n }\n return undefined;\n}\n\nfunction inspectAvif(source: Buffer): SourceInspection | undefined {\n if (source.length < 24 || source.subarray(4, 8).toString(\"ascii\") !== \"ftyp\") return undefined;\n const typeOffset = source.indexOf(Buffer.from(\"ispe\"));\n if (typeOffset < 0 || typeOffset + 16 > source.length) return undefined;\n return positiveDimensions(\n source.readUInt32BE(typeOffset + 8),\n source.readUInt32BE(typeOffset + 12),\n \"avif\",\n false,\n );\n}\n\nexport function inspectSource(sourcePath: string, source: Buffer): SourceInspection {\n const inspection =\n inspectPng(source) ??\n inspectGif(source) ??\n inspectJpeg(source) ??\n inspectSvg(source) ??\n inspectWebp(source) ??\n inspectAvif(source);\n if (!inspection) {\n throw new Error(\n `@askrjs/vite could not determine intrinsic dimensions for pass-through image ${sourcePath}.`,\n );\n }\n return inspection;\n}\n","import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { inspectSource, type AssetFormat } from \"./image-inspection\";\nimport { normalizeDeclarationOptions, normalizeImageOptions } from \"./image-options\";\nimport type { ImageOptions, ImageOutputFormat, ImagePipelineOptions } from \"./image-types\";\n\ntype SharpFactory = (typeof import(\"sharp\"))[\"default\"];\nexport type SharpLoader = () => Promise<SharpFactory>;\ntype TransformFormat = \"avif\" | \"webp\" | \"jpeg\" | \"png\";\n\nexport interface EmittedVariant {\n referenceId: string;\n width: number;\n height: number;\n format: AssetFormat;\n mime: string;\n}\n\nexport interface AssetPluginContext {\n emitFile(file: { type: \"asset\"; name: string; source: string | Uint8Array }): string;\n getFileName(referenceId: string): string;\n}\n\nexport interface ProcessedImage {\n declarationKey: string;\n sourcePath: string;\n sourceHash: string;\n declarationOptions: ImageOptions;\n transformKey: string;\n encoder: string;\n fallback: EmittedVariant;\n variants: EmittedVariant[];\n passThrough: boolean;\n}\n\nfunction hash(value: string | Buffer): string {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nexport function declarationKey(sourcePath: string, options: ImageOptions): string {\n return hash(`${sourcePath}\\0${JSON.stringify(normalizeDeclarationOptions(options))}`);\n}\n\nexport const defaultSharpLoader: SharpLoader = async () => (await import(\"sharp\")).default;\n\nasync function loadSharp(loader: SharpLoader): Promise<SharpFactory> {\n try {\n return await loader();\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ERR_MODULE_NOT_FOUND\") {\n throw new Error(\n '@askrjs/vite responsive images require the optional peer \"sharp\". Install sharp@^0.35.3 and rebuild.',\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nfunction sourceFormat(format: string | undefined): \"jpeg\" | \"png\" | undefined {\n if (format === \"jpeg\" || format === \"jpg\") return \"jpeg\";\n return format === \"png\" ? \"png\" : undefined;\n}\n\nfunction extension(format: AssetFormat): string {\n return format === \"jpeg\" ? \"jpg\" : format;\n}\n\nfunction mime(format: AssetFormat): string {\n return format === \"jpeg\" ? \"image/jpeg\" : `image/${format}`;\n}\n\nfunction outputName(sourcePath: string, width: number, format: EmittedVariant[\"format\"]): string {\n const basename = path.basename(sourcePath, path.extname(sourcePath));\n return `${basename}-${width}.${extension(format)}`;\n}\n\nfunction outputHeight(\n width: number,\n sourceWidth: number,\n sourceHeight: number,\n aspectRatio: number | undefined,\n): number {\n return Math.max(1, Math.round(width / (aspectRatio ?? sourceWidth / sourceHeight)));\n}\n\nasync function encodedVariant(\n sharp: SharpFactory,\n source: Buffer,\n cacheDir: string,\n transformKey: string,\n width: number,\n height: number,\n format: TransformFormat,\n options: ReturnType<typeof normalizeImageOptions>,\n): Promise<Buffer> {\n const cachePath = path.join(cacheDir, `${transformKey}-${width}.${extension(format)}`);\n const cached = await fs.readFile(cachePath).catch(() => undefined);\n if (cached) return cached;\n\n let pipeline = sharp(source, { animated: false }).autoOrient();\n pipeline =\n options.fit === \"cover\"\n ? pipeline.resize({ width, height, fit: \"cover\", position: options.position })\n : pipeline.resize({ width, fit: \"inside\", withoutEnlargement: true });\n if (format === \"avif\") pipeline = pipeline.avif({ quality: options.quality.avif });\n else if (format === \"webp\") pipeline = pipeline.webp({ quality: options.quality.webp });\n else if (format === \"jpeg\") pipeline = pipeline.jpeg({ quality: options.quality.jpeg });\n else {\n pipeline = pipeline.png(\n options.quality.png === 100\n ? { compressionLevel: 9 }\n : { compressionLevel: 9, quality: options.quality.png },\n );\n }\n const encoded = await pipeline.toBuffer();\n await fs.mkdir(cacheDir, { recursive: true });\n await fs.writeFile(cachePath, encoded);\n return encoded;\n}\n\nfunction variantFormats(\n formats: readonly ImageOutputFormat[],\n fallback: \"jpeg\" | \"png\",\n): Array<\"avif\" | \"webp\" | \"jpeg\" | \"png\"> {\n const output: Array<\"avif\" | \"webp\" | \"jpeg\" | \"png\"> = [];\n for (const format of formats) {\n const resolved = format === \"source\" ? fallback : format;\n if (!output.includes(resolved)) output.push(resolved);\n }\n if (!output.includes(fallback)) output.push(fallback);\n return output;\n}\n\nfunction passThroughImage(\n context: AssetPluginContext,\n sourcePath: string,\n source: Buffer,\n width: number,\n height: number,\n format: AssetFormat,\n): { fallback: EmittedVariant; variants: EmittedVariant[] } {\n const referenceId = context.emitFile({ type: \"asset\", name: path.basename(sourcePath), source });\n const fallback = { referenceId, width, height, format, mime: mime(format) };\n return { fallback, variants: [fallback] };\n}\n\nexport async function processImage(\n context: AssetPluginContext,\n sourcePath: string,\n declarationOptions: ImageOptions,\n globalOptions: ImagePipelineOptions,\n cacheDir: string,\n sharpLoader: SharpLoader,\n): Promise<ProcessedImage> {\n const source = await fs.readFile(sourcePath);\n const sourceHash = hash(source);\n const normalized = normalizeImageOptions(globalOptions, declarationOptions);\n const inspection = inspectSource(sourcePath, source);\n const key = declarationKey(sourcePath, declarationOptions);\n const shouldPassThroughWithoutSharp =\n !inspection.transformable ||\n inspection.animated ||\n (normalized.fit === \"inside\" && inspection.width <= normalized.widths[0]!);\n if (shouldPassThroughWithoutSharp) {\n const encoder = \"passthrough\";\n return {\n declarationKey: key,\n sourcePath,\n sourceHash,\n declarationOptions: normalizeDeclarationOptions(declarationOptions),\n transformKey: hash(`${sourceHash}\\0${JSON.stringify(normalized)}\\0${encoder}`),\n encoder,\n ...passThroughImage(\n context,\n sourcePath,\n source,\n inspection.width,\n inspection.height,\n inspection.format,\n ),\n passThrough: true,\n };\n }\n const sharp = await loadSharp(sharpLoader);\n const metadata = await sharp(source, { animated: true }).metadata();\n const sourceWidth = metadata.autoOrient.width ?? metadata.width;\n const sourceHeight =\n (metadata.pages ?? 1) > 1\n ? (metadata.pageHeight ?? metadata.height)\n : (metadata.autoOrient.height ?? metadata.height);\n if (!sourceWidth || !sourceHeight) {\n throw new Error(`@askrjs/vite could not determine intrinsic dimensions for ${sourcePath}.`);\n }\n const encoder = `sharp@${sharp.versions.sharp}`;\n const transformKey = hash(`${sourceHash}\\0${JSON.stringify(normalized)}\\0${encoder}`);\n const fallbackFormat = sourceFormat(metadata.format);\n\n const shouldPassThrough = (metadata.pages ?? 1) > 1 || !fallbackFormat;\n if (shouldPassThrough) {\n return {\n declarationKey: key,\n sourcePath,\n sourceHash,\n declarationOptions: normalizeDeclarationOptions(declarationOptions),\n transformKey,\n encoder,\n ...passThroughImage(\n context,\n sourcePath,\n source,\n sourceWidth,\n sourceHeight,\n fallbackFormat ?? inspection.format,\n ),\n passThrough: true,\n };\n }\n\n const maximumWidth =\n normalized.fit === \"cover\"\n ? Math.min(sourceWidth, Math.floor(sourceHeight * normalized.aspectRatio!))\n : sourceWidth;\n if (maximumWidth < 1) {\n throw new Error(\n `@askrjs/vite cannot crop ${sourcePath} to aspect ratio ${normalized.aspectRatio} without upscaling.`,\n );\n }\n const widths = normalized.widths.filter((width) => width <= maximumWidth);\n if (!widths.includes(maximumWidth)) widths.push(maximumWidth);\n widths.sort((left, right) => left - right);\n const variants: EmittedVariant[] = [];\n for (const format of variantFormats(normalized.formats, fallbackFormat)) {\n for (const width of widths) {\n const height = outputHeight(\n width,\n sourceWidth,\n sourceHeight,\n normalized.fit === \"cover\" ? normalized.aspectRatio : undefined,\n );\n const buffer = await encodedVariant(\n sharp,\n source,\n cacheDir,\n transformKey,\n width,\n height,\n format,\n normalized,\n );\n variants.push({\n referenceId: context.emitFile({\n type: \"asset\",\n name: outputName(sourcePath, width, format),\n source: buffer,\n }),\n width,\n height,\n format,\n mime: mime(format),\n });\n }\n }\n return {\n declarationKey: key,\n sourcePath,\n sourceHash,\n declarationOptions: normalizeDeclarationOptions(declarationOptions),\n transformKey,\n encoder,\n fallback: variants.filter((variant) => variant.format === fallbackFormat).at(-1)!,\n variants,\n passThrough: false,\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ResolvedConfig } from \"vite\";\nimport { imageDeclarationMask } from \"./image-lexical\";\nimport {\n IMAGE_METADATA_PATH,\n IMAGE_METADATA_VERSION,\n type ImageMetadataEntry,\n type ImageMetadataRecord,\n} from \"./image-metadata\";\nimport type { ImageOptions, ImagePipelineOptions, ResponsiveImage } from \"./image-types\";\nimport {\n declarationKey,\n defaultSharpLoader,\n processImage,\n type AssetPluginContext,\n type EmittedVariant,\n type ProcessedImage,\n type SharpLoader,\n} from \"./image-transform\";\n\ninterface Declaration {\n start: number;\n end: number;\n source: string;\n options: ImageOptions;\n}\n\nconst IMAGE_CALL = /\\bimage\\s*\\(\\s*new\\s+URL\\s*\\(\\s*([\"'])([^\"']+)\\1\\s*,\\s*import\\.meta\\.url\\s*\\)/g;\n\nfunction staticJson(source: string, id: string): string {\n let output = \"\";\n for (let index = 0; index < source.length;) {\n const character = source[index]!;\n if (/\\s/.test(character) || \"{}[]:\".includes(character)) {\n output += character;\n index += 1;\n continue;\n }\n if (character === \",\") {\n let next = index + 1;\n while (/\\s/.test(source[next] ?? \"\")) next += 1;\n if (source[next] !== \"}\" && source[next] !== \"]\") output += character;\n index += 1;\n continue;\n }\n if (character === '\"' || character === \"'\") {\n let end = index + 1;\n while (end < source.length && source[end] !== character) {\n if (source[end] === \"\\\\\") {\n throw new Error(\n `@askrjs/vite image() option strings in ${id} cannot contain escape sequences.`,\n );\n }\n end += 1;\n }\n if (end >= source.length) {\n throw new Error(`@askrjs/vite found an unterminated image option in ${id}.`);\n }\n output += JSON.stringify(source.slice(index + 1, end));\n index = end + 1;\n continue;\n }\n const number = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:e[+-]?\\d+)?/i.exec(source.slice(index));\n if (number) {\n output += number[0];\n index += number[0].length;\n continue;\n }\n const identifier = /^[A-Za-z_]\\w*/.exec(source.slice(index));\n if (identifier) {\n let next = index + identifier[0].length;\n while (/\\s/.test(source[next] ?? \"\")) next += 1;\n if (source[next] === \":\") output += JSON.stringify(identifier[0]);\n else if ([\"true\", \"false\", \"null\"].includes(identifier[0])) output += identifier[0];\n else {\n throw new Error(\n `@askrjs/vite image() options in ${id} must not reference ${identifier[0]}; use a static object literal.`,\n );\n }\n index += identifier[0].length;\n continue;\n }\n throw new Error(\n `@askrjs/vite image() options in ${id} must be a static object literal so builds and direct SSG imports agree.`,\n );\n }\n return output;\n}\n\nfunction staticOptions(source: string, id: string): ImageOptions {\n const trimmed = source.trim();\n if (!trimmed) return {};\n let value: unknown;\n try {\n value = JSON.parse(staticJson(trimmed, id));\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"@askrjs/vite\")) throw error;\n throw new Error(`@askrjs/vite could not parse image() options in ${id}.`, { cause: error });\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`@askrjs/vite image() options in ${id} must be an object literal.`);\n }\n return value as ImageOptions;\n}\n\nfunction findCallEnd(code: string, start: number): number {\n let depth = 1;\n let quote = \"\";\n let escaped = false;\n for (let index = start; index < code.length; index += 1) {\n const character = code[index]!;\n if (quote) {\n if (escaped) escaped = false;\n else if (character === \"\\\\\") escaped = true;\n else if (character === quote) quote = \"\";\n continue;\n }\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n if (character === \"(\") depth += 1;\n if (character === \")\") {\n depth -= 1;\n if (depth === 0) return index;\n }\n }\n return -1;\n}\n\nfunction declarations(code: string, id: string): Declaration[] {\n const mask = imageDeclarationMask(code);\n if (!mask) return [];\n const output: Declaration[] = [];\n IMAGE_CALL.lastIndex = 0;\n for (let match = IMAGE_CALL.exec(code); match; match = IMAGE_CALL.exec(code)) {\n if (!mask[match.index]) continue;\n const afterUrl = IMAGE_CALL.lastIndex;\n const end = findCallEnd(code, afterUrl);\n if (end < 0) throw new Error(`@askrjs/vite found an unterminated image() call in ${id}.`);\n const remainder = code.slice(afterUrl, end).trim();\n if (remainder && !remainder.startsWith(\",\")) {\n throw new Error(`@askrjs/vite could not parse image() declaration in ${id}.`);\n }\n output.push({\n start: match.index,\n end: end + 1,\n source: match[2]!,\n options: staticOptions(remainder.replace(/^,/, \"\"), id),\n });\n IMAGE_CALL.lastIndex = end + 1;\n }\n return output;\n}\n\nfunction urlExpression(referenceId: string): string {\n return `import.meta.ROLLUP_FILE_URL_${referenceId}`;\n}\n\nfunction mime(format: EmittedVariant[\"format\"]): string {\n return format === \"jpeg\" ? \"image/jpeg\" : `image/${format}`;\n}\n\nfunction srcsetExpression(variants: readonly EmittedVariant[]): string {\n return `[${variants.map((variant) => `${urlExpression(variant.referenceId)} + ${JSON.stringify(` ${variant.width}w`)}`).join(\",\")}].join(\", \")`;\n}\n\nfunction imageExpression(processed: ProcessedImage): string {\n const fallbackVariants = processed.variants.filter(\n (variant) => variant.format === processed.fallback.format,\n );\n const modernFormats = [\"avif\", \"webp\"] as const;\n const sources = processed.passThrough\n ? []\n : modernFormats.flatMap((format) => {\n const variants = processed.variants.filter((variant) => variant.format === format);\n return variants.length === 0\n ? []\n : [`{type:${JSON.stringify(mime(format))},srcset:${srcsetExpression(variants)}}`];\n });\n return `image({__askrImage:true,src:${urlExpression(processed.fallback.referenceId)},${\n processed.passThrough ? \"\" : `srcset:${srcsetExpression(fallbackVariants)},`\n }width:${processed.fallback.width},height:${processed.fallback.height},sources:[${sources.join(\",\")}]})`;\n}\n\nfunction builtUrl(base: string, fileName: string): string {\n if (/^https?:\\/\\//.test(base))\n return new URL(fileName, base.endsWith(\"/\") ? base : `${base}/`).href;\n if (base === \"\" || base === \"./\" || base === \".\")\n return `${base === \".\" ? \"./\" : base}${fileName}`;\n return `${base.endsWith(\"/\") ? base : `${base}/`}${fileName}`;\n}\n\nfunction responsiveMetadata(\n processed: ProcessedImage,\n fileName: (referenceId: string) => string,\n base: string,\n): ResponsiveImage {\n const url = (variant: EmittedVariant) => builtUrl(base, fileName(variant.referenceId));\n const srcset = (variants: readonly EmittedVariant[]) =>\n variants.map((variant) => `${url(variant)} ${variant.width}w`).join(\", \");\n const fallbackVariants = processed.variants.filter(\n (variant) => variant.format === processed.fallback.format,\n );\n return {\n __askrImage: true,\n src: url(processed.fallback),\n ...(processed.passThrough ? {} : { srcset: srcset(fallbackVariants) }),\n width: processed.fallback.width,\n height: processed.fallback.height,\n sources: processed.passThrough\n ? []\n : ([\"avif\", \"webp\"] as const).flatMap((format) => {\n const variants = processed.variants.filter((variant) => variant.format === format);\n return variants.length === 0 ? [] : [{ type: mime(format), srcset: srcset(variants) }];\n }),\n };\n}\n\nexport class ImagePipeline {\n readonly #options: ImagePipelineOptions;\n readonly #processed = new Map<string, ProcessedImage>();\n readonly #sharpLoader: SharpLoader;\n #config: ResolvedConfig | undefined;\n\n constructor(options: ImagePipelineOptions, sharpLoader: SharpLoader = defaultSharpLoader) {\n this.#options = options;\n this.#sharpLoader = sharpLoader;\n }\n\n configure(config: ResolvedConfig): void {\n this.#config = config;\n }\n\n async transform(\n context: AssetPluginContext,\n code: string,\n id: string,\n ): Promise<string | undefined> {\n const found = declarations(code, id);\n if (found.length === 0) return undefined;\n if (!this.#config) throw new Error(\"@askrjs/vite image pipeline was not configured.\");\n if (this.#config.command !== \"build\") {\n throw new Error(\"@askrjs/vite responsive image declarations currently require a Vite build.\");\n }\n const cacheDir = path.join(this.#config.root, \"node_modules/.cache/@askrjs/vite/images\");\n let transformed = code;\n for (const declaration of [...found].reverse()) {\n const sourcePath = path.resolve(path.dirname(id.split(\"?\", 1)[0]!), declaration.source);\n const key = declarationKey(sourcePath, declaration.options);\n let processed = this.#processed.get(key);\n if (!processed) {\n processed = await processImage(\n context,\n sourcePath,\n declaration.options,\n this.#options,\n cacheDir,\n this.#sharpLoader,\n );\n this.#processed.set(key, processed);\n }\n transformed = `${transformed.slice(0, declaration.start)}${imageExpression(processed)}${transformed.slice(declaration.end)}`;\n }\n return transformed;\n }\n\n async writeMetadata(context: AssetPluginContext): Promise<void> {\n if (!this.#config || this.#processed.size === 0) return;\n const entries: Record<string, ImageMetadataEntry> = {};\n for (const processed of [...this.#processed.values()].sort((left, right) =>\n left.declarationKey.localeCompare(right.declarationKey),\n )) {\n entries[processed.declarationKey] = {\n sourcePath: processed.sourcePath,\n sourceHash: processed.sourceHash,\n declarationOptions: processed.declarationOptions,\n transformKey: processed.transformKey,\n encoder: processed.encoder,\n image: responsiveMetadata(\n processed,\n (referenceId) => context.getFileName(referenceId),\n this.#config.base,\n ),\n };\n }\n const record: ImageMetadataRecord = {\n version: IMAGE_METADATA_VERSION,\n entries,\n };\n const metadataPath = path.join(this.#config.root, IMAGE_METADATA_PATH);\n await fs.mkdir(path.dirname(metadataPath), { recursive: true });\n await fs.writeFile(metadataPath, `${JSON.stringify(record, null, 2)}\\n`, \"utf8\");\n }\n}\n","import { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\nimport { optimizeTemplateOutput } from \"./template-optimizer\";\nimport { ImagePipeline } from \"./image-pipeline\";\nimport type { ImagePipelineOptions } from \"./image-types\";\n\nconst require = createRequire(import.meta.url);\ntype TransformWithOxc = (typeof import(\"vite\"))[\"transformWithOxc\"];\nlet transformWithOxcPromise: Promise<TransformWithOxc> | undefined;\n\nasync function loadTransformWithOxc(): Promise<TransformWithOxc> {\n transformWithOxcPromise ??= (async () => {\n for (const packageName of [\"vite-plus\", \"vite\"] as const) {\n try {\n const buildTool = await import(packageName);\n if (typeof buildTool.transformWithOxc === \"function\") {\n return buildTool.transformWithOxc as TransformWithOxc;\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ERR_MODULE_NOT_FOUND\") throw error;\n }\n }\n throw new Error(\"@askrjs/vite requires either vite or vite-plus to transform JSX.\");\n })();\n return transformWithOxcPromise;\n}\n\n/** Options accepted by {@link askrVitePlugin}. */\nexport interface AskrVitePluginOptions {\n /** Transform `.jsx`/`.tsx` files with the Askr JSX runtime. Defaults to `true`. */\n transformJsx?: boolean;\n /** Hoist repeated JSX class/style literals using parsed compiled output. Defaults to `false`. */\n optimizeTemplates?: boolean;\n ssrPrecompile?: boolean;\n /** Opt into declared responsive image transforms. */\n images?: boolean | ImagePipelineOptions;\n}\n\n/**\n * Portable public plugin identity.\n *\n * Vite-compatible runners only require the plugin name. Keeping versioned Vite\n * hook types out of the installed declaration prevents consumers such as\n * vite-plus from comparing two distinct copies of Vite's recursive Plugin type.\n */\nexport interface AskrVitePlugin {\n readonly name: \"askr:vite\";\n}\n\n/**\n * Create the Askr Vite plugin, which transforms Askr JSX/TSX with oxc, wires\n * up dependency pre-bundling and aliasing for `@askrjs/askr`, and optionally\n * runs the responsive image pipeline and template optimizer.\n * JSX transform failures are reported through the active Vite/Rollup plugin\n * context with the source file and original transform detail.\n *\n * @param options Plugin configuration; all fields are optional.\n * @returns A Vite-compatible plugin object exposing the `askr:vite` name.\n */\nexport function askrVitePlugin(options: AskrVitePluginOptions = {}): AskrVitePlugin {\n const shouldTransform = options.transformJsx ?? true;\n const shouldOptimizeTemplates = options.optimizeTemplates ?? false;\n const imagePipeline = options.images\n ? new ImagePipeline(options.images === true ? {} : options.images)\n : undefined;\n const plugin = {\n name: \"askr:vite\" as const,\n enforce: \"pre\",\n config() {\n let askrEntry: string | null = null;\n try {\n askrEntry = require.resolve(\"@askrjs/askr\");\n } catch {\n askrEntry = null;\n }\n return {\n define: {\n __ASKR_OPTIMIZE_TEMPLATES__: JSON.stringify(shouldOptimizeTemplates),\n },\n resolve: {\n alias: askrEntry ? [{ find: \"@askrjs/askr\", replacement: askrEntry }] : [],\n dedupe: [\"@askrjs/askr\"],\n },\n optimizeDeps: {\n include: [\n \"@askrjs/askr\",\n \"@askrjs/askr/router\",\n \"@askrjs/askr/boot\",\n \"@askrjs/askr/control\",\n \"@askrjs/askr/fx\",\n \"@askrjs/askr/resources\",\n \"@askrjs/askr/data\",\n \"@askrjs/askr/foundations\",\n \"@askrjs/askr/foundations/icon\",\n \"@askrjs/askr/foundations/interactions\",\n \"@askrjs/askr/foundations/state\",\n \"@askrjs/askr/foundations/structures\",\n \"@askrjs/askr/foundations/utilities\",\n \"@askrjs/askr/jsx-runtime\",\n \"@askrjs/askr/jsx-dev-runtime\",\n ],\n },\n oxc: {\n jsx: { runtime: \"automatic\", importSource: \"@askrjs/askr\" },\n jsxInject: \"import { jsx, jsxs, Fragment } from '@askrjs/askr/jsx-runtime';\",\n },\n };\n },\n configResolved(config) {\n imagePipeline?.configure(config);\n },\n async transform(code, id) {\n if (id.includes(\"node_modules\")) return null;\n const imageTransformed = imagePipeline\n ? await imagePipeline.transform(this, code, id)\n : undefined;\n const input = imageTransformed ?? code;\n if (!shouldTransform || !/\\.(jsx|tsx)$/.test(id)) {\n return imageTransformed ? { code: imageTransformed, map: null } : null;\n }\n try {\n const transformWithOxc = await loadTransformWithOxc();\n const result = await transformWithOxc(input, id, {\n lang: id.endsWith(\".tsx\") ? \"tsx\" : \"jsx\",\n jsx: { runtime: \"automatic\", importSource: \"@askrjs/askr\" },\n sourcemap: true,\n });\n if (!result?.code) return null;\n return {\n code: shouldOptimizeTemplates ? optimizeTemplateOutput(result.code) : result.code,\n map: result.map,\n };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n this.error(`@askrjs/vite failed to transform ${id}: ${detail}`);\n }\n },\n async writeBundle() {\n await imagePipeline?.writeMetadata(this);\n },\n } satisfies Plugin;\n return plugin;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["mime","#options","#processed","#sharpLoader","#config"],"sources":["../src/source-map-rewrites.ts","../src/template-optimizer.ts","../src/image-lexical.ts","../src/image-declarations.ts","../src/image-inspection.ts","../src/image-transform.ts","../src/image-pipeline.ts","../src/jsx-plugin.ts"],"sourcesContent":["export interface TextEdit {\n start: number;\n end: number;\n replacement: string;\n mapTo?: number;\n}\n\nexport interface RawSourceMap {\n version: number;\n mappings: string;\n names?: string[];\n sources?: string[];\n sourcesContent?: Array<string | null>;\n file?: string;\n sourceRoot?: string;\n}\n\nconst BASE64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\nconst BASE64_VALUES = new Map([...BASE64].map((character, index) => [character, index]));\n\nfunction decodeVlq(value: string, cursor: { value: number }): number {\n let result = 0;\n let shift = 0;\n for (;;) {\n const digit = BASE64_VALUES.get(value[cursor.value++]);\n if (digit === undefined) throw new Error(\"Invalid sourcemap VLQ segment.\");\n result += (digit & 31) << shift;\n if ((digit & 32) === 0) break;\n shift += 5;\n }\n const negative = (result & 1) === 1;\n result >>= 1;\n return negative ? -result : result;\n}\n\nfunction encodeVlq(value: number): string {\n let remaining = (Math.abs(value) << 1) | (value < 0 ? 1 : 0);\n let output = \"\";\n do {\n let digit = remaining & 31;\n remaining >>>= 5;\n if (remaining > 0) digit |= 32;\n output += BASE64[digit];\n } while (remaining > 0);\n return output;\n}\n\nfunction decodeMappings(value: string): number[][][] {\n const lines: number[][][] = [];\n let source = 0;\n let originalLine = 0;\n let originalColumn = 0;\n let name = 0;\n for (const encodedLine of value.split(\";\")) {\n const segments: number[][] = [];\n let generatedColumn = 0;\n for (const encoded of encodedLine.split(\",\")) {\n if (!encoded) continue;\n const cursor = { value: 0 };\n generatedColumn += decodeVlq(encoded, cursor);\n const segment = [generatedColumn];\n if (cursor.value < encoded.length) {\n source += decodeVlq(encoded, cursor);\n originalLine += decodeVlq(encoded, cursor);\n originalColumn += decodeVlq(encoded, cursor);\n segment.push(source, originalLine, originalColumn);\n if (cursor.value < encoded.length) {\n name += decodeVlq(encoded, cursor);\n segment.push(name);\n }\n }\n segments.push(segment);\n }\n lines.push(segments);\n }\n return lines;\n}\n\nfunction encodeMappings(lines: number[][][]): string {\n let previousSource = 0;\n let previousOriginalLine = 0;\n let previousOriginalColumn = 0;\n let previousName = 0;\n return lines\n .map((segments) => {\n let previousGeneratedColumn = 0;\n return segments\n .map((segment) => {\n let encoded = encodeVlq(segment[0]! - previousGeneratedColumn);\n previousGeneratedColumn = segment[0]!;\n if (segment.length >= 4) {\n encoded += encodeVlq(segment[1]! - previousSource);\n encoded += encodeVlq(segment[2]! - previousOriginalLine);\n encoded += encodeVlq(segment[3]! - previousOriginalColumn);\n previousSource = segment[1]!;\n previousOriginalLine = segment[2]!;\n previousOriginalColumn = segment[3]!;\n if (segment.length === 5) {\n encoded += encodeVlq(segment[4]! - previousName);\n previousName = segment[4]!;\n }\n }\n return encoded;\n })\n .join(\",\");\n })\n .join(\";\");\n}\n\nfunction lineStarts(code: string): number[] {\n const starts = [0];\n for (let index = 0; index < code.length; index += 1) {\n if (code[index] === \"\\n\") starts.push(index + 1);\n }\n return starts;\n}\n\nfunction offsetAt(starts: number[], line: number, column: number): number {\n return (starts[line] ?? starts[starts.length - 1]!) + column;\n}\n\nfunction positionAt(starts: number[], offset: number): [number, number] {\n let low = 0;\n let high = starts.length;\n while (low + 1 < high) {\n const middle = (low + high) >>> 1;\n if (starts[middle]! <= offset) low = middle;\n else high = middle;\n }\n return [low, offset - starts[low]!];\n}\n\nfunction forwardOffset(offset: number, edits: readonly TextEdit[]): number {\n let delta = 0;\n for (const edit of edits) {\n if (offset < edit.start) break;\n if (offset < edit.end) return edit.start + delta;\n delta += edit.replacement.length - (edit.end - edit.start);\n }\n return offset + delta;\n}\n\nfunction reverseOffset(offset: number, edits: readonly TextEdit[]): number {\n let delta = 0;\n for (const edit of edits) {\n const generatedStart = edit.start + delta;\n const generatedEnd = generatedStart + edit.replacement.length;\n if (offset < generatedStart) break;\n if (offset < generatedEnd) return edit.start;\n delta += edit.replacement.length - (edit.end - edit.start);\n }\n return offset - delta;\n}\n\nfunction normalize(lines: number[][][]): number[][][] {\n return lines.map((segments) => {\n const sorted = segments.sort((left, right) => left[0]! - right[0]!);\n return sorted.filter((segment, index) => index === 0 || segment[0] !== sorted[index - 1]![0]);\n });\n}\n\nfunction mappingAt(lines: number[][][], starts: number[], offset: number): number[] | undefined {\n const [line, column] = positionAt(starts, offset);\n let match: number[] | undefined;\n for (const segment of lines[line] ?? []) {\n if (segment[0]! > column) break;\n if (segment.length >= 4) match = segment;\n }\n return match;\n}\n\n/** Move generated coordinates after deterministic text edits. */\nexport function remapGenerated(\n map: RawSourceMap,\n before: string,\n after: string,\n edits: readonly TextEdit[],\n): RawSourceMap {\n const beforeStarts = lineStarts(before);\n const afterStarts = lineStarts(after);\n const decoded = decodeMappings(map.mappings);\n const output: number[][][] = Array.from({ length: afterStarts.length }, () => []);\n for (const [line, segments] of decoded.entries()) {\n for (const segment of segments) {\n const offset = forwardOffset(offsetAt(beforeStarts, line, segment[0]!), edits);\n const [nextLine, nextColumn] = positionAt(afterStarts, offset);\n output[nextLine]!.push([nextColumn, ...segment.slice(1)]);\n }\n }\n let delta = 0;\n for (const edit of edits) {\n if (edit.mapTo !== undefined) {\n const mapped = mappingAt(decoded, beforeStarts, edit.mapTo);\n if (mapped) {\n const [line, column] = positionAt(afterStarts, edit.start + delta);\n output[line]!.push([column, ...mapped.slice(1)]);\n }\n }\n delta += edit.replacement.length - (edit.end - edit.start);\n }\n return { ...map, mappings: encodeMappings(normalize(output)) };\n}\n\n/** Move original coordinates back through deterministic text edits. */\nexport function remapOriginal(\n map: RawSourceMap,\n original: string,\n rewritten: string,\n edits: readonly TextEdit[],\n): RawSourceMap {\n const originalStarts = lineStarts(original);\n const rewrittenStarts = lineStarts(rewritten);\n const lines = decodeMappings(map.mappings);\n for (const segments of lines) {\n for (const segment of segments) {\n if (segment.length < 4 || segment[1] !== 0) continue;\n const offset = reverseOffset(offsetAt(rewrittenStarts, segment[2]!, segment[3]!), edits);\n const [line, column] = positionAt(originalStarts, offset);\n segment[2] = line;\n segment[3] = column;\n }\n }\n return {\n ...map,\n mappings: encodeMappings(lines),\n sourcesContent: map.sources?.map((_source, index) =>\n index === 0 ? original : (map.sourcesContent?.[index] ?? null),\n ),\n };\n}\n\n/** Build a complete map for a rewritten source when no downstream map exists. */\nexport function sourceMapForRewrite(\n original: string,\n rewritten: string,\n edits: readonly TextEdit[],\n id: string,\n): RawSourceMap {\n const originalStarts = lineStarts(original);\n const rewrittenStarts = lineStarts(rewritten);\n const lines: number[][][] = Array.from({ length: rewrittenStarts.length }, () => []);\n for (let offset = 0; offset < rewritten.length; offset += 1) {\n const [generatedLine, generatedColumn] = positionAt(rewrittenStarts, offset);\n const [originalLine, originalColumn] = positionAt(originalStarts, reverseOffset(offset, edits));\n lines[generatedLine]!.push([generatedColumn, 0, originalLine, originalColumn]);\n }\n return {\n version: 3,\n names: [],\n sources: [id],\n sourcesContent: [original],\n mappings: encodeMappings(lines),\n };\n}\n\nexport function traceSourcePosition(\n map: RawSourceMap,\n line: number,\n column: number,\n): { line: number; column: number } | undefined {\n const segments = decodeMappings(map.mappings)[line] ?? [];\n let match: number[] | undefined;\n for (const segment of segments) {\n if (segment[0]! > column) break;\n if (segment.length >= 4) match = segment;\n }\n return match ? { line: match[2]!, column: match[3]! } : undefined;\n}\n","import { parseSync, Visitor, type ObjectProperty } from \"oxc-parser\";\nimport type { TextEdit } from \"./source-map-rewrites\";\n\nconst OPTIMIZED_PROPS = new Set([\"class\", \"className\", \"style\"]);\nconst JSX_RUNTIME_SOURCE = \"@askrjs/askr/jsx-runtime\";\nconst JSX_FACTORIES = new Set([\"jsx\", \"jsxs\", \"jsxDEV\"]);\n\ntype Candidate = {\n literal: string;\n start: number;\n end: number;\n};\n\nfunction importedName(specifier: { imported: { type: string; name?: string; value?: unknown } }) {\n return specifier.imported.type === \"Identifier\"\n ? specifier.imported.name\n : specifier.imported.value;\n}\n\nfunction collectRuntimeFactories(program: ReturnType<typeof parseSync>[\"program\"]): Set<string> {\n const factories = new Set<string>();\n\n for (const statement of program.body) {\n if (statement.type !== \"ImportDeclaration\" || statement.source.value !== JSX_RUNTIME_SOURCE) {\n continue;\n }\n\n for (const specifier of statement.specifiers) {\n if (\n specifier.type === \"ImportSpecifier\" &&\n JSX_FACTORIES.has(String(importedName(specifier)))\n ) {\n factories.add(specifier.local.name);\n }\n }\n }\n\n return factories;\n}\n\nfunction collectCandidate(\n property: ObjectProperty,\n code: string,\n candidates: Map<string, Candidate[]>,\n) {\n if (\n property.kind !== \"init\" ||\n property.computed ||\n property.method ||\n property.key.type !== \"Identifier\" ||\n !OPTIMIZED_PROPS.has(property.key.name) ||\n property.value.type !== \"Literal\" ||\n typeof property.value.value !== \"string\"\n ) {\n return;\n }\n\n const literal = code.slice(property.value.start, property.value.end);\n const cacheKey = `${property.key.name}:${literal}`;\n const group = candidates.get(cacheKey) ?? [];\n group.push({\n literal,\n start: property.value.start,\n end: property.value.end,\n });\n candidates.set(cacheKey, group);\n}\n\nexport interface OptimizedTemplateOutput {\n code: string;\n edits: TextEdit[];\n}\n\nexport function optimizeTemplateOutputWithEdits(code: string): OptimizedTemplateOutput {\n const parsed = parseSync(\"askr-compiled.js\", code, {\n lang: \"js\",\n sourceType: \"module\",\n });\n if (parsed.errors.length > 0) return { code, edits: [] };\n\n const runtimeFactories = collectRuntimeFactories(parsed.program);\n if (runtimeFactories.size === 0) return { code, edits: [] };\n\n const candidates = new Map<string, Candidate[]>();\n const identifiers = new Set<string>();\n new Visitor({\n Identifier(identifier) {\n identifiers.add(identifier.name);\n },\n CallExpression(call) {\n if (\n call.callee.type !== \"Identifier\" ||\n !runtimeFactories.has(call.callee.name) ||\n call.arguments[1]?.type !== \"ObjectExpression\"\n ) {\n return;\n }\n\n for (const property of call.arguments[1].properties) {\n if (property.type === \"Property\") {\n collectCandidate(property, code, candidates);\n }\n }\n },\n }).visit(parsed.program);\n\n const declarations: string[] = [];\n const replacements: Array<{ start: number; end: number; identifier: string }> = [];\n let hoistIndex = 0;\n for (const group of candidates.values()) {\n if (group.length < 2) continue;\n\n let identifier: string;\n do {\n identifier = `__askrStaticLiteral${hoistIndex++}`;\n } while (identifiers.has(identifier));\n identifiers.add(identifier);\n declarations.push(`const ${identifier} = ${group[0].literal};`);\n for (const candidate of group) {\n replacements.push({ start: candidate.start, end: candidate.end, identifier });\n }\n }\n\n if (declarations.length === 0) return { code, edits: [] };\n\n const prefix = `${declarations.join(\"\\n\")}\\n`;\n const edits: TextEdit[] = [\n { start: 0, end: 0, replacement: prefix, mapTo: replacements[0]!.start },\n ...replacements\n .map(({ start, end, identifier }) => ({ start, end, replacement: identifier }))\n .sort((left, right) => left.start - right.start),\n ];\n let optimized = code;\n for (const replacement of replacements.sort((left, right) => right.start - left.start)) {\n optimized =\n optimized.slice(0, replacement.start) +\n replacement.identifier +\n optimized.slice(replacement.end);\n }\n return { code: `${prefix}${optimized}`, edits };\n}\n\nexport function optimizeTemplateOutput(code: string): string {\n return optimizeTemplateOutputWithEdits(code).code;\n}\n","const IMAGE_IMPORT = /from\\s+[\"']@askrjs\\/vite\\/image[\"']/g;\n\nfunction lexicalCodeMask(source: string): Uint8Array {\n const mask = new Uint8Array(source.length);\n let state: \"code\" | \"single\" | \"double\" | \"template\" | \"line-comment\" | \"block-comment\" = \"code\";\n let escaped = false;\n for (let index = 0; index < source.length; index += 1) {\n const character = source[index]!;\n const next = source[index + 1];\n if (state === \"code\") {\n if (character === \"/\" && next === \"/\") {\n state = \"line-comment\";\n index += 1;\n } else if (character === \"/\" && next === \"*\") {\n state = \"block-comment\";\n index += 1;\n } else if (character === \"'\") state = \"single\";\n else if (character === '\"') state = \"double\";\n else if (character === \"`\") state = \"template\";\n else mask[index] = 1;\n continue;\n }\n if (state === \"line-comment\") {\n if (character === \"\\n\" || character === \"\\r\") {\n state = \"code\";\n mask[index] = 1;\n }\n continue;\n }\n if (state === \"block-comment\") {\n if (character === \"*\" && next === \"/\") {\n state = \"code\";\n index += 1;\n }\n continue;\n }\n if (escaped) escaped = false;\n else if (character === \"\\\\\") escaped = true;\n else if (\n (state === \"single\" && character === \"'\") ||\n (state === \"double\" && character === '\"') ||\n (state === \"template\" && character === \"`\")\n ) {\n state = \"code\";\n }\n }\n return mask;\n}\n\nexport function imageDeclarationMask(code: string): Uint8Array | undefined {\n const mask = lexicalCodeMask(code);\n IMAGE_IMPORT.lastIndex = 0;\n for (let match = IMAGE_IMPORT.exec(code); match; match = IMAGE_IMPORT.exec(code)) {\n if (mask[match.index]) return mask;\n }\n return undefined;\n}\n","import { imageDeclarationMask } from \"./image-lexical\";\nimport type { ImageOptions } from \"./image-types\";\n\nexport interface ImageDeclaration {\n start: number;\n end: number;\n source: string;\n options: ImageOptions;\n}\n\nconst IMAGE_CALL = /\\bimage\\s*\\(\\s*new\\s+URL\\s*\\(\\s*([\"'])([^\"']+)\\1\\s*,\\s*import\\.meta\\.url\\s*\\)/g;\n\nfunction staticJson(source: string, id: string): string {\n let output = \"\";\n for (let index = 0; index < source.length;) {\n const character = source[index]!;\n if (/\\s/.test(character) || \"{}[]:\".includes(character)) {\n output += character;\n index += 1;\n continue;\n }\n if (character === \",\") {\n let next = index + 1;\n while (/\\s/.test(source[next] ?? \"\")) next += 1;\n if (source[next] !== \"}\" && source[next] !== \"]\") output += character;\n index += 1;\n continue;\n }\n if (character === '\"' || character === \"'\") {\n let end = index + 1;\n while (end < source.length && source[end] !== character) {\n if (source[end] === \"\\\\\") {\n throw new Error(\n `@askrjs/vite image() option strings in ${id} cannot contain escape sequences.`,\n );\n }\n end += 1;\n }\n if (end >= source.length) {\n throw new Error(`@askrjs/vite found an unterminated image option in ${id}.`);\n }\n output += JSON.stringify(source.slice(index + 1, end));\n index = end + 1;\n continue;\n }\n const number = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:e[+-]?\\d+)?/i.exec(source.slice(index));\n if (number) {\n output += number[0];\n index += number[0].length;\n continue;\n }\n const identifier = /^[A-Za-z_]\\w*/.exec(source.slice(index));\n if (identifier) {\n let next = index + identifier[0].length;\n while (/\\s/.test(source[next] ?? \"\")) next += 1;\n if (source[next] === \":\") output += JSON.stringify(identifier[0]);\n else if ([\"true\", \"false\", \"null\"].includes(identifier[0])) output += identifier[0];\n else {\n throw new Error(\n `@askrjs/vite image() options in ${id} must not reference ${identifier[0]}; use a static object literal.`,\n );\n }\n index += identifier[0].length;\n continue;\n }\n throw new Error(\n `@askrjs/vite image() options in ${id} must be a static object literal so builds and direct SSG imports agree.`,\n );\n }\n return output;\n}\n\nfunction staticOptions(source: string, id: string): ImageOptions {\n const trimmed = source.trim();\n if (!trimmed) return {};\n let value: unknown;\n try {\n value = JSON.parse(staticJson(trimmed, id));\n } catch (error) {\n if (error instanceof Error && error.message.startsWith(\"@askrjs/vite\")) throw error;\n throw new Error(`@askrjs/vite could not parse image() options in ${id}.`, { cause: error });\n }\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`@askrjs/vite image() options in ${id} must be an object literal.`);\n }\n return value as ImageOptions;\n}\n\nfunction findCallEnd(code: string, start: number): number {\n let depth = 1;\n let quote = \"\";\n let escaped = false;\n for (let index = start; index < code.length; index += 1) {\n const character = code[index]!;\n if (quote) {\n if (escaped) escaped = false;\n else if (character === \"\\\\\") escaped = true;\n else if (character === quote) quote = \"\";\n continue;\n }\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n if (character === \"(\") depth += 1;\n if (character === \")\") {\n depth -= 1;\n if (depth === 0) return index;\n }\n }\n return -1;\n}\n\nexport function imageDeclarations(code: string, id: string): ImageDeclaration[] {\n const mask = imageDeclarationMask(code);\n if (!mask) return [];\n const output: ImageDeclaration[] = [];\n IMAGE_CALL.lastIndex = 0;\n for (let match = IMAGE_CALL.exec(code); match; match = IMAGE_CALL.exec(code)) {\n if (!mask[match.index]) continue;\n const afterUrl = IMAGE_CALL.lastIndex;\n const end = findCallEnd(code, afterUrl);\n if (end < 0) throw new Error(`@askrjs/vite found an unterminated image() call in ${id}.`);\n const remainder = code.slice(afterUrl, end).trim();\n if (remainder && !remainder.startsWith(\",\")) {\n throw new Error(`@askrjs/vite could not parse image() declaration in ${id}.`);\n }\n output.push({\n start: match.index,\n end: end + 1,\n source: match[2]!,\n options: staticOptions(remainder.replace(/^,/, \"\"), id),\n });\n IMAGE_CALL.lastIndex = end + 1;\n }\n return output;\n}\n","export type AssetFormat = \"avif\" | \"webp\" | \"jpeg\" | \"png\" | \"gif\" | \"svg\";\n\nexport interface SourceInspection {\n width: number;\n height: number;\n format: AssetFormat;\n transformable: boolean;\n animated: boolean;\n}\n\nfunction positiveDimensions(\n width: number,\n height: number,\n format: AssetFormat,\n transformable: boolean,\n animated = false,\n): SourceInspection | undefined {\n return width > 0 && height > 0 ? { width, height, format, transformable, animated } : undefined;\n}\n\nfunction inspectPng(source: Buffer): SourceInspection | undefined {\n if (\n source.length < 24 ||\n !source.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))\n ) {\n return undefined;\n }\n return positiveDimensions(\n source.readUInt32BE(16),\n source.readUInt32BE(20),\n \"png\",\n true,\n source.includes(Buffer.from(\"acTL\")),\n );\n}\n\nfunction inspectGif(source: Buffer): SourceInspection | undefined {\n if (source.length < 10 || !/^GIF8[79]a$/.test(source.subarray(0, 6).toString(\"ascii\"))) {\n return undefined;\n }\n return positiveDimensions(source.readUInt16LE(6), source.readUInt16LE(8), \"gif\", false, true);\n}\n\nfunction exifOrientation(segment: Buffer): number | undefined {\n if (segment.length < 14 || segment.subarray(0, 6).toString(\"binary\") !== \"Exif\\0\\0\") {\n return undefined;\n }\n const tiff = 6;\n const byteOrder = segment.subarray(tiff, tiff + 2).toString(\"ascii\");\n const littleEndian = byteOrder === \"II\";\n if (!littleEndian && byteOrder !== \"MM\") return undefined;\n const read16 = (offset: number): number | undefined => {\n const absolute = tiff + offset;\n if (absolute < tiff || absolute + 2 > segment.length) return undefined;\n return littleEndian ? segment.readUInt16LE(absolute) : segment.readUInt16BE(absolute);\n };\n const read32 = (offset: number): number | undefined => {\n const absolute = tiff + offset;\n if (absolute < tiff || absolute + 4 > segment.length) return undefined;\n return littleEndian ? segment.readUInt32LE(absolute) : segment.readUInt32BE(absolute);\n };\n if (read16(2) !== 42) return undefined;\n const directoryOffset = read32(4);\n if (directoryOffset === undefined) return undefined;\n const entries = read16(directoryOffset);\n if (entries === undefined) return undefined;\n for (let index = 0; index < entries; index += 1) {\n const entry = directoryOffset + 2 + index * 12;\n if (read16(entry) !== 0x0112 || read16(entry + 2) !== 3 || read32(entry + 4) !== 1) {\n continue;\n }\n const orientation = read16(entry + 8);\n return orientation && orientation >= 1 && orientation <= 8 ? orientation : undefined;\n }\n return undefined;\n}\n\nfunction inspectJpeg(source: Buffer): SourceInspection | undefined {\n if (source.length < 4 || source[0] !== 0xff || source[1] !== 0xd8) return undefined;\n const startOfFrame = new Set([\n 0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf,\n ]);\n let orientation: number | undefined;\n let offset = 2;\n while (offset + 8 < source.length) {\n if (source[offset] !== 0xff) {\n offset += 1;\n continue;\n }\n while (source[offset] === 0xff) offset += 1;\n const marker = source[offset++]!;\n if (marker === 0xd8 || marker === 0xd9 || marker === 0x01) continue;\n if (marker >= 0xd0 && marker <= 0xd7) continue;\n if (offset + 2 > source.length) break;\n const length = source.readUInt16BE(offset);\n if (length < 2 || offset + length > source.length) break;\n if (marker === 0xe1) {\n orientation = exifOrientation(source.subarray(offset + 2, offset + length)) ?? orientation;\n }\n if (startOfFrame.has(marker) && length >= 7) {\n const width = source.readUInt16BE(offset + 5);\n const height = source.readUInt16BE(offset + 3);\n return positiveDimensions(\n orientation !== undefined && orientation >= 5 ? height : width,\n orientation !== undefined && orientation >= 5 ? width : height,\n \"jpeg\",\n true,\n );\n }\n offset += length;\n }\n return undefined;\n}\n\nfunction inspectSvg(source: Buffer): SourceInspection | undefined {\n const openingTag = source\n .subarray(0, 16_384)\n .toString(\"utf8\")\n .match(/<svg\\b[^>]*>/i)?.[0];\n if (!openingTag) return undefined;\n const numberAttribute = (name: string): number | undefined => {\n const value = openingTag.match(new RegExp(`\\\\b${name}\\\\s*=\\\\s*[\"']\\\\s*([0-9.]+)`, \"i\"))?.[1];\n const parsed = value ? Number(value) : Number.NaN;\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n };\n let width = numberAttribute(\"width\");\n let height = numberAttribute(\"height\");\n const viewBox = openingTag\n .match(/\\bviewBox\\s*=\\s*[\"']\\s*[-+0-9.e]+[ ,]+[-+0-9.e]+[ ,]+([-+0-9.e]+)[ ,]+([-+0-9.e]+)/i)\n ?.slice(1)\n .map(Number);\n if (!width && viewBox?.[0] && viewBox[0] > 0) width = viewBox[0];\n if (!height && viewBox?.[1] && viewBox[1] > 0) height = viewBox[1];\n if (!width && height && viewBox?.[0] && viewBox?.[1]) width = height * (viewBox[0] / viewBox[1]);\n if (!height && width && viewBox?.[0] && viewBox?.[1]) height = width / (viewBox[0] / viewBox[1]);\n return width && height ? positiveDimensions(width, height, \"svg\", false) : undefined;\n}\n\nfunction inspectWebp(source: Buffer): SourceInspection | undefined {\n if (\n source.length < 30 ||\n source.subarray(0, 4).toString(\"ascii\") !== \"RIFF\" ||\n source.subarray(8, 12).toString(\"ascii\") !== \"WEBP\"\n ) {\n return undefined;\n }\n const chunk = source.subarray(12, 16).toString(\"ascii\");\n if (chunk === \"VP8X\") {\n const width = 1 + source.readUIntLE(24, 3);\n const height = 1 + source.readUIntLE(27, 3);\n return positiveDimensions(width, height, \"webp\", false, Boolean(source[20]! & 0x02));\n }\n if (chunk === \"VP8 \") {\n return positiveDimensions(\n source.readUInt16LE(26) & 0x3fff,\n source.readUInt16LE(28) & 0x3fff,\n \"webp\",\n false,\n );\n }\n if (chunk === \"VP8L\" && source[20] === 0x2f) {\n const bits = source.readUInt32LE(21);\n return positiveDimensions(1 + (bits & 0x3fff), 1 + ((bits >>> 14) & 0x3fff), \"webp\", false);\n }\n return undefined;\n}\n\nfunction inspectAvif(source: Buffer): SourceInspection | undefined {\n if (source.length < 24 || source.subarray(4, 8).toString(\"ascii\") !== \"ftyp\") return undefined;\n const typeOffset = source.indexOf(Buffer.from(\"ispe\"));\n if (typeOffset < 0 || typeOffset + 16 > source.length) return undefined;\n return positiveDimensions(\n source.readUInt32BE(typeOffset + 8),\n source.readUInt32BE(typeOffset + 12),\n \"avif\",\n false,\n );\n}\n\nexport function inspectSource(sourcePath: string, source: Buffer): SourceInspection {\n const inspection =\n inspectPng(source) ??\n inspectGif(source) ??\n inspectJpeg(source) ??\n inspectSvg(source) ??\n inspectWebp(source) ??\n inspectAvif(source);\n if (!inspection) {\n throw new Error(\n `@askrjs/vite could not determine intrinsic dimensions for pass-through image ${sourcePath}.`,\n );\n }\n return inspection;\n}\n","import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { inspectSource, type AssetFormat } from \"./image-inspection\";\nimport { normalizeDeclarationOptions, normalizeImageOptions } from \"./image-options\";\nimport type { ImageOptions, ImageOutputFormat, ImagePipelineOptions } from \"./image-types\";\n\ntype SharpFactory = (typeof import(\"sharp\"))[\"default\"];\nexport type SharpLoader = () => Promise<SharpFactory>;\ntype TransformFormat = \"avif\" | \"webp\" | \"jpeg\" | \"png\";\n\nexport interface EmittedVariant {\n referenceId: string;\n width: number;\n height: number;\n format: AssetFormat;\n mime: string;\n}\n\nexport interface AssetPluginContext {\n emitFile(file: { type: \"asset\"; name: string; source: string | Uint8Array }): string;\n getFileName(referenceId: string): string;\n}\n\nexport interface ProcessedImage {\n declarationKey: string;\n sourcePath: string;\n sourceHash: string;\n declarationOptions: ImageOptions;\n transformKey: string;\n encoder: string;\n fallback: EmittedVariant;\n variants: EmittedVariant[];\n passThrough: boolean;\n}\n\nfunction hash(value: string | Buffer): string {\n return createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nexport function declarationKey(sourcePath: string, options: ImageOptions): string {\n return hash(`${sourcePath}\\0${JSON.stringify(normalizeDeclarationOptions(options))}`);\n}\n\nexport const defaultSharpLoader: SharpLoader = async () => (await import(\"sharp\")).default;\n\nasync function loadSharp(loader: SharpLoader): Promise<SharpFactory> {\n try {\n return await loader();\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ERR_MODULE_NOT_FOUND\") {\n throw new Error(\n '@askrjs/vite responsive images require the optional peer \"sharp\". Install sharp@^0.35.3 and rebuild.',\n { cause: error },\n );\n }\n throw error;\n }\n}\n\nfunction sourceFormat(format: string | undefined): \"jpeg\" | \"png\" | undefined {\n if (format === \"jpeg\" || format === \"jpg\") return \"jpeg\";\n return format === \"png\" ? \"png\" : undefined;\n}\n\nfunction extension(format: AssetFormat): string {\n return format === \"jpeg\" ? \"jpg\" : format;\n}\n\nfunction mime(format: AssetFormat): string {\n return format === \"jpeg\" ? \"image/jpeg\" : `image/${format}`;\n}\n\nfunction outputName(sourcePath: string, width: number, format: EmittedVariant[\"format\"]): string {\n const basename = path.basename(sourcePath, path.extname(sourcePath));\n return `${basename}-${width}.${extension(format)}`;\n}\n\nfunction outputHeight(\n width: number,\n sourceWidth: number,\n sourceHeight: number,\n aspectRatio: number | undefined,\n): number {\n return Math.max(1, Math.round(width / (aspectRatio ?? sourceWidth / sourceHeight)));\n}\n\nasync function encodedVariant(\n sharp: SharpFactory,\n source: Buffer,\n cacheDir: string,\n transformKey: string,\n width: number,\n height: number,\n format: TransformFormat,\n options: ReturnType<typeof normalizeImageOptions>,\n): Promise<Buffer> {\n const cachePath = path.join(cacheDir, `${transformKey}-${width}.${extension(format)}`);\n const cached = await fs.readFile(cachePath).catch(() => undefined);\n if (cached) return cached;\n\n let pipeline = sharp(source, { animated: false }).autoOrient();\n pipeline =\n options.fit === \"cover\"\n ? pipeline.resize({ width, height, fit: \"cover\", position: options.position })\n : pipeline.resize({ width, fit: \"inside\", withoutEnlargement: true });\n if (format === \"avif\") pipeline = pipeline.avif({ quality: options.quality.avif });\n else if (format === \"webp\") pipeline = pipeline.webp({ quality: options.quality.webp });\n else if (format === \"jpeg\") pipeline = pipeline.jpeg({ quality: options.quality.jpeg });\n else {\n pipeline = pipeline.png(\n options.quality.png === 100\n ? { compressionLevel: 9 }\n : { compressionLevel: 9, quality: options.quality.png },\n );\n }\n const encoded = await pipeline.toBuffer();\n await fs.mkdir(cacheDir, { recursive: true });\n await fs.writeFile(cachePath, encoded);\n return encoded;\n}\n\nfunction variantFormats(\n formats: readonly ImageOutputFormat[],\n fallback: \"jpeg\" | \"png\",\n): Array<\"avif\" | \"webp\" | \"jpeg\" | \"png\"> {\n const output: Array<\"avif\" | \"webp\" | \"jpeg\" | \"png\"> = [];\n for (const format of formats) {\n const resolved = format === \"source\" ? fallback : format;\n if (!output.includes(resolved)) output.push(resolved);\n }\n if (!output.includes(fallback)) output.push(fallback);\n return output;\n}\n\nfunction passThroughImage(\n context: AssetPluginContext,\n sourcePath: string,\n source: Buffer,\n width: number,\n height: number,\n format: AssetFormat,\n): { fallback: EmittedVariant; variants: EmittedVariant[] } {\n const referenceId = context.emitFile({ type: \"asset\", name: path.basename(sourcePath), source });\n const fallback = { referenceId, width, height, format, mime: mime(format) };\n return { fallback, variants: [fallback] };\n}\n\nexport async function processImage(\n context: AssetPluginContext,\n sourcePath: string,\n declarationOptions: ImageOptions,\n globalOptions: ImagePipelineOptions,\n cacheDir: string,\n sharpLoader: SharpLoader,\n): Promise<ProcessedImage> {\n const source = await fs.readFile(sourcePath);\n const sourceHash = hash(source);\n const normalized = normalizeImageOptions(globalOptions, declarationOptions);\n const inspection = inspectSource(sourcePath, source);\n const key = declarationKey(sourcePath, declarationOptions);\n const shouldPassThroughWithoutSharp =\n !inspection.transformable ||\n inspection.animated ||\n (normalized.fit === \"inside\" && inspection.width <= normalized.widths[0]!);\n if (shouldPassThroughWithoutSharp) {\n const encoder = \"passthrough\";\n return {\n declarationKey: key,\n sourcePath,\n sourceHash,\n declarationOptions: normalizeDeclarationOptions(declarationOptions),\n transformKey: hash(`${sourceHash}\\0${JSON.stringify(normalized)}\\0${encoder}`),\n encoder,\n ...passThroughImage(\n context,\n sourcePath,\n source,\n inspection.width,\n inspection.height,\n inspection.format,\n ),\n passThrough: true,\n };\n }\n const sharp = await loadSharp(sharpLoader);\n const metadata = await sharp(source, { animated: true }).metadata();\n const sourceWidth = metadata.autoOrient.width ?? metadata.width;\n const sourceHeight =\n (metadata.pages ?? 1) > 1\n ? (metadata.pageHeight ?? metadata.height)\n : (metadata.autoOrient.height ?? metadata.height);\n if (!sourceWidth || !sourceHeight) {\n throw new Error(`@askrjs/vite could not determine intrinsic dimensions for ${sourcePath}.`);\n }\n const encoder = `sharp@${sharp.versions.sharp}`;\n const transformKey = hash(`${sourceHash}\\0${JSON.stringify(normalized)}\\0${encoder}`);\n const fallbackFormat = sourceFormat(metadata.format);\n\n const shouldPassThrough = (metadata.pages ?? 1) > 1 || !fallbackFormat;\n if (shouldPassThrough) {\n return {\n declarationKey: key,\n sourcePath,\n sourceHash,\n declarationOptions: normalizeDeclarationOptions(declarationOptions),\n transformKey,\n encoder,\n ...passThroughImage(\n context,\n sourcePath,\n source,\n sourceWidth,\n sourceHeight,\n fallbackFormat ?? inspection.format,\n ),\n passThrough: true,\n };\n }\n\n const maximumWidth =\n normalized.fit === \"cover\"\n ? Math.min(sourceWidth, Math.floor(sourceHeight * normalized.aspectRatio!))\n : sourceWidth;\n if (maximumWidth < 1) {\n throw new Error(\n `@askrjs/vite cannot crop ${sourcePath} to aspect ratio ${normalized.aspectRatio} without upscaling.`,\n );\n }\n const widths = normalized.widths.filter((width) => width <= maximumWidth);\n if (!widths.includes(maximumWidth)) widths.push(maximumWidth);\n widths.sort((left, right) => left - right);\n const variants: EmittedVariant[] = [];\n for (const format of variantFormats(normalized.formats, fallbackFormat)) {\n for (const width of widths) {\n const height = outputHeight(\n width,\n sourceWidth,\n sourceHeight,\n normalized.fit === \"cover\" ? normalized.aspectRatio : undefined,\n );\n const buffer = await encodedVariant(\n sharp,\n source,\n cacheDir,\n transformKey,\n width,\n height,\n format,\n normalized,\n );\n variants.push({\n referenceId: context.emitFile({\n type: \"asset\",\n name: outputName(sourcePath, width, format),\n source: buffer,\n }),\n width,\n height,\n format,\n mime: mime(format),\n });\n }\n }\n return {\n declarationKey: key,\n sourcePath,\n sourceHash,\n declarationOptions: normalizeDeclarationOptions(declarationOptions),\n transformKey,\n encoder,\n fallback: variants.filter((variant) => variant.format === fallbackFormat).at(-1)!,\n variants,\n passThrough: false,\n };\n}\n","import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ResolvedConfig } from \"vite\";\nimport { imageDeclarations } from \"./image-declarations\";\nimport {\n IMAGE_METADATA_PATH,\n IMAGE_METADATA_VERSION,\n type ImageMetadataEntry,\n type ImageMetadataRecord,\n} from \"./image-metadata\";\nimport type { ImagePipelineOptions, ResponsiveImage } from \"./image-types\";\nimport type { TextEdit } from \"./source-map-rewrites\";\nimport {\n declarationKey,\n defaultSharpLoader,\n processImage,\n type AssetPluginContext,\n type EmittedVariant,\n type ProcessedImage,\n type SharpLoader,\n} from \"./image-transform\";\n\nexport interface ImagePipelineTransform {\n code: string;\n edits: TextEdit[];\n}\n\nfunction urlExpression(referenceId: string): string {\n return `import.meta.ROLLUP_FILE_URL_${referenceId}`;\n}\n\nfunction mime(format: EmittedVariant[\"format\"]): string {\n return format === \"jpeg\" ? \"image/jpeg\" : `image/${format}`;\n}\n\nfunction srcsetExpression(variants: readonly EmittedVariant[]): string {\n return `[${variants.map((variant) => `${urlExpression(variant.referenceId)} + ${JSON.stringify(` ${variant.width}w`)}`).join(\",\")}].join(\", \")`;\n}\n\nfunction imageExpression(processed: ProcessedImage): string {\n const fallbackVariants = processed.variants.filter(\n (variant) => variant.format === processed.fallback.format,\n );\n const modernFormats = [\"avif\", \"webp\"] as const;\n const sources = processed.passThrough\n ? []\n : modernFormats.flatMap((format) => {\n const variants = processed.variants.filter((variant) => variant.format === format);\n return variants.length === 0\n ? []\n : [`{type:${JSON.stringify(mime(format))},srcset:${srcsetExpression(variants)}}`];\n });\n return `image({__askrImage:true,src:${urlExpression(processed.fallback.referenceId)},${\n processed.passThrough ? \"\" : `srcset:${srcsetExpression(fallbackVariants)},`\n }width:${processed.fallback.width},height:${processed.fallback.height},sources:[${sources.join(\",\")}]})`;\n}\n\nfunction builtUrl(base: string, fileName: string): string {\n if (/^https?:\\/\\//.test(base))\n return new URL(fileName, base.endsWith(\"/\") ? base : `${base}/`).href;\n if (base === \"\" || base === \"./\" || base === \".\")\n return `${base === \".\" ? \"./\" : base}${fileName}`;\n return `${base.endsWith(\"/\") ? base : `${base}/`}${fileName}`;\n}\n\nfunction responsiveMetadata(\n processed: ProcessedImage,\n fileName: (referenceId: string) => string,\n base: string,\n): ResponsiveImage {\n const url = (variant: EmittedVariant) => builtUrl(base, fileName(variant.referenceId));\n const srcset = (variants: readonly EmittedVariant[]) =>\n variants.map((variant) => `${url(variant)} ${variant.width}w`).join(\", \");\n const fallbackVariants = processed.variants.filter(\n (variant) => variant.format === processed.fallback.format,\n );\n return {\n __askrImage: true,\n src: url(processed.fallback),\n ...(processed.passThrough ? {} : { srcset: srcset(fallbackVariants) }),\n width: processed.fallback.width,\n height: processed.fallback.height,\n sources: processed.passThrough\n ? []\n : ([\"avif\", \"webp\"] as const).flatMap((format) => {\n const variants = processed.variants.filter((variant) => variant.format === format);\n return variants.length === 0 ? [] : [{ type: mime(format), srcset: srcset(variants) }];\n }),\n };\n}\n\nexport class ImagePipeline {\n readonly #options: ImagePipelineOptions;\n readonly #processed = new Map<string, ProcessedImage>();\n readonly #sharpLoader: SharpLoader;\n #config: ResolvedConfig | undefined;\n\n constructor(options: ImagePipelineOptions, sharpLoader: SharpLoader = defaultSharpLoader) {\n this.#options = options;\n this.#sharpLoader = sharpLoader;\n }\n\n configure(config: ResolvedConfig): void {\n this.#config = config;\n }\n\n async transform(\n context: AssetPluginContext,\n code: string,\n id: string,\n ): Promise<string | undefined> {\n return (await this.transformWithEdits(context, code, id))?.code;\n }\n\n async transformWithEdits(\n context: AssetPluginContext,\n code: string,\n id: string,\n ): Promise<ImagePipelineTransform | undefined> {\n const found = imageDeclarations(code, id);\n if (found.length === 0) return undefined;\n if (!this.#config) throw new Error(\"@askrjs/vite image pipeline was not configured.\");\n if (this.#config.command !== \"build\") {\n throw new Error(\"@askrjs/vite responsive image declarations currently require a Vite build.\");\n }\n const cacheDir = path.join(this.#config.root, \"node_modules/.cache/@askrjs/vite/images\");\n let transformed = code;\n const edits: TextEdit[] = [];\n for (const declaration of [...found].reverse()) {\n const sourcePath = path.resolve(path.dirname(id.split(\"?\", 1)[0]!), declaration.source);\n const key = declarationKey(sourcePath, declaration.options);\n let processed = this.#processed.get(key);\n if (processed) {\n const sourceHash = createHash(\"sha256\")\n .update(await fs.readFile(sourcePath))\n .digest(\"hex\");\n if (sourceHash !== processed.sourceHash) processed = undefined;\n }\n if (!processed) {\n processed = await processImage(\n context,\n sourcePath,\n declaration.options,\n this.#options,\n cacheDir,\n this.#sharpLoader,\n );\n this.#processed.set(key, processed);\n }\n const replacement = imageExpression(processed);\n edits.push({ start: declaration.start, end: declaration.end, replacement });\n transformed = `${transformed.slice(0, declaration.start)}${replacement}${transformed.slice(declaration.end)}`;\n }\n return { code: transformed, edits: edits.sort((left, right) => left.start - right.start) };\n }\n\n async writeMetadata(context: AssetPluginContext): Promise<void> {\n if (!this.#config || this.#processed.size === 0) return;\n const entries: Record<string, ImageMetadataEntry> = {};\n for (const processed of [...this.#processed.values()].sort((left, right) =>\n left.declarationKey.localeCompare(right.declarationKey),\n )) {\n entries[processed.declarationKey] = {\n sourcePath: processed.sourcePath,\n sourceHash: processed.sourceHash,\n declarationOptions: processed.declarationOptions,\n transformKey: processed.transformKey,\n encoder: processed.encoder,\n image: responsiveMetadata(\n processed,\n (referenceId) => context.getFileName(referenceId),\n this.#config.base,\n ),\n };\n }\n const record: ImageMetadataRecord = {\n version: IMAGE_METADATA_VERSION,\n entries,\n };\n const metadataPath = path.join(this.#config.root, IMAGE_METADATA_PATH);\n await fs.mkdir(path.dirname(metadataPath), { recursive: true });\n await fs.writeFile(metadataPath, `${JSON.stringify(record, null, 2)}\\n`, \"utf8\");\n }\n}\n","import { createRequire } from \"node:module\";\nimport type { Plugin } from \"vite\";\nimport {\n remapGenerated,\n remapOriginal,\n sourceMapForRewrite,\n type RawSourceMap,\n} from \"./source-map-rewrites\";\nimport { optimizeTemplateOutputWithEdits } from \"./template-optimizer\";\nimport { ImagePipeline } from \"./image-pipeline\";\nimport type { ImagePipelineOptions } from \"./image-types\";\n\nconst require = createRequire(import.meta.url);\ntype TransformWithOxc = (typeof import(\"vite\"))[\"transformWithOxc\"];\nlet transformWithOxcPromise: Promise<TransformWithOxc> | undefined;\n\nasync function loadTransformWithOxc(): Promise<TransformWithOxc> {\n transformWithOxcPromise ??= (async () => {\n for (const packageName of [\"vite-plus\", \"vite\"] as const) {\n try {\n const buildTool = await import(packageName);\n if (typeof buildTool.transformWithOxc === \"function\") {\n return buildTool.transformWithOxc as TransformWithOxc;\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ERR_MODULE_NOT_FOUND\") throw error;\n }\n }\n throw new Error(\"@askrjs/vite requires either vite or vite-plus to transform JSX.\");\n })();\n return transformWithOxcPromise;\n}\n\n/** Options accepted by {@link askrVitePlugin}. */\nexport interface AskrVitePluginOptions {\n /** Transform `.jsx`/`.tsx` files with the Askr JSX runtime. Defaults to `true`. */\n transformJsx?: boolean;\n /** Hoist repeated JSX class/style literals using parsed compiled output. Defaults to `false`. */\n optimizeTemplates?: boolean;\n ssrPrecompile?: boolean;\n /** Opt into declared responsive image transforms. */\n images?: boolean | ImagePipelineOptions;\n}\n\n/**\n * Portable public plugin identity.\n *\n * Vite-compatible runners only require the plugin name. Keeping versioned Vite\n * hook types out of the installed declaration prevents consumers such as\n * vite-plus from comparing two distinct copies of Vite's recursive Plugin type.\n */\nexport interface AskrVitePlugin {\n readonly name: \"askr:vite\";\n}\n\n/**\n * Create the Askr Vite plugin, which transforms Askr JSX/TSX with oxc, wires\n * up dependency pre-bundling and aliasing for `@askrjs/askr`, and optionally\n * runs the responsive image pipeline and template optimizer.\n * JSX transform failures are reported through the active Vite/Rollup plugin\n * context with the source file and original transform detail.\n *\n * @param options Plugin configuration; all fields are optional.\n * @returns A Vite-compatible plugin object exposing the `askr:vite` name.\n */\nexport function askrVitePlugin(options: AskrVitePluginOptions = {}): AskrVitePlugin {\n const shouldTransform = options.transformJsx ?? true;\n const shouldOptimizeTemplates = options.optimizeTemplates ?? false;\n const imagePipeline = options.images\n ? new ImagePipeline(options.images === true ? {} : options.images)\n : undefined;\n const plugin = {\n name: \"askr:vite\" as const,\n enforce: \"pre\",\n config() {\n let askrEntry: string | null = null;\n try {\n askrEntry = require.resolve(\"@askrjs/askr\");\n } catch {\n askrEntry = null;\n }\n return {\n define: {\n __ASKR_OPTIMIZE_TEMPLATES__: JSON.stringify(shouldOptimizeTemplates),\n },\n resolve: {\n alias: askrEntry ? [{ find: \"@askrjs/askr\", replacement: askrEntry }] : [],\n dedupe: [\"@askrjs/askr\"],\n },\n optimizeDeps: {\n include: [\n \"@askrjs/askr\",\n \"@askrjs/askr/router\",\n \"@askrjs/askr/boot\",\n \"@askrjs/askr/control\",\n \"@askrjs/askr/fx\",\n \"@askrjs/askr/resources\",\n \"@askrjs/askr/data\",\n \"@askrjs/askr/foundations\",\n \"@askrjs/askr/foundations/icon\",\n \"@askrjs/askr/foundations/interactions\",\n \"@askrjs/askr/foundations/state\",\n \"@askrjs/askr/foundations/structures\",\n \"@askrjs/askr/foundations/utilities\",\n \"@askrjs/askr/jsx-runtime\",\n \"@askrjs/askr/jsx-dev-runtime\",\n ],\n },\n oxc: {\n jsx: { runtime: \"automatic\", importSource: \"@askrjs/askr\" },\n jsxInject: \"import { jsx, jsxs, Fragment } from '@askrjs/askr/jsx-runtime';\",\n },\n };\n },\n configResolved(config) {\n imagePipeline?.configure(config);\n },\n async transform(code, id) {\n if (id.includes(\"node_modules\")) return null;\n const imageTransformed = imagePipeline\n ? await imagePipeline.transformWithEdits(this, code, id)\n : undefined;\n const input = imageTransformed?.code ?? code;\n if (!shouldTransform || !/\\.(jsx|tsx)$/.test(id)) {\n return imageTransformed\n ? {\n code: imageTransformed.code,\n map: sourceMapForRewrite(code, imageTransformed.code, imageTransformed.edits, id),\n }\n : null;\n }\n try {\n const transformWithOxc = await loadTransformWithOxc();\n const result = await transformWithOxc(input, id, {\n lang: id.endsWith(\".tsx\") ? \"tsx\" : \"jsx\",\n jsx: { runtime: \"automatic\", importSource: \"@askrjs/askr\" },\n sourcemap: true,\n });\n if (!result?.code) return null;\n let map = result.map as RawSourceMap;\n if (imageTransformed) {\n map = remapOriginal(map, code, input, imageTransformed.edits);\n }\n if (!shouldOptimizeTemplates) return { code: result.code, map };\n const optimized = optimizeTemplateOutputWithEdits(result.code);\n return {\n code: optimized.code,\n map: remapGenerated(map, result.code, optimized.code, optimized.edits),\n };\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n this.error(`@askrjs/vite failed to transform ${id}: ${detail}`);\n }\n },\n async writeBundle() {\n await imagePipeline?.writeMetadata(this);\n },\n } satisfies Plugin;\n return plugin;\n}\n"],"mappings":";;;;;;;;AAiBA,MAAM,SAAS;AACf,MAAM,gBAAgB,IAAI,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,KAAK,WAAW,UAAU,CAAC,WAAW,KAAK,CAAC,CAAC;AAEvF,SAAS,UAAU,OAAe,QAAmC;CACnE,IAAI,SAAS;CACb,IAAI,QAAQ;CACZ,SAAS;EACP,MAAM,QAAQ,cAAc,IAAI,MAAM,OAAO,QAAQ;EACrD,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,MAAM,gCAAgC;EACzE,WAAW,QAAQ,OAAO;EAC1B,KAAK,QAAQ,QAAQ,GAAG;EACxB,SAAS;CACX;CACA,MAAM,YAAY,SAAS,OAAO;CAClC,WAAW;CACX,OAAO,WAAW,CAAC,SAAS;AAC9B;AAEA,SAAS,UAAU,OAAuB;CACxC,IAAI,YAAa,KAAK,IAAI,KAAK,KAAK,KAAM,QAAQ,IAAI,IAAI;CAC1D,IAAI,SAAS;CACb,GAAG;EACD,IAAI,QAAQ,YAAY;EACxB,eAAe;EACf,IAAI,YAAY,GAAG,SAAS;EAC5B,UAAU,OAAO;CACnB,SAAS,YAAY;CACrB,OAAO;AACT;AAEA,SAAS,eAAe,OAA6B;CACnD,MAAM,QAAsB,CAAC;CAC7B,IAAI,SAAS;CACb,IAAI,eAAe;CACnB,IAAI,iBAAiB;CACrB,IAAI,OAAO;CACX,KAAK,MAAM,eAAe,MAAM,MAAM,GAAG,GAAG;EAC1C,MAAM,WAAuB,CAAC;EAC9B,IAAI,kBAAkB;EACtB,KAAK,MAAM,WAAW,YAAY,MAAM,GAAG,GAAG;GAC5C,IAAI,CAAC,SAAS;GACd,MAAM,SAAS,EAAE,OAAO,EAAE;GAC1B,mBAAmB,UAAU,SAAS,MAAM;GAC5C,MAAM,UAAU,CAAC,eAAe;GAChC,IAAI,OAAO,QAAQ,QAAQ,QAAQ;IACjC,UAAU,UAAU,SAAS,MAAM;IACnC,gBAAgB,UAAU,SAAS,MAAM;IACzC,kBAAkB,UAAU,SAAS,MAAM;IAC3C,QAAQ,KAAK,QAAQ,cAAc,cAAc;IACjD,IAAI,OAAO,QAAQ,QAAQ,QAAQ;KACjC,QAAQ,UAAU,SAAS,MAAM;KACjC,QAAQ,KAAK,IAAI;IACnB;GACF;GACA,SAAS,KAAK,OAAO;EACvB;EACA,MAAM,KAAK,QAAQ;CACrB;CACA,OAAO;AACT;AAEA,SAAS,eAAe,OAA6B;CACnD,IAAI,iBAAiB;CACrB,IAAI,uBAAuB;CAC3B,IAAI,yBAAyB;CAC7B,IAAI,eAAe;CACnB,OAAO,MACJ,KAAK,aAAa;EACjB,IAAI,0BAA0B;EAC9B,OAAO,SACJ,KAAK,YAAY;GAChB,IAAI,UAAU,UAAU,QAAQ,KAAM,uBAAuB;GAC7D,0BAA0B,QAAQ;GAClC,IAAI,QAAQ,UAAU,GAAG;IACvB,WAAW,UAAU,QAAQ,KAAM,cAAc;IACjD,WAAW,UAAU,QAAQ,KAAM,oBAAoB;IACvD,WAAW,UAAU,QAAQ,KAAM,sBAAsB;IACzD,iBAAiB,QAAQ;IACzB,uBAAuB,QAAQ;IAC/B,yBAAyB,QAAQ;IACjC,IAAI,QAAQ,WAAW,GAAG;KACxB,WAAW,UAAU,QAAQ,KAAM,YAAY;KAC/C,eAAe,QAAQ;IACzB;GACF;GACA,OAAO;EACT,CAAC,CAAC,CACD,KAAK,GAAG;CACb,CAAC,CAAC,CACD,KAAK,GAAG;AACb;AAEA,SAAS,WAAW,MAAwB;CAC1C,MAAM,SAAS,CAAC,CAAC;CACjB,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAChD,IAAI,KAAK,WAAW,MAAM,OAAO,KAAK,QAAQ,CAAC;CAEjD,OAAO;AACT;AAEA,SAAS,SAAS,QAAkB,MAAc,QAAwB;CACxE,QAAQ,OAAO,SAAS,OAAO,OAAO,SAAS,MAAO;AACxD;AAEA,SAAS,WAAW,QAAkB,QAAkC;CACtE,IAAI,MAAM;CACV,IAAI,OAAO,OAAO;CAClB,OAAO,MAAM,IAAI,MAAM;EACrB,MAAM,SAAU,MAAM,SAAU;EAChC,IAAI,OAAO,WAAY,QAAQ,MAAM;OAChC,OAAO;CACd;CACA,OAAO,CAAC,KAAK,SAAS,OAAO,IAAK;AACpC;AAEA,SAAS,cAAc,QAAgB,OAAoC;CACzE,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,SAAS,KAAK,OAAO;EACzB,IAAI,SAAS,KAAK,KAAK,OAAO,KAAK,QAAQ;EAC3C,SAAS,KAAK,YAAY,UAAU,KAAK,MAAM,KAAK;CACtD;CACA,OAAO,SAAS;AAClB;AAEA,SAAS,cAAc,QAAgB,OAAoC;CACzE,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,iBAAiB,KAAK,QAAQ;EACpC,MAAM,eAAe,iBAAiB,KAAK,YAAY;EACvD,IAAI,SAAS,gBAAgB;EAC7B,IAAI,SAAS,cAAc,OAAO,KAAK;EACvC,SAAS,KAAK,YAAY,UAAU,KAAK,MAAM,KAAK;CACtD;CACA,OAAO,SAAS;AAClB;AAEA,SAAS,UAAU,OAAmC;CACpD,OAAO,MAAM,KAAK,aAAa;EAC7B,MAAM,SAAS,SAAS,MAAM,MAAM,UAAU,KAAK,KAAM,MAAM,EAAG;EAClE,OAAO,OAAO,QAAQ,SAAS,UAAU,UAAU,KAAK,QAAQ,OAAO,OAAO,QAAQ,EAAE,CAAE,EAAE;CAC9F,CAAC;AACH;AAEA,SAAS,UAAU,OAAqB,QAAkB,QAAsC;CAC9F,MAAM,CAAC,MAAM,UAAU,WAAW,QAAQ,MAAM;CAChD,IAAI;CACJ,KAAK,MAAM,WAAW,MAAM,SAAS,CAAC,GAAG;EACvC,IAAI,QAAQ,KAAM,QAAQ;EAC1B,IAAI,QAAQ,UAAU,GAAG,QAAQ;CACnC;CACA,OAAO;AACT;;AAGA,SAAgB,eACd,KACA,QACA,OACA,OACc;CACd,MAAM,eAAe,WAAW,MAAM;CACtC,MAAM,cAAc,WAAW,KAAK;CACpC,MAAM,UAAU,eAAe,IAAI,QAAQ;CAC3C,MAAM,SAAuB,MAAM,KAAK,EAAE,QAAQ,YAAY,OAAO,SAAS,CAAC,CAAC;CAChF,KAAK,MAAM,CAAC,MAAM,aAAa,QAAQ,QAAQ,GAC7C,KAAK,MAAM,WAAW,UAAU;EAE9B,MAAM,CAAC,UAAU,cAAc,WAAW,aAD3B,cAAc,SAAS,cAAc,MAAM,QAAQ,EAAG,GAAG,KACZ,CAAC;EAC7D,OAAO,SAAS,CAAE,KAAK,CAAC,YAAY,GAAG,QAAQ,MAAM,CAAC,CAAC,CAAC;CAC1D;CAEF,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,KAAK,UAAU,KAAA,GAAW;GAC5B,MAAM,SAAS,UAAU,SAAS,cAAc,KAAK,KAAK;GAC1D,IAAI,QAAQ;IACV,MAAM,CAAC,MAAM,UAAU,WAAW,aAAa,KAAK,QAAQ,KAAK;IACjE,OAAO,KAAK,CAAE,KAAK,CAAC,QAAQ,GAAG,OAAO,MAAM,CAAC,CAAC,CAAC;GACjD;EACF;EACA,SAAS,KAAK,YAAY,UAAU,KAAK,MAAM,KAAK;CACtD;CACA,OAAO;EAAE,GAAG;EAAK,UAAU,eAAe,UAAU,MAAM,CAAC;CAAE;AAC/D;;AAGA,SAAgB,cACd,KACA,UACA,WACA,OACc;CACd,MAAM,iBAAiB,WAAW,QAAQ;CAC1C,MAAM,kBAAkB,WAAW,SAAS;CAC5C,MAAM,QAAQ,eAAe,IAAI,QAAQ;CACzC,KAAK,MAAM,YAAY,OACrB,KAAK,MAAM,WAAW,UAAU;EAC9B,IAAI,QAAQ,SAAS,KAAK,QAAQ,OAAO,GAAG;EAE5C,MAAM,CAAC,MAAM,UAAU,WAAW,gBADnB,cAAc,SAAS,iBAAiB,QAAQ,IAAK,QAAQ,EAAG,GAAG,KAC3B,CAAC;EACxD,QAAQ,KAAK;EACb,QAAQ,KAAK;CACf;CAEF,OAAO;EACL,GAAG;EACH,UAAU,eAAe,KAAK;EAC9B,gBAAgB,IAAI,SAAS,KAAK,SAAS,UACzC,UAAU,IAAI,WAAY,IAAI,iBAAiB,UAAU,IAC3D;CACF;AACF;;AAGA,SAAgB,oBACd,UACA,WACA,OACA,IACc;CACd,MAAM,iBAAiB,WAAW,QAAQ;CAC1C,MAAM,kBAAkB,WAAW,SAAS;CAC5C,MAAM,QAAsB,MAAM,KAAK,EAAE,QAAQ,gBAAgB,OAAO,SAAS,CAAC,CAAC;CACnF,KAAK,IAAI,SAAS,GAAG,SAAS,UAAU,QAAQ,UAAU,GAAG;EAC3D,MAAM,CAAC,eAAe,mBAAmB,WAAW,iBAAiB,MAAM;EAC3E,MAAM,CAAC,cAAc,kBAAkB,WAAW,gBAAgB,cAAc,QAAQ,KAAK,CAAC;EAC9F,MAAM,cAAc,CAAE,KAAK;GAAC;GAAiB;GAAG;GAAc;EAAc,CAAC;CAC/E;CACA,OAAO;EACL,SAAS;EACT,OAAO,CAAC;EACR,SAAS,CAAC,EAAE;EACZ,gBAAgB,CAAC,QAAQ;EACzB,UAAU,eAAe,KAAK;CAChC;AACF;;;AC1PA,MAAM,kCAAkB,IAAI,IAAI;CAAC;CAAS;CAAa;AAAO,CAAC;AAC/D,MAAM,qBAAqB;AAC3B,MAAM,gCAAgB,IAAI,IAAI;CAAC;CAAO;CAAQ;AAAQ,CAAC;AAQvD,SAAS,aAAa,WAA2E;CAC/F,OAAO,UAAU,SAAS,SAAS,eAC/B,UAAU,SAAS,OACnB,UAAU,SAAS;AACzB;AAEA,SAAS,wBAAwB,SAA+D;CAC9F,MAAM,4BAAY,IAAI,IAAY;CAElC,KAAK,MAAM,aAAa,QAAQ,MAAM;EACpC,IAAI,UAAU,SAAS,uBAAuB,UAAU,OAAO,UAAU,oBACvE;EAGF,KAAK,MAAM,aAAa,UAAU,YAChC,IACE,UAAU,SAAS,qBACnB,cAAc,IAAI,OAAO,aAAa,SAAS,CAAC,CAAC,GAEjD,UAAU,IAAI,UAAU,MAAM,IAAI;CAGxC;CAEA,OAAO;AACT;AAEA,SAAS,iBACP,UACA,MACA,YACA;CACA,IACE,SAAS,SAAS,UAClB,SAAS,YACT,SAAS,UACT,SAAS,IAAI,SAAS,gBACtB,CAAC,gBAAgB,IAAI,SAAS,IAAI,IAAI,KACtC,SAAS,MAAM,SAAS,aACxB,OAAO,SAAS,MAAM,UAAU,UAEhC;CAGF,MAAM,UAAU,KAAK,MAAM,SAAS,MAAM,OAAO,SAAS,MAAM,GAAG;CACnE,MAAM,WAAW,GAAG,SAAS,IAAI,KAAK,GAAG;CACzC,MAAM,QAAQ,WAAW,IAAI,QAAQ,KAAK,CAAC;CAC3C,MAAM,KAAK;EACT;EACA,OAAO,SAAS,MAAM;EACtB,KAAK,SAAS,MAAM;CACtB,CAAC;CACD,WAAW,IAAI,UAAU,KAAK;AAChC;AAOA,SAAgB,gCAAgC,MAAuC;CACrF,MAAM,SAAS,UAAU,oBAAoB,MAAM;EACjD,MAAM;EACN,YAAY;CACd,CAAC;CACD,IAAI,OAAO,OAAO,SAAS,GAAG,OAAO;EAAE;EAAM,OAAO,CAAC;CAAE;CAEvD,MAAM,mBAAmB,wBAAwB,OAAO,OAAO;CAC/D,IAAI,iBAAiB,SAAS,GAAG,OAAO;EAAE;EAAM,OAAO,CAAC;CAAE;CAE1D,MAAM,6BAAa,IAAI,IAAyB;CAChD,MAAM,8BAAc,IAAI,IAAY;CACpC,IAAI,QAAQ;EACV,WAAW,YAAY;GACrB,YAAY,IAAI,WAAW,IAAI;EACjC;EACA,eAAe,MAAM;GACnB,IACE,KAAK,OAAO,SAAS,gBACrB,CAAC,iBAAiB,IAAI,KAAK,OAAO,IAAI,KACtC,KAAK,UAAU,EAAE,EAAE,SAAS,oBAE5B;GAGF,KAAK,MAAM,YAAY,KAAK,UAAU,EAAE,CAAC,YACvC,IAAI,SAAS,SAAS,YACpB,iBAAiB,UAAU,MAAM,UAAU;EAGjD;CACF,CAAC,CAAC,CAAC,MAAM,OAAO,OAAO;CAEvB,MAAM,eAAyB,CAAC;CAChC,MAAM,eAA0E,CAAC;CACjF,IAAI,aAAa;CACjB,KAAK,MAAM,SAAS,WAAW,OAAO,GAAG;EACvC,IAAI,MAAM,SAAS,GAAG;EAEtB,IAAI;EACJ;GACE,aAAa,sBAAsB;SAC5B,YAAY,IAAI,UAAU;EACnC,YAAY,IAAI,UAAU;EAC1B,aAAa,KAAK,SAAS,WAAW,KAAK,MAAM,EAAE,CAAC,QAAQ,EAAE;EAC9D,KAAK,MAAM,aAAa,OACtB,aAAa,KAAK;GAAE,OAAO,UAAU;GAAO,KAAK,UAAU;GAAK;EAAW,CAAC;CAEhF;CAEA,IAAI,aAAa,WAAW,GAAG,OAAO;EAAE;EAAM,OAAO,CAAC;CAAE;CAExD,MAAM,SAAS,GAAG,aAAa,KAAK,IAAI,EAAE;CAC1C,MAAM,QAAoB,CACxB;EAAE,OAAO;EAAG,KAAK;EAAG,aAAa;EAAQ,OAAO,aAAa,EAAE,CAAE;CAAM,GACvE,GAAG,aACA,KAAK,EAAE,OAAO,KAAK,kBAAkB;EAAE;EAAO;EAAK,aAAa;CAAW,EAAE,CAAC,CAC9E,MAAM,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK,CACnD;CACA,IAAI,YAAY;CAChB,KAAK,MAAM,eAAe,aAAa,MAAM,MAAM,UAAU,MAAM,QAAQ,KAAK,KAAK,GACnF,YACE,UAAU,MAAM,GAAG,YAAY,KAAK,IACpC,YAAY,aACZ,UAAU,MAAM,YAAY,GAAG;CAEnC,OAAO;EAAE,MAAM,GAAG,SAAS;EAAa;CAAM;AAChD;;;AC5IA,MAAM,eAAe;AAErB,SAAS,gBAAgB,QAA4B;CACnD,MAAM,OAAO,IAAI,WAAW,OAAO,MAAM;CACzC,IAAI,QAAsF;CAC1F,IAAI,UAAU;CACd,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;EACrD,MAAM,YAAY,OAAO;EACzB,MAAM,OAAO,OAAO,QAAQ;EAC5B,IAAI,UAAU,QAAQ;GACpB,IAAI,cAAc,OAAO,SAAS,KAAK;IACrC,QAAQ;IACR,SAAS;GACX,OAAO,IAAI,cAAc,OAAO,SAAS,KAAK;IAC5C,QAAQ;IACR,SAAS;GACX,OAAO,IAAI,cAAc,KAAK,QAAQ;QACjC,IAAI,cAAc,MAAK,QAAQ;QAC/B,IAAI,cAAc,KAAK,QAAQ;QAC/B,KAAK,SAAS;GACnB;EACF;EACA,IAAI,UAAU,gBAAgB;GAC5B,IAAI,cAAc,QAAQ,cAAc,MAAM;IAC5C,QAAQ;IACR,KAAK,SAAS;GAChB;GACA;EACF;EACA,IAAI,UAAU,iBAAiB;GAC7B,IAAI,cAAc,OAAO,SAAS,KAAK;IACrC,QAAQ;IACR,SAAS;GACX;GACA;EACF;EACA,IAAI,SAAS,UAAU;OAClB,IAAI,cAAc,MAAM,UAAU;OAClC,IACF,UAAU,YAAY,cAAc,OACpC,UAAU,YAAY,cAAc,QACpC,UAAU,cAAc,cAAc,KAEvC,QAAQ;CAEZ;CACA,OAAO;AACT;AAEA,SAAgB,qBAAqB,MAAsC;CACzE,MAAM,OAAO,gBAAgB,IAAI;CACjC,aAAa,YAAY;CACzB,KAAK,IAAI,QAAQ,aAAa,KAAK,IAAI,GAAG,OAAO,QAAQ,aAAa,KAAK,IAAI,GAC7E,IAAI,KAAK,MAAM,QAAQ,OAAO;AAGlC;;;AC9CA,MAAM,aAAa;AAEnB,SAAS,WAAW,QAAgB,IAAoB;CACtD,IAAI,SAAS;CACb,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,SAAS;EAC1C,MAAM,YAAY,OAAO;EACzB,IAAI,KAAK,KAAK,SAAS,KAAK,QAAQ,SAAS,SAAS,GAAG;GACvD,UAAU;GACV,SAAS;GACT;EACF;EACA,IAAI,cAAc,KAAK;GACrB,IAAI,OAAO,QAAQ;GACnB,OAAO,KAAK,KAAK,OAAO,SAAS,EAAE,GAAG,QAAQ;GAC9C,IAAI,OAAO,UAAU,OAAO,OAAO,UAAU,KAAK,UAAU;GAC5D,SAAS;GACT;EACF;EACA,IAAI,cAAc,QAAO,cAAc,KAAK;GAC1C,IAAI,MAAM,QAAQ;GAClB,OAAO,MAAM,OAAO,UAAU,OAAO,SAAS,WAAW;IACvD,IAAI,OAAO,SAAS,MAClB,MAAM,IAAI,MACR,0CAA0C,GAAG,kCAC/C;IAEF,OAAO;GACT;GACA,IAAI,OAAO,OAAO,QAChB,MAAM,IAAI,MAAM,sDAAsD,GAAG,EAAE;GAE7E,UAAU,KAAK,UAAU,OAAO,MAAM,QAAQ,GAAG,GAAG,CAAC;GACrD,QAAQ,MAAM;GACd;EACF;EACA,MAAM,SAAS,6CAA6C,KAAK,OAAO,MAAM,KAAK,CAAC;EACpF,IAAI,QAAQ;GACV,UAAU,OAAO;GACjB,SAAS,OAAO,EAAE,CAAC;GACnB;EACF;EACA,MAAM,aAAa,gBAAgB,KAAK,OAAO,MAAM,KAAK,CAAC;EAC3D,IAAI,YAAY;GACd,IAAI,OAAO,QAAQ,WAAW,EAAE,CAAC;GACjC,OAAO,KAAK,KAAK,OAAO,SAAS,EAAE,GAAG,QAAQ;GAC9C,IAAI,OAAO,UAAU,KAAK,UAAU,KAAK,UAAU,WAAW,EAAE;QAC3D,IAAI;IAAC;IAAQ;IAAS;GAAM,CAAC,CAAC,SAAS,WAAW,EAAE,GAAG,UAAU,WAAW;QAE/E,MAAM,IAAI,MACR,mCAAmC,GAAG,sBAAsB,WAAW,GAAG,+BAC5E;GAEF,SAAS,WAAW,EAAE,CAAC;GACvB;EACF;EACA,MAAM,IAAI,MACR,mCAAmC,GAAG,yEACxC;CACF;CACA,OAAO;AACT;AAEA,SAAS,cAAc,QAAgB,IAA0B;CAC/D,MAAM,UAAU,OAAO,KAAK;CAC5B,IAAI,CAAC,SAAS,OAAO,CAAC;CACtB,IAAI;CACJ,IAAI;EACF,QAAQ,KAAK,MAAM,WAAW,SAAS,EAAE,CAAC;CAC5C,SAAS,OAAO;EACd,IAAI,iBAAiB,SAAS,MAAM,QAAQ,WAAW,cAAc,GAAG,MAAM;EAC9E,MAAM,IAAI,MAAM,mDAAmD,GAAG,IAAI,EAAE,OAAO,MAAM,CAAC;CAC5F;CACA,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC5D,MAAM,IAAI,MAAM,mCAAmC,GAAG,4BAA4B;CAEpF,OAAO;AACT;AAEA,SAAS,YAAY,MAAc,OAAuB;CACxD,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,IAAI,UAAU;CACd,KAAK,IAAI,QAAQ,OAAO,QAAQ,KAAK,QAAQ,SAAS,GAAG;EACvD,MAAM,YAAY,KAAK;EACvB,IAAI,OAAO;GACT,IAAI,SAAS,UAAU;QAClB,IAAI,cAAc,MAAM,UAAU;QAClC,IAAI,cAAc,OAAO,QAAQ;GACtC;EACF;EACA,IAAI,cAAc,QAAO,cAAc,KAAK;GAC1C,QAAQ;GACR;EACF;EACA,IAAI,cAAc,KAAK,SAAS;EAChC,IAAI,cAAc,KAAK;GACrB,SAAS;GACT,IAAI,UAAU,GAAG,OAAO;EAC1B;CACF;CACA,OAAO;AACT;AAEA,SAAgB,kBAAkB,MAAc,IAAgC;CAC9E,MAAM,OAAO,qBAAqB,IAAI;CACtC,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,MAAM,SAA6B,CAAC;CACpC,WAAW,YAAY;CACvB,KAAK,IAAI,QAAQ,WAAW,KAAK,IAAI,GAAG,OAAO,QAAQ,WAAW,KAAK,IAAI,GAAG;EAC5E,IAAI,CAAC,KAAK,MAAM,QAAQ;EACxB,MAAM,WAAW,WAAW;EAC5B,MAAM,MAAM,YAAY,MAAM,QAAQ;EACtC,IAAI,MAAM,GAAG,MAAM,IAAI,MAAM,sDAAsD,GAAG,EAAE;EACxF,MAAM,YAAY,KAAK,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK;EACjD,IAAI,aAAa,CAAC,UAAU,WAAW,GAAG,GACxC,MAAM,IAAI,MAAM,uDAAuD,GAAG,EAAE;EAE9E,OAAO,KAAK;GACV,OAAO,MAAM;GACb,KAAK,MAAM;GACX,QAAQ,MAAM;GACd,SAAS,cAAc,UAAU,QAAQ,MAAM,EAAE,GAAG,EAAE;EACxD,CAAC;EACD,WAAW,YAAY,MAAM;CAC/B;CACA,OAAO;AACT;;;AC9HA,SAAS,mBACP,OACA,QACA,QACA,eACA,WAAW,OACmB;CAC9B,OAAO,QAAQ,KAAK,SAAS,IAAI;EAAE;EAAO;EAAQ;EAAQ;EAAe;CAAS,IAAI,KAAA;AACxF;AAEA,SAAS,WAAW,QAA8C;CAChE,IACE,OAAO,SAAS,MAChB,CAAC,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK;EAAC;EAAK;EAAI;EAAI;EAAI;EAAI;EAAI;EAAI;CAAE,CAAC,CAAC,GAE5E;CAEF,OAAO,mBACL,OAAO,aAAa,EAAE,GACtB,OAAO,aAAa,EAAE,GACtB,OACA,MACA,OAAO,SAAS,OAAO,KAAK,MAAM,CAAC,CACrC;AACF;AAEA,SAAS,WAAW,QAA8C;CAChE,IAAI,OAAO,SAAS,MAAM,CAAC,cAAc,KAAK,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,CAAC,GACnF;CAEF,OAAO,mBAAmB,OAAO,aAAa,CAAC,GAAG,OAAO,aAAa,CAAC,GAAG,OAAO,OAAO,IAAI;AAC9F;AAEA,SAAS,gBAAgB,SAAqC;CAC5D,IAAI,QAAQ,SAAS,MAAM,QAAQ,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,QAAQ,MAAM,YACvE;CAEF,MAAM,OAAO;CACb,MAAM,YAAY,QAAQ,SAAS,MAAM,CAAQ,CAAC,CAAC,SAAS,OAAO;CACnE,MAAM,eAAe,cAAc;CACnC,IAAI,CAAC,gBAAgB,cAAc,MAAM,OAAO,KAAA;CAChD,MAAM,UAAU,WAAuC;EACrD,MAAM,WAAW,OAAO;EACxB,IAAI,WAAW,QAAQ,WAAW,IAAI,QAAQ,QAAQ,OAAO,KAAA;EAC7D,OAAO,eAAe,QAAQ,aAAa,QAAQ,IAAI,QAAQ,aAAa,QAAQ;CACtF;CACA,MAAM,UAAU,WAAuC;EACrD,MAAM,WAAW,OAAO;EACxB,IAAI,WAAW,QAAQ,WAAW,IAAI,QAAQ,QAAQ,OAAO,KAAA;EAC7D,OAAO,eAAe,QAAQ,aAAa,QAAQ,IAAI,QAAQ,aAAa,QAAQ;CACtF;CACA,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,KAAA;CAC7B,MAAM,kBAAkB,OAAO,CAAC;CAChC,IAAI,oBAAoB,KAAA,GAAW,OAAO,KAAA;CAC1C,MAAM,UAAU,OAAO,eAAe;CACtC,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;CAClC,KAAK,IAAI,QAAQ,GAAG,QAAQ,SAAS,SAAS,GAAG;EAC/C,MAAM,QAAQ,kBAAkB,IAAI,QAAQ;EAC5C,IAAI,OAAO,KAAK,MAAM,OAAU,OAAO,QAAQ,CAAC,MAAM,KAAK,OAAO,QAAQ,CAAC,MAAM,GAC/E;EAEF,MAAM,cAAc,OAAO,QAAQ,CAAC;EACpC,OAAO,eAAe,eAAe,KAAK,eAAe,IAAI,cAAc,KAAA;CAC7E;AAEF;AAEA,SAAS,YAAY,QAA8C;CACjE,IAAI,OAAO,SAAS,KAAK,OAAO,OAAO,OAAQ,OAAO,OAAO,KAAM,OAAO,KAAA;CAC1E,MAAM,+BAAe,IAAI,IAAI;EAC3B;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;EAAM;CAC1E,CAAC;CACD,IAAI;CACJ,IAAI,SAAS;CACb,OAAO,SAAS,IAAI,OAAO,QAAQ;EACjC,IAAI,OAAO,YAAY,KAAM;GAC3B,UAAU;GACV;EACF;EACA,OAAO,OAAO,YAAY,KAAM,UAAU;EAC1C,MAAM,SAAS,OAAO;EACtB,IAAI,WAAW,OAAQ,WAAW,OAAQ,WAAW,GAAM;EAC3D,IAAI,UAAU,OAAQ,UAAU,KAAM;EACtC,IAAI,SAAS,IAAI,OAAO,QAAQ;EAChC,MAAM,SAAS,OAAO,aAAa,MAAM;EACzC,IAAI,SAAS,KAAK,SAAS,SAAS,OAAO,QAAQ;EACnD,IAAI,WAAW,KACb,cAAc,gBAAgB,OAAO,SAAS,SAAS,GAAG,SAAS,MAAM,CAAC,KAAK;EAEjF,IAAI,aAAa,IAAI,MAAM,KAAK,UAAU,GAAG;GAC3C,MAAM,QAAQ,OAAO,aAAa,SAAS,CAAC;GAC5C,MAAM,SAAS,OAAO,aAAa,SAAS,CAAC;GAC7C,OAAO,mBACL,gBAAgB,KAAA,KAAa,eAAe,IAAI,SAAS,OACzD,gBAAgB,KAAA,KAAa,eAAe,IAAI,QAAQ,QACxD,QACA,IACF;EACF;EACA,UAAU;CACZ;AAEF;AAEA,SAAS,WAAW,QAA8C;CAChE,MAAM,aAAa,OAChB,SAAS,GAAG,KAAM,CAAC,CACnB,SAAS,MAAM,CAAC,CAChB,MAAM,eAAe,CAAC,GAAG;CAC5B,IAAI,CAAC,YAAY,OAAO,KAAA;CACxB,MAAM,mBAAmB,SAAqC;EAC5D,MAAM,QAAQ,WAAW,MAAM,IAAI,OAAO,MAAM,KAAK,6BAA6B,GAAG,CAAC,CAAC,GAAG;EAC1F,MAAM,SAAS,QAAQ,OAAO,KAAK,IAAI;EACvC,OAAO,OAAO,SAAS,MAAM,KAAK,SAAS,IAAI,SAAS,KAAA;CAC1D;CACA,IAAI,QAAQ,gBAAgB,OAAO;CACnC,IAAI,SAAS,gBAAgB,QAAQ;CACrC,MAAM,UAAU,WACb,MAAM,qFAAqF,CAAC,EAC3F,MAAM,CAAC,CAAC,CACT,IAAI,MAAM;CACb,IAAI,CAAC,SAAS,UAAU,MAAM,QAAQ,KAAK,GAAG,QAAQ,QAAQ;CAC9D,IAAI,CAAC,UAAU,UAAU,MAAM,QAAQ,KAAK,GAAG,SAAS,QAAQ;CAChE,IAAI,CAAC,SAAS,UAAU,UAAU,MAAM,UAAU,IAAI,QAAQ,UAAU,QAAQ,KAAK,QAAQ;CAC7F,IAAI,CAAC,UAAU,SAAS,UAAU,MAAM,UAAU,IAAI,SAAS,SAAS,QAAQ,KAAK,QAAQ;CAC7F,OAAO,SAAS,SAAS,mBAAmB,OAAO,QAAQ,OAAO,KAAK,IAAI,KAAA;AAC7E;AAEA,SAAS,YAAY,QAA8C;CACjE,IACE,OAAO,SAAS,MAChB,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,UAC5C,OAAO,SAAS,GAAG,EAAE,CAAC,CAAC,SAAS,OAAO,MAAM,QAE7C;CAEF,MAAM,QAAQ,OAAO,SAAS,IAAI,EAAE,CAAC,CAAC,SAAS,OAAO;CACtD,IAAI,UAAU,QAGZ,OAAO,mBAFO,IAAI,OAAO,WAAW,IAAI,CAAC,GAC1B,IAAI,OAAO,WAAW,IAAI,CAAC,GACD,QAAQ,OAAO,QAAQ,OAAO,MAAO,CAAI,CAAC;CAErF,IAAI,UAAU,QACZ,OAAO,mBACL,OAAO,aAAa,EAAE,IAAI,OAC1B,OAAO,aAAa,EAAE,IAAI,OAC1B,QACA,KACF;CAEF,IAAI,UAAU,UAAU,OAAO,QAAQ,IAAM;EAC3C,MAAM,OAAO,OAAO,aAAa,EAAE;EACnC,OAAO,mBAAmB,KAAK,OAAO,QAAS,KAAM,SAAS,KAAM,QAAS,QAAQ,KAAK;CAC5F;AAEF;AAEA,SAAS,YAAY,QAA8C;CACjE,IAAI,OAAO,SAAS,MAAM,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,QAAQ,OAAO,KAAA;CACrF,MAAM,aAAa,OAAO,QAAQ,OAAO,KAAK,MAAM,CAAC;CACrD,IAAI,aAAa,KAAK,aAAa,KAAK,OAAO,QAAQ,OAAO,KAAA;CAC9D,OAAO,mBACL,OAAO,aAAa,aAAa,CAAC,GAClC,OAAO,aAAa,aAAa,EAAE,GACnC,QACA,KACF;AACF;AAEA,SAAgB,cAAc,YAAoB,QAAkC;CAClF,MAAM,aACJ,WAAW,MAAM,KACjB,WAAW,MAAM,KACjB,YAAY,MAAM,KAClB,WAAW,MAAM,KACjB,YAAY,MAAM,KAClB,YAAY,MAAM;CACpB,IAAI,CAAC,YACH,MAAM,IAAI,MACR,gFAAgF,WAAW,EAC7F;CAEF,OAAO;AACT;;;AC7JA,SAAS,KAAK,OAAgC;CAC5C,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK;AACxD;AAEA,SAAgB,eAAe,YAAoB,SAA+B;CAChF,OAAO,KAAK,GAAG,WAAW,IAAI,KAAK,UAAU,4BAA4B,OAAO,CAAC,GAAG;AACtF;AAEA,MAAa,qBAAkC,aAAa,MAAM,OAAO,SAAA,CAAU;AAEnF,eAAe,UAAU,QAA4C;CACnE,IAAI;EACF,OAAO,MAAM,OAAO;CACtB,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,wBAC5C,MAAM,IAAI,MACR,0GACA,EAAE,OAAO,MAAM,CACjB;EAEF,MAAM;CACR;AACF;AAEA,SAAS,aAAa,QAAwD;CAC5E,IAAI,WAAW,UAAU,WAAW,OAAO,OAAO;CAClD,OAAO,WAAW,QAAQ,QAAQ,KAAA;AACpC;AAEA,SAAS,UAAU,QAA6B;CAC9C,OAAO,WAAW,SAAS,QAAQ;AACrC;AAEA,SAASA,OAAK,QAA6B;CACzC,OAAO,WAAW,SAAS,eAAe,SAAS;AACrD;AAEA,SAAS,WAAW,YAAoB,OAAe,QAA0C;CAE/F,OAAO,GADU,KAAK,SAAS,YAAY,KAAK,QAAQ,UAAU,CACjD,EAAE,GAAG,MAAM,GAAG,UAAU,MAAM;AACjD;AAEA,SAAS,aACP,OACA,aACA,cACA,aACQ;CACR,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,SAAS,eAAe,cAAc,aAAa,CAAC;AACpF;AAEA,eAAe,eACb,OACA,QACA,UACA,cACA,OACA,QACA,QACA,SACiB;CACjB,MAAM,YAAY,KAAK,KAAK,UAAU,GAAG,aAAa,GAAG,MAAM,GAAG,UAAU,MAAM,GAAG;CACrF,MAAM,SAAS,MAAM,GAAG,SAAS,SAAS,CAAC,CAAC,YAAY,KAAA,CAAS;CACjE,IAAI,QAAQ,OAAO;CAEnB,IAAI,WAAW,MAAM,QAAQ,EAAE,UAAU,MAAM,CAAC,CAAC,CAAC,WAAW;CAC7D,WACE,QAAQ,QAAQ,UACZ,SAAS,OAAO;EAAE;EAAO;EAAQ,KAAK;EAAS,UAAU,QAAQ;CAAS,CAAC,IAC3E,SAAS,OAAO;EAAE;EAAO,KAAK;EAAU,oBAAoB;CAAK,CAAC;CACxE,IAAI,WAAW,QAAQ,WAAW,SAAS,KAAK,EAAE,SAAS,QAAQ,QAAQ,KAAK,CAAC;MAC5E,IAAI,WAAW,QAAQ,WAAW,SAAS,KAAK,EAAE,SAAS,QAAQ,QAAQ,KAAK,CAAC;MACjF,IAAI,WAAW,QAAQ,WAAW,SAAS,KAAK,EAAE,SAAS,QAAQ,QAAQ,KAAK,CAAC;MAEpF,WAAW,SAAS,IAClB,QAAQ,QAAQ,QAAQ,MACpB,EAAE,kBAAkB,EAAE,IACtB;EAAE,kBAAkB;EAAG,SAAS,QAAQ,QAAQ;CAAI,CAC1D;CAEF,MAAM,UAAU,MAAM,SAAS,SAAS;CACxC,MAAM,GAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;CAC5C,MAAM,GAAG,UAAU,WAAW,OAAO;CACrC,OAAO;AACT;AAEA,SAAS,eACP,SACA,UACyC;CACzC,MAAM,SAAkD,CAAC;CACzD,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,WAAW,WAAW,WAAW,WAAW;EAClD,IAAI,CAAC,OAAO,SAAS,QAAQ,GAAG,OAAO,KAAK,QAAQ;CACtD;CACA,IAAI,CAAC,OAAO,SAAS,QAAQ,GAAG,OAAO,KAAK,QAAQ;CACpD,OAAO;AACT;AAEA,SAAS,iBACP,SACA,YACA,QACA,OACA,QACA,QAC0D;CAE1D,MAAM,WAAW;EAAE,aADC,QAAQ,SAAS;GAAE,MAAM;GAAS,MAAM,KAAK,SAAS,UAAU;GAAG;EAAO,CACjE;EAAG;EAAO;EAAQ;EAAQ,MAAMA,OAAK,MAAM;CAAE;CAC1E,OAAO;EAAE;EAAU,UAAU,CAAC,QAAQ;CAAE;AAC1C;AAEA,eAAsB,aACpB,SACA,YACA,oBACA,eACA,UACA,aACyB;CACzB,MAAM,SAAS,MAAM,GAAG,SAAS,UAAU;CAC3C,MAAM,aAAa,KAAK,MAAM;CAC9B,MAAM,aAAa,sBAAsB,eAAe,kBAAkB;CAC1E,MAAM,aAAa,cAAc,YAAY,MAAM;CACnD,MAAM,MAAM,eAAe,YAAY,kBAAkB;CAKzD,IAHE,CAAC,WAAW,iBACZ,WAAW,YACV,WAAW,QAAQ,YAAY,WAAW,SAAS,WAAW,OAAO,IACrC;EACjC,MAAM,UAAU;EAChB,OAAO;GACL,gBAAgB;GAChB;GACA;GACA,oBAAoB,4BAA4B,kBAAkB;GAClE,cAAc,KAAK,GAAG,WAAW,IAAI,KAAK,UAAU,UAAU,EAAE,IAAI,SAAS;GAC7E;GACA,GAAG,iBACD,SACA,YACA,QACA,WAAW,OACX,WAAW,QACX,WAAW,MACb;GACA,aAAa;EACf;CACF;CACA,MAAM,QAAQ,MAAM,UAAU,WAAW;CACzC,MAAM,WAAW,MAAM,MAAM,QAAQ,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC,SAAS;CAClE,MAAM,cAAc,SAAS,WAAW,SAAS,SAAS;CAC1D,MAAM,gBACH,SAAS,SAAS,KAAK,IACnB,SAAS,cAAc,SAAS,SAChC,SAAS,WAAW,UAAU,SAAS;CAC9C,IAAI,CAAC,eAAe,CAAC,cACnB,MAAM,IAAI,MAAM,6DAA6D,WAAW,EAAE;CAE5F,MAAM,UAAU,SAAS,MAAM,SAAS;CACxC,MAAM,eAAe,KAAK,GAAG,WAAW,IAAI,KAAK,UAAU,UAAU,EAAE,IAAI,SAAS;CACpF,MAAM,iBAAiB,aAAa,SAAS,MAAM;CAGnD,KAD2B,SAAS,SAAS,KAAK,KAAK,CAAC,gBAEtD,OAAO;EACL,gBAAgB;EAChB;EACA;EACA,oBAAoB,4BAA4B,kBAAkB;EAClE;EACA;EACA,GAAG,iBACD,SACA,YACA,QACA,aACA,cACA,kBAAkB,WAAW,MAC/B;EACA,aAAa;CACf;CAGF,MAAM,eACJ,WAAW,QAAQ,UACf,KAAK,IAAI,aAAa,KAAK,MAAM,eAAe,WAAW,WAAY,CAAC,IACxE;CACN,IAAI,eAAe,GACjB,MAAM,IAAI,MACR,4BAA4B,WAAW,mBAAmB,WAAW,YAAY,oBACnF;CAEF,MAAM,SAAS,WAAW,OAAO,QAAQ,UAAU,SAAS,YAAY;CACxE,IAAI,CAAC,OAAO,SAAS,YAAY,GAAG,OAAO,KAAK,YAAY;CAC5D,OAAO,MAAM,MAAM,UAAU,OAAO,KAAK;CACzC,MAAM,WAA6B,CAAC;CACpC,KAAK,MAAM,UAAU,eAAe,WAAW,SAAS,cAAc,GACpE,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,SAAS,aACb,OACA,aACA,cACA,WAAW,QAAQ,UAAU,WAAW,cAAc,KAAA,CACxD;EACA,MAAM,SAAS,MAAM,eACnB,OACA,QACA,UACA,cACA,OACA,QACA,QACA,UACF;EACA,SAAS,KAAK;GACZ,aAAa,QAAQ,SAAS;IAC5B,MAAM;IACN,MAAM,WAAW,YAAY,OAAO,MAAM;IAC1C,QAAQ;GACV,CAAC;GACD;GACA;GACA;GACA,MAAMA,OAAK,MAAM;EACnB,CAAC;CACH;CAEF,OAAO;EACL,gBAAgB;EAChB;EACA;EACA,oBAAoB,4BAA4B,kBAAkB;EAClE;EACA;EACA,UAAU,SAAS,QAAQ,YAAY,QAAQ,WAAW,cAAc,CAAC,CAAC,GAAG,EAAE;EAC/E;EACA,aAAa;CACf;AACF;;;ACvPA,SAAS,cAAc,aAA6B;CAClD,OAAO,+BAA+B;AACxC;AAEA,SAAS,KAAK,QAA0C;CACtD,OAAO,WAAW,SAAS,eAAe,SAAS;AACrD;AAEA,SAAS,iBAAiB,UAA6C;CACrE,OAAO,IAAI,SAAS,KAAK,YAAY,GAAG,cAAc,QAAQ,WAAW,EAAE,KAAK,KAAK,UAAU,IAAI,QAAQ,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;AACpI;AAEA,SAAS,gBAAgB,WAAmC;CAC1D,MAAM,mBAAmB,UAAU,SAAS,QACzC,YAAY,QAAQ,WAAW,UAAU,SAAS,MACrD;CAEA,MAAM,UAAU,UAAU,cACtB,CAAC,IACD,CAHmB,QAAQ,MAGf,CAAC,CAAC,SAAS,WAAW;EAChC,MAAM,WAAW,UAAU,SAAS,QAAQ,YAAY,QAAQ,WAAW,MAAM;EACjF,OAAO,SAAS,WAAW,IACvB,CAAC,IACD,CAAC,SAAS,KAAK,UAAU,KAAK,MAAM,CAAC,EAAE,UAAU,iBAAiB,QAAQ,EAAE,EAAE;CACpF,CAAC;CACL,OAAO,+BAA+B,cAAc,UAAU,SAAS,WAAW,EAAE,GAClF,UAAU,cAAc,KAAK,UAAU,iBAAiB,gBAAgB,EAAE,GAC3E,QAAQ,UAAU,SAAS,MAAM,UAAU,UAAU,SAAS,OAAO,YAAY,QAAQ,KAAK,GAAG,EAAE;AACtG;AAEA,SAAS,SAAS,MAAc,UAA0B;CACxD,IAAI,eAAe,KAAK,IAAI,GAC1B,OAAO,IAAI,IAAI,UAAU,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC;CACnE,IAAI,SAAS,MAAM,SAAS,QAAQ,SAAS,KAC3C,OAAO,GAAG,SAAS,MAAM,OAAO,OAAO;CACzC,OAAO,GAAG,KAAK,SAAS,GAAG,IAAI,OAAO,GAAG,KAAK,KAAK;AACrD;AAEA,SAAS,mBACP,WACA,UACA,MACiB;CACjB,MAAM,OAAO,YAA4B,SAAS,MAAM,SAAS,QAAQ,WAAW,CAAC;CACrF,MAAM,UAAU,aACd,SAAS,KAAK,YAAY,GAAG,IAAI,OAAO,EAAE,GAAG,QAAQ,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI;CAC1E,MAAM,mBAAmB,UAAU,SAAS,QACzC,YAAY,QAAQ,WAAW,UAAU,SAAS,MACrD;CACA,OAAO;EACL,aAAa;EACb,KAAK,IAAI,UAAU,QAAQ;EAC3B,GAAI,UAAU,cAAc,CAAC,IAAI,EAAE,QAAQ,OAAO,gBAAgB,EAAE;EACpE,OAAO,UAAU,SAAS;EAC1B,QAAQ,UAAU,SAAS;EAC3B,SAAS,UAAU,cACf,CAAC,IACA,CAAC,QAAQ,MAAM,CAAC,CAAW,SAAS,WAAW;GAC9C,MAAM,WAAW,UAAU,SAAS,QAAQ,YAAY,QAAQ,WAAW,MAAM;GACjF,OAAO,SAAS,WAAW,IAAI,CAAC,IAAI,CAAC;IAAE,MAAM,KAAK,MAAM;IAAG,QAAQ,OAAO,QAAQ;GAAE,CAAC;EACvF,CAAC;CACP;AACF;AAEA,IAAa,gBAAb,MAA2B;CACzB;CACA,6BAAsB,IAAI,IAA4B;CACtD;CACA;CAEA,YAAY,SAA+B,cAA2B,oBAAoB;EACxF,KAAKC,WAAW;EAChB,KAAKE,eAAe;CACtB;CAEA,UAAU,QAA8B;EACtC,KAAKC,UAAU;CACjB;CAEA,MAAM,UACJ,SACA,MACA,IAC6B;EAC7B,QAAQ,MAAM,KAAK,mBAAmB,SAAS,MAAM,EAAE,EAAA,EAAI;CAC7D;CAEA,MAAM,mBACJ,SACA,MACA,IAC6C;EAC7C,MAAM,QAAQ,kBAAkB,MAAM,EAAE;EACxC,IAAI,MAAM,WAAW,GAAG,OAAO,KAAA;EAC/B,IAAI,CAAC,KAAKA,SAAS,MAAM,IAAI,MAAM,iDAAiD;EACpF,IAAI,KAAKA,QAAQ,YAAY,SAC3B,MAAM,IAAI,MAAM,4EAA4E;EAE9F,MAAM,WAAW,KAAK,KAAK,KAAKA,QAAQ,MAAM,yCAAyC;EACvF,IAAI,cAAc;EAClB,MAAM,QAAoB,CAAC;EAC3B,KAAK,MAAM,eAAe,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,GAAG;GAC9C,MAAM,aAAa,KAAK,QAAQ,KAAK,QAAQ,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,EAAG,GAAG,YAAY,MAAM;GACtF,MAAM,MAAM,eAAe,YAAY,YAAY,OAAO;GAC1D,IAAI,YAAY,KAAKF,WAAW,IAAI,GAAG;GACvC,IAAI,WACiB;QAAA,WAAW,QAAQ,CAAC,CACpC,OAAO,MAAM,GAAG,SAAS,UAAU,CAAC,CAAC,CACrC,OAAO,KACG,MAAM,UAAU,YAAY,YAAY,KAAA;GAAA;GAEvD,IAAI,CAAC,WAAW;IACd,YAAY,MAAM,aAChB,SACA,YACA,YAAY,SACZ,KAAKD,UACL,UACA,KAAKE,YACP;IACA,KAAKD,WAAW,IAAI,KAAK,SAAS;GACpC;GACA,MAAM,cAAc,gBAAgB,SAAS;GAC7C,MAAM,KAAK;IAAE,OAAO,YAAY;IAAO,KAAK,YAAY;IAAK;GAAY,CAAC;GAC1E,cAAc,GAAG,YAAY,MAAM,GAAG,YAAY,KAAK,IAAI,cAAc,YAAY,MAAM,YAAY,GAAG;EAC5G;EACA,OAAO;GAAE,MAAM;GAAa,OAAO,MAAM,MAAM,MAAM,UAAU,KAAK,QAAQ,MAAM,KAAK;EAAE;CAC3F;CAEA,MAAM,cAAc,SAA4C;EAC9D,IAAI,CAAC,KAAKE,WAAW,KAAKF,WAAW,SAAS,GAAG;EACjD,MAAM,UAA8C,CAAC;EACrD,KAAK,MAAM,aAAa,CAAC,GAAG,KAAKA,WAAW,OAAO,CAAC,CAAC,CAAC,MAAM,MAAM,UAChE,KAAK,eAAe,cAAc,MAAM,cAAc,CACxD,GACE,QAAQ,UAAU,kBAAkB;GAClC,YAAY,UAAU;GACtB,YAAY,UAAU;GACtB,oBAAoB,UAAU;GAC9B,cAAc,UAAU;GACxB,SAAS,UAAU;GACnB,OAAO,mBACL,YACC,gBAAgB,QAAQ,YAAY,WAAW,GAChD,KAAKE,QAAQ,IACf;EACF;EAEF,MAAM,SAA8B;GAClC,SAAA;GACA;EACF;EACA,MAAM,eAAe,KAAK,KAAK,KAAKA,QAAQ,MAAM,mBAAmB;EACrE,MAAM,GAAG,MAAM,KAAK,QAAQ,YAAY,GAAG,EAAE,WAAW,KAAK,CAAC;EAC9D,MAAM,GAAG,UAAU,cAAc,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,KAAK,MAAM;CACjF;AACF;;;AC5KA,MAAM,UAAU,cAAc,YAAY,GAAG;AAE7C,IAAI;AAEJ,eAAe,uBAAkD;CAC/D,6BAA6B,YAAY;EACvC,KAAK,MAAM,eAAe,CAAC,aAAa,MAAM,GAC5C,IAAI;GACF,MAAM,YAAY,MAAM,OAAO;GAC/B,IAAI,OAAO,UAAU,qBAAqB,YACxC,OAAO,UAAU;EAErB,SAAS,OAAO;GACd,IAAK,MAAgC,SAAS,wBAAwB,MAAM;EAC9E;EAEF,MAAM,IAAI,MAAM,kEAAkE;CACpF,EAAA,CAAG;CACH,OAAO;AACT;;;;;;;;;;;AAkCA,SAAgB,eAAe,UAAiC,CAAC,GAAmB;CAClF,MAAM,kBAAkB,QAAQ,gBAAgB;CAChD,MAAM,0BAA0B,QAAQ,qBAAqB;CAC7D,MAAM,gBAAgB,QAAQ,SAC1B,IAAI,cAAc,QAAQ,WAAW,OAAO,CAAC,IAAI,QAAQ,MAAM,IAC/D,KAAA;CAwFJ,OAAO;EAtFL,MAAM;EACN,SAAS;EACT,SAAS;GACP,IAAI,YAA2B;GAC/B,IAAI;IACF,YAAY,QAAQ,QAAQ,cAAc;GAC5C,QAAQ;IACN,YAAY;GACd;GACA,OAAO;IACL,QAAQ,EACN,6BAA6B,KAAK,UAAU,uBAAuB,EACrE;IACA,SAAS;KACP,OAAO,YAAY,CAAC;MAAE,MAAM;MAAgB,aAAa;KAAU,CAAC,IAAI,CAAC;KACzE,QAAQ,CAAC,cAAc;IACzB;IACA,cAAc,EACZ,SAAS;KACP;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACF,EACF;IACA,KAAK;KACH,KAAK;MAAE,SAAS;MAAa,cAAc;KAAe;KAC1D,WAAW;IACb;GACF;EACF;EACA,eAAe,QAAQ;GACrB,eAAe,UAAU,MAAM;EACjC;EACA,MAAM,UAAU,MAAM,IAAI;GACxB,IAAI,GAAG,SAAS,cAAc,GAAG,OAAO;GACxC,MAAM,mBAAmB,gBACrB,MAAM,cAAc,mBAAmB,MAAM,MAAM,EAAE,IACrD,KAAA;GACJ,MAAM,QAAQ,kBAAkB,QAAQ;GACxC,IAAI,CAAC,mBAAmB,CAAC,eAAe,KAAK,EAAE,GAC7C,OAAO,mBACH;IACE,MAAM,iBAAiB;IACvB,KAAK,oBAAoB,MAAM,iBAAiB,MAAM,iBAAiB,OAAO,EAAE;GAClF,IACA;GAEN,IAAI;IAEF,MAAM,SAAS,OAAM,MADU,qBAAqB,EAAA,CACd,OAAO,IAAI;KAC/C,MAAM,GAAG,SAAS,MAAM,IAAI,QAAQ;KACpC,KAAK;MAAE,SAAS;MAAa,cAAc;KAAe;KAC1D,WAAW;IACb,CAAC;IACD,IAAI,CAAC,QAAQ,MAAM,OAAO;IAC1B,IAAI,MAAM,OAAO;IACjB,IAAI,kBACF,MAAM,cAAc,KAAK,MAAM,OAAO,iBAAiB,KAAK;IAE9D,IAAI,CAAC,yBAAyB,OAAO;KAAE,MAAM,OAAO;KAAM;IAAI;IAC9D,MAAM,YAAY,gCAAgC,OAAO,IAAI;IAC7D,OAAO;KACL,MAAM,UAAU;KAChB,KAAK,eAAe,KAAK,OAAO,MAAM,UAAU,MAAM,UAAU,KAAK;IACvE;GACF,SAAS,OAAO;IACd,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IACpE,KAAK,MAAM,oCAAoC,GAAG,IAAI,QAAQ;GAChE;EACF;EACA,MAAM,cAAc;GAClB,MAAM,eAAe,cAAc,IAAI;EACzC;CAEU;AACd"}
|
package/dist/server.js
CHANGED
|
@@ -174,6 +174,7 @@ function composeDocumentBody(fragment, prefix, suffix) {
|
|
|
174
174
|
let suffixPending = true;
|
|
175
175
|
let reading = false;
|
|
176
176
|
let cancelled = false;
|
|
177
|
+
let finished = false;
|
|
177
178
|
return new ReadableStream({
|
|
178
179
|
pull(controller) {
|
|
179
180
|
if (prefixPending) {
|
|
@@ -181,7 +182,7 @@ function composeDocumentBody(fragment, prefix, suffix) {
|
|
|
181
182
|
if (prefix) controller.enqueue(encoder.encode(prefix));
|
|
182
183
|
return;
|
|
183
184
|
}
|
|
184
|
-
if (reading) return;
|
|
185
|
+
if (reading || finished) return;
|
|
185
186
|
reading = true;
|
|
186
187
|
reader.read().then((part) => {
|
|
187
188
|
reading = false;
|
|
@@ -190,8 +191,10 @@ function composeDocumentBody(fragment, prefix, suffix) {
|
|
|
190
191
|
controller.enqueue(part.value);
|
|
191
192
|
return;
|
|
192
193
|
}
|
|
193
|
-
|
|
194
|
+
const finalSuffix = suffixPending ? suffix : "";
|
|
195
|
+
finished = true;
|
|
194
196
|
suffixPending = false;
|
|
197
|
+
if (finalSuffix) controller.enqueue(encoder.encode(finalSuffix));
|
|
195
198
|
controller.close();
|
|
196
199
|
}, (error) => {
|
|
197
200
|
reading = false;
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","names":[],"sources":["../src/server/head.ts","../src/server/document.ts","../src/server/development.ts","../src/server/plugin.ts"],"sourcesContent":["import { parseFragment, serialize, type DefaultTreeAdapterMap } from \"parse5\";\n\nconst htmlNamespace = \"http://www.w3.org/1999/xhtml\";\nconst linkAttributes = new Set([\n \"as\",\n \"crossorigin\",\n \"data-askr-head\",\n \"fetchpriority\",\n \"href\",\n \"hreflang\",\n \"imagesizes\",\n \"imagesrcset\",\n \"media\",\n \"referrerpolicy\",\n \"rel\",\n \"sizes\",\n \"type\",\n]);\n\nfunction headMarkupError(message: string): never {\n throw new TypeError(`Invalid x-askr-head metadata: ${message}`);\n}\n\nfunction attributesOf(node: DefaultTreeAdapterMap[\"element\"]): Map<string, string> {\n const attributes = new Map<string, string>();\n for (const attribute of node.attrs) {\n if (attribute.namespace || attribute.prefix)\n headMarkupError(\"namespaced attributes are not allowed.\");\n attributes.set(attribute.name.toLowerCase(), attribute.value);\n }\n return attributes;\n}\n\nfunction requireAllowedAttributes(\n attributes: Map<string, string>,\n allowed: ReadonlySet<string>,\n): void {\n for (const name of attributes.keys()) {\n if (!allowed.has(name)) headMarkupError(`attribute ${name} is not allowed.`);\n }\n if (attributes.get(\"data-askr-head\") !== \"\")\n headMarkupError(\"every metadata node must be Askr-owned.\");\n}\n\nfunction isTextNode(\n node: DefaultTreeAdapterMap[\"childNode\"],\n): node is DefaultTreeAdapterMap[\"textNode\"] {\n return \"value\" in node;\n}\n\nfunction textContent(node: DefaultTreeAdapterMap[\"element\"]): string {\n let value = \"\";\n for (const child of node.childNodes) {\n if (!isTextNode(child)) headMarkupError(`${node.tagName} must contain only text.`);\n value += child.value;\n }\n return value;\n}\n\nfunction validateHeadElement(node: DefaultTreeAdapterMap[\"element\"]): void {\n if (node.namespaceURI !== htmlNamespace) headMarkupError(\"foreign elements are not allowed.\");\n const attributes = attributesOf(node);\n if (node.tagName === \"title\") {\n requireAllowedAttributes(attributes, new Set([\"data-askr-head\"]));\n textContent(node);\n return;\n }\n if (node.tagName === \"meta\") {\n requireAllowedAttributes(\n attributes,\n new Set([\"content\", \"data-askr-head\", \"name\", \"property\"]),\n );\n const hasName = attributes.has(\"name\");\n const hasProperty = attributes.has(\"property\");\n if (hasName === hasProperty || !attributes.has(\"content\"))\n headMarkupError(\"meta requires content and exactly one of name or property.\");\n if (node.childNodes.length) headMarkupError(\"meta cannot contain child nodes.\");\n return;\n }\n if (node.tagName === \"link\") {\n requireAllowedAttributes(attributes, linkAttributes);\n if (!attributes.has(\"rel\") || !attributes.has(\"href\"))\n headMarkupError(\"link requires rel and href.\");\n if (node.childNodes.length) headMarkupError(\"link cannot contain child nodes.\");\n return;\n }\n if (node.tagName === \"script\") {\n requireAllowedAttributes(attributes, new Set([\"data-askr-head\", \"type\"]));\n if (attributes.get(\"type\") !== \"application/ld+json\")\n headMarkupError(\"only application/ld+json script nodes are allowed.\");\n const json = textContent(node);\n try {\n JSON.parse(json);\n } catch {\n headMarkupError(\"JSON-LD content must be valid JSON.\");\n }\n return;\n }\n headMarkupError(`element ${node.tagName} is not allowed.`);\n}\n\nexport function normalizeAskrHead(head: string): string {\n const fragment = parseFragment(head);\n for (const node of fragment.childNodes) {\n if (isTextNode(node)) {\n if (node.value.trim()) headMarkupError(\"top-level text is not allowed.\");\n continue;\n }\n if (!(\"tagName\" in node)) headMarkupError(\"non-element nodes are not allowed.\");\n validateHeadElement(node);\n }\n return serialize(fragment);\n}\n","import type { ServerApp } from \"@askrjs/server\";\nimport { normalizeAskrHead } from \"./head\";\n\ninterface ViteTelemetryFields {\n status?: number;\n}\n\ninterface ViteTelemetry {\n viteDocument?<T>(fields: ViteTelemetryFields, work: () => T): T;\n}\n\n/** Options for composing a rendered Askr fragment into the HTML document. */\nexport interface AskrDocumentOptions {\n telemetry?: ViteTelemetry;\n}\n\n/** Placeholder marker in `index.html` replaced with the rendered app fragment. */\nexport const ASKR_APP_MARKER = \"<!--askr-app-->\";\n/** Placeholder marker in `index.html` replaced with rendered `<head>` content. */\nexport const ASKR_HEAD_MARKER = \"<!--askr-head-->\";\n\nfunction markerCount(document: string): number {\n return document.split(ASKR_APP_MARKER).length - 1;\n}\n\nfunction headMarkerCount(document: string): number {\n return document.split(ASKR_HEAD_MARKER).length - 1;\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction patchHtmlAttribute(document: string, name: \"lang\" | \"dir\", value: string): string {\n return document.replace(/<html\\b([^>]*)>/i, (_match, attributes: string) => {\n const matcher = new RegExp(\n `\\\\s+${name}(?:\\\\s*=\\\\s*(?:\"[^\"]*\"|'[^']*'|[^\\\\s\"'=<>\\u0060]+))?`,\n \"gi\",\n );\n const withoutExisting = attributes.replace(matcher, \"\");\n return `<html${withoutExisting} ${name}=\"${escapeAttribute(value)}\">`;\n });\n}\n\n/**\n * Replace the single {@link ASKR_APP_MARKER} in `document` with `fragment`.\n *\n * @throws If `document` does not contain exactly one app marker.\n */\nexport function insertAskrFragment(document: string, fragment: string): string {\n const count = markerCount(document);\n if (count !== 1) {\n throw new Error(\n `index.html must contain exactly one ${ASKR_APP_MARKER} marker; found ${count}.`,\n );\n }\n return document.replace(ASKR_APP_MARKER, fragment);\n}\n\n/**\n * Replace the {@link ASKR_HEAD_MARKER} in `document` with normalized `head`\n * markup, and patch the `<html>` tag's `lang`/`dir` attributes when given.\n */\nexport function composeAskrHead(\n document: string,\n head: string,\n lang?: string,\n dir?: string,\n): string {\n let output = document.replace(ASKR_HEAD_MARKER, normalizeAskrHead(head));\n if (lang) output = patchHtmlAttribute(output, \"lang\", lang);\n if (dir) output = patchHtmlAttribute(output, \"dir\", dir);\n return output;\n}\n\n/** Whether `response` carries the `askr-fragment=1` content-type marker. */\nexport function isAskrFragment(response: Response): boolean {\n return (\n response.headers\n .get(\"content-type\")\n ?.split(\";\")\n .some((part) => part.trim().toLowerCase() === \"askr-fragment=1\") ?? false\n );\n}\n\nfunction documentHeaders(response: Response): Headers {\n const headers = new Headers(response.headers);\n const type = response.headers\n .get(\"content-type\")\n ?.split(\";\")\n .map((part) => part.trim())\n .filter((part) => part.toLowerCase() !== \"askr-fragment=1\")\n .join(\"; \");\n if (type) headers.set(\"content-type\", type);\n for (const name of [\n \"accept-ranges\",\n \"content-digest\",\n \"content-encoding\",\n \"content-length\",\n \"content-md5\",\n \"content-range\",\n \"digest\",\n \"etag\",\n \"last-modified\",\n \"repr-digest\",\n \"trailer\",\n ]) {\n headers.delete(name);\n }\n const internalHeaders: string[] = [];\n headers.forEach((_value, key) => {\n if (key.toLowerCase().startsWith(\"x-askr-\")) internalHeaders.push(key);\n });\n for (const key of internalHeaders) headers.delete(key);\n return headers;\n}\n\nfunction composeDocumentBody(\n fragment: ReadableStream<Uint8Array> | null,\n prefix: string,\n suffix: string,\n): BodyInit {\n if (!fragment) return `${prefix}${suffix}`;\n const encoder = new TextEncoder();\n const reader = fragment.getReader();\n let prefixPending = true;\n let suffixPending = true;\n let reading = false;\n let cancelled = false;\n\n return new ReadableStream<Uint8Array>({\n pull(controller) {\n if (prefixPending) {\n prefixPending = false;\n if (prefix) controller.enqueue(encoder.encode(prefix));\n return;\n }\n if (reading) return;\n reading = true;\n void reader.read().then(\n (part) => {\n reading = false;\n if (cancelled) return;\n if (!part.done) {\n controller.enqueue(part.value);\n return;\n }\n if (suffixPending && suffix) controller.enqueue(encoder.encode(suffix));\n suffixPending = false;\n controller.close();\n },\n (error) => {\n reading = false;\n if (cancelled) return;\n controller.error(error);\n void reader.cancel(error).catch(() => undefined);\n },\n );\n },\n async cancel(reason) {\n cancelled = true;\n await reader.cancel(reason).catch(() => undefined);\n },\n });\n}\n\n/**\n * Compose an Askr fragment response into the full `transformedDocument` HTML,\n * streaming the fragment's body between the document prefix and suffix.\n * Non-fragment responses are returned unchanged.\n *\n * @param response The upstream response, expected to be an Askr fragment.\n * @param transformedDocument The `index.html` document with app/head markers.\n * @param options Optional telemetry hook wrapping the compose work.\n * @returns The composed full-document `Response`, or `response` unchanged.\n */\nexport async function composeAskrDocumentResponse(\n response: Response,\n transformedDocument: string,\n options: AskrDocumentOptions = {},\n): Promise<Response> {\n if (!isAskrFragment(response)) return response;\n const compose = () => {\n if (headMarkerCount(transformedDocument) !== 1) {\n throw new Error(\n `index.html must contain exactly one ${ASKR_HEAD_MARKER} marker; found ${headMarkerCount(transformedDocument)}.`,\n );\n }\n const withHead = composeAskrHead(\n transformedDocument,\n response.headers.get(\"x-askr-head\") ?? \"\",\n response.headers.get(\"x-askr-html-lang\") ?? undefined,\n response.headers.get(\"x-askr-html-dir\") ?? undefined,\n );\n const appCount = markerCount(withHead);\n if (appCount !== 1) {\n throw new Error(\n `index.html must contain exactly one ${ASKR_APP_MARKER} marker; found ${appCount}.`,\n );\n }\n const markerIndex = withHead.indexOf(ASKR_APP_MARKER);\n const prefix = withHead.slice(0, markerIndex);\n const suffix = withHead.slice(markerIndex + ASKR_APP_MARKER.length);\n return new Response(composeDocumentBody(response.body, prefix, suffix), {\n status: response.status,\n statusText: response.statusText,\n headers: documentHeaders(response),\n });\n };\n return options.telemetry?.viteDocument\n ? options.telemetry.viteDocument({ status: response.status }, compose)\n : compose();\n}\n\n/**\n * Wrap `app` so every response is composed into `transformedDocument` via\n * {@link composeAskrDocumentResponse}.\n */\nexport function createDocumentApp(\n app: ServerApp,\n transformedDocument: string,\n options: AskrDocumentOptions = {},\n): ServerApp {\n return {\n async fetch(request) {\n return composeAskrDocumentResponse(await app.fetch(request), transformedDocument, options);\n },\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { ServerApp } from \"@askrjs/server\";\nimport type { ViteDevServer } from \"vite\";\nimport { composeAskrDocumentResponse, isAskrFragment } from \"./document\";\nimport type { AskrServerOptions } from \"./types\";\n\nfunction serverApp(module: Record<string, unknown>, options: AskrServerOptions): ServerApp {\n const value = module[options.exportName ?? \"app\"] ?? module.default;\n if (!value || typeof (value as ServerApp).fetch !== \"function\") {\n throw new Error(\n `@askrjs/vite: ${options.entry} must export a ServerApp as ${options.exportName ?? \"app\"} or default`,\n );\n }\n return value as ServerApp;\n}\n\nfunction moduleTelemetry(module: Record<string, unknown>) {\n const telemetry = module[\"telemetry\"];\n return telemetry && typeof telemetry === \"object\"\n ? {\n telemetry: telemetry as NonNullable<\n Parameters<typeof composeAskrDocumentResponse>[2]\n >[\"telemetry\"],\n }\n : undefined;\n}\n\nexport function createDevelopmentApp(server: ViteDevServer, options: AskrServerOptions): ServerApp {\n return {\n async fetch(request) {\n const module = await server.ssrLoadModule(options.entry);\n const response = await serverApp(module, options).fetch(request);\n if (!isAskrFragment(response)) return response;\n const file = resolve(server.config.root, options.indexHtml ?? \"index.html\");\n const document = await readFile(file, \"utf8\");\n const transformed = await server.transformIndexHtml(new URL(request.url).pathname, document);\n return composeAskrDocumentResponse(response, transformed, moduleTelemetry(module));\n },\n };\n}\n","import { createNodeHandler } from \"@askrjs/node\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Plugin, ResolvedConfig, ViteDevServer } from \"vite\";\nimport { createDevelopmentApp } from \"./development\";\nimport type { AskrServerOptions } from \"./types\";\n\n/** Virtual module id that resolves to the generated server document app. */\nexport const ASKR_SERVER_MODULE_ID = \"virtual:askr-server\";\nconst RESOLVED_SERVER_MODULE_ID = \"\\0askr:server\";\n\n/** Portable public identity for the server integration plugin. */\nexport interface AskrServerPlugin {\n readonly name: \"askr:server\";\n}\n\nfunction createNodeHandlerOptions(server: ViteDevServer): {\n baseUrl?: string;\n allowedHosts?: readonly string[];\n} {\n const serverConfig = server.config?.server;\n const baseUrl = serverConfig?.origin;\n\n if (\n serverConfig?.allowedHosts &&\n serverConfig.allowedHosts !== true &&\n serverConfig.allowedHosts.length > 0\n ) {\n return { baseUrl, allowedHosts: serverConfig.allowedHosts };\n }\n\n if (baseUrl) {\n return { baseUrl };\n }\n\n const host = typeof serverConfig?.host === \"string\" ? serverConfig.host : \"localhost\";\n const allowedHosts = new Set([host, \"localhost\", \"127.0.0.1\", \"[::1]\"]);\n return { allowedHosts: Array.from(allowedHosts) };\n}\n\n/**\n * Create the Vite plugin that serves Askr's server-rendered document during\n * development and generates the {@link ASKR_SERVER_MODULE_ID} virtual module\n * that composes the built server app with the HTML document.\n *\n * @param options Server entry and document configuration.\n * @returns A Vite-compatible plugin object exposing the `askr:server` name.\n */\nexport function askrServer(options: AskrServerOptions): AskrServerPlugin {\n let config: ResolvedConfig | undefined;\n const plugin = {\n name: \"askr:server\" as const,\n config() {\n // Askr owns document routing. Vite should serve modules and assets, but\n // must not rewrite page URLs to /index.html before the Askr fallback.\n // Keep the Askr package family inside Vite's module graph so file-linked\n // peers cannot load a second runtime with a different component context.\n // Vitest derives its dependency inlining from resolve.noExternal, which\n // is also Vite 8's replacement for the deprecated ssr.noExternal option.\n return {\n appType: \"custom\",\n resolve: { noExternal: [\"@askrjs/*\"] },\n };\n },\n configResolved(resolved) {\n config = resolved;\n },\n resolveId(id) {\n return id === ASKR_SERVER_MODULE_ID ? RESOLVED_SERVER_MODULE_ID : null;\n },\n async load(id) {\n if (id !== RESOLVED_SERVER_MODULE_ID) return null;\n if (!config) throw new Error(\"@askrjs/vite: server plugin was not configured.\");\n const sourceDocument = resolve(config.root, options.indexHtml ?? \"index.html\");\n const serverOutDocument = resolve(config.root, config.build.outDir, \"index.html\");\n const clientOutDocument = resolve(config.root, config.build.outDir, \"..\", \"index.html\");\n const builtDocument = [serverOutDocument, clientOutDocument].find(existsSync);\n const document = await readFile(builtDocument ?? sourceDocument, \"utf8\");\n const entry = resolve(config.root, options.entry);\n const exportName = options.exportName ?? \"app\";\n return [\n `import * as source from ${JSON.stringify(entry)};`,\n `import { createDocumentApp } from '@askrjs/vite/server';`,\n `const sourceApp = source[${JSON.stringify(exportName)}] ?? source.default;`,\n `const sourceTelemetry = Reflect.get(source, 'telemetry');`,\n `if (!sourceApp?.fetch) throw new Error(${JSON.stringify(`@askrjs/vite: ${options.entry} must export a ServerApp`)});`,\n `export const app = createDocumentApp(sourceApp, ${JSON.stringify(document)}, sourceTelemetry ? { telemetry: sourceTelemetry } : undefined);`,\n `export default app;`,\n ].join(\"\\n\");\n },\n configureServer(server) {\n const handler = createNodeHandler(\n createDevelopmentApp(server, options),\n createNodeHandlerOptions(server),\n );\n // Page rendering is the development fallback. Register it after Vite's\n // module, asset, and HTML middleware so client entries and imported CSS\n // are served by Vite instead of being mistaken for application routes.\n return () => server.middlewares.use(handler);\n },\n } satisfies Plugin;\n return plugin;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","names":[],"sources":["../src/server/head.ts","../src/server/document.ts","../src/server/development.ts","../src/server/plugin.ts"],"sourcesContent":["import { parseFragment, serialize, type DefaultTreeAdapterMap } from \"parse5\";\n\nconst htmlNamespace = \"http://www.w3.org/1999/xhtml\";\nconst linkAttributes = new Set([\n \"as\",\n \"crossorigin\",\n \"data-askr-head\",\n \"fetchpriority\",\n \"href\",\n \"hreflang\",\n \"imagesizes\",\n \"imagesrcset\",\n \"media\",\n \"referrerpolicy\",\n \"rel\",\n \"sizes\",\n \"type\",\n]);\n\nfunction headMarkupError(message: string): never {\n throw new TypeError(`Invalid x-askr-head metadata: ${message}`);\n}\n\nfunction attributesOf(node: DefaultTreeAdapterMap[\"element\"]): Map<string, string> {\n const attributes = new Map<string, string>();\n for (const attribute of node.attrs) {\n if (attribute.namespace || attribute.prefix)\n headMarkupError(\"namespaced attributes are not allowed.\");\n attributes.set(attribute.name.toLowerCase(), attribute.value);\n }\n return attributes;\n}\n\nfunction requireAllowedAttributes(\n attributes: Map<string, string>,\n allowed: ReadonlySet<string>,\n): void {\n for (const name of attributes.keys()) {\n if (!allowed.has(name)) headMarkupError(`attribute ${name} is not allowed.`);\n }\n if (attributes.get(\"data-askr-head\") !== \"\")\n headMarkupError(\"every metadata node must be Askr-owned.\");\n}\n\nfunction isTextNode(\n node: DefaultTreeAdapterMap[\"childNode\"],\n): node is DefaultTreeAdapterMap[\"textNode\"] {\n return \"value\" in node;\n}\n\nfunction textContent(node: DefaultTreeAdapterMap[\"element\"]): string {\n let value = \"\";\n for (const child of node.childNodes) {\n if (!isTextNode(child)) headMarkupError(`${node.tagName} must contain only text.`);\n value += child.value;\n }\n return value;\n}\n\nfunction validateHeadElement(node: DefaultTreeAdapterMap[\"element\"]): void {\n if (node.namespaceURI !== htmlNamespace) headMarkupError(\"foreign elements are not allowed.\");\n const attributes = attributesOf(node);\n if (node.tagName === \"title\") {\n requireAllowedAttributes(attributes, new Set([\"data-askr-head\"]));\n textContent(node);\n return;\n }\n if (node.tagName === \"meta\") {\n requireAllowedAttributes(\n attributes,\n new Set([\"content\", \"data-askr-head\", \"name\", \"property\"]),\n );\n const hasName = attributes.has(\"name\");\n const hasProperty = attributes.has(\"property\");\n if (hasName === hasProperty || !attributes.has(\"content\"))\n headMarkupError(\"meta requires content and exactly one of name or property.\");\n if (node.childNodes.length) headMarkupError(\"meta cannot contain child nodes.\");\n return;\n }\n if (node.tagName === \"link\") {\n requireAllowedAttributes(attributes, linkAttributes);\n if (!attributes.has(\"rel\") || !attributes.has(\"href\"))\n headMarkupError(\"link requires rel and href.\");\n if (node.childNodes.length) headMarkupError(\"link cannot contain child nodes.\");\n return;\n }\n if (node.tagName === \"script\") {\n requireAllowedAttributes(attributes, new Set([\"data-askr-head\", \"type\"]));\n if (attributes.get(\"type\") !== \"application/ld+json\")\n headMarkupError(\"only application/ld+json script nodes are allowed.\");\n const json = textContent(node);\n try {\n JSON.parse(json);\n } catch {\n headMarkupError(\"JSON-LD content must be valid JSON.\");\n }\n return;\n }\n headMarkupError(`element ${node.tagName} is not allowed.`);\n}\n\nexport function normalizeAskrHead(head: string): string {\n const fragment = parseFragment(head);\n for (const node of fragment.childNodes) {\n if (isTextNode(node)) {\n if (node.value.trim()) headMarkupError(\"top-level text is not allowed.\");\n continue;\n }\n if (!(\"tagName\" in node)) headMarkupError(\"non-element nodes are not allowed.\");\n validateHeadElement(node);\n }\n return serialize(fragment);\n}\n","import type { ServerApp } from \"@askrjs/server\";\nimport { normalizeAskrHead } from \"./head\";\n\ninterface ViteTelemetryFields {\n status?: number;\n}\n\ninterface ViteTelemetry {\n viteDocument?<T>(fields: ViteTelemetryFields, work: () => T): T;\n}\n\n/** Options for composing a rendered Askr fragment into the HTML document. */\nexport interface AskrDocumentOptions {\n telemetry?: ViteTelemetry;\n}\n\n/** Placeholder marker in `index.html` replaced with the rendered app fragment. */\nexport const ASKR_APP_MARKER = \"<!--askr-app-->\";\n/** Placeholder marker in `index.html` replaced with rendered `<head>` content. */\nexport const ASKR_HEAD_MARKER = \"<!--askr-head-->\";\n\nfunction markerCount(document: string): number {\n return document.split(ASKR_APP_MARKER).length - 1;\n}\n\nfunction headMarkerCount(document: string): number {\n return document.split(ASKR_HEAD_MARKER).length - 1;\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\nfunction patchHtmlAttribute(document: string, name: \"lang\" | \"dir\", value: string): string {\n return document.replace(/<html\\b([^>]*)>/i, (_match, attributes: string) => {\n const matcher = new RegExp(\n `\\\\s+${name}(?:\\\\s*=\\\\s*(?:\"[^\"]*\"|'[^']*'|[^\\\\s\"'=<>\\u0060]+))?`,\n \"gi\",\n );\n const withoutExisting = attributes.replace(matcher, \"\");\n return `<html${withoutExisting} ${name}=\"${escapeAttribute(value)}\">`;\n });\n}\n\n/**\n * Replace the single {@link ASKR_APP_MARKER} in `document` with `fragment`.\n *\n * @throws If `document` does not contain exactly one app marker.\n */\nexport function insertAskrFragment(document: string, fragment: string): string {\n const count = markerCount(document);\n if (count !== 1) {\n throw new Error(\n `index.html must contain exactly one ${ASKR_APP_MARKER} marker; found ${count}.`,\n );\n }\n return document.replace(ASKR_APP_MARKER, fragment);\n}\n\n/**\n * Replace the {@link ASKR_HEAD_MARKER} in `document` with normalized `head`\n * markup, and patch the `<html>` tag's `lang`/`dir` attributes when given.\n */\nexport function composeAskrHead(\n document: string,\n head: string,\n lang?: string,\n dir?: string,\n): string {\n let output = document.replace(ASKR_HEAD_MARKER, normalizeAskrHead(head));\n if (lang) output = patchHtmlAttribute(output, \"lang\", lang);\n if (dir) output = patchHtmlAttribute(output, \"dir\", dir);\n return output;\n}\n\n/** Whether `response` carries the `askr-fragment=1` content-type marker. */\nexport function isAskrFragment(response: Response): boolean {\n return (\n response.headers\n .get(\"content-type\")\n ?.split(\";\")\n .some((part) => part.trim().toLowerCase() === \"askr-fragment=1\") ?? false\n );\n}\n\nfunction documentHeaders(response: Response): Headers {\n const headers = new Headers(response.headers);\n const type = response.headers\n .get(\"content-type\")\n ?.split(\";\")\n .map((part) => part.trim())\n .filter((part) => part.toLowerCase() !== \"askr-fragment=1\")\n .join(\"; \");\n if (type) headers.set(\"content-type\", type);\n for (const name of [\n \"accept-ranges\",\n \"content-digest\",\n \"content-encoding\",\n \"content-length\",\n \"content-md5\",\n \"content-range\",\n \"digest\",\n \"etag\",\n \"last-modified\",\n \"repr-digest\",\n \"trailer\",\n ]) {\n headers.delete(name);\n }\n const internalHeaders: string[] = [];\n headers.forEach((_value, key) => {\n if (key.toLowerCase().startsWith(\"x-askr-\")) internalHeaders.push(key);\n });\n for (const key of internalHeaders) headers.delete(key);\n return headers;\n}\n\nfunction composeDocumentBody(\n fragment: ReadableStream<Uint8Array> | null,\n prefix: string,\n suffix: string,\n): BodyInit {\n if (!fragment) return `${prefix}${suffix}`;\n const encoder = new TextEncoder();\n const reader = fragment.getReader();\n let prefixPending = true;\n let suffixPending = true;\n let reading = false;\n let cancelled = false;\n let finished = false;\n\n return new ReadableStream<Uint8Array>({\n pull(controller) {\n if (prefixPending) {\n prefixPending = false;\n if (prefix) controller.enqueue(encoder.encode(prefix));\n return;\n }\n if (reading || finished) return;\n reading = true;\n void reader.read().then(\n (part) => {\n reading = false;\n if (cancelled) return;\n if (!part.done) {\n controller.enqueue(part.value);\n return;\n }\n const finalSuffix = suffixPending ? suffix : \"\";\n finished = true;\n suffixPending = false;\n if (finalSuffix) controller.enqueue(encoder.encode(finalSuffix));\n controller.close();\n },\n (error) => {\n reading = false;\n if (cancelled) return;\n controller.error(error);\n void reader.cancel(error).catch(() => undefined);\n },\n );\n },\n async cancel(reason) {\n cancelled = true;\n await reader.cancel(reason).catch(() => undefined);\n },\n });\n}\n\n/**\n * Compose an Askr fragment response into the full `transformedDocument` HTML,\n * streaming the fragment's body between the document prefix and suffix.\n * Non-fragment responses are returned unchanged.\n *\n * @param response The upstream response, expected to be an Askr fragment.\n * @param transformedDocument The `index.html` document with app/head markers.\n * @param options Optional telemetry hook wrapping the compose work.\n * @returns The composed full-document `Response`, or `response` unchanged.\n */\nexport async function composeAskrDocumentResponse(\n response: Response,\n transformedDocument: string,\n options: AskrDocumentOptions = {},\n): Promise<Response> {\n if (!isAskrFragment(response)) return response;\n const compose = () => {\n if (headMarkerCount(transformedDocument) !== 1) {\n throw new Error(\n `index.html must contain exactly one ${ASKR_HEAD_MARKER} marker; found ${headMarkerCount(transformedDocument)}.`,\n );\n }\n const withHead = composeAskrHead(\n transformedDocument,\n response.headers.get(\"x-askr-head\") ?? \"\",\n response.headers.get(\"x-askr-html-lang\") ?? undefined,\n response.headers.get(\"x-askr-html-dir\") ?? undefined,\n );\n const appCount = markerCount(withHead);\n if (appCount !== 1) {\n throw new Error(\n `index.html must contain exactly one ${ASKR_APP_MARKER} marker; found ${appCount}.`,\n );\n }\n const markerIndex = withHead.indexOf(ASKR_APP_MARKER);\n const prefix = withHead.slice(0, markerIndex);\n const suffix = withHead.slice(markerIndex + ASKR_APP_MARKER.length);\n return new Response(composeDocumentBody(response.body, prefix, suffix), {\n status: response.status,\n statusText: response.statusText,\n headers: documentHeaders(response),\n });\n };\n return options.telemetry?.viteDocument\n ? options.telemetry.viteDocument({ status: response.status }, compose)\n : compose();\n}\n\n/**\n * Wrap `app` so every response is composed into `transformedDocument` via\n * {@link composeAskrDocumentResponse}.\n */\nexport function createDocumentApp(\n app: ServerApp,\n transformedDocument: string,\n options: AskrDocumentOptions = {},\n): ServerApp {\n return {\n async fetch(request) {\n return composeAskrDocumentResponse(await app.fetch(request), transformedDocument, options);\n },\n };\n}\n","import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { ServerApp } from \"@askrjs/server\";\nimport type { ViteDevServer } from \"vite\";\nimport { composeAskrDocumentResponse, isAskrFragment } from \"./document\";\nimport type { AskrServerOptions } from \"./types\";\n\nfunction serverApp(module: Record<string, unknown>, options: AskrServerOptions): ServerApp {\n const value = module[options.exportName ?? \"app\"] ?? module.default;\n if (!value || typeof (value as ServerApp).fetch !== \"function\") {\n throw new Error(\n `@askrjs/vite: ${options.entry} must export a ServerApp as ${options.exportName ?? \"app\"} or default`,\n );\n }\n return value as ServerApp;\n}\n\nfunction moduleTelemetry(module: Record<string, unknown>) {\n const telemetry = module[\"telemetry\"];\n return telemetry && typeof telemetry === \"object\"\n ? {\n telemetry: telemetry as NonNullable<\n Parameters<typeof composeAskrDocumentResponse>[2]\n >[\"telemetry\"],\n }\n : undefined;\n}\n\nexport function createDevelopmentApp(server: ViteDevServer, options: AskrServerOptions): ServerApp {\n return {\n async fetch(request) {\n const module = await server.ssrLoadModule(options.entry);\n const response = await serverApp(module, options).fetch(request);\n if (!isAskrFragment(response)) return response;\n const file = resolve(server.config.root, options.indexHtml ?? \"index.html\");\n const document = await readFile(file, \"utf8\");\n const transformed = await server.transformIndexHtml(new URL(request.url).pathname, document);\n return composeAskrDocumentResponse(response, transformed, moduleTelemetry(module));\n },\n };\n}\n","import { createNodeHandler } from \"@askrjs/node\";\nimport { readFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Plugin, ResolvedConfig, ViteDevServer } from \"vite\";\nimport { createDevelopmentApp } from \"./development\";\nimport type { AskrServerOptions } from \"./types\";\n\n/** Virtual module id that resolves to the generated server document app. */\nexport const ASKR_SERVER_MODULE_ID = \"virtual:askr-server\";\nconst RESOLVED_SERVER_MODULE_ID = \"\\0askr:server\";\n\n/** Portable public identity for the server integration plugin. */\nexport interface AskrServerPlugin {\n readonly name: \"askr:server\";\n}\n\nfunction createNodeHandlerOptions(server: ViteDevServer): {\n baseUrl?: string;\n allowedHosts?: readonly string[];\n} {\n const serverConfig = server.config?.server;\n const baseUrl = serverConfig?.origin;\n\n if (\n serverConfig?.allowedHosts &&\n serverConfig.allowedHosts !== true &&\n serverConfig.allowedHosts.length > 0\n ) {\n return { baseUrl, allowedHosts: serverConfig.allowedHosts };\n }\n\n if (baseUrl) {\n return { baseUrl };\n }\n\n const host = typeof serverConfig?.host === \"string\" ? serverConfig.host : \"localhost\";\n const allowedHosts = new Set([host, \"localhost\", \"127.0.0.1\", \"[::1]\"]);\n return { allowedHosts: Array.from(allowedHosts) };\n}\n\n/**\n * Create the Vite plugin that serves Askr's server-rendered document during\n * development and generates the {@link ASKR_SERVER_MODULE_ID} virtual module\n * that composes the built server app with the HTML document.\n *\n * @param options Server entry and document configuration.\n * @returns A Vite-compatible plugin object exposing the `askr:server` name.\n */\nexport function askrServer(options: AskrServerOptions): AskrServerPlugin {\n let config: ResolvedConfig | undefined;\n const plugin = {\n name: \"askr:server\" as const,\n config() {\n // Askr owns document routing. Vite should serve modules and assets, but\n // must not rewrite page URLs to /index.html before the Askr fallback.\n // Keep the Askr package family inside Vite's module graph so file-linked\n // peers cannot load a second runtime with a different component context.\n // Vitest derives its dependency inlining from resolve.noExternal, which\n // is also Vite 8's replacement for the deprecated ssr.noExternal option.\n return {\n appType: \"custom\",\n resolve: { noExternal: [\"@askrjs/*\"] },\n };\n },\n configResolved(resolved) {\n config = resolved;\n },\n resolveId(id) {\n return id === ASKR_SERVER_MODULE_ID ? RESOLVED_SERVER_MODULE_ID : null;\n },\n async load(id) {\n if (id !== RESOLVED_SERVER_MODULE_ID) return null;\n if (!config) throw new Error(\"@askrjs/vite: server plugin was not configured.\");\n const sourceDocument = resolve(config.root, options.indexHtml ?? \"index.html\");\n const serverOutDocument = resolve(config.root, config.build.outDir, \"index.html\");\n const clientOutDocument = resolve(config.root, config.build.outDir, \"..\", \"index.html\");\n const builtDocument = [serverOutDocument, clientOutDocument].find(existsSync);\n const document = await readFile(builtDocument ?? sourceDocument, \"utf8\");\n const entry = resolve(config.root, options.entry);\n const exportName = options.exportName ?? \"app\";\n return [\n `import * as source from ${JSON.stringify(entry)};`,\n `import { createDocumentApp } from '@askrjs/vite/server';`,\n `const sourceApp = source[${JSON.stringify(exportName)}] ?? source.default;`,\n `const sourceTelemetry = Reflect.get(source, 'telemetry');`,\n `if (!sourceApp?.fetch) throw new Error(${JSON.stringify(`@askrjs/vite: ${options.entry} must export a ServerApp`)});`,\n `export const app = createDocumentApp(sourceApp, ${JSON.stringify(document)}, sourceTelemetry ? { telemetry: sourceTelemetry } : undefined);`,\n `export default app;`,\n ].join(\"\\n\");\n },\n configureServer(server) {\n const handler = createNodeHandler(\n createDevelopmentApp(server, options),\n createNodeHandlerOptions(server),\n );\n // Page rendering is the development fallback. Register it after Vite's\n // module, asset, and HTML middleware so client entries and imported CSS\n // are served by Vite instead of being mistaken for application routes.\n return () => server.middlewares.use(handler);\n },\n } satisfies Plugin;\n return plugin;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askrjs/vite",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Vite plugin for Askr JSX and template transforms",
|
|
5
5
|
"homepage": "https://github.com/askrjs/askr-vite#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -59,26 +59,26 @@
|
|
|
59
59
|
"prepublishOnly": "npm run check"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@askrjs/node": ">=0.2.
|
|
63
|
-
"oxc-parser": "^0.
|
|
62
|
+
"@askrjs/node": ">=0.2.1 <0.3.0",
|
|
63
|
+
"oxc-parser": "^0.147.0",
|
|
64
64
|
"parse5": "^8.0.1"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@askrjs/askr": ">=0.2.
|
|
68
|
-
"@askrjs/server": ">=0.2.
|
|
69
|
-
"@types/node": "^26.
|
|
70
|
-
"publint": "^0.3.
|
|
67
|
+
"@askrjs/askr": ">=0.2.3 <0.3.0",
|
|
68
|
+
"@askrjs/server": ">=0.2.1 <0.3.0",
|
|
69
|
+
"@types/node": "^26.3.0",
|
|
70
|
+
"publint": "^0.3.24",
|
|
71
71
|
"sharp": "^0.35.3",
|
|
72
72
|
"typescript": "^7.0.2",
|
|
73
|
-
"vite": "^8.2.
|
|
74
|
-
"vite-plus": "^0.
|
|
75
|
-
"vitest": "^4.1.
|
|
73
|
+
"vite": "^8.2.2",
|
|
74
|
+
"vite-plus": "^0.3.0",
|
|
75
|
+
"vitest": "^4.1.11"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@askrjs/askr": ">=0.2.
|
|
78
|
+
"@askrjs/askr": ">=0.2.3 <0.3.0",
|
|
79
79
|
"sharp": "^0.35.3",
|
|
80
|
-
"vite": "^8.2.
|
|
81
|
-
"vite-plus": "^0.2.8"
|
|
80
|
+
"vite": "^8.2.2",
|
|
81
|
+
"vite-plus": "^0.2.8 || ^0.3.0"
|
|
82
82
|
},
|
|
83
83
|
"peerDependenciesMeta": {
|
|
84
84
|
"sharp": {
|