@nielspeter/eess 0.4.0 → 0.5.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.
- package/README.md +94 -1
- package/dist/baseline-generator.d.ts +9 -0
- package/dist/baseline-generator.d.ts.map +1 -1
- package/dist/baseline-generator.js +9 -0
- package/dist/baseline-generator.js.map +1 -1
- package/dist/baseline.d.ts +1 -1
- package/dist/cardinality.d.ts.map +1 -1
- package/dist/cardinality.js +20 -5
- package/dist/cardinality.js.map +1 -1
- package/dist/cli-config.d.ts +59 -0
- package/dist/cli-config.d.ts.map +1 -0
- package/dist/cli-config.js +84 -0
- package/dist/cli-config.js.map +1 -0
- package/dist/collect-result.d.ts +94 -0
- package/dist/collect-result.d.ts.map +1 -0
- package/dist/collect-result.js +142 -0
- package/dist/collect-result.js.map +1 -0
- package/dist/combinators.d.ts +14 -0
- package/dist/combinators.d.ts.map +1 -1
- package/dist/combinators.js +53 -16
- package/dist/combinators.js.map +1 -1
- package/dist/condition.d.ts +37 -0
- package/dist/condition.d.ts.map +1 -1
- package/dist/condition.js +48 -1
- package/dist/condition.js.map +1 -1
- package/dist/correspondence.d.ts +30 -0
- package/dist/correspondence.d.ts.map +1 -1
- package/dist/correspondence.js +36 -1
- package/dist/correspondence.js.map +1 -1
- package/dist/dedupe-config-findings.d.ts.map +1 -1
- package/dist/dedupe-config-findings.js +27 -0
- package/dist/dedupe-config-findings.js.map +1 -1
- package/dist/diff-aware.d.ts +8 -9
- package/dist/diff-aware.d.ts.map +1 -1
- package/dist/diff-aware.js +38 -17
- package/dist/diff-aware.js.map +1 -1
- package/dist/emitter-findings.d.ts +167 -0
- package/dist/emitter-findings.d.ts.map +1 -0
- package/dist/emitter-findings.js +237 -0
- package/dist/emitter-findings.js.map +1 -0
- package/dist/errors.d.ts +48 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +61 -0
- package/dist/errors.js.map +1 -1
- package/dist/exclusion-comments.d.ts +36 -1
- package/dist/exclusion-comments.d.ts.map +1 -1
- package/dist/exclusion-comments.js +185 -37
- package/dist/exclusion-comments.js.map +1 -1
- package/dist/execute-rule.d.ts +12 -3
- package/dist/execute-rule.d.ts.map +1 -1
- package/dist/execute-rule.js +184 -7
- package/dist/execute-rule.js.map +1 -1
- package/dist/file-walk.d.ts +22 -0
- package/dist/file-walk.d.ts.map +1 -0
- package/dist/file-walk.js +51 -0
- package/dist/file-walk.js.map +1 -0
- package/dist/format-json.d.ts +13 -0
- package/dist/format-json.d.ts.map +1 -1
- package/dist/format-json.js +24 -0
- package/dist/format-json.js.map +1 -1
- package/dist/index.d.ts +14 -46
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -41
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +55 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +92 -0
- package/dist/internal.js.map +1 -0
- package/dist/mask-non-comment.d.ts +49 -0
- package/dist/mask-non-comment.d.ts.map +1 -0
- package/dist/mask-non-comment.js +261 -0
- package/dist/mask-non-comment.js.map +1 -0
- package/dist/owns-empty-discovery.d.ts.map +1 -1
- package/dist/owns-empty-discovery.js +12 -4
- package/dist/owns-empty-discovery.js.map +1 -1
- package/dist/path-suffix.d.ts +57 -0
- package/dist/path-suffix.d.ts.map +1 -0
- package/dist/path-suffix.js +73 -0
- package/dist/path-suffix.js.map +1 -0
- package/dist/predicate.d.ts +12 -0
- package/dist/predicate.d.ts.map +1 -1
- package/dist/predicate.js +20 -1
- package/dist/predicate.js.map +1 -1
- package/dist/preset-dispatch.d.ts +6 -34
- package/dist/preset-dispatch.d.ts.map +1 -1
- package/dist/preset-dispatch.js +30 -52
- package/dist/preset-dispatch.js.map +1 -1
- package/dist/report.d.ts +31 -7
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +174 -15
- package/dist/report.js.map +1 -1
- package/dist/rule-builder-like.d.ts +8 -2
- package/dist/rule-builder-like.d.ts.map +1 -1
- package/dist/rule-builder.d.ts +15 -0
- package/dist/rule-builder.d.ts.map +1 -1
- package/dist/rule-builder.js +41 -36
- package/dist/rule-builder.js.map +1 -1
- package/dist/rule-description.d.ts +50 -0
- package/dist/rule-description.d.ts.map +1 -1
- package/dist/rule-description.js +58 -0
- package/dist/rule-description.js.map +1 -1
- package/dist/selection-memo.d.ts +1 -3
- package/dist/selection-memo.d.ts.map +1 -1
- package/dist/selection-memo.js +1 -3
- package/dist/selection-memo.js.map +1 -1
- package/dist/silent-exclusion.d.ts +12 -0
- package/dist/silent-exclusion.d.ts.map +1 -1
- package/dist/silent-exclusion.js +22 -0
- package/dist/silent-exclusion.js.map +1 -1
- package/dist/terminal-builder.d.ts +29 -15
- package/dist/terminal-builder.d.ts.map +1 -1
- package/dist/terminal-builder.js +97 -51
- package/dist/terminal-builder.js.map +1 -1
- package/dist/vacuity-findings.d.ts +0 -6
- package/dist/vacuity-findings.d.ts.map +1 -1
- package/dist/vacuity-findings.js +27 -57
- package/dist/vacuity-findings.js.map +1 -1
- package/dist/violation.d.ts +22 -1
- package/dist/violation.d.ts.map +1 -1
- package/dist/violation.js.map +1 -1
- package/dist/watch.d.ts +71 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +129 -0
- package/dist/watch.js.map +1 -0
- package/package.json +6 -1
package/dist/terminal-builder.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { zeroExaminedViolation, deadGlobViolation, unmetExpectNonEmptyViolation, zeroLoadedSourceViolation, expiredExpectEmptyViolation, } from './vacuity-findings.js';
|
|
2
2
|
import { UNSUPPRESSABLE } from './unsuppressable.js';
|
|
3
|
-
import {
|
|
3
|
+
import { collectResult } from './collect-result.js';
|
|
4
|
+
import { ruleDescriptionFrom } from './rule-description.js';
|
|
5
|
+
import { recordExclusions } from './silent-exclusion.js';
|
|
4
6
|
import { executeCheck, executeWarn, applyFilters } from './execute-rule.js';
|
|
5
7
|
import { shallowClone } from './shallow-clone.js';
|
|
6
8
|
/**
|
|
@@ -87,15 +89,7 @@ export class TerminalBuilder {
|
|
|
87
89
|
*/
|
|
88
90
|
excluding(...patterns) {
|
|
89
91
|
const next = this.copy();
|
|
90
|
-
|
|
91
|
-
if (isSilent(p)) {
|
|
92
|
-
next._exclusions.push(p.pattern);
|
|
93
|
-
next._silentIndices.add(next._exclusions.length - 1);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
next._exclusions.push(p);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
92
|
+
recordExclusions(patterns, next._exclusions, next._silentIndices);
|
|
99
93
|
return next;
|
|
100
94
|
}
|
|
101
95
|
/**
|
|
@@ -103,14 +97,11 @@ export class TerminalBuilder {
|
|
|
103
97
|
* Used by the `explain` CLI subcommand.
|
|
104
98
|
*/
|
|
105
99
|
describeRule() {
|
|
106
|
-
return {
|
|
100
|
+
return ruleDescriptionFrom({
|
|
101
|
+
metadata: this._metadata,
|
|
102
|
+
reason: this._reason,
|
|
107
103
|
rule: this._metadata?.id ?? 'unnamed',
|
|
108
|
-
|
|
109
|
-
because: this._reason,
|
|
110
|
-
suggestion: this._metadata?.suggestion,
|
|
111
|
-
docs: this._metadata?.docs,
|
|
112
|
-
imperative: this._metadata?.imperative,
|
|
113
|
-
};
|
|
104
|
+
});
|
|
114
105
|
}
|
|
115
106
|
/** This rule's own account of itself, for `vacuity-findings.ts`. */
|
|
116
107
|
facts() {
|
|
@@ -121,15 +112,45 @@ export class TerminalBuilder {
|
|
|
121
112
|
};
|
|
122
113
|
}
|
|
123
114
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
115
|
+
* What every terminal method hands the filter pipeline.
|
|
116
|
+
*
|
|
117
|
+
* The same four fields were written out at each of `violations`, `check` and
|
|
118
|
+
* `warn` — `no-copy-paste` reported the three at 100% with `applyFilters ->
|
|
119
|
+
* executeCheck` as the only varying axis. `eess-ts`'s `TerminalBuilder`
|
|
120
|
+
* already had exactly this method; the kernel never adopted it.
|
|
121
|
+
*
|
|
122
|
+
* Not just tidier: three terminal methods that build the filter context
|
|
123
|
+
* separately can drift, and a field present on `.check()` but missing on
|
|
124
|
+
* `.violations()` means a rule fails in CI and passes when a preset
|
|
125
|
+
* aggregates it — the same finding, two answers.
|
|
126
126
|
*/
|
|
127
|
-
|
|
128
|
-
return
|
|
127
|
+
filterContext() {
|
|
128
|
+
return {
|
|
129
129
|
reason: this._reason,
|
|
130
130
|
metadata: this._metadata,
|
|
131
131
|
exclusions: this._exclusions,
|
|
132
132
|
silentIndices: this._silentIndices,
|
|
133
|
+
// Bug 0258 round 2: an id-less rule still has a sentence, and every
|
|
134
|
+
// builder already implements `describeRule()`. Deferred, because this
|
|
135
|
+
// runs on every terminal call and is read only when an id-less rule meets
|
|
136
|
+
// an exclusion comment it cannot honour.
|
|
137
|
+
describe: () => this.describeRule().rule,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Execute the rule and return violations after exclusion filtering.
|
|
142
|
+
* Does not throw — use for programmatic access (presets, aggregation).
|
|
143
|
+
*/
|
|
144
|
+
violations() {
|
|
145
|
+
const evidenced = this.evidencedViolations();
|
|
146
|
+
// `applyFilters` returns a bare array (and the SAME reference when no
|
|
147
|
+
// exclusion applies), so the evidence is re-stamped onto a fresh one here —
|
|
148
|
+
// stamping onto its return would mutate whatever a family memoized.
|
|
149
|
+
return collectResult(applyFilters(evidenced, this.filterContext()), {
|
|
150
|
+
examined: evidenced.examined,
|
|
151
|
+
sourceEmpty: evidenced.sourceEmpty,
|
|
152
|
+
declaredEmpty: evidenced.declaredEmpty,
|
|
153
|
+
deadGlob: evidenced.deadGlob,
|
|
133
154
|
});
|
|
134
155
|
}
|
|
135
156
|
/**
|
|
@@ -139,12 +160,7 @@ export class TerminalBuilder {
|
|
|
139
160
|
* @param options - Optional baseline, diff filtering, and output format
|
|
140
161
|
*/
|
|
141
162
|
check(options) {
|
|
142
|
-
executeCheck(this.evidencedViolations(),
|
|
143
|
-
reason: this._reason,
|
|
144
|
-
metadata: this._metadata,
|
|
145
|
-
exclusions: this._exclusions,
|
|
146
|
-
silentIndices: this._silentIndices,
|
|
147
|
-
}, options);
|
|
163
|
+
executeCheck(this.evidencedViolations(), this.filterContext(), options);
|
|
148
164
|
}
|
|
149
165
|
/**
|
|
150
166
|
* Execute the rule and log violations to stderr. Does not throw.
|
|
@@ -153,12 +169,7 @@ export class TerminalBuilder {
|
|
|
153
169
|
* @param options - Optional baseline, diff filtering, and output format
|
|
154
170
|
*/
|
|
155
171
|
warn(options) {
|
|
156
|
-
executeWarn(this.evidencedViolations(),
|
|
157
|
-
reason: this._reason,
|
|
158
|
-
metadata: this._metadata,
|
|
159
|
-
exclusions: this._exclusions,
|
|
160
|
-
silentIndices: this._silentIndices,
|
|
161
|
-
}, options);
|
|
172
|
+
executeWarn(this.evidencedViolations(), this.filterContext(), options);
|
|
162
173
|
}
|
|
163
174
|
/**
|
|
164
175
|
* ADR-010 — the evidence gate. Calls `collectViolations()` once and turns
|
|
@@ -201,28 +212,63 @@ export class TerminalBuilder {
|
|
|
201
212
|
* exist): the rule's own violations stand as computed.
|
|
202
213
|
*/
|
|
203
214
|
evidencedViolations() {
|
|
204
|
-
const
|
|
215
|
+
const collected = this.collectViolations();
|
|
216
|
+
const { examined, sourceEmpty, deadGlob } = collected;
|
|
217
|
+
const violations = [...collected];
|
|
218
|
+
// The evidence travels with every return below. A declaration reaches the
|
|
219
|
+
// emitter ON the receipt (ADR-014 §3) rather than through delivery options:
|
|
220
|
+
// one boolean over a sum cannot carry per-rule declarations, and this is the
|
|
221
|
+
// moment the terminal knows the fact and used to discard it.
|
|
222
|
+
const evidence = {
|
|
223
|
+
examined,
|
|
224
|
+
sourceEmpty,
|
|
225
|
+
deadGlob,
|
|
226
|
+
// `assertsCardinality()` is a declaration ONLY over zero subjects — ADR-010
|
|
227
|
+
// §3: "`.notExist()` over zero subjects is a declaration by construction."
|
|
228
|
+
// Over a non-empty selection it is an ordinary assertion that examined
|
|
229
|
+
// real units, and marking it declared there made every passing
|
|
230
|
+
// `.notExist()` expire the moment the emitter checked. Measured: it
|
|
231
|
+
// reddened six crossvalidate tests.
|
|
232
|
+
declaredEmpty: this._expectEmpty === true || (examined === 0 && this.assertsCardinality())
|
|
233
|
+
? true
|
|
234
|
+
: undefined,
|
|
235
|
+
};
|
|
236
|
+
const withFinding = (f) => collectResult([...violations, f], evidence);
|
|
237
|
+
// Split out because threading the evidence through every branch pushed this
|
|
238
|
+
// method to cyclomatic complexity 11 and the repo's own `check:arch` said so.
|
|
239
|
+
// The ORDER is the content here, and it is unchanged.
|
|
205
240
|
if (examined === 0) {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (this._expectEmpty === true)
|
|
209
|
-
return violations;
|
|
210
|
-
if (this._expectEmpty === false)
|
|
211
|
-
return [...violations, unmetExpectNonEmptyViolation(this.facts())];
|
|
212
|
-
if (this.assertsCardinality())
|
|
213
|
-
return violations;
|
|
214
|
-
// A specific dead-glob explanation, when the dialect could compute
|
|
215
|
-
// one, outranks the generic zero-examined message — both name the
|
|
216
|
-
// same underlying fact, and the specific one is strictly more
|
|
217
|
-
// actionable (it names the actual glob and why it can never match).
|
|
218
|
-
if (deadGlob !== undefined)
|
|
219
|
-
return [...violations, deadGlobViolation(this.facts(), deadGlob)];
|
|
220
|
-
return [...violations, zeroExaminedViolation(this.facts())];
|
|
241
|
+
const zero = this.zeroExaminedFinding(sourceEmpty, deadGlob);
|
|
242
|
+
return zero === undefined ? collectResult(violations, evidence) : withFinding(zero);
|
|
221
243
|
}
|
|
222
244
|
if (this._expectEmpty === true) {
|
|
223
|
-
return
|
|
245
|
+
return withFinding(expiredExpectEmptyViolation(this.facts(), examined));
|
|
224
246
|
}
|
|
225
|
-
return violations;
|
|
247
|
+
return collectResult(violations, evidence);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Which finding a zero-examined rule earns, or `undefined` when it earned none
|
|
251
|
+
* because it declared the emptiness.
|
|
252
|
+
*
|
|
253
|
+
* Extracted from `evidencedViolations` under `check:arch`'s complexity rule.
|
|
254
|
+
* The precedence is the whole content and is unchanged: an empty source
|
|
255
|
+
* outranks every declaration (ADR-010 §3), an explicit declaration is
|
|
256
|
+
* satisfied, `.expectNonEmpty()` is unmet, a cardinality condition is
|
|
257
|
+
* satisfied by emptiness, and a nameable dead glob outranks the generic
|
|
258
|
+
* message because it is strictly more actionable.
|
|
259
|
+
*/
|
|
260
|
+
zeroExaminedFinding(sourceEmpty, deadGlob) {
|
|
261
|
+
if (sourceEmpty === true)
|
|
262
|
+
return zeroLoadedSourceViolation(this.facts());
|
|
263
|
+
if (this._expectEmpty === true)
|
|
264
|
+
return undefined;
|
|
265
|
+
if (this._expectEmpty === false)
|
|
266
|
+
return unmetExpectNonEmptyViolation(this.facts());
|
|
267
|
+
if (this.assertsCardinality())
|
|
268
|
+
return undefined;
|
|
269
|
+
if (deadGlob !== undefined)
|
|
270
|
+
return deadGlobViolation(this.facts(), deadGlob);
|
|
271
|
+
return zeroExaminedViolation(this.facts());
|
|
226
272
|
}
|
|
227
273
|
/**
|
|
228
274
|
* Execute the rule with the given severity.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-builder.js","sourceRoot":"","sources":["../src/terminal-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"terminal-builder.js","sourceRoot":"","sources":["../src/terminal-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,12 +15,6 @@ export interface RuleFacts {
|
|
|
15
15
|
readonly reason: string | undefined;
|
|
16
16
|
describeRule(): RuleDescription;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* The configuration finding for a rule that examined zero units with no
|
|
20
|
-
* declared exemption — ADR-009 rule 2: named as a distinct cause (dead
|
|
21
|
-
* selector, empty corpus, or an unreachable examining seam), not folded
|
|
22
|
-
* into an ordinary violation message.
|
|
23
|
-
*/
|
|
24
18
|
export declare function zeroExaminedViolation(facts: RuleFacts): ArchViolation;
|
|
25
19
|
/**
|
|
26
20
|
* The configuration finding for a rule that examined zero units BECAUSE one
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vacuity-findings.d.ts","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,YAAY,IAAI,eAAe,CAAA;CAChC;
|
|
1
|
+
{"version":3,"file":"vacuity-findings.d.ts","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,YAAY,IAAI,eAAe,CAAA;CAChC;AAuCD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAOrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAGnF;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAO5E;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa,CAOzE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,CAM7F"}
|
package/dist/vacuity-findings.js
CHANGED
|
@@ -4,13 +4,24 @@
|
|
|
4
4
|
* selector, empty corpus, or an unreachable examining seam), not folded
|
|
5
5
|
* into an ordinary violation message.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The shape every configuration finding in this module shares.
|
|
9
|
+
*
|
|
10
|
+
* All five differ ONLY in their `message`, which `no-copy-paste` reported as one
|
|
11
|
+
* cluster at 100%. Extracting it puts the contract they have in common in one
|
|
12
|
+
* place, and that contract is load-bearing rather than incidental:
|
|
13
|
+
*
|
|
14
|
+
* - `bypassFilters: true` — a vacuity finding must survive `--changed`, a
|
|
15
|
+
* baseline and an `eess-exclude`. A suppression mechanism that can suppress
|
|
16
|
+
* the complaint about itself is not a mechanism.
|
|
17
|
+
* - `file: ''`, `line: 0` — there is no source position, because the fault is
|
|
18
|
+
* the RULE, not a place in the code. That is also why the diff filter has to
|
|
19
|
+
* exempt these explicitly (see `diff-aware.ts`).
|
|
20
|
+
* - `suggestion` is the message — its own remedy, never the author's (bug 0021).
|
|
21
|
+
*/
|
|
22
|
+
function configFinding(facts, message) {
|
|
8
23
|
const described = facts.describeRule();
|
|
9
24
|
const name = described.id ?? described.rule ?? facts.ruleClass.name;
|
|
10
|
-
const message = `this rule examined zero units. If this is expected (the corpus is legitimately ` +
|
|
11
|
-
`empty right now), declare it explicitly with .expectEmpty() — otherwise this is a ` +
|
|
12
|
-
`dead selector, an empty project, or a rule that never reaches its own examining ` +
|
|
13
|
-
`seam, and the fix is to widen the selection, not to suppress this finding.`;
|
|
14
25
|
return {
|
|
15
26
|
rule: described.rule ?? name,
|
|
16
27
|
ruleId: described.id,
|
|
@@ -23,6 +34,13 @@ export function zeroExaminedViolation(facts) {
|
|
|
23
34
|
bypassFilters: true,
|
|
24
35
|
};
|
|
25
36
|
}
|
|
37
|
+
export function zeroExaminedViolation(facts) {
|
|
38
|
+
const message = `this rule examined zero units. If this is expected (the corpus is legitimately ` +
|
|
39
|
+
`empty right now), declare it explicitly with .expectEmpty() — otherwise this is a ` +
|
|
40
|
+
`dead selector, an empty project, or a rule that never reaches its own examining ` +
|
|
41
|
+
`seam, and the fix is to widen the selection, not to suppress this finding.`;
|
|
42
|
+
return configFinding(facts, message);
|
|
43
|
+
}
|
|
26
44
|
/**
|
|
27
45
|
* The configuration finding for a rule that examined zero units BECAUSE one
|
|
28
46
|
* of its declared globs is diagnosably dead — `deadGlob` is the pre-formed
|
|
@@ -33,20 +51,8 @@ export function zeroExaminedViolation(facts) {
|
|
|
33
51
|
* diagnosis is available; see `evidencedViolations()`.
|
|
34
52
|
*/
|
|
35
53
|
export function deadGlobViolation(facts, deadGlob) {
|
|
36
|
-
const described = facts.describeRule();
|
|
37
|
-
const name = described.id ?? described.rule ?? facts.ruleClass.name;
|
|
38
54
|
const message = `this rule examined zero units — ${deadGlob}`;
|
|
39
|
-
return
|
|
40
|
-
rule: described.rule ?? name,
|
|
41
|
-
ruleId: described.id,
|
|
42
|
-
element: name,
|
|
43
|
-
file: '',
|
|
44
|
-
line: 0,
|
|
45
|
-
message,
|
|
46
|
-
suggestion: message,
|
|
47
|
-
because: facts.reason,
|
|
48
|
-
bypassFilters: true,
|
|
49
|
-
};
|
|
55
|
+
return configFinding(facts, message);
|
|
50
56
|
}
|
|
51
57
|
/**
|
|
52
58
|
* The configuration finding for a `.expectNonEmpty()` declaration that
|
|
@@ -56,23 +62,11 @@ export function deadGlobViolation(facts, deadGlob) {
|
|
|
56
62
|
* condition itself would otherwise tolerate.
|
|
57
63
|
*/
|
|
58
64
|
export function unmetExpectNonEmptyViolation(facts) {
|
|
59
|
-
const described = facts.describeRule();
|
|
60
|
-
const name = described.id ?? described.rule ?? facts.ruleClass.name;
|
|
61
65
|
const message = `this rule declared .expectNonEmpty() but examined zero units — the corpus this ` +
|
|
62
66
|
`rule asserted should never be empty is empty right now. If that's still true, fix ` +
|
|
63
67
|
`the selection (a glob typo, a missing folder); if the corpus legitimately can be ` +
|
|
64
68
|
`empty, remove .expectNonEmpty().`;
|
|
65
|
-
return
|
|
66
|
-
rule: described.rule ?? name,
|
|
67
|
-
ruleId: described.id,
|
|
68
|
-
element: name,
|
|
69
|
-
file: '',
|
|
70
|
-
line: 0,
|
|
71
|
-
message,
|
|
72
|
-
suggestion: message,
|
|
73
|
-
because: facts.reason,
|
|
74
|
-
bypassFilters: true,
|
|
75
|
-
};
|
|
69
|
+
return configFinding(facts, message);
|
|
76
70
|
}
|
|
77
71
|
/**
|
|
78
72
|
* The configuration finding for the ADR-010 part 3 precedence case: the
|
|
@@ -81,44 +75,20 @@ export function unmetExpectNonEmptyViolation(facts) {
|
|
|
81
75
|
* "widen the selection", there is no selection yet to widen).
|
|
82
76
|
*/
|
|
83
77
|
export function zeroLoadedSourceViolation(facts) {
|
|
84
|
-
const described = facts.describeRule();
|
|
85
|
-
const name = described.id ?? described.rule ?? facts.ruleClass.name;
|
|
86
78
|
const message = `this rule's source loaded zero units before any selection ran — an empty project, ` +
|
|
87
79
|
`an unreadable tsconfig, or a glob resolving to nothing. This outranks any ` +
|
|
88
80
|
`.expectEmpty() declaration and any condition satisfied by emptiness: fix the ` +
|
|
89
81
|
`project/source configuration, not the rule.`;
|
|
90
|
-
return
|
|
91
|
-
rule: described.rule ?? name,
|
|
92
|
-
ruleId: described.id,
|
|
93
|
-
element: name,
|
|
94
|
-
file: '',
|
|
95
|
-
line: 0,
|
|
96
|
-
message,
|
|
97
|
-
suggestion: message,
|
|
98
|
-
because: facts.reason,
|
|
99
|
-
bypassFilters: true,
|
|
100
|
-
};
|
|
82
|
+
return configFinding(facts, message);
|
|
101
83
|
}
|
|
102
84
|
/**
|
|
103
85
|
* The configuration finding for a `.expectEmpty()` declaration that has
|
|
104
86
|
* expired — ADR-010 part 3: the number IS the finding, so it is named.
|
|
105
87
|
*/
|
|
106
88
|
export function expiredExpectEmptyViolation(facts, examined) {
|
|
107
|
-
const described = facts.describeRule();
|
|
108
|
-
const name = described.id ?? described.rule ?? facts.ruleClass.name;
|
|
109
89
|
const message = `this rule declared .expectEmpty() but examined ${String(examined)} unit(s) — the ` +
|
|
110
90
|
`declaration has expired. If the corpus legitimately grew past empty, remove ` +
|
|
111
91
|
`.expectEmpty() from this rule; the underlying violations (if any) above still stand.`;
|
|
112
|
-
return
|
|
113
|
-
rule: described.rule ?? name,
|
|
114
|
-
ruleId: described.id,
|
|
115
|
-
element: name,
|
|
116
|
-
file: '',
|
|
117
|
-
line: 0,
|
|
118
|
-
message,
|
|
119
|
-
suggestion: message,
|
|
120
|
-
because: facts.reason,
|
|
121
|
-
bypassFilters: true,
|
|
122
|
-
};
|
|
92
|
+
return configFinding(facts, message);
|
|
123
93
|
}
|
|
124
94
|
//# sourceMappingURL=vacuity-findings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vacuity-findings.js","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH,
|
|
1
|
+
{"version":3,"file":"vacuity-findings.js","sourceRoot":"","sources":["../src/vacuity-findings.ts"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH;;;;;;;;;;;;;;GAcG;AACH,SAAS,aAAa,CAAC,KAAgB,EAAE,OAAe;IACtD,MAAM,SAAS,GAAG,KAAK,CAAC,YAAY,EAAE,CAAA;IACtC,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,IAAI,SAAS,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAA;IACnE,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,IAAI;QAC5B,MAAM,EAAE,SAAS,CAAC,EAAE;QACpB,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,CAAC;QACP,OAAO;QACP,UAAU,EAAE,OAAO;QACnB,OAAO,EAAE,KAAK,CAAC,MAAM;QACrB,aAAa,EAAE,IAAI;KACpB,CAAA;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAgB;IACpD,MAAM,OAAO,GACX,iFAAiF;QACjF,oFAAoF;QACpF,kFAAkF;QAClF,4EAA4E,CAAA;IAC9E,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAgB,EAAE,QAAgB;IAClE,MAAM,OAAO,GAAG,mCAAmC,QAAQ,EAAE,CAAA;IAC7D,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,KAAgB;IAC3D,MAAM,OAAO,GACX,iFAAiF;QACjF,oFAAoF;QACpF,mFAAmF;QACnF,kCAAkC,CAAA;IACpC,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAgB;IACxD,MAAM,OAAO,GACX,oFAAoF;QACpF,4EAA4E;QAC5E,+EAA+E;QAC/E,6CAA6C,CAAA;IAC/C,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAgB,EAAE,QAAgB;IAC5E,MAAM,OAAO,GACX,kDAAkD,MAAM,CAAC,QAAQ,CAAC,iBAAiB;QACnF,8EAA8E;QAC9E,sFAAsF,CAAA;IACxF,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AACtC,CAAC"}
|
package/dist/violation.d.ts
CHANGED
|
@@ -32,6 +32,27 @@ export interface ArchViolation {
|
|
|
32
32
|
file: string;
|
|
33
33
|
/** Line number where the violating element starts */
|
|
34
34
|
line: number;
|
|
35
|
+
/**
|
|
36
|
+
* Other files this one finding concerns, when it concerns more than one.
|
|
37
|
+
*
|
|
38
|
+
* A finding carries a single `file`, which is where it is REPORTED. Some
|
|
39
|
+
* findings are about a relationship — two bodies that duplicate each other,
|
|
40
|
+
* a cluster of them — and for those, one path cannot say what the finding is
|
|
41
|
+
* about. Anything that filters by file must see the rest, or it hides the
|
|
42
|
+
* finding from the very person who caused it.
|
|
43
|
+
*
|
|
44
|
+
* Bug 0239 is the measured case: a duplicate-body finding anchors on whichever
|
|
45
|
+
* member the source walk reached first, so a developer who pasted a body into
|
|
46
|
+
* a second file ran `--changed` and was told nothing — the finding sat on the
|
|
47
|
+
* file they had not touched, and which file that was came down to how the OS
|
|
48
|
+
* enumerated a directory.
|
|
49
|
+
*
|
|
50
|
+
* Optional, and additive. A single-file finding omits it and every existing
|
|
51
|
+
* producer keeps compiling; a consumer that ignores it behaves exactly as
|
|
52
|
+
* before. `file` remains where the finding is reported, so messages, editors
|
|
53
|
+
* and baselines are unaffected.
|
|
54
|
+
*/
|
|
55
|
+
relatedFiles?: readonly string[];
|
|
35
56
|
/** Human-readable description of what went wrong */
|
|
36
57
|
message: string;
|
|
37
58
|
/**
|
|
@@ -73,7 +94,7 @@ export interface ArchViolation {
|
|
|
73
94
|
*
|
|
74
95
|
* The baseline persists it and refuses to compare a stored measurement
|
|
75
96
|
* against a current one carrying a different unit
|
|
76
|
-
* ([bug 0171](../../../work/bugs/0171-a-metric-unit-change-silently-loosens-every-baselined-ratchet.md)).
|
|
97
|
+
* ([bug 0171](../../../work/bugs/fixed/0171-a-metric-unit-change-silently-loosens-every-baselined-ratchet.md)).
|
|
77
98
|
* Without it, changing what a metric COUNTS silently moved every baselined
|
|
78
99
|
* ceiling: `linesOfCode` went from span lines to code lines, entries kept
|
|
79
100
|
* matching on identity, and a class could then grow to roughly three times
|
package/dist/violation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../src/violation.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC3B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,OAAO,GAAG,MAAM,GACzB,OAAO,GAAG,MAAM,CAElB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAEtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAE1D;AA0GD,0EAA0E;AAC1E,wBAAgB,kBAAkB,IAAI,SAAS;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,EAAE,CAEF;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAID,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CA6DnF"}
|
|
1
|
+
{"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../src/violation.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAA;IACb,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAA;IACX,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAA;IACnB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAA;IACZ;;;;;;;;;;;;;;;;;;;OAmBG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,sEAAsE;IACtE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC3B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,OAAO,GAAG,MAAM,GACzB,OAAO,GAAG,MAAM,CAElB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAEtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAE1D;AA0GD,0EAA0E;AAC1E,wBAAgB,kBAAkB,IAAI,SAAS;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,EAAE,CAEF;AAED,mFAAmF;AACnF,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C;AAID,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CA6DnF"}
|
package/dist/violation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"violation.js","sourceRoot":"","sources":["../src/violation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"violation.js","sourceRoot":"","sources":["../src/violation.ts"],"names":[],"mappings":"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"}
|
package/dist/watch.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watch-mode scheduling and the watch loop, shared by every dialect CLI.
|
|
3
|
+
*
|
|
4
|
+
* **Why this is in the kernel.** It was copied, and the copies drifted. Measured
|
|
5
|
+
* on 2026-08-31: `watchAndRerun` scored 98% between `eess-ts` and `eess-mermaid`,
|
|
6
|
+
* `RunScheduler.schedule` 100%, `RunScheduler.executeRun` 98% — and the drift was
|
|
7
|
+
* not cosmetic. Two fixes had landed on the ts copy alone:
|
|
8
|
+
*
|
|
9
|
+
* - `isArchRuleError` instead of `err instanceof ArchRuleError`. The structural
|
|
10
|
+
* check exists because a rule file does not load through the same module
|
|
11
|
+
* registry as the CLI loading it, so `instanceof` is FALSE for an error that is
|
|
12
|
+
* an `ArchRuleError` in every way that matters. With the `instanceof` form,
|
|
13
|
+
* `eess-mermaid --watch` printed an ordinary rule failure as an unexpected
|
|
14
|
+
* crash.
|
|
15
|
+
* - `isNullaryCallable(w.return)` instead of a `typeof` test plus
|
|
16
|
+
* `w.return.call(w)`, which the copy's own comment noted yields `any`.
|
|
17
|
+
*
|
|
18
|
+
* Nothing here needs a project or a tokenizer, so this unification is not
|
|
19
|
+
* waiting on either decision plan 0188 turns on — see that plan's inventory.
|
|
20
|
+
*
|
|
21
|
+
* Kernel-safe: node builtins and this package only.
|
|
22
|
+
*/
|
|
23
|
+
export interface WatchOptions {
|
|
24
|
+
/** Directories to watch, recursively. */
|
|
25
|
+
watchDirs: string[];
|
|
26
|
+
/** Additional individual files to watch (e.g. rule files). */
|
|
27
|
+
watchFiles: string[];
|
|
28
|
+
/** Which filenames inside `watchDirs` count as a change. */
|
|
29
|
+
watchedFileRe: RegExp;
|
|
30
|
+
/** Runs on a debounced change. */
|
|
31
|
+
onChangeDetected: () => Promise<void>;
|
|
32
|
+
/** Debounce window in ms. Default: 250. */
|
|
33
|
+
debounceMs?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Scheduling logic for watch mode — separate from the loop so it is testable
|
|
37
|
+
* without a filesystem.
|
|
38
|
+
*
|
|
39
|
+
* Debounces rapid triggers. A trigger arriving mid-run is remembered and
|
|
40
|
+
* replayed once the run finishes, so a save during a run is never dropped and
|
|
41
|
+
* never starts a second concurrent run.
|
|
42
|
+
*/
|
|
43
|
+
export declare class RunScheduler {
|
|
44
|
+
#private;
|
|
45
|
+
private debounceTimer;
|
|
46
|
+
private running;
|
|
47
|
+
private _pendingRerun;
|
|
48
|
+
private readonly debounceMs;
|
|
49
|
+
private readonly onRun;
|
|
50
|
+
constructor(onRun: (trigger: string) => Promise<void>, debounceMs?: number);
|
|
51
|
+
/**
|
|
52
|
+
* Completed runs.
|
|
53
|
+
*
|
|
54
|
+
* Hard-private with a getter: the counter is this class's own bookkeeping, and
|
|
55
|
+
* a caller that could reassign it would make the number mean nothing.
|
|
56
|
+
*/
|
|
57
|
+
get runCount(): number;
|
|
58
|
+
get pendingRerun(): boolean;
|
|
59
|
+
get isRunning(): boolean;
|
|
60
|
+
/** Debounce a change on `trigger`, coalescing bursts into a single re-run. */
|
|
61
|
+
schedule(trigger: string): void;
|
|
62
|
+
private executeRun;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Watch for file changes and re-run the callback.
|
|
66
|
+
*
|
|
67
|
+
* Uses `fs.watch` with `recursive: true` (Node 24+). Debounces rapid events; a
|
|
68
|
+
* change during a run is queued and executed after it completes.
|
|
69
|
+
*/
|
|
70
|
+
export declare function watchAndRerun(options: WatchOptions): void;
|
|
71
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAA;IACrB,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAOD;;;;;;;GAOG;AACH,qBAAa,YAAY;;IACvB,OAAO,CAAC,aAAa,CAA2C;IAChE,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAG9C,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,SAAsB;IAKvF;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAW/B,OAAO,CAAC,UAAU;CAuBnB;AAmBD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAsCzD"}
|