@gesslar/sassy 0.20.2 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,7 +10,6 @@ import Theme from "./Theme.js"
10
10
  import Util from "./Util.js"
11
11
  import Data from "./Data.js"
12
12
 
13
-
14
13
  // ansiColors.enabled = colorSupport.hasBasic
15
14
 
16
15
  /**
@@ -26,12 +25,12 @@ export default class ResolveCommand extends Command {
26
25
  constructor(base) {
27
26
  super(base)
28
27
 
29
- this.cliCommand = "resolve <file>"
30
- this.cliOptions = {
28
+ this.setCliCommand("resolve <file>")
29
+ this.setCliOptions({
31
30
  "color": ["-c, --color <key>", "resolve a color key to its final evaluated value"],
32
31
  "tokenColor": ["-t, --tokenColor <scope>", "resolve a tokenColors scope to its final evaluated value"],
33
32
  "semanticTokenColor": ["-s, --semanticTokenColor <scope>", "resolve a semanticTokenColors scope to its final evaluated value"],
34
- }
33
+ })
35
34
  }
36
35
 
37
36
  /**
@@ -43,22 +42,23 @@ export default class ResolveCommand extends Command {
43
42
  * @returns {Promise<void>} Resolves when resolution is complete
44
43
  */
45
44
  async execute(inputArg, options={}) {
45
+ const cliOptionNames = this.getCliOptionNames()
46
46
  const intersection =
47
- Data.arrayIntersection(this.cliOptionNames, Object.keys(options))
47
+ Data.arrayIntersection(cliOptionNames, Object.keys(options))
48
48
 
49
49
  if(intersection.length > 1)
50
50
  throw Sass.new(
51
- `The options ${this.cliOptionNames.join(", ")} are ` +
51
+ `The options ${cliOptionNames.join(", ")} are ` +
52
52
  `mutually exclusive and may only have one expressed in the request.`
53
53
  )
54
54
 
55
- const {cwd} = this
55
+ const cwd = this.getCwd()
56
56
  const optionName = Object.keys(options??{})
57
- .find(o => this.cliOptionNames.includes(o))
57
+ .find(o => cliOptionNames.includes(o))
58
58
 
59
59
  if(!optionName) {
60
60
  throw Sass.new(
61
- `No valid option provided. Please specify one of: ${this.cliOptionNames.join(", ")}.`
61
+ `No valid option provided. Please specify one of: ${cliOptionNames.join(", ")}.`
62
62
  )
63
63
  }
64
64
 
@@ -71,7 +71,8 @@ export default class ResolveCommand extends Command {
71
71
 
72
72
  const fileObject = await this.resolveThemeFileName(inputArg, cwd)
73
73
  const theme = new Theme(fileObject, cwd, options)
74
- theme.cache = this.cache
74
+
75
+ theme.setCache(this.getCache())
75
76
 
76
77
  await theme.load()
77
78
  await theme.build()
@@ -88,11 +89,12 @@ export default class ResolveCommand extends Command {
88
89
  * @returns {void}
89
90
  */
90
91
  async resolveColor(theme, colorName) {
91
- const pool = theme.pool
92
+ const pool = theme.getPool()
93
+
92
94
  if(!pool || !pool.has(colorName))
93
95
  return Term.info(`'${colorName}' not found.`)
94
96
 
95
- const tokens = pool.getTokens
97
+ const tokens = pool.getTokens()
96
98
  const token = tokens.get(colorName)
97
99
  const trail = token.getTrail()
98
100
  const fullTrail = this.#buildCompleteTrail(token, trail)
@@ -114,7 +116,7 @@ export default class ResolveCommand extends Command {
114
116
  * @returns {void}
115
117
  */
116
118
  async resolveTokenColor(theme, scopeName) {
117
- const tokenColors = theme.output?.tokenColors || []
119
+ const tokenColors = theme.getOutput()?.tokenColors || []
118
120
 
119
121
  // Check if this is a disambiguated scope (ends with .1, .2, etc.)
120
122
  const disambiguatedMatch = scopeName.match(/^(.+)\.(\d+)$/)
@@ -127,7 +129,9 @@ export default class ResolveCommand extends Command {
127
129
 
128
130
  if(index >= 0 && index < matches.length) {
129
131
  const match = matches[index]
132
+
130
133
  await this.#resolveScopeMatch(theme, match, `${baseScope}.${indexStr}`)
134
+
131
135
  return
132
136
  } else {
133
137
  return Term.info(`'${scopeName}' not found. Available: ${baseScope}.1 through ${baseScope}.${matches.length}`)
@@ -149,6 +153,7 @@ export default class ResolveCommand extends Command {
149
153
  Term.info(`Multiple entries found for '${scopeName}', please try again with the specific query:\n`)
150
154
  matches.forEach((match, index) => {
151
155
  const name = match.name || `Entry ${index + 1}`
156
+
152
157
  Term.info(`${name}: ${scopeName}.${index + 1}`)
153
158
  })
154
159
  }
@@ -161,24 +166,26 @@ export default class ResolveCommand extends Command {
161
166
 
162
167
  // Handle comma-separated scopes
163
168
  const scopes = entry.scope.split(",").map(s => s.trim())
169
+
164
170
  return scopes.includes(targetScope)
165
171
  })
166
172
  }
167
173
 
168
174
  async #resolveScopeMatch(theme, match, displayName) {
169
- const pool = theme.pool
175
+ const pool = theme.getPool()
170
176
  const settings = match.settings || {}
171
177
  const name = match.name || "Unnamed"
172
178
 
173
179
  // Look for the foreground property specifically
174
180
  const foreground = settings.foreground
181
+
175
182
  if(!foreground) {
176
183
  return Term.info(`${displayName} (${name})\n\n(no foreground property)`)
177
184
  }
178
185
 
179
186
  // First, try to find the token by looking for variables that resolve to this value
180
187
  // but prioritize source variable names over computed results
181
- const tokens = pool ? pool.getTokens : new Map()
188
+ const tokens = pool ? pool.getTokens() : new Map()
182
189
  let bestToken = null
183
190
 
184
191
  // First try to find a scope.* token that matches
@@ -205,16 +212,18 @@ export default class ResolveCommand extends Command {
205
212
  }
206
213
  }
207
214
 
208
- if(!bestToken) {
209
- return Term.info(`${displayName} (${name})\n\n(resolved to static value: ${foreground})`)
210
- }
215
+ if(!bestToken)
216
+ return Term.info(
217
+ `${displayName} (${name})\n\n(resolved to static value: ${foreground})`
218
+ )
211
219
 
212
220
  const trail = bestToken.getTrail()
213
221
  const fullTrail = this.#buildCompleteTrail(bestToken, trail)
214
222
  const finalValue = bestToken.getValue()
215
223
  const [formattedFinalValue] = this.#formatLeaf(finalValue)
216
-
217
- const output = c`{head}${displayName}{/} {hex}${(`${name}`)}{/}\n${this.#formatOutput(fullTrail)}\n\n{head}${"Resolution:"}{/} ${formattedFinalValue}`
224
+ const output = c`{head}${displayName}{/} {hex}${(`${name}`)}{/}\n`+
225
+ `${this.#formatOutput(fullTrail)}\n\n{head}`+
226
+ `${"Resolution:"}{/} ${formattedFinalValue}`
218
227
 
219
228
  Term.info(output)
220
229
  }
@@ -230,18 +239,19 @@ export default class ResolveCommand extends Command {
230
239
  async resolveSemanticTokenColor(theme, scopeName) {
231
240
  // semanticTokenColors has the same structure as tokenColors, so we can reuse the logic
232
241
  // but we need to look at the semanticTokenColors array instead
233
- const originalTokenColors = theme.output?.tokenColors
242
+ const originalTokenColors = theme.getOutput()?.tokenColors
234
243
 
235
244
  // Temporarily replace tokenColors with semanticTokenColors for resolution
236
- if(theme.output?.semanticTokenColors) {
237
- theme.output.tokenColors = theme.output.semanticTokenColors
245
+ const themeOutput = theme.getOutput()
246
+ if(themeOutput?.semanticTokenColors) {
247
+ themeOutput.tokenColors = themeOutput.semanticTokenColors
238
248
  }
239
249
 
240
250
  await this.resolveTokenColor(theme, scopeName)
241
251
 
242
252
  // Restore original tokenColors
243
- if(originalTokenColors) {
244
- theme.output.tokenColors = originalTokenColors
253
+ if(originalTokenColors && themeOutput) {
254
+ themeOutput.tokenColors = originalTokenColors
245
255
  }
246
256
  }
247
257
 
@@ -251,6 +261,7 @@ export default class ResolveCommand extends Command {
251
261
 
252
262
  // Add the root token's original expression
253
263
  const rootRaw = rootToken.getRawValue()
264
+
254
265
  if(rootRaw !== rootToken.getName()) {
255
266
  steps.push({
256
267
  value: rootRaw,
@@ -265,6 +276,7 @@ export default class ResolveCommand extends Command {
265
276
  return
266
277
 
267
278
  const id = `${token.getName()}-${token.getRawValue()}`
279
+
268
280
  if(seen.has(id))
269
281
  return
270
282
 
@@ -290,7 +302,8 @@ export default class ResolveCommand extends Command {
290
302
  const depFinal = dependency.getValue()
291
303
 
292
304
  // Add dependency's expression if it's a function call
293
- if(depRaw !== dependency.getName() && !steps.some(s => s.value === depRaw)) {
305
+ if(depRaw !== dependency.getName() &&
306
+ !steps.some(s => s.value === depRaw)) {
294
307
  steps.push({
295
308
  value: depRaw,
296
309
  type: "expression",
@@ -300,6 +313,7 @@ export default class ResolveCommand extends Command {
300
313
 
301
314
  // Process dependency's trail
302
315
  const depTrail = dependency.getTrail()
316
+
303
317
  if(depTrail && depTrail.length > 0) {
304
318
  depTrail.forEach(depToken => processToken(depToken, level + 1))
305
319
  }
@@ -372,10 +386,12 @@ export default class ResolveCommand extends Command {
372
386
  // Hex results are indented one extra level with just spaces and arrow
373
387
  const prefix = " ".repeat(depth + 1)
374
388
  const arrow = c`{arrow}→{/} `
389
+
375
390
  out.push(`${prefix}${arrow}${line}`)
376
391
  } else {
377
392
  // Everything else just gets clean indentation
378
393
  const prefix = " ".repeat(depth)
394
+
379
395
  out.push(`${prefix}${line}`)
380
396
  }
381
397
  })
@@ -411,17 +427,18 @@ export default class ResolveCommand extends Command {
411
427
 
412
428
  if(this.#func.test(value)) {
413
429
  const {func,args} = this.#func.exec(value).groups
430
+
414
431
  return [
415
432
  c`{func}${func}{/}{parens}${"("}{/}{leaf}${args}{/}{parens}${")"}{/}`,
416
433
  "function"
417
434
  ]
418
435
  }
419
436
 
420
-
421
437
  if(this.#sub.test(value)) {
422
438
  const {parens,none,braces} = Evaluator.sub.exec(value)?.groups || {}
423
439
  const style = (braces && ["{","}"]) || (parens && ["(",")"]) || (none && ["",""])
424
440
  const varValue = braces || parens || none || value
441
+
425
442
  return [
426
443
  c`{func}{/}{parens}${style[0]}{/}{leaf}${varValue}{/}{parens}${style[1]}{/}`,
427
444
  "variable"
package/src/Sass.js CHANGED
@@ -24,7 +24,7 @@ export default class Sass extends Error {
24
24
  * Creates a new Sass instance.
25
25
  *
26
26
  * @param {string} message - The error message
27
- * @param {...any} arg - Additional arguments passed to parent Error constructor
27
+ * @param {...unknown} [arg] - Additional arguments passed to parent Error constructor
28
28
  */
29
29
  constructor(message, ...arg) {
30
30
  super(message, ...arg)
@@ -115,6 +115,7 @@ export default class Sass extends Error {
115
115
  .split("\n")
116
116
  .map(line => {
117
117
  const at = line.match(/^\s{4}at\s(?<at>.*)$/)?.groups?.at ?? {}
118
+
118
119
  return at
119
120
  ? `* ${at}`
120
121
  : line
package/src/Session.js CHANGED
@@ -7,19 +7,156 @@ import Term from "./Term.js"
7
7
  import Theme from "./Theme.js"
8
8
  import Util from "./Util.js"
9
9
 
10
+ /**
11
+ * @typedef {object} SessionOptions
12
+ * @property {boolean} [watch] - Whether to enable file watching
13
+ * @property {boolean} [nerd] - Whether to show verbose output
14
+ * @property {boolean} [dryRun] - Whether to skip file writes
15
+ */
16
+
17
+ /**
18
+ * @typedef {object} BuildRecord
19
+ * @property {number} timestamp - Epoch ms when the build started
20
+ * @property {number} loadTime - Time (ms) spent loading theme sources
21
+ * @property {number} buildTime - Time (ms) spent compiling the theme
22
+ * @property {number} writeTime - Time (ms) spent writing the output file
23
+ * @property {boolean} success - Whether the build completed successfully
24
+ * @property {string} [error] - Error message when success is false
25
+ */
26
+
10
27
  export default class Session {
28
+ /**
29
+ * The theme instance managed by this session.
30
+ *
31
+ * @type {Theme|null}
32
+ * @private
33
+ */
11
34
  #theme = null
35
+
36
+ /**
37
+ * The parent command orchestrating this session.
38
+ *
39
+ * @type {Command|null}
40
+ * @private
41
+ */
12
42
  #command = null
43
+
44
+ /**
45
+ * Build configuration options for this session.
46
+ *
47
+ * @type {SessionOptions|null}
48
+ * @private
49
+ */
13
50
  #options = null
51
+
52
+ /**
53
+ * Active file system watcher for theme dependencies.
54
+ *
55
+ * @type {import("chokidar").FSWatcher|null}
56
+ * @private
57
+ */
14
58
  #watcher = null
59
+
60
+ /**
61
+ * Historical records of builds executed during this session.
62
+ *
63
+ * @type {Array<BuildRecord>}
64
+ * @private
65
+ */
15
66
  #history = []
67
+
68
+ /**
69
+ * Cumulative build statistics for this session.
70
+ *
71
+ * @type {{builds: number, failures: number}}
72
+ * @private
73
+ */
16
74
  #stats = Object.seal({builds: 0, failures: 0})
75
+
76
+ /**
77
+ * Flag indicating whether a build is currently in progress.
78
+ *
79
+ * @type {boolean}
80
+ * @private
81
+ */
17
82
  #building = false
18
83
 
19
84
  get theme() {
20
85
  return this.#theme
21
86
  }
22
87
 
88
+ /**
89
+ * Gets the theme instance managed by this session.
90
+ *
91
+ * @returns {Theme} The theme instance
92
+ */
93
+ getTheme() {
94
+ return this.#theme
95
+ }
96
+
97
+ /**
98
+ * Gets the command instance orchestrating this session.
99
+ *
100
+ * @returns {Command} The command instance
101
+ */
102
+ getCommand() {
103
+ return this.#command
104
+ }
105
+
106
+ /**
107
+ * Gets the session options.
108
+ *
109
+ * @returns {SessionOptions} The session options
110
+ */
111
+ getOptions() {
112
+ return this.#options
113
+ }
114
+
115
+ /**
116
+ * Gets the build history for this session.
117
+ *
118
+ * @returns {Array<BuildRecord>} Array of build records
119
+ */
120
+ getHistory() {
121
+ return this.#history
122
+ }
123
+
124
+ /**
125
+ * Gets the build statistics for this session.
126
+ *
127
+ * @returns {{builds: number, failures: number}} Build statistics
128
+ */
129
+ getStats() {
130
+ return this.#stats
131
+ }
132
+
133
+ /**
134
+ * Checks if a build is currently in progress.
135
+ *
136
+ * @returns {boolean} True if building
137
+ */
138
+ isBuilding() {
139
+ return this.#building
140
+ }
141
+
142
+ /**
143
+ * Checks if watch mode is enabled.
144
+ *
145
+ * @returns {boolean} True if watching
146
+ */
147
+ isWatching() {
148
+ return this.#options?.watch === true
149
+ }
150
+
151
+ /**
152
+ * Checks if there's an active file watcher.
153
+ *
154
+ * @returns {boolean} True if watcher exists
155
+ */
156
+ hasWatcher() {
157
+ return this.#watcher !== null
158
+ }
159
+
23
160
  /**
24
161
  * Creates a new Session instance for managing theme compilation lifecycle.
25
162
  * Sessions provide persistent state across rebuilds, error tracking, and
@@ -27,10 +164,7 @@ export default class Session {
27
164
  *
28
165
  * @param {Command} command - The parent build command instance
29
166
  * @param {Theme} theme - The theme instance to manage
30
- * @param {object} options - Build configuration options
31
- * @param {boolean} [options.watch] - Whether to enable file watching
32
- * @param {boolean} [options.nerd] - Whether to show verbose output
33
- * @param {boolean} [options.dryRun] - Whether to skip file writes
167
+ * @param {SessionOptions} options - Build configuration options
34
168
  */
35
169
  constructor(command, theme, options) {
36
170
  this.#command = command
@@ -88,11 +222,12 @@ export default class Session {
88
222
  */
89
223
 
90
224
  loadCost = (await Util.time(() => this.#theme.load())).cost
91
- const bytes = await File.fileSize(this.#theme.sourceFile)
225
+ const bytes = await File.fileSize(this.#theme.getSourceFile())
226
+
92
227
  Term.status([
93
228
  ["success", Util.rightAlignText(`${loadCost.toLocaleString()}ms`, 10), ["[","]"]],
94
- `${this.#theme.name} loaded`,
95
- ["info", `${bytes} bytes`, ["[","]"]]
229
+ `${this.#theme.getName()} loaded`,
230
+ ["info", `${bytes.toLocaleString()} bytes`, ["[","]"]]
96
231
  ], this.#options)
97
232
  /**
98
233
  * ****************************************************************
@@ -101,30 +236,48 @@ export default class Session {
101
236
  */
102
237
 
103
238
  buildCost = (await Util.time(() => this.#theme.build())).cost
104
-
105
- const compileResult =
106
- await Promise.allSettled(this.#theme.dependencies.map(async dep => {
107
-
108
- return await (async fileObject => {
109
- const fileName = File.relativeOrAbsolutePath(this.#command.cwd, fileObject)
110
- const fileSize = await File.fileSize(fileObject)
111
- return [fileName, fileSize]
112
- })(dep)
113
-
239
+ const dependencyFiles = Array
240
+ .from(this.#theme.getDependencies())
241
+ .map(d => d.getSourceFile())
242
+ .filter(f => f != null) // Filter out any null/undefined files
243
+
244
+ const compileResult = await Promise
245
+ .allSettled(dependencyFiles.map(async fileObject => {
246
+ if(!fileObject) {
247
+ throw new Error("Invalid dependency file object")
248
+ }
249
+
250
+ const fileName = File.relativeOrAbsolutePath(
251
+ this.#command.getCwd(), fileObject
252
+ )
253
+ const fileSize = await File.fileSize(fileObject)
254
+
255
+ return [fileName, fileSize]
114
256
  }))
115
257
 
116
258
  const rejected = compileResult.filter(result => result.status === "rejected")
259
+
117
260
  if(rejected.length > 0) {
118
261
  rejected.forEach(reject => Term.error(reject.reason))
119
262
  throw new Error("Compilation failed")
120
263
  }
121
264
 
122
- const dependencies = compileResult.slice(1).map(dep => dep.value)
123
- const totalBytes = compileResult.reduce((acc,curr) => acc + curr.value[1], 0)
265
+ const dependencies = compileResult
266
+ .slice(1)
267
+ .map(dep => dep?.value)
268
+ .filter(Boolean)
269
+
270
+ const totalBytes = compileResult.reduce(
271
+ (acc,curr) => acc + (curr?.value[1] ?? 0), 0
272
+ )
124
273
 
125
274
  Term.status([
126
- ["success", Util.rightAlignText(`${buildCost.toLocaleString()}ms`, 10), ["[","]"]],
127
- `${this.#theme.name} compiled`,
275
+ [
276
+ "success",
277
+ Util.rightAlignText(`${buildCost.toLocaleString()}ms`, 10),
278
+ ["[","]"]
279
+ ],
280
+ `${this.#theme.getName()} compiled`,
128
281
  ["success", `${compileResult[0].value[1].toLocaleString()} bytes`, ["[","]"]],
129
282
  ["info", `${totalBytes.toLocaleString()} total bytes`, ["(",")"]],
130
283
  ], this.#options)
@@ -150,19 +303,25 @@ export default class Session {
150
303
  */
151
304
 
152
305
  const writeResult = await Util.time(() => this.#theme.write(forceWrite))
306
+
153
307
  writeCost = writeResult.cost
154
- const result = writeResult.result
155
308
  const {
156
309
  status: writeStatus,
157
310
  file: outputFile,
158
311
  bytes: writeBytes
159
- } = result
160
- const outputFilename = File.relativeOrAbsolutePath(this.#command.cwd, outputFile)
312
+ } = writeResult.result
313
+ const outputFilename = File.relativeOrAbsolutePath(
314
+ this.#command.getCwd(), outputFile
315
+ )
161
316
  const status = [
162
- ["success", Util.rightAlignText(`${writeCost.toLocaleString()}ms`, 10), ["[","]"]],
317
+ [
318
+ "success",
319
+ Util.rightAlignText(`${writeCost.toLocaleString()}ms`, 10),
320
+ ["[","]"]
321
+ ],
163
322
  ]
164
323
 
165
- if(writeStatus === "written") {
324
+ if(writeStatus.description === "written") {
166
325
  status.push(
167
326
  `${outputFilename} written`,
168
327
  ["success", `${writeBytes.toLocaleString()} bytes`, ["[","]"]]
@@ -170,7 +329,7 @@ export default class Session {
170
329
  } else {
171
330
  status.push(
172
331
  `${outputFilename}`,
173
- ["warn", writeStatus.toLocaleUpperCase(), ["[","]"]]
332
+ ["warn", writeStatus.description.toLocaleUpperCase(), ["[","]"]]
174
333
  )
175
334
  }
176
335
 
@@ -198,8 +357,7 @@ export default class Session {
198
357
  error: error.message
199
358
  })
200
359
 
201
- if(error instanceof Sass)
202
- error.report(this.#options.nerd)
360
+ Sass.new("Build process failed.", error).report(this.#options.nerd)
203
361
  } finally {
204
362
  this.#building = false
205
363
  this.#command.asyncEmit("finishedBuilding")
@@ -221,16 +379,20 @@ export default class Session {
221
379
  this.#building = true
222
380
  this.#command.asyncEmit("building")
223
381
 
224
- const changedFile = this.#theme.dependencies.find(dep => dep.path === changed)
382
+ const changedFile = Array.from(this.#theme.getDependencies()).find(
383
+ dep => dep.getSourceFile().path === changed
384
+ )?.getSourceFile()
225
385
 
226
386
  if(!changedFile)
227
387
  return
228
388
 
229
- const fileName = File.relativeOrAbsolutePath(this.#command.cwd, changedFile)
389
+ const fileName = File.relativeOrAbsolutePath(
390
+ this.#command.getCwd(), changedFile
391
+ )
230
392
 
231
393
  const message = [
232
394
  ["info", "REBUILDING", ["[","]"]],
233
- this.#theme.name,
395
+ this.#theme.getName(),
234
396
  ]
235
397
 
236
398
  if(this.#options.nerd)
@@ -262,7 +424,7 @@ export default class Session {
262
424
 
263
425
  Term.status([
264
426
  [builds > 0 ? "success" : "error", "SESSION SUMMARY"],
265
- [builds > 0 ? "info" : "error", this.#theme.name, ["[", "]"]]
427
+ [builds > 0 ? "info" : "error", this.#theme.getName(), ["[", "]"]]
266
428
  ], this.#options)
267
429
 
268
430
  Term.status([
@@ -277,7 +439,8 @@ export default class Session {
277
439
 
278
440
  if(this.#history.length > 0) {
279
441
  const lastBuild = this.#history[this.#history.length - 1]
280
- const totalTime = lastBuild.loadTime + lastBuild.buildTime + lastBuild.writeTime
442
+ const totalTime = lastBuild.loadTime +
443
+ lastBuild.buildTime + lastBuild.writeTime
281
444
 
282
445
  Term.status([
283
446
  [builds > 0 ? "info" : "muted", "Last Build", ["[", "]"]],
@@ -318,10 +481,11 @@ export default class Session {
318
481
  if(this.#watcher)
319
482
  await this.#watcher.close()
320
483
 
321
- const dependencies = this.#theme.dependencies.map(d => d.path)
484
+ const dependencies = Array.from(this.#theme.getDependencies()).map(d => d.getSourceFile().path)
485
+
322
486
  this.#watcher = chokidar.watch(dependencies, {
323
487
  // Prevent watching own output files
324
- ignored: [this.#theme.outputFileName],
488
+ ignored: [this.#theme.getOutputFileName()],
325
489
  // Add some stability options
326
490
  awaitWriteFinish: {
327
491
  stabilityThreshold: 100,
package/src/Term.js CHANGED
@@ -9,7 +9,7 @@ export default class Term {
9
9
  /**
10
10
  * Log an informational message.
11
11
  *
12
- * @param {...any} arg - Values to log.
12
+ * @param {...unknown} [arg] - Values to log.
13
13
  */
14
14
  static log(...arg) {
15
15
  console.log(...arg)
@@ -18,7 +18,7 @@ export default class Term {
18
18
  /**
19
19
  * Log an informational message.
20
20
  *
21
- * @param {...any} arg - Values to log.
21
+ * @param {...unknown} [arg] - Values to log.
22
22
  */
23
23
  static info(...arg) {
24
24
  console.info(...arg)
@@ -27,16 +27,16 @@ export default class Term {
27
27
  /**
28
28
  * Log a warning message.
29
29
  *
30
- * @param {any} msg - Warning text / object.
30
+ * @param {...unknown} [arg] - Warning text / object.
31
31
  */
32
- static warn(...msg) {
33
- console.warn(...msg)
32
+ static warn(...arg) {
33
+ console.warn(...arg)
34
34
  }
35
35
 
36
36
  /**
37
37
  * Log an error message (plus optional details).
38
38
  *
39
- * @param {...any} arg - Values to log.
39
+ * @param {...unknown} [arg] - Values to log.
40
40
  */
41
41
  static error(...arg) {
42
42
  console.error(...arg)
@@ -45,7 +45,7 @@ export default class Term {
45
45
  /**
46
46
  * Log a debug message (no-op unless console.debug provided/visible by env).
47
47
  *
48
- * @param {...any} arg - Values to log.
48
+ * @param {...unknown} [arg] - Values to log.
49
49
  */
50
50
  static debug(...arg) {
51
51
  console.debug(...arg)