@descent-vtt/spec-guard 0.7.0 → 0.9.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/README.md +224 -27
  3. package/dist/cli.d.ts +37 -2
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +275 -59
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config.d.ts +66 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +165 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/engine.d.ts +22 -8
  12. package/dist/engine.d.ts.map +1 -1
  13. package/dist/engine.js +118 -67
  14. package/dist/engine.js.map +1 -1
  15. package/dist/facts.d.ts +106 -0
  16. package/dist/facts.d.ts.map +1 -0
  17. package/dist/facts.js +188 -0
  18. package/dist/facts.js.map +1 -0
  19. package/dist/glob.d.ts +17 -21
  20. package/dist/glob.d.ts.map +1 -1
  21. package/dist/glob.js +13 -24
  22. package/dist/glob.js.map +1 -1
  23. package/dist/imports.d.ts +6 -1
  24. package/dist/imports.d.ts.map +1 -1
  25. package/dist/imports.js +9 -5
  26. package/dist/imports.js.map +1 -1
  27. package/dist/index.d.ts +20 -8
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +11 -5
  30. package/dist/index.js.map +1 -1
  31. package/dist/io.d.ts +51 -0
  32. package/dist/io.d.ts.map +1 -0
  33. package/dist/io.js +44 -0
  34. package/dist/io.js.map +1 -0
  35. package/dist/mcp.d.ts +11 -0
  36. package/dist/mcp.d.ts.map +1 -1
  37. package/dist/mcp.js +23 -18
  38. package/dist/mcp.js.map +1 -1
  39. package/dist/memo.d.ts +53 -0
  40. package/dist/memo.d.ts.map +1 -0
  41. package/dist/memo.js +67 -0
  42. package/dist/memo.js.map +1 -0
  43. package/dist/parser.d.ts.map +1 -1
  44. package/dist/parser.js +17 -0
  45. package/dist/parser.js.map +1 -1
  46. package/dist/query.d.ts +5 -2
  47. package/dist/query.d.ts.map +1 -1
  48. package/dist/query.js +12 -3
  49. package/dist/query.js.map +1 -1
  50. package/dist/reporter.d.ts +10 -0
  51. package/dist/reporter.d.ts.map +1 -1
  52. package/dist/reporter.js +33 -4
  53. package/dist/reporter.js.map +1 -1
  54. package/dist/rules.d.ts +12 -1
  55. package/dist/rules.d.ts.map +1 -1
  56. package/dist/rules.js +45 -1
  57. package/dist/rules.js.map +1 -1
  58. package/dist/runner.d.ts +42 -2
  59. package/dist/runner.d.ts.map +1 -1
  60. package/dist/runner.js +261 -76
  61. package/dist/runner.js.map +1 -1
  62. package/dist/specs.d.ts +3 -1
  63. package/dist/specs.d.ts.map +1 -1
  64. package/dist/specs.js +6 -5
  65. package/dist/specs.js.map +1 -1
  66. package/dist/structure.d.ts +104 -0
  67. package/dist/structure.d.ts.map +1 -0
  68. package/dist/structure.js +254 -0
  69. package/dist/structure.js.map +1 -0
  70. package/dist/types.d.ts +50 -5
  71. package/dist/types.d.ts.map +1 -1
  72. package/dist/watch.d.ts +125 -0
  73. package/dist/watch.d.ts.map +1 -0
  74. package/dist/watch.js +321 -0
  75. package/dist/watch.js.map +1 -0
  76. package/package.json +8 -2
@@ -0,0 +1,254 @@
1
+ /**
2
+ * `@assert-structure`: what files are called, what directories hold, and which
3
+ * files come in pairs. ADR-0013.
4
+ *
5
+ * Names only. Nothing here reads a file's contents, and nothing asks the
6
+ * filesystem whether a path exists: a path exists when its name is in its
7
+ * parent's listing, compared exactly. A lookup of `README.md` finds `Readme.md`
8
+ * on Windows and macOS and does not on Linux, and a rule about names that
9
+ * answers one way on a laptop and the other in CI is not a rule about names.
10
+ */
11
+ import path from 'node:path';
12
+ import { comparePaths } from './engine.js';
13
+ import { createExcludeMatcher, createGlobMatcher, globToRegExp, isGlob, toPosix, walkPaths, } from './glob.js';
14
+ import { nodeIo } from './io.js';
15
+ import { LedgerBuilder, UNCERTAIN_REASONS } from './scope.js';
16
+ export function createTreeIndex(root, io = nodeIo) {
17
+ // Each directory's read, by its path from the root, kept twice over: as the
18
+ // reader returned it, for the walk - which needs a failed read to fail, and
19
+ // sorts in place a list that is then already sorted - and as a lookup by
20
+ // name, built once. Keyed by the relative path rather than the absolute one
21
+ // because a lookup names every directory on its way, and joining an absolute
22
+ // path per segment was most of what a partner rule cost over ten thousand
23
+ // files.
24
+ const reads = new Map();
25
+ const walks = new Map();
26
+ const read = (relativeDirectory) => {
27
+ let cached = reads.get(relativeDirectory);
28
+ if (!cached) {
29
+ const entries = io.readDirectory(path.join(root, relativeDirectory));
30
+ const listing = entries.then((found) => new Map(found.map((entry) => [entry.name, entry])), () => null);
31
+ cached = { entries, listing };
32
+ reads.set(relativeDirectory, cached);
33
+ }
34
+ return cached;
35
+ };
36
+ const listing = async (relativeDirectory) => {
37
+ let current = await read('.').listing;
38
+ if (relativeDirectory === '.')
39
+ return current;
40
+ const names = relativeDirectory.split('/');
41
+ for (const [depth, name] of names.entries()) {
42
+ if (current?.get(name)?.isDirectory() !== true)
43
+ return null;
44
+ current = await read(names.slice(0, depth + 1).join('/')).listing;
45
+ }
46
+ return current;
47
+ };
48
+ const walk = (target, scope) => {
49
+ const key = JSON.stringify([target, [...scope.skippedDirectories.keys()]]);
50
+ let pending = walks.get(key);
51
+ if (!pending) {
52
+ pending = (async () => {
53
+ const tree = { files: [], directories: [], gaps: [] };
54
+ const fromRoot = (relativePath) => path.posix.join(target, relativePath);
55
+ const walked = walkPaths(path.join(root, target), {
56
+ scope,
57
+ io: { ...io, readDirectory: (directory) => read(toPosix(path.relative(root, directory)) || '.').entries },
58
+ onDirectory: (relativePath) => tree.directories.push(fromRoot(relativePath)),
59
+ // Only the gaps. `.git` and `node_modules` are the run's policy, and
60
+ // are no more news here than they are to a search.
61
+ onSkip: (relativePath, reason) => {
62
+ if (UNCERTAIN_REASONS.has(reason))
63
+ tree.gaps.push(fromRoot(relativePath));
64
+ },
65
+ });
66
+ for await (const file of walked)
67
+ tree.files.push(fromRoot(file.relativePath));
68
+ return tree;
69
+ })();
70
+ walks.set(key, pending);
71
+ }
72
+ return pending;
73
+ };
74
+ return { listing, walk };
75
+ }
76
+ /** What a root-relative path is, by name - or null, which a link is too. */
77
+ async function kindOf(index, relativePath) {
78
+ if (relativePath === '.')
79
+ return 'directory';
80
+ const entry = (await index.listing(path.posix.dirname(relativePath)))?.get(path.posix.basename(relativePath));
81
+ return entry?.isDirectory() ? 'directory' : entry?.isFile() ? 'file' : null;
82
+ }
83
+ /**
84
+ * Whether a directory holds a required entry: a file, or a directory when it
85
+ * ends in `/` - which `basename` and `dirname` both already ignore.
86
+ */
87
+ async function holds(index, directory, entry) {
88
+ const wantsDirectory = entry.endsWith('/');
89
+ const named = globToRegExp(path.posix.basename(entry));
90
+ const listing = await index.listing(path.posix.join(directory, path.posix.dirname(entry)));
91
+ return [...(listing?.values() ?? [])].some((item) => named.test(item.name) && (wantsDirectory ? item.isDirectory() : item.isFile()));
92
+ }
93
+ /* -------------------------------------------------------------- the grammar */
94
+ const PLACEHOLDER = /\[(name|ext|dir)\]/g;
95
+ /**
96
+ * The path a partner template names for a file.
97
+ *
98
+ * `[name]` is the base name up to its last dot and `[ext]` is what follows it;
99
+ * a name whose only dot leads it, like `.env`, is all name. `[dir]` is the
100
+ * file's directory below the target it was found from - empty for a file at the
101
+ * top, or for a target that is the file itself - and a segment left empty leaves
102
+ * no separator behind. A template without a `/` names a sibling; a template
103
+ * with one names a path from the root.
104
+ *
105
+ * That is the whole grammar, and it is small on purpose: a reader can expand a
106
+ * template by eye, which is the property a substitution engine gives up.
107
+ */
108
+ export function expandPartner(template, file, target) {
109
+ const directory = path.posix.dirname(file);
110
+ const base = path.posix.basename(file);
111
+ const dot = base.lastIndexOf('.');
112
+ const values = {
113
+ name: dot > 0 ? base.slice(0, dot) : base,
114
+ ext: dot > 0 ? base.slice(dot + 1) : '',
115
+ dir: path.posix.relative(file === target ? directory : target, directory),
116
+ };
117
+ const filled = template
118
+ .split('/')
119
+ .map((segment) => segment.replace(PLACEHOLDER, (_, key) => values[key]))
120
+ .filter((segment) => segment.length > 0)
121
+ .join('/');
122
+ return template.includes('/') ? filled : path.posix.join(directory, filled);
123
+ }
124
+ /** Why a partner template cannot be used, or null when it can. */
125
+ export function partnerTemplateIssue(template) {
126
+ const literal = template.replace(PLACEHOLDER, '');
127
+ const unknown = /\[[^\]]*\]/.exec(literal);
128
+ if (unknown) {
129
+ return `Partner template "${template}" uses ${unknown[0]}; the placeholders are [name], [ext] and [dir].`;
130
+ }
131
+ if (isGlob(literal)) {
132
+ return `Partner template "${template}" is a name, not a glob, so it cannot hold *, ?, [, ], { or }.`;
133
+ }
134
+ if (template.split('/').some((segment) => segment === '' || segment === '.' || segment === '..')) {
135
+ return `Partner template "${template}" must be a path inside the root, with no empty, "." or ".." segment.`;
136
+ }
137
+ return null;
138
+ }
139
+ /** Why a required entry cannot be used, or null when it can. */
140
+ export function requiredEntryIssue(entry) {
141
+ const segments = entry.replace(/\/$/, '').split('/');
142
+ if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
143
+ return `Required entry "${entry}" must be a path inside the directory, with no empty, "." or ".." segment.`;
144
+ }
145
+ if (segments.slice(0, -1).some(isGlob)) {
146
+ return `Required entry "${entry}" can use a glob only in its last segment.`;
147
+ }
148
+ return null;
149
+ }
150
+ /**
151
+ * Holds every file or directory in scope to the claim.
152
+ *
153
+ * A subject is counted once, with the first target that reaches it - which is
154
+ * the target `[dir]` is measured from when two targets overlap.
155
+ */
156
+ export async function checkStructure(query, request, index) {
157
+ const excluded = createExcludeMatcher(request.excludeGlobs);
158
+ const included = createGlobMatcher(request.globs);
159
+ const required = query.claim === 'required';
160
+ const selects = query.dirs === undefined ? null : globToRegExp(query.dirs);
161
+ const missing = [];
162
+ const notDirectories = [];
163
+ const gaps = new Set();
164
+ const subjects = new Map();
165
+ const add = (subject, target) => {
166
+ if (!subjects.has(subject))
167
+ subjects.set(subject, target);
168
+ };
169
+ for (const target of request.targets) {
170
+ const kind = await kindOf(index, target);
171
+ if (kind === 'file') {
172
+ if (required)
173
+ notDirectories.push(target);
174
+ else if (included(target) && !excluded(target))
175
+ add(target, target);
176
+ }
177
+ else if (kind !== 'directory') {
178
+ missing.push(target);
179
+ }
180
+ else if (required && selects === null) {
181
+ if (!excluded(target))
182
+ add(target, target);
183
+ }
184
+ else {
185
+ const tree = await index.walk(target, request.scope);
186
+ for (const gap of tree.gaps)
187
+ gaps.add(gap);
188
+ if (selects !== null) {
189
+ for (const directory of tree.directories) {
190
+ if (!excluded(directory) && selects.test(path.posix.relative(target, directory)))
191
+ add(directory, target);
192
+ }
193
+ }
194
+ else {
195
+ for (const file of tree.files)
196
+ if (included(file) && !excluded(file))
197
+ add(file, target);
198
+ }
199
+ }
200
+ }
201
+ const ledger = new LedgerBuilder();
202
+ for (const gap of gaps)
203
+ ledger.add(gap, 'unreadable');
204
+ const ordered = [...subjects].sort(([a], [b]) => comparePaths(a, b));
205
+ const check = {
206
+ missing,
207
+ notDirectories,
208
+ inspected: ordered.length,
209
+ violations: [],
210
+ scope: ledger.build(),
211
+ };
212
+ if (query.claim === 'pattern') {
213
+ const named = createGlobMatcher(query.values);
214
+ for (const [file] of ordered) {
215
+ if (!named(file))
216
+ check.violations.push({ path: file, text: `matches none of ${query.values.join(', ')}` });
217
+ }
218
+ return check;
219
+ }
220
+ if (required) {
221
+ const found = await Promise.all(ordered.map(([directory]) => Promise.all(query.values.map((entry) => holds(index, directory, entry)))));
222
+ ordered.forEach(([directory], at) => {
223
+ const lacking = query.values.filter((_, position) => !found[at][position]);
224
+ if (lacking.length > 0)
225
+ check.violations.push({ path: directory, text: `missing ${lacking.join(', ')}` });
226
+ });
227
+ return check;
228
+ }
229
+ // Partners. Expanded before anything is looked up, so a template naming the
230
+ // file itself is refused rather than satisfied by every file.
231
+ const partners = ordered.map(([file, target]) => query.values.map((template) => expandPartner(template, file, target)));
232
+ const expectedBy = new Map();
233
+ for (const [at, [file]] of ordered.entries()) {
234
+ const names = partners[at];
235
+ const own = names.indexOf(file);
236
+ if (own !== -1)
237
+ return { ...check, selfPartner: { file, template: query.values[own] } };
238
+ for (const name of names)
239
+ if (!expectedBy.has(name))
240
+ expectedBy.set(name, file);
241
+ }
242
+ const found = await Promise.all(partners.map((names) => Promise.all(names.map(async (name) => (await index.listing(path.posix.dirname(name)))?.get(path.posix.basename(name))?.isFile() === true))));
243
+ ordered.forEach(([file], at) => {
244
+ if (found[at].includes(true))
245
+ return;
246
+ // The likeliest reason a file has no partner is that it is one, and the
247
+ // directive forgot to exclude the partners.
248
+ const owner = expectedBy.get(file);
249
+ const hint = owner === undefined ? '' : ` (it is the partner of ${owner} - exclude it?)`;
250
+ check.violations.push({ path: file, text: `has no partner ${partners[at].join(' or ')}${hint}` });
251
+ });
252
+ return check;
253
+ }
254
+ //# sourceMappingURL=structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure.js","sourceRoot":"","sources":["../src/structure.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -6,7 +6,24 @@ import type { ScopeLedger, ScopePolicy } from './scope.js';
6
6
  * parser -> Directive[] -> runner (+ engine) -> AssertionResult[] -> reporter
7
7
  */
8
8
  /** Every assertion kind the parser understands. */
9
- export type DirectiveKind = 'assert-absence' | 'assert-count' | 'assert-present' | 'assert-import-absence' | 'assert-import-count' | 'assert-import-cycle' | 'assert-layers';
9
+ export type DirectiveKind = 'assert-absence' | 'assert-count' | 'assert-present' | 'assert-import-absence' | 'assert-import-count' | 'assert-import-cycle' | 'assert-layers' | 'assert-structure';
10
+ /** What an `@assert-structure` directive claims. Exactly one per directive; see ADR-0013. */
11
+ export type StructureClaim = 'pattern' | 'required' | 'partner';
12
+ /** The claim of an `@assert-structure` directive, resolved. */
13
+ export interface StructureQuery {
14
+ claim: StructureClaim;
15
+ /**
16
+ * The claim's list, as written: the name patterns every file must match, the
17
+ * entries every directory must hold, or the partner templates of which one
18
+ * must exist.
19
+ */
20
+ values: string[];
21
+ /**
22
+ * For `required`, the glob choosing directories below each target. Absent
23
+ * when the rule is about the targets themselves.
24
+ */
25
+ dirs?: string;
26
+ }
10
27
  /** Extra scope carried by the import assertions. */
11
28
  export interface ImportQuery {
12
29
  /** Module patterns, matched with gitignore-style rules. */
@@ -145,9 +162,12 @@ export interface Bounds {
145
162
  export interface MatchLocation {
146
163
  /** Path relative to root, forward slashes. */
147
164
  file: string;
148
- /** 1-based line number. */
165
+ /**
166
+ * 1-based line number, or 0 when the match is the path as a whole - a file
167
+ * with the wrong name, or a directory missing an entry, has no line.
168
+ */
149
169
  line: number;
150
- /** 1-based column of the first match on that line. */
170
+ /** 1-based column of the first match on that line; 0 alongside a line of 0. */
151
171
  column: number;
152
172
  /** Trimmed line content, truncated for display. */
153
173
  text: string;
@@ -200,6 +220,8 @@ export interface Assertion {
200
220
  * on to the layer that may depend on everything. See ADR-0011.
201
221
  */
202
222
  layers?: string[];
223
+ /** Present on `@assert-structure`. */
224
+ structure?: StructureQuery;
203
225
  /**
204
226
  * Known violations that do not count. Empty when the directive declared none.
205
227
  *
@@ -211,8 +233,6 @@ export interface Assertion {
211
233
  baseline: readonly BaselineEntry[];
212
234
  /** Whether a baseline entry that no longer matches fails the run. */
213
235
  ratchet: RatchetMode;
214
- /** Targets that do not exist on disk. */
215
- missingTargets: string[];
216
236
  /**
217
237
  * Tolerate a scope containing no files.
218
238
  *
@@ -234,6 +254,14 @@ export interface AssertionResult {
234
254
  targets: string[];
235
255
  files: string[];
236
256
  bounds: Bounds;
257
+ /**
258
+ * The claim of an `@assert-structure` result.
259
+ *
260
+ * Carried because it decides what a match is: a file for `pattern` and
261
+ * `partner`, a directory for `required` - and a directory is not something a
262
+ * code-scanning annotation can be placed on.
263
+ */
264
+ claim?: StructureClaim;
237
265
  /** Observed count: matches for searches, existing files for `assert-present`. */
238
266
  actual: number;
239
267
  /** Short "expected X, found Y" style explanation. */
@@ -290,6 +318,21 @@ export interface RunSummary {
290
318
  */
291
319
  inactive: number;
292
320
  }
321
+ /**
322
+ * What a command took from a project's configuration, by key. ADR-0014.
323
+ *
324
+ * Carried on a report because an option in a file nobody is looking at is an
325
+ * option nobody knows is in force - and `allowEmptyScope` there weakens every
326
+ * rule in the project.
327
+ */
328
+ export interface ConfigUse {
329
+ /** The file the options came from, relative to the root. */
330
+ file: string;
331
+ /** Keys whose values were used. */
332
+ applied: string[];
333
+ /** Keys the command line set too, and won. */
334
+ overridden: string[];
335
+ }
293
336
  export interface RunReport {
294
337
  ok: boolean;
295
338
  root: string;
@@ -310,5 +353,7 @@ export interface RunReport {
310
353
  * tool exists to prevent.
311
354
  */
312
355
  inactiveSpecs: InactiveSpec[];
356
+ /** What the command line took from the project's configuration, when it took anything. */
357
+ config?: ConfigUse;
313
358
  }
314
359
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * `spec-guard --watch`: the same report, again, whenever the tree changes.
3
+ * ADR-0014.
4
+ *
5
+ * Two parts. A session answers "what does a run say now" and re-executes a
6
+ * rule only when its resolved form or something it read has changed; what may
7
+ * be reused, and why, is in facts.ts and memo.ts. The scheduler around it turns
8
+ * a watcher's events into batches, never runs two at once, redraws the terminal,
9
+ * and stops on Ctrl+C.
10
+ *
11
+ * The session is held to a fresh run of the same tree by
12
+ * tests/watch-equivalence.test.ts, and nothing here is trusted beyond that.
13
+ */
14
+ import { type FactPolicy, type WatchEvent } from './facts.js';
15
+ import { type Io, type TreeWatcher } from './io.js';
16
+ import { type Memo, type SessionMemo } from './memo.js';
17
+ import { type ReporterOptions } from './reporter.js';
18
+ import { type ExecuteOptions, type RunOptions, type RunResult } from './runner.js';
19
+ import type { Assertion, ConfigUse } from './types.js';
20
+ /** The options a session's run takes: a run's, less the engine it never uses. */
21
+ export type SessionRunOptions = Pick<RunOptions, 'allowMissingTargets' | 'strictTargets' | 'allowEmptyScope' | 'maxSnippets' | 'includeSpecs' | 'defaultSkips' | 'ignoreStatus' | 'concurrency'>;
22
+ /** What one run of a session is asked to do. */
23
+ export interface SessionSettings {
24
+ patterns: readonly string[];
25
+ run: SessionRunOptions;
26
+ /** What those settings took from the project's configuration, for the report. */
27
+ config?: ConfigUse;
28
+ }
29
+ export interface SessionOptions {
30
+ root: string;
31
+ /** The filesystem underneath the session's cache. */
32
+ io?: Io;
33
+ /**
34
+ * Decides a run's settings, reading whatever it needs through the door it is
35
+ * handed - so an edit to `package.json` reaches the session as a changed fact
36
+ * like any other. Throws to fail the run with its message.
37
+ */
38
+ settings: (io: Io) => Promise<SessionSettings>;
39
+ /** What an event evicts and what counts as a change. */
40
+ policy?: FactPolicy;
41
+ /** Where pure work is remembered. */
42
+ memo?: SessionMemo;
43
+ /** What decides whether a rule's last result can be reused. */
44
+ identify?: (assertion: Assertion, run: SessionRunOptions) => string;
45
+ /** The per-run caches a rule executes with. */
46
+ caches?: (root: string, door: Io, memo: Memo) => RuleCaches;
47
+ }
48
+ /** The caches one execution of one rule reads through. */
49
+ export type RuleCaches = Pick<ExecuteOptions, 'engine' | 'imports' | 'hasFiles' | 'tree'>;
50
+ /**
51
+ * A rule's own caches, over its own door.
52
+ *
53
+ * Never shared between rules. Each is keyed by path, which makes it a fact
54
+ * under another name: a second rule served from the first one's walk would skip
55
+ * the reads, and with them the record of what it depends on.
56
+ */
57
+ export declare function ruleCaches(root: string, door: Io, memo: Memo): RuleCaches;
58
+ export interface SessionRun {
59
+ report: RunResult;
60
+ /** How many snippets a failure shows, as the run was configured. */
61
+ maxSnippets: number;
62
+ /** Rules executed by this run rather than carried over from the last. */
63
+ executed: number;
64
+ }
65
+ export interface Session {
66
+ /** What a run says now. */
67
+ run(): Promise<SessionRun>;
68
+ /** Evicts what the events may have changed, and reads it again. Returns how many facts changed. */
69
+ observe(events: readonly WatchEvent[]): Promise<number>;
70
+ /** Forgets every fact, so the next run executes every rule. */
71
+ forget(): void;
72
+ /** Facts held, for the numbers ADR-0014 reports. */
73
+ readonly facts: number;
74
+ }
75
+ /**
76
+ * What decides a rule's result besides the tree: its resolved form, and the run
77
+ * options its execution reads. Two rules with equal identities executed over the
78
+ * same facts give the same result, which is the whole of what reuse relies on.
79
+ *
80
+ * Only the options execution reads. The ones resolution reads - which specs are
81
+ * excluded, which directories skipped - are already in the resolved form, as the
82
+ * spec files it leaves out and the scope it walks, and are held there, where a
83
+ * rule is changed by them, rather than beside it.
84
+ */
85
+ export declare function identity(assertion: Assertion, run: SessionRunOptions): string;
86
+ export declare function createSession(options: SessionOptions): Session;
87
+ /** How long a batch waits for quiet after its last event. */
88
+ export declare const QUIET_MS = 50;
89
+ /** How long a batch waits after its first event, however noisy the tree stays. */
90
+ export declare const MAX_WAIT_MS = 500;
91
+ /** The exit code of an interrupted command, as a shell reports one: 128 + SIGINT. */
92
+ export declare const EXIT_INTERRUPTED = 130;
93
+ /** Timers, injectable so a test can run the scheduler without waiting. */
94
+ export interface Clock {
95
+ now(): number;
96
+ setTimeout(callback: () => void, ms: number): unknown;
97
+ clearTimeout(handle: unknown): void;
98
+ }
99
+ export declare const systemClock: Clock;
100
+ export interface WatchOptions {
101
+ root: string;
102
+ session: Session;
103
+ /** Starts watching the root; may throw. */
104
+ watch: (listener: (event: WatchEvent) => void, onError: (error: Error) => void) => TreeWatcher;
105
+ /** Writes text as it is, with no newline added. */
106
+ write: (text: string) => void;
107
+ /** Clear the screen and redraw, rather than append. */
108
+ isTTY: boolean;
109
+ reporter: ReporterOptions;
110
+ /** Registers the handler for Ctrl+C and SIGTERM, and returns how to unregister it. */
111
+ onInterrupt: (handler: () => void) => () => void;
112
+ /** Registers the handler for a line on stdin, and returns how to unregister it. */
113
+ onLine?: (handler: () => void) => () => void;
114
+ clock?: Clock;
115
+ }
116
+ /**
117
+ * Runs a session until it is interrupted, and resolves to the exit code.
118
+ *
119
+ * 130 when stopped, since a session is neither a pass nor a failure. 2 when it
120
+ * cannot start or its watcher fails, including when the root disappears.
121
+ */
122
+ export declare function runWatch(options: WatchOptions): Promise<number>;
123
+ /** A watcher's error, with what to do about the one a person can fix. */
124
+ export declare function describeWatchError(error: Error): string;
125
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}