@sveltejs/vite-plugin-svelte 2.3.0 → 2.4.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.
Files changed (40) hide show
  1. package/package.json +9 -14
  2. package/src/{handle-hot-update.ts → handle-hot-update.js} +35 -20
  3. package/src/index.d.ts +215 -0
  4. package/src/{index.ts → index.js} +40 -69
  5. package/src/{preprocess.ts → preprocess.js} +37 -28
  6. package/src/types/compile.d.ts +48 -0
  7. package/src/types/id.d.ts +31 -0
  8. package/src/types/log.d.ts +24 -0
  9. package/src/types/options.d.ts +20 -0
  10. package/src/types/plugin-api.d.ts +11 -0
  11. package/src/types/vite-plugin-svelte-stats.d.ts +30 -0
  12. package/src/utils/{compile.ts → compile.js} +38 -64
  13. package/src/utils/{dependencies.ts → dependencies.js} +14 -11
  14. package/src/utils/{error.ts → error.js} +21 -14
  15. package/src/utils/{esbuild.ts → esbuild.js} +28 -19
  16. package/src/utils/{hash.ts → hash.js} +14 -3
  17. package/src/utils/{id.ts → id.js} +59 -60
  18. package/src/utils/{load-raw.ts → load-raw.js} +16 -16
  19. package/src/utils/{load-svelte-config.ts → load-svelte-config.js} +12 -10
  20. package/src/utils/{log.ts → log.js} +81 -48
  21. package/src/utils/{optimizer.ts → optimizer.js} +15 -7
  22. package/src/utils/{options.ts → options.js} +146 -296
  23. package/src/utils/{preprocess.ts → preprocess.js} +28 -12
  24. package/src/utils/{resolve.ts → resolve.js} +18 -9
  25. package/src/utils/{sourcemaps.ts → sourcemaps.js} +22 -14
  26. package/src/utils/svelte-version.js +6 -0
  27. package/src/utils/vite-plugin-svelte-cache.js +253 -0
  28. package/src/utils/{vite-plugin-svelte-stats.ts → vite-plugin-svelte-stats.js} +66 -62
  29. package/src/utils/{watch.ts → watch.js} +30 -22
  30. package/dist/index.d.ts +0 -193
  31. package/dist/index.js +0 -2272
  32. package/dist/index.js.map +0 -1
  33. package/src/__tests__/fixtures/preprocess/foo.scss +0 -3
  34. package/src/__tests__/preprocess.spec.ts +0 -51
  35. package/src/utils/__tests__/compile.spec.ts +0 -49
  36. package/src/utils/__tests__/sourcemaps.spec.ts +0 -79
  37. package/src/utils/__tests__/svelte-version.spec.ts +0 -102
  38. package/src/utils/svelte-version.ts +0 -37
  39. package/src/utils/vite-plugin-svelte-cache.ts +0 -182
  40. /package/src/utils/{constants.ts → constants.js} +0 -0
@@ -1,7 +1,5 @@
1
- import type { ResolvedConfig, Plugin } from 'vite';
2
1
  import MagicString from 'magic-string';
3
- import { PreprocessorGroup, ResolvedOptions } from './options';
4
- import { log } from './log';
2
+ import { log } from './log.js';
5
3
  import path from 'path';
6
4
 
7
5
  /**
@@ -9,8 +7,10 @@ import path from 'path';
9
7
  * That means adding/removing class rules from <style> node won't trigger js updates as the scope classes are not changed
10
8
  *
11
9
  * only used during dev with enabled css hmr
10
+ *
11
+ * @returns {import('svelte/types/compiler/preprocess').PreprocessorGroup}
12
12
  */
13
- export function createInjectScopeEverythingRulePreprocessorGroup(): PreprocessorGroup {
13
+ export function createInjectScopeEverythingRulePreprocessorGroup() {
14
14
  return {
15
15
  style({ content, filename }) {
16
16
  const s = new MagicString(content);
@@ -26,9 +26,19 @@ export function createInjectScopeEverythingRulePreprocessorGroup(): Preprocessor
26
26
  };
27
27
  }
28
28
 
29
- function buildExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfig) {
30
- const prependPreprocessors: PreprocessorGroup[] = [];
31
- const appendPreprocessors: PreprocessorGroup[] = [];
29
+ /**
30
+ * @param {import('../types/options.d.ts').ResolvedOptions} options
31
+ * @param {import('vite').ResolvedConfig} config
32
+ * @returns {{
33
+ * prependPreprocessors: import('svelte/types/compiler/preprocess').PreprocessorGroup[],
34
+ * appendPreprocessors: import('svelte/types/compiler/preprocess').PreprocessorGroup[]
35
+ * }}
36
+ */
37
+ function buildExtraPreprocessors(options, config) {
38
+ /** @type {import('svelte/types/compiler/preprocess').PreprocessorGroup[]} */
39
+ const prependPreprocessors = [];
40
+ /** @type {import('svelte/types/compiler/preprocess').PreprocessorGroup[]} */
41
+ const appendPreprocessors = [];
32
42
 
33
43
  // @ts-ignore
34
44
  const pluginsWithPreprocessorsDeprecated = config.plugins.filter((p) => p?.sveltePreprocess);
@@ -53,10 +63,12 @@ function buildExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfi
53
63
  }
54
64
  });
55
65
  }
56
-
57
- const pluginsWithPreprocessors: Plugin[] = config.plugins.filter((p) => p?.api?.sveltePreprocess);
58
- const ignored: Plugin[] = [],
59
- included: Plugin[] = [];
66
+ /** @type {import('vite').Plugin[]} */
67
+ const pluginsWithPreprocessors = config.plugins.filter((p) => p?.api?.sveltePreprocess);
68
+ /** @type {import('vite').Plugin[]} */
69
+ const ignored = [];
70
+ /** @type {import('vite').Plugin[]} */
71
+ const included = [];
60
72
  for (const p of pluginsWithPreprocessors) {
61
73
  if (
62
74
  options.ignorePluginPreprocessors === true ||
@@ -87,7 +99,11 @@ function buildExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfi
87
99
  return { prependPreprocessors, appendPreprocessors };
88
100
  }
89
101
 
90
- export function addExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfig) {
102
+ /**
103
+ * @param {import('../types/options.d.ts').ResolvedOptions} options
104
+ * @param {import('vite').ResolvedConfig} config
105
+ */
106
+ export function addExtraPreprocessors(options, config) {
91
107
  const { prependPreprocessors, appendPreprocessors } = buildExtraPreprocessors(options, config);
92
108
  if (prependPreprocessors.length > 0 || appendPreprocessors.length > 0) {
93
109
  if (!options.preprocess) {
@@ -1,14 +1,15 @@
1
1
  import path from 'path';
2
2
  import { builtinModules } from 'module';
3
- import { resolveDependencyData, isCommonDepWithoutSvelteField } from './dependencies';
4
- import { VitePluginSvelteCache } from './vite-plugin-svelte-cache';
3
+ import { resolveDependencyData, isCommonDepWithoutSvelteField } from './dependencies.js';
5
4
  import { normalizePath } from 'vite';
6
5
 
7
- export async function resolveViaPackageJsonSvelte(
8
- importee: string,
9
- importer: string | undefined,
10
- cache: VitePluginSvelteCache
11
- ): Promise<string | void> {
6
+ /**
7
+ * @param {string} importee
8
+ * @param {string | undefined} importer
9
+ * @param {import('./vite-plugin-svelte-cache').VitePluginSvelteCache} cache
10
+ * @returns {Promise<string | void>}
11
+ */
12
+ export async function resolveViaPackageJsonSvelte(importee, importer, cache) {
12
13
  if (
13
14
  importer &&
14
15
  isBareImport(importee) &&
@@ -31,11 +32,19 @@ export async function resolveViaPackageJsonSvelte(
31
32
  }
32
33
  }
33
34
 
34
- function isNodeInternal(importee: string) {
35
+ /**
36
+ * @param {string} importee
37
+ * @returns {boolean}
38
+ */
39
+ function isNodeInternal(importee) {
35
40
  return importee.startsWith('node:') || builtinModules.includes(importee);
36
41
  }
37
42
 
38
- function isBareImport(importee: string): boolean {
43
+ /**
44
+ * @param {string} importee
45
+ * @returns {boolean}
46
+ */
47
+ function isBareImport(importee) {
39
48
  if (
40
49
  !importee ||
41
50
  importee[0] === '.' ||
@@ -1,30 +1,37 @@
1
1
  import path from 'path';
2
+
2
3
  const IS_WINDOWS = process.platform === 'win32';
3
- interface SourceMapFileRefs {
4
- file?: string;
5
- sources?: string[];
6
- sourceRoot?: string;
7
- }
4
+
5
+ /**
6
+ * @typedef {{
7
+ * file?: string;
8
+ * sources?: string[];
9
+ * sourceRoot?: string;
10
+ * }} SourceMapFileRefs
11
+ */
8
12
 
9
13
  /**
10
14
  * convert absolute paths in sourcemap file refs to their relative equivalents to avoid leaking fs info
11
15
  *
12
16
  * map is modified in place.
13
17
  *
14
- * @param map sourcemap
15
- * @param filename absolute path to file the sourcemap is for
18
+ * @param {SourceMapFileRefs | undefined} map sourcemap
19
+ * @param {string} filename absolute path to file the sourcemap is for
16
20
  */
17
- export function mapToRelative(map: SourceMapFileRefs | undefined, filename: string) {
21
+ export function mapToRelative(map, filename) {
18
22
  if (!map) {
19
23
  return;
20
24
  }
21
25
  const sourceRoot = map.sourceRoot;
22
26
  const dirname = path.dirname(filename);
23
- const toRelative = (s: string) => {
27
+
28
+ /** @type {(s: string) => string} */
29
+ const toRelative = (s) => {
24
30
  if (!s) {
25
31
  return s;
26
32
  }
27
- let sourcePath: string;
33
+ /** @type {string} */
34
+ let sourcePath;
28
35
  if (s.startsWith('file:///')) {
29
36
  // windows has file:///C:/foo and posix has file:///foo, so we have to remove one extra on windows
30
37
  sourcePath = s.slice(IS_WINDOWS ? 8 : 7);
@@ -56,14 +63,15 @@ export function mapToRelative(map: SourceMapFileRefs | undefined, filename: stri
56
63
  *
57
64
  * map is modified in place.
58
65
  *
59
- * @param map the output sourcemap
60
- * @param suffix the suffix to remove
66
+ * @param {SourceMapFileRefs | undefined} map the output sourcemap
67
+ * @param {string} suffix the suffix to remove
61
68
  */
62
- export function removeLangSuffix(map: SourceMapFileRefs | undefined, suffix: string) {
69
+ export function removeLangSuffix(map, suffix) {
63
70
  if (!map) {
64
71
  return;
65
72
  }
66
- const removeSuffix = (s: string) => (s?.endsWith(suffix) ? s.slice(0, -1 * suffix.length) : s);
73
+ /** @type {(s:string)=> string} */
74
+ const removeSuffix = (s) => (s?.endsWith(suffix) ? s.slice(0, -1 * suffix.length) : s);
67
75
  if (map.file) {
68
76
  map.file = removeSuffix(map.file);
69
77
  }
@@ -0,0 +1,6 @@
1
+ import { VERSION } from 'svelte/compiler';
2
+
3
+ /**
4
+ * @type {boolean}
5
+ */
6
+ export const isSvelte3 = VERSION.startsWith('3.');
@@ -0,0 +1,253 @@
1
+ import { readFileSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { findClosestPkgJsonPath } from 'vitefu';
4
+ import { normalizePath } from 'vite';
5
+
6
+ /**
7
+ * @typedef {{
8
+ * name: string;
9
+ * version: string;
10
+ * svelte?: string;
11
+ * path: string;
12
+ * }} PackageInfo
13
+ */
14
+
15
+ /**
16
+ * @class
17
+ */
18
+ export class VitePluginSvelteCache {
19
+ /** @type {Map<string, import('../types/compile.d.ts').Code>} */
20
+ #css = new Map();
21
+ /** @type {Map<string, import('../types/compile.d.ts').Code>} */
22
+ #js = new Map();
23
+ /** @type {Map<string, string[]>} */
24
+ #dependencies = new Map();
25
+ /** @type {Map<string, Set<string>>} */
26
+ #dependants = new Map();
27
+ /** @type {Map<string, string>} */
28
+ #resolvedSvelteFields = new Map();
29
+ /** @type {Map<string, any>} */
30
+ #errors = new Map();
31
+ /** @type {PackageInfo[]} */
32
+ #packageInfos = [];
33
+
34
+ /**
35
+ * @param {import('../types/compile.d.ts').CompileData} compileData
36
+ */
37
+ update(compileData) {
38
+ this.#errors.delete(compileData.normalizedFilename);
39
+ this.#updateCSS(compileData);
40
+ this.#updateJS(compileData);
41
+ this.#updateDependencies(compileData);
42
+ }
43
+
44
+ /**
45
+ * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
46
+ * @returns {boolean}
47
+ */
48
+ has(svelteRequest) {
49
+ const id = svelteRequest.normalizedFilename;
50
+ return this.#errors.has(id) || this.#js.has(id) || this.#css.has(id);
51
+ }
52
+
53
+ /**
54
+ * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
55
+ * @param {any} error
56
+ */
57
+ setError(svelteRequest, error) {
58
+ // keep dependency info, otherwise errors in dependants would not trigger an update after fixing
59
+ // because they are no longer watched
60
+ this.remove(svelteRequest, true);
61
+ this.#errors.set(svelteRequest.normalizedFilename, error);
62
+ }
63
+
64
+ /**
65
+ * @param {import('../types/compile.d.ts').CompileData} compileData
66
+ */
67
+ #updateCSS(compileData) {
68
+ this.#css.set(compileData.normalizedFilename, compileData.compiled.css);
69
+ }
70
+
71
+ /**
72
+ * @param {import('../types/compile.d.ts').CompileData} compileData
73
+ */
74
+ #updateJS(compileData) {
75
+ if (!compileData.ssr) {
76
+ // do not cache SSR js
77
+ this.#js.set(compileData.normalizedFilename, compileData.compiled.js);
78
+ }
79
+ }
80
+
81
+ /**
82
+ * @param {import('../types/compile.d.ts').CompileData} compileData
83
+ */
84
+ #updateDependencies(compileData) {
85
+ const id = compileData.normalizedFilename;
86
+ const prevDependencies = this.#dependencies.get(id) || [];
87
+ const dependencies = compileData.dependencies;
88
+ this.#dependencies.set(id, dependencies);
89
+ const removed = prevDependencies.filter((d) => !dependencies.includes(d));
90
+ const added = dependencies.filter((d) => !prevDependencies.includes(d));
91
+ added.forEach((d) => {
92
+ if (!this.#dependants.has(d)) {
93
+ this.#dependants.set(d, new Set());
94
+ }
95
+ /** @type {Set<string>} */ (this.#dependants.get(d)).add(compileData.filename);
96
+ });
97
+ removed.forEach((d) => {
98
+ /** @type {Set<string>} */ (this.#dependants.get(d)).delete(compileData.filename);
99
+ });
100
+ }
101
+
102
+ /**
103
+ * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
104
+ * @param {boolean} [keepDependencies]
105
+ * @returns {boolean}
106
+ */
107
+ remove(svelteRequest, keepDependencies = false) {
108
+ const id = svelteRequest.normalizedFilename;
109
+ let removed = false;
110
+ if (this.#errors.delete(id)) {
111
+ removed = true;
112
+ }
113
+ if (this.#js.delete(id)) {
114
+ removed = true;
115
+ }
116
+ if (this.#css.delete(id)) {
117
+ removed = true;
118
+ }
119
+ if (!keepDependencies) {
120
+ const dependencies = this.#dependencies.get(id);
121
+ if (dependencies) {
122
+ removed = true;
123
+ dependencies.forEach((d) => {
124
+ const dependants = this.#dependants.get(d);
125
+ if (dependants && dependants.has(svelteRequest.filename)) {
126
+ dependants.delete(svelteRequest.filename);
127
+ }
128
+ });
129
+ this.#dependencies.delete(id);
130
+ }
131
+ }
132
+
133
+ return removed;
134
+ }
135
+
136
+ /**
137
+ * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
138
+ * @returns {import('../types/compile.d.ts').Code | undefined}
139
+ */
140
+ getCSS(svelteRequest) {
141
+ return this.#css.get(svelteRequest.normalizedFilename);
142
+ }
143
+
144
+ /**
145
+ * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
146
+ * @returns {import('../types/compile.d.ts').Code | undefined}
147
+ */
148
+ getJS(svelteRequest) {
149
+ if (!svelteRequest.ssr) {
150
+ // SSR js isn't cached
151
+ return this.#js.get(svelteRequest.normalizedFilename);
152
+ }
153
+ }
154
+ /**
155
+ * @param {import('../types/id.d.ts').SvelteRequest} svelteRequest
156
+ * @returns {any}
157
+ */
158
+ getError(svelteRequest) {
159
+ return this.#errors.get(svelteRequest.normalizedFilename);
160
+ }
161
+
162
+ /**
163
+ * @param {string} path
164
+ * @returns {string[]}
165
+ */
166
+ getDependants(path) {
167
+ const dependants = this.#dependants.get(path);
168
+ return dependants ? [...dependants] : [];
169
+ }
170
+
171
+ /**
172
+ * @param {string} name
173
+ * @param {string} [importer]
174
+ * @returns {string|void}
175
+ */
176
+ getResolvedSvelteField(name, importer) {
177
+ return this.#resolvedSvelteFields.get(this.#getResolvedSvelteFieldKey(name, importer));
178
+ }
179
+
180
+ /**
181
+ * @param {string} name
182
+ * @param {string} [importer]
183
+ * @returns {boolean}
184
+ */
185
+ hasResolvedSvelteField(name, importer) {
186
+ return this.#resolvedSvelteFields.has(this.#getResolvedSvelteFieldKey(name, importer));
187
+ }
188
+ /**
189
+ *
190
+ * @param {string} importee
191
+ * @param {string | undefined} importer
192
+ * @param {string} resolvedSvelte
193
+ */
194
+ setResolvedSvelteField(importee, importer, resolvedSvelte) {
195
+ this.#resolvedSvelteFields.set(
196
+ this.#getResolvedSvelteFieldKey(importee, importer),
197
+ resolvedSvelte
198
+ );
199
+ }
200
+
201
+ /**
202
+ * @param {string} importee
203
+ * @param {string | undefined} importer
204
+ * @returns {string}
205
+ */
206
+ #getResolvedSvelteFieldKey(importee, importer) {
207
+ return importer ? `${importer} > ${importee}` : importee;
208
+ }
209
+
210
+ /**
211
+ * @param {string} file
212
+ * @returns {Promise<PackageInfo>}
213
+ */
214
+ async getPackageInfo(file) {
215
+ let info = this.#packageInfos.find((pi) => file.startsWith(pi.path));
216
+ if (!info) {
217
+ info = await findPackageInfo(file);
218
+ this.#packageInfos.push(info);
219
+ }
220
+ return info;
221
+ }
222
+ }
223
+
224
+ /**
225
+ * utility to get some info from the closest package.json with a "name" set
226
+ *
227
+ * @param {string} file to find info for
228
+ * @returns {Promise<PackageInfo>}
229
+ */
230
+ async function findPackageInfo(file) {
231
+ /** @type {PackageInfo} */
232
+ const info = {
233
+ name: '$unknown',
234
+ version: '0.0.0-unknown',
235
+ path: '$unknown'
236
+ };
237
+ let path = await findClosestPkgJsonPath(file, (pkgPath) => {
238
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
239
+ if (pkg.name != null) {
240
+ info.name = pkg.name;
241
+ if (pkg.version != null) {
242
+ info.version = pkg.version;
243
+ }
244
+ info.svelte = pkg.svelte;
245
+ return true;
246
+ }
247
+ return false;
248
+ });
249
+ // return normalized path with appended '/' so .startsWith works for future file checks
250
+ path = normalizePath(dirname(path ?? file)) + '/';
251
+ info.path = path;
252
+ return info;
253
+ }
@@ -1,54 +1,29 @@
1
- import { log } from './log';
1
+ import { log } from './log.js';
2
2
  import { performance } from 'perf_hooks';
3
3
  import { normalizePath } from 'vite';
4
- import { VitePluginSvelteCache } from './vite-plugin-svelte-cache';
5
4
 
6
- interface Stat {
7
- file: string;
8
- pkg?: string;
9
- start: number;
10
- end: number;
11
- }
12
-
13
- export interface StatCollection {
14
- name: string;
15
- options: CollectionOptions;
16
- //eslint-disable-next-line no-unused-vars
17
- start: (file: string) => () => void;
18
- stats: Stat[];
19
- packageStats?: PackageStats[];
20
- collectionStart: number;
21
- duration?: number;
22
- finish: () => Promise<void> | void;
23
- finished: boolean;
24
- }
25
-
26
- interface PackageStats {
27
- pkg: string;
28
- files: number;
29
- duration: number;
30
- }
31
-
32
- export interface CollectionOptions {
33
- //eslint-disable-next-line no-unused-vars
34
- logInProgress: (collection: StatCollection, now: number) => boolean;
35
- //eslint-disable-next-line no-unused-vars
36
- logResult: (collection: StatCollection) => boolean;
37
- }
38
-
39
- const defaultCollectionOptions: CollectionOptions = {
5
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').CollectionOptions} */
6
+ const defaultCollectionOptions = {
40
7
  // log after 500ms and more than one file processed
41
8
  logInProgress: (c, now) => now - c.collectionStart > 500 && c.stats.length > 1,
42
9
  // always log results
43
10
  logResult: () => true
44
11
  };
45
12
 
46
- function humanDuration(n: number) {
13
+ /**
14
+ * @param {number} n
15
+ * @returns
16
+ */
17
+ function humanDuration(n) {
47
18
  // 99.9ms 0.10s
48
19
  return n < 100 ? `${n.toFixed(1)}ms` : `${(n / 1000).toFixed(2)}s`;
49
20
  }
50
21
 
51
- function formatPackageStats(pkgStats: PackageStats[]) {
22
+ /**
23
+ * @param {import('../types/vite-plugin-svelte-stats.d.ts').PackageStats[]} pkgStats
24
+ * @returns {string}
25
+ */
26
+ function formatPackageStats(pkgStats) {
52
27
  const statLines = pkgStats.map((pkgStat) => {
53
28
  const duration = pkgStat.duration;
54
29
  const avg = duration / pkgStat.files;
@@ -56,7 +31,7 @@ function formatPackageStats(pkgStats: PackageStats[]) {
56
31
  });
57
32
  statLines.unshift(['package', 'files', 'time', 'avg']);
58
33
  const columnWidths = statLines.reduce(
59
- (widths: number[], row) => {
34
+ (widths, row) => {
60
35
  for (let i = 0; i < row.length; i++) {
61
36
  const cell = row[i];
62
37
  if (widths[i] < cell.length) {
@@ -69,9 +44,9 @@ function formatPackageStats(pkgStats: PackageStats[]) {
69
44
  );
70
45
 
71
46
  const table = statLines
72
- .map((row: string[]) =>
47
+ .map((row) =>
73
48
  row
74
- .map((cell: string, i: number) => {
49
+ .map((cell, i) => {
75
50
  if (i === 0) {
76
51
  return cell.padEnd(columnWidths[i], ' ');
77
52
  } else {
@@ -84,23 +59,40 @@ function formatPackageStats(pkgStats: PackageStats[]) {
84
59
  return table;
85
60
  }
86
61
 
62
+ /**
63
+ * @class
64
+ */
87
65
  export class VitePluginSvelteStats {
88
66
  // package directory -> package name
89
- private _cache: VitePluginSvelteCache;
90
- private _collections: StatCollection[] = [];
91
- constructor(cache: VitePluginSvelteCache) {
92
- this._cache = cache;
67
+ /** @type {import('./vite-plugin-svelte-cache.js').VitePluginSvelteCache} */
68
+ #cache;
69
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection[]} */
70
+ #collections = [];
71
+
72
+ /**
73
+ * @param {import('./vite-plugin-svelte-cache.js').VitePluginSvelteCache} cache
74
+ */
75
+ constructor(cache) {
76
+ this.#cache = cache;
93
77
  }
94
- startCollection(name: string, opts?: Partial<CollectionOptions>) {
78
+
79
+ /**
80
+ * @param {string} name
81
+ * @param {Partial<import('../types/vite-plugin-svelte-stats.d.ts').CollectionOptions>} [opts]
82
+ * @returns {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection}
83
+ */
84
+ startCollection(name, opts) {
95
85
  const options = {
96
86
  ...defaultCollectionOptions,
97
87
  ...opts
98
88
  };
99
- const stats: Stat[] = [];
89
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').Stat[]} */
90
+ const stats = [];
100
91
  const collectionStart = performance.now();
101
92
  const _this = this;
102
93
  let hasLoggedProgress = false;
103
- const collection: StatCollection = {
94
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} */
95
+ const collection = {
104
96
  name,
105
97
  options,
106
98
  stats,
@@ -112,7 +104,8 @@ export class VitePluginSvelteStats {
112
104
  }
113
105
  file = normalizePath(file);
114
106
  const start = performance.now();
115
- const stat: Stat = { file, start, end: start };
107
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').Stat} */
108
+ const stat = { file, start, end: start };
116
109
  return () => {
117
110
  const now = performance.now();
118
111
  stat.end = now;
@@ -124,34 +117,41 @@ export class VitePluginSvelteStats {
124
117
  };
125
118
  },
126
119
  async finish() {
127
- await _this._finish(collection);
120
+ await _this.#finish(collection);
128
121
  }
129
122
  };
130
- _this._collections.push(collection);
123
+ _this.#collections.push(collection);
131
124
  return collection;
132
125
  }
133
126
 
134
- public async finishAll() {
135
- await Promise.all(this._collections.map((c) => c.finish()));
127
+ async finishAll() {
128
+ await Promise.all(this.#collections.map((c) => c.finish()));
136
129
  }
137
130
 
138
- private async _finish(collection: StatCollection) {
131
+ /**
132
+ * @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} collection
133
+ */
134
+ async #finish(collection) {
139
135
  try {
140
136
  collection.finished = true;
141
137
  const now = performance.now();
142
138
  collection.duration = now - collection.collectionStart;
143
139
  const logResult = collection.options.logResult(collection);
144
140
  if (logResult) {
145
- await this._aggregateStatsResult(collection);
141
+ await this.#aggregateStatsResult(collection);
146
142
  log.debug(
147
- `${collection.name} done.\n${formatPackageStats(collection.packageStats!)}`,
143
+ `${collection.name} done.\n${formatPackageStats(
144
+ /** @type {import('../types/vite-plugin-svelte-stats.d.ts').PackageStats[]}*/ (
145
+ collection.packageStats
146
+ )
147
+ )}`,
148
148
  undefined,
149
149
  'stats'
150
150
  );
151
151
  }
152
152
  // cut some ties to free it for garbage collection
153
- const index = this._collections.indexOf(collection);
154
- this._collections.splice(index, 1);
153
+ const index = this.#collections.indexOf(collection);
154
+ this.#collections.splice(index, 1);
155
155
  collection.stats.length = 0;
156
156
  collection.stats = [];
157
157
  if (collection.packageStats) {
@@ -166,16 +166,20 @@ export class VitePluginSvelteStats {
166
166
  }
167
167
  }
168
168
 
169
- private async _aggregateStatsResult(collection: StatCollection) {
169
+ /**
170
+ * @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} collection
171
+ */
172
+ async #aggregateStatsResult(collection) {
170
173
  const stats = collection.stats;
171
174
  for (const stat of stats) {
172
- stat.pkg = (await this._cache.getPackageInfo(stat.file)).name;
175
+ stat.pkg = (await this.#cache.getPackageInfo(stat.file)).name;
173
176
  }
174
177
 
175
178
  // group stats
176
- const grouped: { [key: string]: PackageStats } = {};
179
+ /** @type {Record<string, import('../types/vite-plugin-svelte-stats.d.ts').PackageStats>} */
180
+ const grouped = {};
177
181
  stats.forEach((stat) => {
178
- const pkg = stat.pkg!;
182
+ const pkg = /** @type {string} */ (stat.pkg);
179
183
  let group = grouped[pkg];
180
184
  if (!group) {
181
185
  group = grouped[pkg] = {