@sveltejs/vite-plugin-svelte 1.2.0 → 1.3.1
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/index.cjs +473 -224
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.js +454 -205
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +4 -1
- package/src/utils/compile.ts +36 -3
- package/src/utils/constants.ts +2 -0
- package/src/utils/esbuild.ts +19 -7
- package/src/utils/options.ts +90 -13
- package/src/utils/vite-plugin-svelte-stats.ts +217 -0
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
7
7
|
});
|
|
8
8
|
|
|
9
9
|
// src/index.ts
|
|
10
|
-
import
|
|
10
|
+
import fs7 from "fs";
|
|
11
11
|
import { isDepExcluded as isDepExcluded2 } from "vitefu";
|
|
12
12
|
|
|
13
13
|
// src/utils/log.ts
|
|
@@ -289,81 +289,105 @@ function toSafe(base64) {
|
|
|
289
289
|
|
|
290
290
|
// src/utils/compile.ts
|
|
291
291
|
var scriptLangRE = /<script [^>]*lang=["']?([^"' >]+)["']?[^>]*>/;
|
|
292
|
-
var _createCompileSvelte = (makeHot) =>
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
292
|
+
var _createCompileSvelte = (makeHot) => {
|
|
293
|
+
let stats;
|
|
294
|
+
return async function compileSvelte2(svelteRequest, code, options) {
|
|
295
|
+
const { filename, normalizedFilename, cssId, ssr } = svelteRequest;
|
|
296
|
+
const { emitCss = true } = options;
|
|
297
|
+
const dependencies = [];
|
|
298
|
+
if (options.stats) {
|
|
299
|
+
if (options.isBuild) {
|
|
300
|
+
if (!stats) {
|
|
301
|
+
stats = options.stats.startCollection(`${ssr ? "ssr" : "dom"} compile`, {
|
|
302
|
+
logInProgress: () => false
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
} else {
|
|
306
|
+
if (ssr && !stats) {
|
|
307
|
+
stats = options.stats.startCollection("ssr compile");
|
|
308
|
+
}
|
|
309
|
+
if (!ssr && stats) {
|
|
310
|
+
stats.finish();
|
|
311
|
+
stats = void 0;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
312
314
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
|
|
315
|
+
const compileOptions = {
|
|
316
|
+
...options.compilerOptions,
|
|
317
|
+
filename,
|
|
318
|
+
generate: ssr ? "ssr" : "dom",
|
|
319
|
+
format: "esm"
|
|
320
|
+
};
|
|
321
|
+
if (options.hot && options.emitCss) {
|
|
322
|
+
const hash = `s-${safeBase64Hash(normalizedFilename)}`;
|
|
323
|
+
log.debug(`setting cssHash ${hash} for ${normalizedFilename}`);
|
|
324
|
+
compileOptions.cssHash = () => hash;
|
|
321
325
|
}
|
|
322
|
-
if (
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
326
|
+
if (ssr && compileOptions.enableSourcemap !== false) {
|
|
327
|
+
if (typeof compileOptions.enableSourcemap === "object") {
|
|
328
|
+
compileOptions.enableSourcemap.css = false;
|
|
329
|
+
} else {
|
|
330
|
+
compileOptions.enableSourcemap = { js: true, css: false };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
let preprocessed;
|
|
334
|
+
if (options.preprocess) {
|
|
335
|
+
try {
|
|
336
|
+
preprocessed = await preprocess(code, options.preprocess, { filename });
|
|
337
|
+
} catch (e) {
|
|
338
|
+
e.message = `Error while preprocessing ${filename}${e.message ? ` - ${e.message}` : ""}`;
|
|
339
|
+
throw e;
|
|
340
|
+
}
|
|
341
|
+
if (preprocessed.dependencies)
|
|
342
|
+
dependencies.push(...preprocessed.dependencies);
|
|
343
|
+
if (preprocessed.map)
|
|
344
|
+
compileOptions.sourcemap = preprocessed.map;
|
|
345
|
+
}
|
|
346
|
+
const finalCode = preprocessed ? preprocessed.code : code;
|
|
347
|
+
const dynamicCompileOptions = await options.experimental?.dynamicCompileOptions?.({
|
|
348
|
+
filename,
|
|
349
|
+
code: finalCode,
|
|
350
|
+
compileOptions
|
|
351
|
+
});
|
|
352
|
+
if (dynamicCompileOptions && log.debug.enabled) {
|
|
353
|
+
log.debug(
|
|
354
|
+
`dynamic compile options for ${filename}: ${JSON.stringify(dynamicCompileOptions)}`
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
const finalCompileOptions = dynamicCompileOptions ? {
|
|
358
|
+
...compileOptions,
|
|
359
|
+
...dynamicCompileOptions
|
|
360
|
+
} : compileOptions;
|
|
361
|
+
const endStat = stats?.start(filename);
|
|
362
|
+
const compiled = compile(finalCode, finalCompileOptions);
|
|
363
|
+
if (endStat) {
|
|
364
|
+
endStat();
|
|
365
|
+
}
|
|
366
|
+
const hasCss = compiled.css?.code?.trim().length > 0;
|
|
367
|
+
if (emitCss && hasCss) {
|
|
368
|
+
compiled.js.code += `
|
|
346
369
|
import ${JSON.stringify(cssId)};
|
|
347
370
|
`;
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
371
|
+
}
|
|
372
|
+
if (!ssr && makeHot) {
|
|
373
|
+
compiled.js.code = makeHot({
|
|
374
|
+
id: filename,
|
|
375
|
+
compiledCode: compiled.js.code,
|
|
376
|
+
hotOptions: { ...options.hot, injectCss: options.hot?.injectCss === true && hasCss },
|
|
377
|
+
compiled,
|
|
378
|
+
originalCode: code,
|
|
379
|
+
compileOptions: finalCompileOptions
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
compiled.js.dependencies = dependencies;
|
|
383
|
+
return {
|
|
384
|
+
filename,
|
|
385
|
+
normalizedFilename,
|
|
386
|
+
lang: code.match(scriptLangRE)?.[1] || "js",
|
|
354
387
|
compiled,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
compiled.js.dependencies = dependencies;
|
|
360
|
-
return {
|
|
361
|
-
filename,
|
|
362
|
-
normalizedFilename,
|
|
363
|
-
lang: code.match(scriptLangRE)?.[1] || "js",
|
|
364
|
-
compiled,
|
|
365
|
-
ssr,
|
|
366
|
-
dependencies
|
|
388
|
+
ssr,
|
|
389
|
+
dependencies
|
|
390
|
+
};
|
|
367
391
|
};
|
|
368
392
|
};
|
|
369
393
|
function buildMakeHot(options) {
|
|
@@ -463,7 +487,7 @@ function buildIdParser(options) {
|
|
|
463
487
|
}
|
|
464
488
|
|
|
465
489
|
// src/utils/options.ts
|
|
466
|
-
import { normalizePath as
|
|
490
|
+
import { normalizePath as normalizePath3 } from "vite";
|
|
467
491
|
|
|
468
492
|
// src/utils/load-svelte-config.ts
|
|
469
493
|
import { createRequire } from "module";
|
|
@@ -571,12 +595,13 @@ var SVELTE_HMR_IMPORTS = [
|
|
|
571
595
|
"svelte-hmr/runtime/proxy-adapter-dom.js",
|
|
572
596
|
"svelte-hmr"
|
|
573
597
|
];
|
|
598
|
+
var SVELTE_EXPORT_CONDITIONS = ["svelte"];
|
|
574
599
|
|
|
575
600
|
// src/utils/options.ts
|
|
576
601
|
import path4 from "path";
|
|
577
602
|
|
|
578
603
|
// src/utils/esbuild.ts
|
|
579
|
-
import {
|
|
604
|
+
import { readFileSync } from "fs";
|
|
580
605
|
import { compile as compile2, preprocess as preprocess2 } from "svelte/compiler";
|
|
581
606
|
|
|
582
607
|
// src/utils/error.ts
|
|
@@ -673,19 +698,28 @@ function esbuildSveltePlugin(options) {
|
|
|
673
698
|
return;
|
|
674
699
|
const svelteExtensions = (options.extensions ?? [".svelte"]).map((ext) => ext.slice(1));
|
|
675
700
|
const svelteFilter = new RegExp(`\\.(` + svelteExtensions.join("|") + `)(\\?.*)?$`);
|
|
701
|
+
let statsCollection;
|
|
702
|
+
build.onStart(() => {
|
|
703
|
+
statsCollection = options.stats?.startCollection("prebundle libraries", {
|
|
704
|
+
logResult: (c) => c.stats.length > 1
|
|
705
|
+
});
|
|
706
|
+
});
|
|
676
707
|
build.onLoad({ filter: svelteFilter }, async ({ path: filename }) => {
|
|
677
|
-
const code =
|
|
708
|
+
const code = readFileSync(filename, "utf8");
|
|
678
709
|
try {
|
|
679
|
-
const contents = await compileSvelte(options, { filename, code });
|
|
710
|
+
const contents = await compileSvelte(options, { filename, code }, statsCollection);
|
|
680
711
|
return { contents };
|
|
681
712
|
} catch (e) {
|
|
682
713
|
return { errors: [toESBuildError(e, options)] };
|
|
683
714
|
}
|
|
684
715
|
});
|
|
716
|
+
build.onEnd(() => {
|
|
717
|
+
statsCollection?.finish();
|
|
718
|
+
});
|
|
685
719
|
}
|
|
686
720
|
};
|
|
687
721
|
}
|
|
688
|
-
async function compileSvelte(options, { filename, code }) {
|
|
722
|
+
async function compileSvelte(options, { filename, code }, statsCollection) {
|
|
689
723
|
let css = options.compilerOptions.css;
|
|
690
724
|
if (css !== "none") {
|
|
691
725
|
css = isCssString ? "injected" : true;
|
|
@@ -721,7 +755,11 @@ async function compileSvelte(options, { filename, code }) {
|
|
|
721
755
|
...compileOptions,
|
|
722
756
|
...dynamicCompileOptions
|
|
723
757
|
} : compileOptions;
|
|
758
|
+
const endStat = statsCollection?.start(filename);
|
|
724
759
|
const compiled = compile2(finalCode, finalCompileOptions);
|
|
760
|
+
if (endStat) {
|
|
761
|
+
endStat();
|
|
762
|
+
}
|
|
725
763
|
return compiled.js.code + "//# sourceMappingURL=" + compiled.js.map.toUrl();
|
|
726
764
|
}
|
|
727
765
|
|
|
@@ -993,7 +1031,7 @@ import {
|
|
|
993
1031
|
|
|
994
1032
|
// src/utils/dependencies.ts
|
|
995
1033
|
import path3 from "path";
|
|
996
|
-
import
|
|
1034
|
+
import fs3 from "fs/promises";
|
|
997
1035
|
import { findDepPkgJsonPath } from "vitefu";
|
|
998
1036
|
async function resolveDependencyData(dep, parent) {
|
|
999
1037
|
const depDataPath = await findDepPkgJsonPath(dep, parent);
|
|
@@ -1002,7 +1040,7 @@ async function resolveDependencyData(dep, parent) {
|
|
|
1002
1040
|
try {
|
|
1003
1041
|
return {
|
|
1004
1042
|
dir: path3.dirname(depDataPath),
|
|
1005
|
-
pkg: JSON.parse(await
|
|
1043
|
+
pkg: JSON.parse(await fs3.readFile(depDataPath, "utf-8"))
|
|
1006
1044
|
};
|
|
1007
1045
|
} catch {
|
|
1008
1046
|
return void 0;
|
|
@@ -1053,6 +1091,165 @@ function isCommonDepWithoutSvelteField(dependency) {
|
|
|
1053
1091
|
);
|
|
1054
1092
|
}
|
|
1055
1093
|
|
|
1094
|
+
// src/utils/vite-plugin-svelte-stats.ts
|
|
1095
|
+
import { findClosestPkgJsonPath } from "vitefu";
|
|
1096
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
1097
|
+
import { dirname } from "path";
|
|
1098
|
+
import { performance } from "perf_hooks";
|
|
1099
|
+
import { normalizePath as normalizePath2 } from "vite";
|
|
1100
|
+
var defaultCollectionOptions = {
|
|
1101
|
+
logInProgress: (c, now) => now - c.collectionStart > 500 && c.stats.length > 1,
|
|
1102
|
+
logResult: () => true
|
|
1103
|
+
};
|
|
1104
|
+
function humanDuration(n) {
|
|
1105
|
+
return n < 100 ? `${n.toFixed(1)}ms` : `${(n / 1e3).toFixed(2)}s`;
|
|
1106
|
+
}
|
|
1107
|
+
function formatPackageStats(pkgStats) {
|
|
1108
|
+
const statLines = pkgStats.map((pkgStat) => {
|
|
1109
|
+
const duration = pkgStat.duration;
|
|
1110
|
+
const avg = duration / pkgStat.files;
|
|
1111
|
+
return [pkgStat.pkg, `${pkgStat.files}`, humanDuration(duration), humanDuration(avg)];
|
|
1112
|
+
});
|
|
1113
|
+
statLines.unshift(["package", "files", "time", "avg"]);
|
|
1114
|
+
const columnWidths = statLines.reduce(
|
|
1115
|
+
(widths, row) => {
|
|
1116
|
+
for (let i = 0; i < row.length; i++) {
|
|
1117
|
+
const cell = row[i];
|
|
1118
|
+
if (widths[i] < cell.length) {
|
|
1119
|
+
widths[i] = cell.length;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
return widths;
|
|
1123
|
+
},
|
|
1124
|
+
statLines[0].map(() => 0)
|
|
1125
|
+
);
|
|
1126
|
+
const table = statLines.map(
|
|
1127
|
+
(row) => row.map((cell, i) => {
|
|
1128
|
+
if (i === 0) {
|
|
1129
|
+
return cell.padEnd(columnWidths[i], " ");
|
|
1130
|
+
} else {
|
|
1131
|
+
return cell.padStart(columnWidths[i], " ");
|
|
1132
|
+
}
|
|
1133
|
+
}).join(" ")
|
|
1134
|
+
).join("\n");
|
|
1135
|
+
return table;
|
|
1136
|
+
}
|
|
1137
|
+
async function getClosestNamedPackage(file) {
|
|
1138
|
+
let name = "$unknown";
|
|
1139
|
+
let path9 = await findClosestPkgJsonPath(file, (pkgPath) => {
|
|
1140
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
1141
|
+
if (pkg.name != null) {
|
|
1142
|
+
name = pkg.name;
|
|
1143
|
+
return true;
|
|
1144
|
+
}
|
|
1145
|
+
return false;
|
|
1146
|
+
});
|
|
1147
|
+
path9 = normalizePath2(dirname(path9 ?? file)) + "/";
|
|
1148
|
+
return { name, path: path9 };
|
|
1149
|
+
}
|
|
1150
|
+
var VitePluginSvelteStats = class {
|
|
1151
|
+
constructor() {
|
|
1152
|
+
this._packages = [];
|
|
1153
|
+
this._collections = [];
|
|
1154
|
+
}
|
|
1155
|
+
startCollection(name, opts) {
|
|
1156
|
+
const options = {
|
|
1157
|
+
...defaultCollectionOptions,
|
|
1158
|
+
...opts
|
|
1159
|
+
};
|
|
1160
|
+
const stats = [];
|
|
1161
|
+
const collectionStart = performance.now();
|
|
1162
|
+
const _this = this;
|
|
1163
|
+
let hasLoggedProgress = false;
|
|
1164
|
+
const collection = {
|
|
1165
|
+
name,
|
|
1166
|
+
options,
|
|
1167
|
+
stats,
|
|
1168
|
+
collectionStart,
|
|
1169
|
+
finished: false,
|
|
1170
|
+
start(file) {
|
|
1171
|
+
if (collection.finished) {
|
|
1172
|
+
throw new Error("called after finish() has been used");
|
|
1173
|
+
}
|
|
1174
|
+
file = normalizePath2(file);
|
|
1175
|
+
const start = performance.now();
|
|
1176
|
+
const stat = { file, start, end: start };
|
|
1177
|
+
return () => {
|
|
1178
|
+
const now = performance.now();
|
|
1179
|
+
stat.end = now;
|
|
1180
|
+
stats.push(stat);
|
|
1181
|
+
if (!hasLoggedProgress && options.logInProgress(collection, now)) {
|
|
1182
|
+
hasLoggedProgress = true;
|
|
1183
|
+
log.info(`${name} in progress ...`);
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
},
|
|
1187
|
+
async finish() {
|
|
1188
|
+
await _this._finish(collection);
|
|
1189
|
+
}
|
|
1190
|
+
};
|
|
1191
|
+
_this._collections.push(collection);
|
|
1192
|
+
return collection;
|
|
1193
|
+
}
|
|
1194
|
+
async finishAll() {
|
|
1195
|
+
await Promise.all(this._collections.map((c) => c.finish()));
|
|
1196
|
+
}
|
|
1197
|
+
async _finish(collection) {
|
|
1198
|
+
try {
|
|
1199
|
+
collection.finished = true;
|
|
1200
|
+
const now = performance.now();
|
|
1201
|
+
collection.duration = now - collection.collectionStart;
|
|
1202
|
+
const logResult = collection.options.logResult(collection);
|
|
1203
|
+
if (logResult) {
|
|
1204
|
+
await this._aggregateStatsResult(collection);
|
|
1205
|
+
log.info(`${collection.name} done.`, formatPackageStats(collection.packageStats));
|
|
1206
|
+
}
|
|
1207
|
+
const index = this._collections.indexOf(collection);
|
|
1208
|
+
this._collections.splice(index, 1);
|
|
1209
|
+
collection.stats.length = 0;
|
|
1210
|
+
collection.stats = [];
|
|
1211
|
+
if (collection.packageStats) {
|
|
1212
|
+
collection.packageStats.length = 0;
|
|
1213
|
+
collection.packageStats = [];
|
|
1214
|
+
}
|
|
1215
|
+
collection.start = () => () => {
|
|
1216
|
+
};
|
|
1217
|
+
collection.finish = () => {
|
|
1218
|
+
};
|
|
1219
|
+
} catch (e) {
|
|
1220
|
+
log.debug.once(`failed to finish stats for ${collection.name}`, e);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
async _aggregateStatsResult(collection) {
|
|
1224
|
+
const stats = collection.stats;
|
|
1225
|
+
for (const stat of stats) {
|
|
1226
|
+
let pkg = this._packages.find((p) => stat.file.startsWith(p.path));
|
|
1227
|
+
if (!pkg) {
|
|
1228
|
+
pkg = await getClosestNamedPackage(stat.file);
|
|
1229
|
+
this._packages.push(pkg);
|
|
1230
|
+
}
|
|
1231
|
+
stat.pkg = pkg.name;
|
|
1232
|
+
}
|
|
1233
|
+
const grouped = {};
|
|
1234
|
+
stats.forEach((stat) => {
|
|
1235
|
+
const pkg = stat.pkg;
|
|
1236
|
+
let group = grouped[pkg];
|
|
1237
|
+
if (!group) {
|
|
1238
|
+
group = grouped[pkg] = {
|
|
1239
|
+
files: 0,
|
|
1240
|
+
duration: 0,
|
|
1241
|
+
pkg
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1244
|
+
group.files += 1;
|
|
1245
|
+
group.duration += stat.end - stat.start;
|
|
1246
|
+
});
|
|
1247
|
+
const groups = Object.values(grouped);
|
|
1248
|
+
groups.sort((a, b) => b.duration - a.duration);
|
|
1249
|
+
collection.packageStats = groups;
|
|
1250
|
+
}
|
|
1251
|
+
};
|
|
1252
|
+
|
|
1056
1253
|
// src/utils/options.ts
|
|
1057
1254
|
var cssAsString = atLeastSvelte("3.53.0");
|
|
1058
1255
|
var allowedPluginOptions = /* @__PURE__ */ new Set([
|
|
@@ -1138,16 +1335,18 @@ async function preResolveOptions(inlineOptions = {}, viteUserConfig, viteEnv) {
|
|
|
1138
1335
|
...viteUserConfig,
|
|
1139
1336
|
root: resolveViteRoot(viteUserConfig)
|
|
1140
1337
|
};
|
|
1338
|
+
const isBuild = viteEnv.command === "build";
|
|
1141
1339
|
const defaultOptions = {
|
|
1142
1340
|
extensions: [".svelte"],
|
|
1143
|
-
emitCss: true
|
|
1341
|
+
emitCss: true,
|
|
1342
|
+
prebundleSvelteLibraries: !isBuild
|
|
1144
1343
|
};
|
|
1145
1344
|
const svelteConfig = convertPluginOptions(
|
|
1146
1345
|
await loadSvelteConfig(viteConfigWithResolvedRoot, inlineOptions)
|
|
1147
1346
|
);
|
|
1148
1347
|
const extraOptions = {
|
|
1149
1348
|
root: viteConfigWithResolvedRoot.root,
|
|
1150
|
-
isBuild
|
|
1349
|
+
isBuild,
|
|
1151
1350
|
isServe: viteEnv.command === "serve",
|
|
1152
1351
|
isDebug: process.env.DEBUG != null
|
|
1153
1352
|
};
|
|
@@ -1194,6 +1393,12 @@ function resolveOptions(preResolveOptions2, viteConfig) {
|
|
|
1194
1393
|
addExtraPreprocessors(merged, viteConfig);
|
|
1195
1394
|
enforceOptionsForHmr(merged);
|
|
1196
1395
|
enforceOptionsForProduction(merged);
|
|
1396
|
+
const isLogLevelInfo = [void 0, "info"].includes(viteConfig.logLevel);
|
|
1397
|
+
const disableCompileStats = merged.experimental?.disableCompileStats;
|
|
1398
|
+
const statsEnabled = disableCompileStats !== true && disableCompileStats !== (merged.isBuild ? "build" : "dev");
|
|
1399
|
+
if (statsEnabled && isLogLevelInfo) {
|
|
1400
|
+
merged.stats = new VitePluginSvelteStats();
|
|
1401
|
+
}
|
|
1197
1402
|
return merged;
|
|
1198
1403
|
}
|
|
1199
1404
|
function enforceOptionsForHmr(options) {
|
|
@@ -1284,13 +1489,14 @@ function handleDeprecatedOptions(options) {
|
|
|
1284
1489
|
}
|
|
1285
1490
|
}
|
|
1286
1491
|
function resolveViteRoot(viteConfig) {
|
|
1287
|
-
return
|
|
1492
|
+
return normalizePath3(viteConfig.root ? path4.resolve(viteConfig.root) : process.cwd());
|
|
1288
1493
|
}
|
|
1289
1494
|
async function buildExtraViteConfig(options, config) {
|
|
1290
1495
|
const extraViteConfig = {
|
|
1291
1496
|
resolve: {
|
|
1292
1497
|
mainFields: [...SVELTE_RESOLVE_MAIN_FIELDS],
|
|
1293
|
-
dedupe: [...SVELTE_IMPORTS, ...SVELTE_HMR_IMPORTS]
|
|
1498
|
+
dedupe: [...SVELTE_IMPORTS, ...SVELTE_HMR_IMPORTS],
|
|
1499
|
+
conditions: [...SVELTE_EXPORT_CONDITIONS]
|
|
1294
1500
|
}
|
|
1295
1501
|
};
|
|
1296
1502
|
const extraSvelteConfig = buildExtraConfigForSvelte(config);
|
|
@@ -1324,25 +1530,65 @@ async function buildExtraViteConfig(options, config) {
|
|
|
1324
1530
|
]
|
|
1325
1531
|
};
|
|
1326
1532
|
if (options.prebundleSvelteLibraries) {
|
|
1327
|
-
extraViteConfig.optimizeDeps
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1533
|
+
extraViteConfig.optimizeDeps = {
|
|
1534
|
+
...extraViteConfig.optimizeDeps,
|
|
1535
|
+
extensions: options.extensions ?? [".svelte"],
|
|
1536
|
+
esbuildOptions: {
|
|
1537
|
+
plugins: [{ name: facadeEsbuildSveltePluginName, setup: () => {
|
|
1538
|
+
} }]
|
|
1539
|
+
}
|
|
1331
1540
|
};
|
|
1332
1541
|
}
|
|
1333
1542
|
if ((options.hot == null || options.hot === true || options.hot && options.hot.partialAccept !== false) && config.experimental?.hmrPartialAccept !== false) {
|
|
1334
1543
|
log.debug('enabling "experimental.hmrPartialAccept" in vite config');
|
|
1335
1544
|
extraViteConfig.experimental = { hmrPartialAccept: true };
|
|
1336
1545
|
}
|
|
1546
|
+
validateViteConfig(extraViteConfig, config, options);
|
|
1337
1547
|
return extraViteConfig;
|
|
1338
1548
|
}
|
|
1549
|
+
function validateViteConfig(extraViteConfig, config, options) {
|
|
1550
|
+
const { prebundleSvelteLibraries, isBuild } = options;
|
|
1551
|
+
if (prebundleSvelteLibraries) {
|
|
1552
|
+
const isEnabled = (option) => option !== true && option !== (isBuild ? "build" : "dev");
|
|
1553
|
+
const logWarning = (name, value, recommendation) => log.warn.once(
|
|
1554
|
+
`Incompatible options: \`prebundleSvelteLibraries: true\` and vite \`${name}: ${JSON.stringify(
|
|
1555
|
+
value
|
|
1556
|
+
)}\` ${isBuild ? "during build." : "."} ${recommendation}`
|
|
1557
|
+
);
|
|
1558
|
+
const viteOptimizeDepsDisabled = config.optimizeDeps?.disabled ?? "build";
|
|
1559
|
+
const isOptimizeDepsEnabled = isEnabled(viteOptimizeDepsDisabled);
|
|
1560
|
+
if (!isBuild && !isOptimizeDepsEnabled) {
|
|
1561
|
+
logWarning(
|
|
1562
|
+
"optimizeDeps.disabled",
|
|
1563
|
+
viteOptimizeDepsDisabled,
|
|
1564
|
+
'Forcing `optimizeDeps.disabled: "build"`. Disable prebundleSvelteLibraries or update your vite config to enable optimizeDeps during dev.'
|
|
1565
|
+
);
|
|
1566
|
+
extraViteConfig.optimizeDeps.disabled = "build";
|
|
1567
|
+
} else if (isBuild && isOptimizeDepsEnabled) {
|
|
1568
|
+
logWarning(
|
|
1569
|
+
"optimizeDeps.disabled",
|
|
1570
|
+
viteOptimizeDepsDisabled,
|
|
1571
|
+
"Disable optimizeDeps or prebundleSvelteLibraries for build if you experience errors."
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1339
1576
|
async function buildExtraConfigForDependencies(options, config) {
|
|
1340
1577
|
const depsConfig = await crawlFrameworkPkgs({
|
|
1341
1578
|
root: options.root,
|
|
1342
1579
|
isBuild: options.isBuild,
|
|
1343
1580
|
viteUserConfig: config,
|
|
1344
1581
|
isFrameworkPkgByJson(pkgJson) {
|
|
1345
|
-
|
|
1582
|
+
let hasSvelteCondition = false;
|
|
1583
|
+
if (typeof pkgJson.exports === "object") {
|
|
1584
|
+
JSON.stringify(pkgJson.exports, (key, value) => {
|
|
1585
|
+
if (SVELTE_EXPORT_CONDITIONS.includes(key)) {
|
|
1586
|
+
hasSvelteCondition = true;
|
|
1587
|
+
}
|
|
1588
|
+
return value;
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
return hasSvelteCondition || !!pkgJson.svelte;
|
|
1346
1592
|
},
|
|
1347
1593
|
isSemiFrameworkPkgByJson(pkgJson) {
|
|
1348
1594
|
return !!pkgJson.dependencies?.svelte || !!pkgJson.peerDependencies?.svelte;
|
|
@@ -1408,113 +1654,8 @@ function patchResolvedViteConfig(viteConfig, options) {
|
|
|
1408
1654
|
}
|
|
1409
1655
|
}
|
|
1410
1656
|
|
|
1411
|
-
// src/utils/vite-plugin-svelte-cache.ts
|
|
1412
|
-
var VitePluginSvelteCache = class {
|
|
1413
|
-
constructor() {
|
|
1414
|
-
this._css = /* @__PURE__ */ new Map();
|
|
1415
|
-
this._js = /* @__PURE__ */ new Map();
|
|
1416
|
-
this._dependencies = /* @__PURE__ */ new Map();
|
|
1417
|
-
this._dependants = /* @__PURE__ */ new Map();
|
|
1418
|
-
this._resolvedSvelteFields = /* @__PURE__ */ new Map();
|
|
1419
|
-
this._errors = /* @__PURE__ */ new Map();
|
|
1420
|
-
}
|
|
1421
|
-
update(compileData) {
|
|
1422
|
-
this._errors.delete(compileData.normalizedFilename);
|
|
1423
|
-
this.updateCSS(compileData);
|
|
1424
|
-
this.updateJS(compileData);
|
|
1425
|
-
this.updateDependencies(compileData);
|
|
1426
|
-
}
|
|
1427
|
-
has(svelteRequest) {
|
|
1428
|
-
const id = svelteRequest.normalizedFilename;
|
|
1429
|
-
return this._errors.has(id) || this._js.has(id) || this._css.has(id);
|
|
1430
|
-
}
|
|
1431
|
-
setError(svelteRequest, error) {
|
|
1432
|
-
this.remove(svelteRequest, true);
|
|
1433
|
-
this._errors.set(svelteRequest.normalizedFilename, error);
|
|
1434
|
-
}
|
|
1435
|
-
updateCSS(compileData) {
|
|
1436
|
-
this._css.set(compileData.normalizedFilename, compileData.compiled.css);
|
|
1437
|
-
}
|
|
1438
|
-
updateJS(compileData) {
|
|
1439
|
-
if (!compileData.ssr) {
|
|
1440
|
-
this._js.set(compileData.normalizedFilename, compileData.compiled.js);
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
updateDependencies(compileData) {
|
|
1444
|
-
const id = compileData.normalizedFilename;
|
|
1445
|
-
const prevDependencies = this._dependencies.get(id) || [];
|
|
1446
|
-
const dependencies = compileData.dependencies;
|
|
1447
|
-
this._dependencies.set(id, dependencies);
|
|
1448
|
-
const removed = prevDependencies.filter((d) => !dependencies.includes(d));
|
|
1449
|
-
const added = dependencies.filter((d) => !prevDependencies.includes(d));
|
|
1450
|
-
added.forEach((d) => {
|
|
1451
|
-
if (!this._dependants.has(d)) {
|
|
1452
|
-
this._dependants.set(d, /* @__PURE__ */ new Set());
|
|
1453
|
-
}
|
|
1454
|
-
this._dependants.get(d).add(compileData.filename);
|
|
1455
|
-
});
|
|
1456
|
-
removed.forEach((d) => {
|
|
1457
|
-
this._dependants.get(d).delete(compileData.filename);
|
|
1458
|
-
});
|
|
1459
|
-
}
|
|
1460
|
-
remove(svelteRequest, keepDependencies = false) {
|
|
1461
|
-
const id = svelteRequest.normalizedFilename;
|
|
1462
|
-
let removed = false;
|
|
1463
|
-
if (this._errors.delete(id)) {
|
|
1464
|
-
removed = true;
|
|
1465
|
-
}
|
|
1466
|
-
if (this._js.delete(id)) {
|
|
1467
|
-
removed = true;
|
|
1468
|
-
}
|
|
1469
|
-
if (this._css.delete(id)) {
|
|
1470
|
-
removed = true;
|
|
1471
|
-
}
|
|
1472
|
-
if (!keepDependencies) {
|
|
1473
|
-
const dependencies = this._dependencies.get(id);
|
|
1474
|
-
if (dependencies) {
|
|
1475
|
-
removed = true;
|
|
1476
|
-
dependencies.forEach((d) => {
|
|
1477
|
-
const dependants = this._dependants.get(d);
|
|
1478
|
-
if (dependants && dependants.has(svelteRequest.filename)) {
|
|
1479
|
-
dependants.delete(svelteRequest.filename);
|
|
1480
|
-
}
|
|
1481
|
-
});
|
|
1482
|
-
this._dependencies.delete(id);
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
return removed;
|
|
1486
|
-
}
|
|
1487
|
-
getCSS(svelteRequest) {
|
|
1488
|
-
return this._css.get(svelteRequest.normalizedFilename);
|
|
1489
|
-
}
|
|
1490
|
-
getJS(svelteRequest) {
|
|
1491
|
-
if (!svelteRequest.ssr) {
|
|
1492
|
-
return this._js.get(svelteRequest.normalizedFilename);
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
getError(svelteRequest) {
|
|
1496
|
-
return this._errors.get(svelteRequest.normalizedFilename);
|
|
1497
|
-
}
|
|
1498
|
-
getDependants(path9) {
|
|
1499
|
-
const dependants = this._dependants.get(path9);
|
|
1500
|
-
return dependants ? [...dependants] : [];
|
|
1501
|
-
}
|
|
1502
|
-
getResolvedSvelteField(name, importer) {
|
|
1503
|
-
return this._resolvedSvelteFields.get(this._getResolvedSvelteFieldKey(name, importer));
|
|
1504
|
-
}
|
|
1505
|
-
setResolvedSvelteField(importee, importer = void 0, resolvedSvelte) {
|
|
1506
|
-
this._resolvedSvelteFields.set(
|
|
1507
|
-
this._getResolvedSvelteFieldKey(importee, importer),
|
|
1508
|
-
resolvedSvelte
|
|
1509
|
-
);
|
|
1510
|
-
}
|
|
1511
|
-
_getResolvedSvelteFieldKey(importee, importer) {
|
|
1512
|
-
return importer ? `${importer} > ${importee}` : importee;
|
|
1513
|
-
}
|
|
1514
|
-
};
|
|
1515
|
-
|
|
1516
1657
|
// src/utils/watch.ts
|
|
1517
|
-
import
|
|
1658
|
+
import fs4 from "fs";
|
|
1518
1659
|
import path5 from "path";
|
|
1519
1660
|
function setupWatchers(options, cache, requestParser) {
|
|
1520
1661
|
const { server, configFile: svelteConfigFile } = options;
|
|
@@ -1526,7 +1667,7 @@ function setupWatchers(options, cache, requestParser) {
|
|
|
1526
1667
|
const emitChangeEventOnDependants = (filename) => {
|
|
1527
1668
|
const dependants = cache.getDependants(filename);
|
|
1528
1669
|
dependants.forEach((dependant) => {
|
|
1529
|
-
if (
|
|
1670
|
+
if (fs4.existsSync(dependant)) {
|
|
1530
1671
|
log.debug(
|
|
1531
1672
|
`emitting virtual change event for "${dependant}" because depdendency "${filename}" changed`
|
|
1532
1673
|
);
|
|
@@ -1587,7 +1728,7 @@ function setupWatchers(options, cache, requestParser) {
|
|
|
1587
1728
|
});
|
|
1588
1729
|
}
|
|
1589
1730
|
function ensureWatchedFile(watcher, file, root) {
|
|
1590
|
-
if (file && !file.startsWith(root + "/") && !file.includes("\0") &&
|
|
1731
|
+
if (file && !file.startsWith(root + "/") && !file.includes("\0") && fs4.existsSync(file)) {
|
|
1591
1732
|
watcher.add(path5.resolve(file));
|
|
1592
1733
|
}
|
|
1593
1734
|
}
|
|
@@ -1631,7 +1772,7 @@ function isBareImport(importee) {
|
|
|
1631
1772
|
}
|
|
1632
1773
|
|
|
1633
1774
|
// src/utils/optimizer.ts
|
|
1634
|
-
import { promises as
|
|
1775
|
+
import { promises as fs5 } from "fs";
|
|
1635
1776
|
import path7 from "path";
|
|
1636
1777
|
var PREBUNDLE_SENSITIVE_OPTIONS = [
|
|
1637
1778
|
"compilerOptions",
|
|
@@ -1649,11 +1790,11 @@ async function saveSvelteMetadata(cacheDir, options) {
|
|
|
1649
1790
|
});
|
|
1650
1791
|
let existingSvelteMetadata;
|
|
1651
1792
|
try {
|
|
1652
|
-
existingSvelteMetadata = await
|
|
1793
|
+
existingSvelteMetadata = await fs5.readFile(svelteMetadataPath, "utf8");
|
|
1653
1794
|
} catch {
|
|
1654
1795
|
}
|
|
1655
|
-
await
|
|
1656
|
-
await
|
|
1796
|
+
await fs5.mkdir(cacheDir, { recursive: true });
|
|
1797
|
+
await fs5.writeFile(svelteMetadataPath, currentSvelteMetadata);
|
|
1657
1798
|
return currentSvelteMetadata !== existingSvelteMetadata;
|
|
1658
1799
|
}
|
|
1659
1800
|
function generateSvelteMetadata(options) {
|
|
@@ -1665,10 +1806,10 @@ function generateSvelteMetadata(options) {
|
|
|
1665
1806
|
}
|
|
1666
1807
|
|
|
1667
1808
|
// src/ui/inspector/plugin.ts
|
|
1668
|
-
import { normalizePath as
|
|
1809
|
+
import { normalizePath as normalizePath4 } from "vite";
|
|
1669
1810
|
import path8 from "path";
|
|
1670
1811
|
import { fileURLToPath } from "url";
|
|
1671
|
-
import
|
|
1812
|
+
import fs6 from "fs";
|
|
1672
1813
|
|
|
1673
1814
|
// src/ui/inspector/utils.ts
|
|
1674
1815
|
var FS_PREFIX = `/@fs/`;
|
|
@@ -1693,7 +1834,7 @@ var defaultInspectorOptions = {
|
|
|
1693
1834
|
customStyles: true
|
|
1694
1835
|
};
|
|
1695
1836
|
function getInspectorPath() {
|
|
1696
|
-
const pluginPath =
|
|
1837
|
+
const pluginPath = normalizePath4(path8.dirname(fileURLToPath(import.meta.url)));
|
|
1697
1838
|
return pluginPath.replace(/\/vite-plugin-svelte\/dist$/, "/vite-plugin-svelte/src/ui/inspector/");
|
|
1698
1839
|
}
|
|
1699
1840
|
function svelteInspector() {
|
|
@@ -1745,8 +1886,8 @@ function svelteInspector() {
|
|
|
1745
1886
|
return `export default ${JSON.stringify(inspectorOptions ?? {})}`;
|
|
1746
1887
|
} else if (id.startsWith(inspectorPath)) {
|
|
1747
1888
|
const file = idToFile(id);
|
|
1748
|
-
if (
|
|
1749
|
-
return await
|
|
1889
|
+
if (fs6.existsSync(file)) {
|
|
1890
|
+
return await fs6.promises.readFile(file, "utf-8");
|
|
1750
1891
|
} else {
|
|
1751
1892
|
log.error(`failed to find file for svelte-inspector: ${file}, referenced by id ${id}.`);
|
|
1752
1893
|
}
|
|
@@ -1782,6 +1923,111 @@ import 'virtual:svelte-inspector-path:load-inspector.js'` };
|
|
|
1782
1923
|
};
|
|
1783
1924
|
}
|
|
1784
1925
|
|
|
1926
|
+
// src/utils/vite-plugin-svelte-cache.ts
|
|
1927
|
+
var VitePluginSvelteCache = class {
|
|
1928
|
+
constructor() {
|
|
1929
|
+
this._css = /* @__PURE__ */ new Map();
|
|
1930
|
+
this._js = /* @__PURE__ */ new Map();
|
|
1931
|
+
this._dependencies = /* @__PURE__ */ new Map();
|
|
1932
|
+
this._dependants = /* @__PURE__ */ new Map();
|
|
1933
|
+
this._resolvedSvelteFields = /* @__PURE__ */ new Map();
|
|
1934
|
+
this._errors = /* @__PURE__ */ new Map();
|
|
1935
|
+
}
|
|
1936
|
+
update(compileData) {
|
|
1937
|
+
this._errors.delete(compileData.normalizedFilename);
|
|
1938
|
+
this.updateCSS(compileData);
|
|
1939
|
+
this.updateJS(compileData);
|
|
1940
|
+
this.updateDependencies(compileData);
|
|
1941
|
+
}
|
|
1942
|
+
has(svelteRequest) {
|
|
1943
|
+
const id = svelteRequest.normalizedFilename;
|
|
1944
|
+
return this._errors.has(id) || this._js.has(id) || this._css.has(id);
|
|
1945
|
+
}
|
|
1946
|
+
setError(svelteRequest, error) {
|
|
1947
|
+
this.remove(svelteRequest, true);
|
|
1948
|
+
this._errors.set(svelteRequest.normalizedFilename, error);
|
|
1949
|
+
}
|
|
1950
|
+
updateCSS(compileData) {
|
|
1951
|
+
this._css.set(compileData.normalizedFilename, compileData.compiled.css);
|
|
1952
|
+
}
|
|
1953
|
+
updateJS(compileData) {
|
|
1954
|
+
if (!compileData.ssr) {
|
|
1955
|
+
this._js.set(compileData.normalizedFilename, compileData.compiled.js);
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
updateDependencies(compileData) {
|
|
1959
|
+
const id = compileData.normalizedFilename;
|
|
1960
|
+
const prevDependencies = this._dependencies.get(id) || [];
|
|
1961
|
+
const dependencies = compileData.dependencies;
|
|
1962
|
+
this._dependencies.set(id, dependencies);
|
|
1963
|
+
const removed = prevDependencies.filter((d) => !dependencies.includes(d));
|
|
1964
|
+
const added = dependencies.filter((d) => !prevDependencies.includes(d));
|
|
1965
|
+
added.forEach((d) => {
|
|
1966
|
+
if (!this._dependants.has(d)) {
|
|
1967
|
+
this._dependants.set(d, /* @__PURE__ */ new Set());
|
|
1968
|
+
}
|
|
1969
|
+
this._dependants.get(d).add(compileData.filename);
|
|
1970
|
+
});
|
|
1971
|
+
removed.forEach((d) => {
|
|
1972
|
+
this._dependants.get(d).delete(compileData.filename);
|
|
1973
|
+
});
|
|
1974
|
+
}
|
|
1975
|
+
remove(svelteRequest, keepDependencies = false) {
|
|
1976
|
+
const id = svelteRequest.normalizedFilename;
|
|
1977
|
+
let removed = false;
|
|
1978
|
+
if (this._errors.delete(id)) {
|
|
1979
|
+
removed = true;
|
|
1980
|
+
}
|
|
1981
|
+
if (this._js.delete(id)) {
|
|
1982
|
+
removed = true;
|
|
1983
|
+
}
|
|
1984
|
+
if (this._css.delete(id)) {
|
|
1985
|
+
removed = true;
|
|
1986
|
+
}
|
|
1987
|
+
if (!keepDependencies) {
|
|
1988
|
+
const dependencies = this._dependencies.get(id);
|
|
1989
|
+
if (dependencies) {
|
|
1990
|
+
removed = true;
|
|
1991
|
+
dependencies.forEach((d) => {
|
|
1992
|
+
const dependants = this._dependants.get(d);
|
|
1993
|
+
if (dependants && dependants.has(svelteRequest.filename)) {
|
|
1994
|
+
dependants.delete(svelteRequest.filename);
|
|
1995
|
+
}
|
|
1996
|
+
});
|
|
1997
|
+
this._dependencies.delete(id);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
return removed;
|
|
2001
|
+
}
|
|
2002
|
+
getCSS(svelteRequest) {
|
|
2003
|
+
return this._css.get(svelteRequest.normalizedFilename);
|
|
2004
|
+
}
|
|
2005
|
+
getJS(svelteRequest) {
|
|
2006
|
+
if (!svelteRequest.ssr) {
|
|
2007
|
+
return this._js.get(svelteRequest.normalizedFilename);
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
getError(svelteRequest) {
|
|
2011
|
+
return this._errors.get(svelteRequest.normalizedFilename);
|
|
2012
|
+
}
|
|
2013
|
+
getDependants(path9) {
|
|
2014
|
+
const dependants = this._dependants.get(path9);
|
|
2015
|
+
return dependants ? [...dependants] : [];
|
|
2016
|
+
}
|
|
2017
|
+
getResolvedSvelteField(name, importer) {
|
|
2018
|
+
return this._resolvedSvelteFields.get(this._getResolvedSvelteFieldKey(name, importer));
|
|
2019
|
+
}
|
|
2020
|
+
setResolvedSvelteField(importee, importer = void 0, resolvedSvelte) {
|
|
2021
|
+
this._resolvedSvelteFields.set(
|
|
2022
|
+
this._getResolvedSvelteFieldKey(importee, importer),
|
|
2023
|
+
resolvedSvelte
|
|
2024
|
+
);
|
|
2025
|
+
}
|
|
2026
|
+
_getResolvedSvelteFieldKey(importee, importer) {
|
|
2027
|
+
return importer ? `${importer} > ${importee}` : importee;
|
|
2028
|
+
}
|
|
2029
|
+
};
|
|
2030
|
+
|
|
1785
2031
|
// src/index.ts
|
|
1786
2032
|
function svelte(inlineOptions) {
|
|
1787
2033
|
if (process.env.DEBUG != null) {
|
|
@@ -1846,7 +2092,7 @@ function svelte(inlineOptions) {
|
|
|
1846
2092
|
}
|
|
1847
2093
|
if (viteConfig.assetsInclude(filename)) {
|
|
1848
2094
|
log.debug(`load returns raw content for ${filename}`);
|
|
1849
|
-
return
|
|
2095
|
+
return fs7.readFileSync(filename, "utf-8");
|
|
1850
2096
|
}
|
|
1851
2097
|
}
|
|
1852
2098
|
},
|
|
@@ -1940,6 +2186,9 @@ function svelte(inlineOptions) {
|
|
|
1940
2186
|
throw toRollupError(e, options);
|
|
1941
2187
|
}
|
|
1942
2188
|
}
|
|
2189
|
+
},
|
|
2190
|
+
async buildEnd() {
|
|
2191
|
+
await options.stats?.finishAll();
|
|
1943
2192
|
}
|
|
1944
2193
|
}
|
|
1945
2194
|
];
|