auklet 0.3.1 → 0.3.3

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.
@@ -15,6 +15,7 @@ export declare function mergeAukletConfigOverrides(config: AukletConfig, overrid
15
15
  configureTsdown?: import("#auklet/types").ConfigureTsdown;
16
16
  tsconfig?: string;
17
17
  } | undefined;
18
+ debug?: boolean;
18
19
  source?: string;
19
20
  output?: string;
20
21
  modules?: boolean;
package/dist/cli/help.js CHANGED
@@ -1,4 +1,8 @@
1
1
  export const buildOverrideOptions = [
2
+ [
3
+ '--debug [value]',
4
+ 'Enable debug logging for package CSS build, watch, and HMR flows',
5
+ ],
2
6
  ['--source <dir>', 'Source directory'],
3
7
  ['--output <dir>', 'Output directory'],
4
8
  ['--modules [value]', 'Enable unbundled module output'],
@@ -54,6 +54,16 @@ export function parseBuildOverrideArgs(args, envContext) {
54
54
  index += 1;
55
55
  continue;
56
56
  }
57
+ if (name === '--debug') {
58
+ const value = readOptionalFlagValue(args, index, inlineValue);
59
+ config.debug =
60
+ value === undefined
61
+ ? true
62
+ : resolveCliBoolean(value, { label: name, context: envContext });
63
+ if (inlineValue === undefined && value !== undefined)
64
+ index += 1;
65
+ continue;
66
+ }
57
67
  if (name === '--output') {
58
68
  config.output = getResolvedFlagValue(args, index, inlineValue, name, envContext);
59
69
  if (inlineValue === undefined)
package/dist/config.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { AukletConfig } from '#auklet/types';
2
2
  export declare const aukletConfigFiles: string[];
3
3
  export declare function isAukletConfigFile(file: string): boolean;
4
4
  export declare const aukletDefaultOptions: {
5
+ debug: false;
5
6
  source: string;
6
7
  output: string;
7
8
  modules: false;
@@ -17,6 +18,7 @@ export declare const aukletDefaultOptions: {
17
18
  };
18
19
  };
19
20
  export declare function normalizeAukletConfig(config?: AukletConfig): {
21
+ debug: boolean;
20
22
  source: string;
21
23
  output: string;
22
24
  modules: boolean;
package/dist/config.js CHANGED
@@ -4,6 +4,7 @@ export function isAukletConfigFile(file) {
4
4
  return aukletConfigFiles.includes(file);
5
5
  }
6
6
  export const aukletDefaultOptions = {
7
+ debug: false,
7
8
  source: 'src',
8
9
  output: 'dist',
9
10
  modules: false,
@@ -40,6 +41,7 @@ const normalizeStyleShared = (shared) => {
40
41
  export function normalizeAukletConfig(config = {}) {
41
42
  const dependencies = config.styles?.dependencies ?? aukletDefaultOptions.styles.dependencies;
42
43
  return {
44
+ debug: config.debug ?? aukletDefaultOptions.debug,
43
45
  source: config.source ?? aukletDefaultOptions.source,
44
46
  output: config.output ?? aukletDefaultOptions.output,
45
47
  modules: config.modules ?? aukletDefaultOptions.modules,
@@ -47,6 +47,7 @@ export declare function resolveInspectCssOptions(args: Array<string>): Promise<{
47
47
  configureTsdown?: import("#auklet/types").ConfigureTsdown;
48
48
  tsconfig?: string;
49
49
  } | undefined;
50
+ debug?: boolean;
50
51
  source?: string;
51
52
  output?: string;
52
53
  modules?: boolean;
@@ -37,6 +37,7 @@ export declare class AukletStyleHmr {
37
37
  private sameStyleLoadResult;
38
38
  private suppressFullReload;
39
39
  private shouldSuppressFullReload;
40
+ private logDebug;
40
41
  private isDuplicateUpdate;
41
42
  }
42
43
  export {};
@@ -129,12 +129,18 @@ export class AukletStyleHmr {
129
129
  if (!graph.isStyleFile(context.file)) {
130
130
  return undefined;
131
131
  }
132
+ const totalStartedAt = Date.now();
132
133
  const isSourceGraphFile = graph.isSourceGraphFile(context.file);
133
134
  const trackedEntries = this.getTrackedStyleFileEntries(context.file, context.server.moduleGraph);
135
+ const debug = trackedEntries.length
136
+ ? await graph.isDebugEnabled(trackedEntries[0].parsed)
137
+ : false;
138
+ this.logDebug(debug, `package css hmr start ${getRelativeFile(context.file)} tracked=${trackedEntries.length}`);
134
139
  if (!trackedEntries.length) {
135
140
  if (isSourceGraphFile) {
136
141
  graph.invalidateFile(context.file);
137
142
  }
143
+ this.logDebug(debug, `package css hmr skip ${getRelativeFile(context.file)} total=${Date.now() - totalStartedAt}ms`);
138
144
  return undefined;
139
145
  }
140
146
  const entryEntries = isSourceGraphFile
@@ -160,10 +166,11 @@ export class AukletStyleHmr {
160
166
  ? this.createTrackedVirtualStyleUpdates(context.server, dependencyEntries, context.timestamp)
161
167
  : []),
162
168
  ...(entryEntries.length
163
- ? await this.refreshTrackedVirtualStyleUpdates(context.server, entryEntries, previousResults, context.timestamp)
169
+ ? await this.refreshTrackedVirtualStyleUpdates(context.server, entryEntries, previousResults, context.timestamp, debug)
164
170
  : []),
165
171
  ];
166
172
  if (!updates.length) {
173
+ this.logDebug(debug, `package css hmr no-update ${getRelativeFile(context.file)} total=${Date.now() - totalStartedAt}ms`);
167
174
  return undefined;
168
175
  }
169
176
  this.suppressFullReload();
@@ -172,6 +179,7 @@ export class AukletStyleHmr {
172
179
  updates,
173
180
  });
174
181
  logger.info(`package css hmr ${getRelativeFile(context.file)} tracked=${trackedEntries.length} updates=${updates.length}`);
182
+ this.logDebug(debug, `package css hmr done ${getRelativeFile(context.file)} tracked=${trackedEntries.length} updates=${updates.length} total=${Date.now() - totalStartedAt}ms`);
175
183
  return [];
176
184
  }
177
185
  async handleSourceModuleChange(server, file) {
@@ -179,20 +187,25 @@ export class AukletStyleHmr {
179
187
  if (!graph.isSourceGraphFile(file) || !graph.isSourceModuleFile(file)) {
180
188
  return false;
181
189
  }
190
+ const totalStartedAt = Date.now();
182
191
  const virtualIds = this.getDependencyVirtualIds(file, server.moduleGraph);
183
192
  if (!virtualIds.length) {
184
193
  graph.invalidateFile(file);
194
+ this.logDebug(false, `package css source hmr skip ${getRelativeFile(file)} reason=untracked total=${Date.now() - totalStartedAt}ms`);
185
195
  return false;
186
196
  }
187
197
  const parsedVirtualIds = this.parseTrackedVirtualIds(graph, virtualIds);
188
198
  if (!parsedVirtualIds.length) {
189
199
  graph.invalidateFile(file);
200
+ this.logDebug(false, `package css source hmr skip ${getRelativeFile(file)} reason=unparsed total=${Date.now() - totalStartedAt}ms`);
190
201
  return false;
191
202
  }
203
+ const debug = await graph.isDebugEnabled(parsedVirtualIds[0].parsed);
192
204
  const previousResults = this.createTrackedVirtualStyleResults(graph, parsedVirtualIds);
193
205
  graph.invalidateFile(file);
194
- const updates = await this.refreshTrackedVirtualStyleUpdates(server, parsedVirtualIds, previousResults, Date.now());
206
+ const updates = await this.refreshTrackedVirtualStyleUpdates(server, parsedVirtualIds, previousResults, Date.now(), debug);
195
207
  if (!updates.length) {
208
+ this.logDebug(debug, `package css source hmr no-update ${getRelativeFile(file)} tracked=${parsedVirtualIds.length} total=${Date.now() - totalStartedAt}ms`);
196
209
  return false;
197
210
  }
198
211
  this.suppressFullReload();
@@ -201,6 +214,7 @@ export class AukletStyleHmr {
201
214
  updates,
202
215
  });
203
216
  logger.info(`package css source hmr ${getRelativeFile(file)} tracked=${parsedVirtualIds.length} updates=${updates.length}`);
217
+ this.logDebug(debug, `package css source hmr done ${getRelativeFile(file)} tracked=${parsedVirtualIds.length} updates=${updates.length} total=${Date.now() - totalStartedAt}ms`);
204
218
  return true;
205
219
  }
206
220
  parseTrackedVirtualIds(graph, virtualIds) {
@@ -295,11 +309,13 @@ export class AukletStyleHmr {
295
309
  kind,
296
310
  };
297
311
  }
298
- async refreshTrackedVirtualStyleUpdates(server, parsedVirtualIds, previousResults, timestamp) {
312
+ async refreshTrackedVirtualStyleUpdates(server, parsedVirtualIds, previousResults, timestamp, debug) {
299
313
  const graph = this.graph();
300
314
  const changedVirtualIds = [];
301
315
  for (const item of parsedVirtualIds) {
316
+ const buildStartedAt = Date.now();
302
317
  const nextResult = await graph.createPackageStyleCode(item.parsed);
318
+ this.logDebug(debug, `package css hmr rebuild ${item.id} took=${Date.now() - buildStartedAt}ms`);
303
319
  const previousResult = previousResults.get(item.id);
304
320
  if (!previousResult ||
305
321
  !this.sameStyleLoadResult(previousResult, nextResult)) {
@@ -323,6 +339,11 @@ export class AukletStyleHmr {
323
339
  shouldSuppressFullReload() {
324
340
  return Date.now() <= this.suppressFullReloadUntil;
325
341
  }
342
+ logDebug(enabled, message) {
343
+ if (!enabled)
344
+ return;
345
+ logger.info(message);
346
+ }
326
347
  isDuplicateUpdate(file) {
327
348
  const now = Date.now();
328
349
  const normalizedFile = normalizeFileKey(file);
@@ -17,6 +17,7 @@ export declare class ModuleStyleGraph {
17
17
  getWatchRoots(): Promise<string[]>;
18
18
  createPackageStyleCode(parsed: PackageStyleId): Promise<import("#auklet/css/vite/moduleGraph/types").PackageStyleLoadResult>;
19
19
  peekPackageStyleCode(parsed: PackageStyleId): import("#auklet/css/vite/moduleGraph/types").PackageStyleLoadResult | null;
20
+ isDebugEnabled(parsed: PackageStyleId): Promise<boolean>;
20
21
  invalidatePackage(packageName: string): void;
21
22
  invalidateFile(file: string): string | null;
22
23
  isSourceModuleFile(file: string): boolean;
@@ -63,6 +63,9 @@ export class ModuleStyleGraph {
63
63
  peekPackageStyleCode(parsed) {
64
64
  return this.requestCache.peekLoadResult(parsed);
65
65
  }
66
+ isDebugEnabled(parsed) {
67
+ return this.requestCache.isDebugEnabled(parsed);
68
+ }
66
69
  invalidatePackage(packageName) {
67
70
  this.requestCache.invalidatePackage(packageName);
68
71
  }
@@ -30,7 +30,9 @@ export declare class ModuleStyleGraphRequestCache {
30
30
  private readonly contexts;
31
31
  private readonly loadResults;
32
32
  private readonly settledLoadResults;
33
+ private readonly loadResultsByPackage;
33
34
  private readonly loadResultDependencies;
35
+ private readonly loadResultDependents;
34
36
  private readonly loadResultVersions;
35
37
  private readonly loadAukletConfig;
36
38
  private readonly persistentCache;
@@ -43,6 +45,7 @@ export declare class ModuleStyleGraphRequestCache {
43
45
  configPaths: string[];
44
46
  packageContext: StylePackageContext;
45
47
  normalizedConfig: {
48
+ debug: boolean;
46
49
  source: string;
47
50
  output: string;
48
51
  modules: boolean;
@@ -78,6 +81,7 @@ export declare class ModuleStyleGraphRequestCache {
78
81
  getLoadResult(parsed: PackageStyleId, create: () => Promise<LoadResultEntry>): Promise<PackageStyleLoadResult>;
79
82
  invalidatePackage(packageName: string): void;
80
83
  readPersistentLoadResult(parsed: PackageStyleId, context: PackageStyleContext): PackageStyleLoadResult | null;
84
+ isDebugEnabled(parsed: PackageStyleId): Promise<boolean>;
81
85
  writePersistentLoadResult(parsed: PackageStyleId, context: PackageStyleContext, result: PackageStyleLoadResult): {
82
86
  cacheInputFiles: string[];
83
87
  code: string;
@@ -100,5 +104,8 @@ export declare class ModuleStyleGraphRequestCache {
100
104
  private getGraphVersion;
101
105
  private bumpGraphVersion;
102
106
  private bumpLoadResultVersion;
107
+ private addLoadResultKey;
108
+ private deleteLoadResultKey;
109
+ private replaceLoadResultDependencies;
103
110
  }
104
111
  export {};
@@ -9,7 +9,9 @@ export class ModuleStyleGraphRequestCache {
9
9
  contexts = new Map();
10
10
  loadResults = new Map();
11
11
  settledLoadResults = new Map();
12
+ loadResultsByPackage = new Map();
12
13
  loadResultDependencies = new Map();
14
+ loadResultDependents = new Map();
13
15
  loadResultVersions = new Map();
14
16
  loadAukletConfig;
15
17
  persistentCache;
@@ -41,6 +43,7 @@ export class ModuleStyleGraphRequestCache {
41
43
  if (cachedResult)
42
44
  return cachedResult;
43
45
  const version = this.bumpLoadResultVersion(key);
46
+ this.addLoadResultKey(this.loadResultsByPackage, parsed.packageName, key);
44
47
  const graphVersion = this.getGraphVersion();
45
48
  let result;
46
49
  result = create()
@@ -54,7 +57,7 @@ export class ModuleStyleGraphRequestCache {
54
57
  return this.getLoadResult(parsed, create);
55
58
  }
56
59
  if (this.loadResultVersions.get(key) === version) {
57
- this.loadResultDependencies.set(key, new Set(entry.result.dependencyPackages ?? []));
60
+ this.replaceLoadResultDependencies(key, entry.result.dependencyPackages ?? []);
58
61
  }
59
62
  try {
60
63
  const committedResult = entry.commit?.();
@@ -93,6 +96,10 @@ export class ModuleStyleGraphRequestCache {
93
96
  readPersistentLoadResult(parsed, context) {
94
97
  return this.persistentCache.read(this.createPersistentKey(parsed, context));
95
98
  }
99
+ async isDebugEnabled(parsed) {
100
+ const context = await this.getContext(parsed);
101
+ return context?.normalizedConfig.debug ?? false;
102
+ }
96
103
  writePersistentLoadResult(parsed, context, result) {
97
104
  const cacheInputFiles = this.getPersistentInputFiles(context, result);
98
105
  const cacheResult = {
@@ -226,39 +233,46 @@ export class ModuleStyleGraphRequestCache {
226
233
  return key.split('\0')[0];
227
234
  }
228
235
  invalidateLoadResults(packageName) {
229
- const invalidPackageNames = new Set([packageName]);
230
- let changed = true;
231
- while (changed) {
232
- changed = false;
233
- for (const [key, dependencyPackages] of this.loadResultDependencies) {
234
- const resultPackageName = this.getLoadResultPackageName(key);
235
- const shouldInvalidate = invalidPackageNames.has(resultPackageName) ||
236
- Array.from(dependencyPackages).some((dependencyPackage) => invalidPackageNames.has(dependencyPackage));
237
- if (!shouldInvalidate)
238
- continue;
239
- if (!invalidPackageNames.has(resultPackageName)) {
240
- invalidPackageNames.add(resultPackageName);
241
- changed = true;
242
- }
243
- }
244
- }
245
- for (const key of this.loadResults.keys()) {
246
- if (!invalidPackageNames.has(this.getLoadResultPackageName(key))) {
247
- const dependencyPackages = this.loadResultDependencies.get(key);
248
- if (!dependencyPackages ||
249
- !Array.from(dependencyPackages).some((dependencyPackage) => invalidPackageNames.has(dependencyPackage))) {
236
+ const pendingKeys = [
237
+ ...(this.loadResultsByPackage.get(packageName) ?? []),
238
+ ...(this.loadResultDependents.get(packageName) ?? []),
239
+ ];
240
+ const processedKeys = new Set();
241
+ while (pendingKeys.length) {
242
+ const key = pendingKeys.pop();
243
+ if (!key || processedKeys.has(key))
244
+ continue;
245
+ processedKeys.add(key);
246
+ const dependentPackageName = this.discardLoadResult(key);
247
+ if (!dependentPackageName)
248
+ continue;
249
+ for (const dependentKey of Array.from(this.loadResultDependents.get(dependentPackageName) ?? [])) {
250
+ if (processedKeys.has(dependentKey))
250
251
  continue;
251
- }
252
+ pendingKeys.push(dependentKey);
252
253
  }
253
- this.discardLoadResult(key);
254
254
  }
255
255
  }
256
256
  discardLoadResult(key) {
257
+ const packageName = this.getLoadResultPackageName(key);
258
+ const dependencyPackages = this.loadResultDependencies.get(key);
259
+ const settledResult = this.loadResults.get(key) ?? null;
260
+ if (!settledResult &&
261
+ !dependencyPackages &&
262
+ !this.settledLoadResults.has(key)) {
263
+ return null;
264
+ }
257
265
  this.bumpGraphVersion();
258
266
  this.bumpLoadResultVersion(key);
259
267
  this.loadResults.delete(key);
260
- this.loadResultDependencies.delete(key);
261
268
  this.settledLoadResults.delete(key);
269
+ this.deleteLoadResultKey(this.loadResultsByPackage, packageName, key);
270
+ const previousDependencies = dependencyPackages ?? new Set();
271
+ for (const dependencyPackage of previousDependencies) {
272
+ this.deleteLoadResultKey(this.loadResultDependents, dependencyPackage, key);
273
+ }
274
+ this.loadResultDependencies.delete(key);
275
+ return packageName;
262
276
  }
263
277
  peekLoadResult(parsed) {
264
278
  return this.settledLoadResults.get(this.getLoadResultKey(parsed)) ?? null;
@@ -275,4 +289,33 @@ export class ModuleStyleGraphRequestCache {
275
289
  this.loadResultVersions.set(key, nextVersion);
276
290
  return nextVersion;
277
291
  }
292
+ addLoadResultKey(map, key, value) {
293
+ const values = map.get(key) ?? new Set();
294
+ values.add(value);
295
+ map.set(key, values);
296
+ }
297
+ deleteLoadResultKey(map, key, value) {
298
+ const values = map.get(key);
299
+ if (!values)
300
+ return;
301
+ values.delete(value);
302
+ if (!values.size) {
303
+ map.delete(key);
304
+ }
305
+ }
306
+ replaceLoadResultDependencies(key, dependencyPackages) {
307
+ const nextDependencies = new Set(dependencyPackages);
308
+ const previousDependencies = this.loadResultDependencies.get(key);
309
+ if (previousDependencies) {
310
+ for (const dependencyPackage of previousDependencies) {
311
+ if (nextDependencies.has(dependencyPackage))
312
+ continue;
313
+ this.deleteLoadResultKey(this.loadResultDependents, dependencyPackage, key);
314
+ }
315
+ }
316
+ this.loadResultDependencies.set(key, nextDependencies);
317
+ for (const dependencyPackage of nextDependencies) {
318
+ this.addLoadResultKey(this.loadResultDependents, dependencyPackage, key);
319
+ }
320
+ }
278
321
  }
@@ -1,6 +1,6 @@
1
1
  import { type AukletLogger } from '#auklet/logger';
2
2
  import type { ModuleStyleBuildConfig, ModuleStyleBuildContext } from '#auklet/types';
3
- type ModuleStyleWatcherLogger = Pick<AukletLogger, 'error'>;
3
+ type ModuleStyleWatcherLogger = Pick<AukletLogger, 'error'> & Partial<Pick<AukletLogger, 'info'>>;
4
4
  export declare class ModuleStyleWatcher {
5
5
  private readonly context;
6
6
  private readonly config;
@@ -14,6 +14,7 @@ export declare class ModuleStyleWatcher {
14
14
  constructor(context?: ModuleStyleBuildContext, config?: ModuleStyleBuildConfig, logger?: ModuleStyleWatcherLogger | null);
15
15
  watch(): Promise<void>;
16
16
  private rebuild;
17
+ private logDebug;
17
18
  private refreshWatcher;
18
19
  private logError;
19
20
  private scheduleBuild;
@@ -39,10 +39,12 @@ export class ModuleStyleWatcher {
39
39
  return;
40
40
  }
41
41
  this.isBuilding = true;
42
+ const startedAt = Date.now();
42
43
  try {
43
44
  try {
44
45
  const builder = new ModuleStyleBuilder(this.context, this.config);
45
46
  await builder.build();
47
+ this.logDebug(`CSS build finished in ${Date.now() - startedAt}ms`);
46
48
  }
47
49
  catch (error) {
48
50
  this.logError('build', 'CSS build failed; waiting for changes.', error);
@@ -64,6 +66,11 @@ export class ModuleStyleWatcher {
64
66
  }
65
67
  }
66
68
  }
69
+ logDebug(message) {
70
+ if (this.context.aukletConfig?.debug !== true)
71
+ return;
72
+ this.logger.info?.(message);
73
+ }
67
74
  async refreshWatcher() {
68
75
  if (this.closed)
69
76
  return;
package/dist/types.d.ts CHANGED
@@ -15,6 +15,7 @@ export type NormalizedStyleDependencyGroup = {
15
15
  components?: string | Array<string>;
16
16
  };
17
17
  export interface NormalizedAukletConfig {
18
+ debug: boolean;
18
19
  source: string;
19
20
  output: string;
20
21
  modules: boolean;
@@ -49,6 +50,7 @@ export type PackageBuildOptions = {
49
50
  tsconfig?: string;
50
51
  };
51
52
  export interface AukletConfig {
53
+ debug?: boolean;
52
54
  source?: string;
53
55
  output?: string;
54
56
  modules?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auklet",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "author": "chentao.arthur",
6
6
  "description": "Build utilities for TypeScript packages and module CSS output.",