@rhost/testkit 0.1.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +393 -5
  2. package/ROADMAP.md +241 -0
  3. package/dist/benchmark.d.ts +44 -0
  4. package/dist/benchmark.d.ts.map +1 -0
  5. package/dist/benchmark.js +118 -0
  6. package/dist/benchmark.js.map +1 -0
  7. package/dist/cli/deploy.d.ts +2 -0
  8. package/dist/cli/deploy.d.ts.map +1 -0
  9. package/dist/cli/deploy.js +120 -0
  10. package/dist/cli/deploy.js.map +1 -0
  11. package/dist/cli/fmt.d.ts +2 -0
  12. package/dist/cli/fmt.d.ts.map +1 -0
  13. package/dist/cli/fmt.js +119 -0
  14. package/dist/cli/fmt.js.map +1 -0
  15. package/dist/cli/index.d.ts +3 -0
  16. package/dist/cli/index.d.ts.map +1 -0
  17. package/dist/cli/index.js +81 -0
  18. package/dist/cli/index.js.map +1 -0
  19. package/dist/cli/init.d.ts +2 -0
  20. package/dist/cli/init.d.ts.map +1 -0
  21. package/dist/cli/init.js +210 -0
  22. package/dist/cli/init.js.map +1 -0
  23. package/dist/cli/validate.d.ts +2 -0
  24. package/dist/cli/validate.d.ts.map +1 -0
  25. package/dist/cli/validate.js +126 -0
  26. package/dist/cli/validate.js.map +1 -0
  27. package/dist/cli/watch.d.ts +2 -0
  28. package/dist/cli/watch.d.ts.map +1 -0
  29. package/dist/cli/watch.js +136 -0
  30. package/dist/cli/watch.js.map +1 -0
  31. package/dist/client.d.ts +48 -0
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +113 -30
  34. package/dist/client.js.map +1 -1
  35. package/dist/container.d.ts.map +1 -1
  36. package/dist/container.js +1 -1
  37. package/dist/container.js.map +1 -1
  38. package/dist/deployer.d.ts +86 -0
  39. package/dist/deployer.d.ts.map +1 -0
  40. package/dist/deployer.js +154 -0
  41. package/dist/deployer.js.map +1 -0
  42. package/dist/expect.d.ts +27 -1
  43. package/dist/expect.d.ts.map +1 -1
  44. package/dist/expect.js +47 -2
  45. package/dist/expect.js.map +1 -1
  46. package/dist/index.d.ts +10 -3
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +39 -1
  49. package/dist/index.js.map +1 -1
  50. package/dist/preflight.d.ts +70 -0
  51. package/dist/preflight.d.ts.map +1 -0
  52. package/dist/preflight.js +121 -0
  53. package/dist/preflight.js.map +1 -0
  54. package/dist/reporter.d.ts +2 -0
  55. package/dist/reporter.d.ts.map +1 -1
  56. package/dist/reporter.js +24 -1
  57. package/dist/reporter.js.map +1 -1
  58. package/dist/runner.d.ts +83 -2
  59. package/dist/runner.d.ts.map +1 -1
  60. package/dist/runner.js +137 -8
  61. package/dist/runner.js.map +1 -1
  62. package/dist/snapshots.d.ts +84 -0
  63. package/dist/snapshots.d.ts.map +1 -0
  64. package/dist/snapshots.js +230 -0
  65. package/dist/snapshots.js.map +1 -0
  66. package/dist/validator/builtins.d.ts +18 -0
  67. package/dist/validator/builtins.d.ts.map +1 -0
  68. package/dist/validator/builtins.js +265 -0
  69. package/dist/validator/builtins.js.map +1 -0
  70. package/dist/validator/checker.d.ts +13 -0
  71. package/dist/validator/checker.d.ts.map +1 -0
  72. package/dist/validator/checker.js +111 -0
  73. package/dist/validator/checker.js.map +1 -0
  74. package/dist/validator/clobber.d.ts +7 -0
  75. package/dist/validator/clobber.d.ts.map +1 -0
  76. package/dist/validator/clobber.js +102 -0
  77. package/dist/validator/clobber.js.map +1 -0
  78. package/dist/validator/compat.d.ts +19 -0
  79. package/dist/validator/compat.d.ts.map +1 -0
  80. package/dist/validator/compat.js +58 -0
  81. package/dist/validator/compat.js.map +1 -0
  82. package/dist/validator/formatter.d.ts +21 -0
  83. package/dist/validator/formatter.d.ts.map +1 -0
  84. package/dist/validator/formatter.js +120 -0
  85. package/dist/validator/formatter.js.map +1 -0
  86. package/dist/validator/index.d.ts +57 -0
  87. package/dist/validator/index.d.ts.map +1 -0
  88. package/dist/validator/index.js +133 -0
  89. package/dist/validator/index.js.map +1 -0
  90. package/dist/validator/parser.d.ts +16 -0
  91. package/dist/validator/parser.d.ts.map +1 -0
  92. package/dist/validator/parser.js +260 -0
  93. package/dist/validator/parser.js.map +1 -0
  94. package/dist/validator/tokenizer.d.ts +28 -0
  95. package/dist/validator/tokenizer.d.ts.map +1 -0
  96. package/dist/validator/tokenizer.js +174 -0
  97. package/dist/validator/tokenizer.js.map +1 -0
  98. package/dist/validator/types.d.ts +55 -0
  99. package/dist/validator/types.d.ts.map +1 -0
  100. package/dist/validator/types.js +6 -0
  101. package/dist/validator/types.js.map +1 -0
  102. package/dist/watcher.d.ts +44 -0
  103. package/dist/watcher.d.ts.map +1 -0
  104. package/dist/watcher.js +297 -0
  105. package/dist/watcher.js.map +1 -0
  106. package/dist/world.d.ts +79 -0
  107. package/dist/world.d.ts.map +1 -1
  108. package/dist/world.js +167 -1
  109. package/dist/world.js.map +1 -1
  110. package/package.json +19 -3
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // RhostMUSH softcode tokenizer
4
+ // ---------------------------------------------------------------------------
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.tokenize = tokenize;
7
+ // Characters that end a plain-text accumulation run.
8
+ // These must be checked before starting a new TEXT run.
9
+ const STRUCTURAL_RE = /[\\%\[\]()\,,a-zA-Z_]/;
10
+ function isIdentStart(ch) {
11
+ const c = ch.charCodeAt(0);
12
+ return (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 95; // A-Z, a-z, _
13
+ }
14
+ function isIdentChar(ch) {
15
+ const c = ch.charCodeAt(0);
16
+ return ((c >= 65 && c <= 90) ||
17
+ (c >= 97 && c <= 122) ||
18
+ (c >= 48 && c <= 57) ||
19
+ c === 95); // A-Z, a-z, 0-9, _
20
+ }
21
+ /**
22
+ * Single-character percent substitutions recognised by RhostMUSH.
23
+ * Anything else after % is treated as a literal %, not a substitution.
24
+ */
25
+ const SINGLE_CHAR_SUBST = new Set([
26
+ '#', 'N', 'n', 'L', 'l', 'P', 'p', 'T', 't', 'B', 'b',
27
+ 'R', 'r', 'A', 'a', 'O', 'o', 'S', 's', 'X', 'x', '+',
28
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
29
+ 'C', 'c', // ANSI carry
30
+ 'v', 'V', // attribute value
31
+ 'w', 'W', // attribute name
32
+ 'u', 'U', // room name
33
+ 'f', 'F', // from
34
+ 'k', 'K', // money
35
+ 'm', 'M', // last entered command
36
+ ]);
37
+ /**
38
+ * Tokenize a RhostMUSH softcode expression into a flat token stream.
39
+ *
40
+ * Rules (in priority order):
41
+ * 1. `\X` → ESC(X) — escape always wins
42
+ * 2. `%%` → TEXT('%') — literal percent
43
+ * 3. `%qX` / `%iX` → SUBST('%qX') — 3-char register subst
44
+ * 4. `%X` (known) → SUBST('%X') — 2-char substitution
45
+ * 5. `%` (unknown) → TEXT('%') — treat as literal
46
+ * 6. `[` → LBRACKET
47
+ * 7. `]` → RBRACKET
48
+ * 8. `)` → RPAREN
49
+ * 9. `,` → COMMA
50
+ * 10. `word(` → FNAME(word) + LPAREN('(')
51
+ * 11. `word` → TEXT(word) — identifier not before (
52
+ * 12. `(` → TEXT('(') — ( not after identifier
53
+ * 13. <run> → TEXT(run) — anything else
54
+ */
55
+ function tokenize(input) {
56
+ const tokens = [];
57
+ let pos = 0;
58
+ const len = input.length;
59
+ while (pos < len) {
60
+ const ch = input[pos];
61
+ // ---- 1. Backslash escape ----
62
+ if (ch === '\\') {
63
+ if (pos + 1 < len) {
64
+ tokens.push({ type: 'ESC', value: input[pos + 1], offset: pos });
65
+ pos += 2;
66
+ }
67
+ else {
68
+ // Trailing backslash: literal backslash
69
+ tokens.push({ type: 'TEXT', value: '\\', offset: pos });
70
+ pos++;
71
+ }
72
+ continue;
73
+ }
74
+ // ---- 2–5. Percent substitutions ----
75
+ if (ch === '%') {
76
+ if (pos + 1 >= len) {
77
+ tokens.push({ type: 'TEXT', value: '%', offset: pos });
78
+ pos++;
79
+ continue;
80
+ }
81
+ const next = input[pos + 1];
82
+ // %% → literal %
83
+ if (next === '%') {
84
+ tokens.push({ type: 'TEXT', value: '%', offset: pos });
85
+ pos += 2;
86
+ continue;
87
+ }
88
+ // %q0–%q9, %qA–%qZ (q-register), %i0–%i9 (iter var) → 3-char subst
89
+ if ((next === 'q' || next === 'Q' || next === 'i' || next === 'I') &&
90
+ pos + 2 < len && /[0-9a-zA-Z]/.test(input[pos + 2])) {
91
+ tokens.push({ type: 'SUBST', value: input.slice(pos, pos + 3), offset: pos });
92
+ pos += 3;
93
+ continue;
94
+ }
95
+ // Single-char known substitutions
96
+ if (SINGLE_CHAR_SUBST.has(next)) {
97
+ tokens.push({ type: 'SUBST', value: input.slice(pos, pos + 2), offset: pos });
98
+ pos += 2;
99
+ continue;
100
+ }
101
+ // Unknown %X: literal %
102
+ tokens.push({ type: 'TEXT', value: '%', offset: pos });
103
+ pos++;
104
+ continue;
105
+ }
106
+ // ---- 6–9. Single structural characters ----
107
+ if (ch === '[') {
108
+ tokens.push({ type: 'LBRACKET', value: '[', offset: pos });
109
+ pos++;
110
+ continue;
111
+ }
112
+ if (ch === ']') {
113
+ tokens.push({ type: 'RBRACKET', value: ']', offset: pos });
114
+ pos++;
115
+ continue;
116
+ }
117
+ if (ch === ')') {
118
+ tokens.push({ type: 'RPAREN', value: ')', offset: pos });
119
+ pos++;
120
+ continue;
121
+ }
122
+ if (ch === ',') {
123
+ tokens.push({ type: 'COMMA', value: ',', offset: pos });
124
+ pos++;
125
+ continue;
126
+ }
127
+ // ---- 10–11. Identifier: FNAME+LPAREN or plain TEXT ----
128
+ if (isIdentStart(ch)) {
129
+ const start = pos;
130
+ while (pos < len && isIdentChar(input[pos])) {
131
+ pos++;
132
+ }
133
+ const word = input.slice(start, pos);
134
+ if (pos < len && input[pos] === '(') {
135
+ // Function call: emit FNAME then LPAREN
136
+ tokens.push({ type: 'FNAME', value: word, offset: start });
137
+ tokens.push({ type: 'LPAREN', value: '(', offset: pos });
138
+ pos++;
139
+ }
140
+ else {
141
+ // Bare identifier — text
142
+ tokens.push({ type: 'TEXT', value: word, offset: start });
143
+ }
144
+ continue;
145
+ }
146
+ // ---- 12. '(' not after an identifier: literal ----
147
+ if (ch === '(') {
148
+ tokens.push({ type: 'TEXT', value: '(', offset: pos });
149
+ pos++;
150
+ continue;
151
+ }
152
+ // ---- 13. Plain text accumulation ----
153
+ {
154
+ const start = pos;
155
+ while (pos < len) {
156
+ const c = input[pos];
157
+ // Stop at any character that starts a higher-priority rule
158
+ if (c === '\\' || c === '%' ||
159
+ c === '[' || c === ']' ||
160
+ c === '(' || c === ')' ||
161
+ c === ',' ||
162
+ isIdentStart(c)) {
163
+ break;
164
+ }
165
+ pos++;
166
+ }
167
+ if (pos > start) {
168
+ tokens.push({ type: 'TEXT', value: input.slice(start, pos), offset: start });
169
+ }
170
+ }
171
+ }
172
+ return tokens;
173
+ }
174
+ //# sourceMappingURL=tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/validator/tokenizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export type Severity = 'error' | 'warning';
2
+ /** A single diagnostic produced by the validator. */
3
+ export interface Diagnostic {
4
+ severity: Severity;
5
+ /** Error/warning code, e.g. 'E001', 'W002' */
6
+ code: string;
7
+ message: string;
8
+ /** Character offset in the original expression string */
9
+ offset: number;
10
+ /** Span length in characters (0 = point diagnostic) */
11
+ length: number;
12
+ }
13
+ /** Result returned by `validate()` */
14
+ export interface ValidationResult {
15
+ /** false if any diagnostic has severity 'error' */
16
+ valid: boolean;
17
+ diagnostics: Diagnostic[];
18
+ }
19
+ export type ASTNode = FunctionCallNode | BracketEvalNode | SubstitutionNode | RawTextNode;
20
+ /** A function call: `name(arg1, arg2, ...)` */
21
+ export interface FunctionCallNode {
22
+ type: 'FunctionCall';
23
+ /** Original casing preserved from source */
24
+ name: string;
25
+ /** Offset of the first character of the name */
26
+ nameOffset: number;
27
+ /**
28
+ * Each element is the list of nodes forming one argument.
29
+ * An empty inner array means an empty/missing argument.
30
+ */
31
+ args: ASTNode[][];
32
+ /** Offset of the opening parenthesis */
33
+ offset: number;
34
+ }
35
+ /** An inline evaluation: `[expression]` */
36
+ export interface BracketEvalNode {
37
+ type: 'BracketEval';
38
+ nodes: ASTNode[];
39
+ /** Offset of the '[' */
40
+ offset: number;
41
+ }
42
+ /** A percent-substitution: `%#`, `%N`, `%q0`, `%0`–`%9`, `%%`, etc. */
43
+ export interface SubstitutionNode {
44
+ type: 'Substitution';
45
+ /** The raw substitution text as it appears in the source */
46
+ raw: string;
47
+ offset: number;
48
+ }
49
+ /** Literal text or an escaped character that requires no further analysis */
50
+ export interface RawTextNode {
51
+ type: 'RawText';
52
+ value: string;
53
+ offset: number;
54
+ }
55
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/validator/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3C,qDAAqD;AACrD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,QAAQ,CAAC;IACnB,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,sCAAsC;AACtC,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAMD,MAAM,MAAM,OAAO,GACf,gBAAgB,GAChB,eAAe,GACf,gBAAgB,GAChB,WAAW,CAAC;AAEhB,+CAA+C;AAC/C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAClB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,cAAc,CAAC;IACrB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // Shared types for the RhostMUSH softcode validator
4
+ // ---------------------------------------------------------------------------
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/validator/types.ts"],"names":[],"mappings":";AAAA,8EAA8E;AAC9E,oDAAoD;AACpD,8EAA8E"}
@@ -0,0 +1,44 @@
1
+ export interface WatchOptions {
2
+ /** Absolute paths of test files to watch and run */
3
+ files: string[];
4
+ /** Debounce delay in ms before re-running after a change. Default: 300 */
5
+ debounceMs?: number;
6
+ /** Clear terminal between runs. Default: true */
7
+ clearScreen?: boolean;
8
+ }
9
+ export declare class RhostWatcher {
10
+ private readonly options;
11
+ private readonly debounceMs;
12
+ private readonly clearScreen;
13
+ private watcher;
14
+ private debounceTimer;
15
+ private pendingFiles;
16
+ private currentProcess;
17
+ private stopped;
18
+ private runCount;
19
+ constructor(options: WatchOptions);
20
+ /**
21
+ * Start watching. Runs an initial pass immediately, then re-runs on change.
22
+ * Blocks until `stop()` is called (or SIGINT).
23
+ */
24
+ start(): Promise<void>;
25
+ /** Graceful shutdown: cancel pending timers, close watcher, kill child. */
26
+ stop(): Promise<void>;
27
+ private setupWatcher;
28
+ private runFiles;
29
+ private spawnFile;
30
+ private printBanner;
31
+ private printRunHeader;
32
+ /**
33
+ * Find the longest common directory path shared by all given dirs.
34
+ * Falls back to '/' (or drive root on Windows) if nothing in common.
35
+ */
36
+ private commonRoot;
37
+ }
38
+ /**
39
+ * Recursively walk `rootDir` and return all test files matching
40
+ * `*.test.ts`, `*.test.js`, `*.spec.ts`, `*.spec.js`.
41
+ * Skips `node_modules`, `dist`, `.git`, `.next`, `.turbo`.
42
+ */
43
+ export declare function discoverTestFiles(rootDir: string): string[];
44
+ //# sourceMappingURL=watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAMD,qBAAa,YAAY;IAWX,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IAEtC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAK;gBAEQ,OAAO,EAAE,YAAY;IAKlD;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+B5B,2EAA2E;IACrE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B,OAAO,CAAC,YAAY;YA2CN,QAAQ;IAuBtB,OAAO,CAAC,SAAS;IAyCjB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,cAAc;IAqBtB;;;OAGG;IACH,OAAO,CAAC,UAAU;CAoBnB;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAI3D"}
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ // ---------------------------------------------------------------------------
3
+ // RhostWatcher — file-watch driven test re-runner
4
+ // ---------------------------------------------------------------------------
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.RhostWatcher = void 0;
40
+ exports.discoverTestFiles = discoverTestFiles;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const child_process_1 = require("child_process");
44
+ // ---------------------------------------------------------------------------
45
+ // RhostWatcher class
46
+ // ---------------------------------------------------------------------------
47
+ class RhostWatcher {
48
+ constructor(options) {
49
+ this.options = options;
50
+ this.watcher = null;
51
+ this.debounceTimer = null;
52
+ this.pendingFiles = new Set();
53
+ this.currentProcess = null;
54
+ this.stopped = false;
55
+ this.runCount = 0;
56
+ this.debounceMs = options.debounceMs ?? 300;
57
+ this.clearScreen = options.clearScreen !== false;
58
+ }
59
+ /**
60
+ * Start watching. Runs an initial pass immediately, then re-runs on change.
61
+ * Blocks until `stop()` is called (or SIGINT).
62
+ */
63
+ async start() {
64
+ const files = this.options.files;
65
+ if (files.length === 0) {
66
+ console.error('rhost-testkit: No test files to watch.');
67
+ return;
68
+ }
69
+ this.printBanner(files);
70
+ // Initial run
71
+ await this.runFiles(files, 'initial');
72
+ if (this.stopped)
73
+ return;
74
+ // Set up filesystem watching
75
+ const watchRoot = this.commonRoot(files.map((f) => path.dirname(f)));
76
+ this.setupWatcher(watchRoot, new Set(files.map((f) => path.resolve(f))));
77
+ // Block until stopped
78
+ await new Promise((resolve) => {
79
+ const poll = setInterval(() => {
80
+ if (this.stopped) {
81
+ clearInterval(poll);
82
+ resolve();
83
+ }
84
+ }, 100);
85
+ // Ensure this timer doesn't prevent Node from exiting naturally
86
+ if (typeof poll.unref === 'function')
87
+ poll.unref();
88
+ });
89
+ }
90
+ /** Graceful shutdown: cancel pending timers, close watcher, kill child. */
91
+ async stop() {
92
+ this.stopped = true;
93
+ if (this.debounceTimer) {
94
+ clearTimeout(this.debounceTimer);
95
+ this.debounceTimer = null;
96
+ }
97
+ if (this.watcher) {
98
+ this.watcher.close();
99
+ this.watcher = null;
100
+ }
101
+ if (this.currentProcess) {
102
+ try {
103
+ this.currentProcess.kill('SIGTERM');
104
+ }
105
+ catch {
106
+ // already exited
107
+ }
108
+ this.currentProcess = null;
109
+ }
110
+ }
111
+ // -------------------------------------------------------------------------
112
+ // Internal: filesystem watcher setup
113
+ // -------------------------------------------------------------------------
114
+ setupWatcher(watchRoot, testFileSet) {
115
+ try {
116
+ this.watcher = fs.watch(watchRoot, { recursive: true }, (event, filename) => {
117
+ if (!filename || this.stopped)
118
+ return;
119
+ const resolved = path.isAbsolute(filename)
120
+ ? filename
121
+ : path.resolve(watchRoot, filename);
122
+ if (!testFileSet.has(resolved))
123
+ return;
124
+ this.pendingFiles.add(resolved);
125
+ if (this.debounceTimer)
126
+ clearTimeout(this.debounceTimer);
127
+ this.debounceTimer = setTimeout(() => {
128
+ this.debounceTimer = null;
129
+ const changed = Array.from(this.pendingFiles);
130
+ this.pendingFiles.clear();
131
+ this.runFiles(changed, 'changed').catch((err) => {
132
+ console.error('Watch run error:', err.message);
133
+ });
134
+ }, this.debounceMs);
135
+ });
136
+ this.watcher.on('error', (err) => {
137
+ if (!this.stopped) {
138
+ console.error('\nWatcher error:', err.message);
139
+ }
140
+ });
141
+ }
142
+ catch (err) {
143
+ console.error(`\nrhost-testkit: Failed to start file watcher: ${err.message}`);
144
+ console.error('Tip: if you need recursive watching on older Linux, install chokidar: npm install chokidar --save-dev');
145
+ }
146
+ }
147
+ // -------------------------------------------------------------------------
148
+ // Internal: running files
149
+ // -------------------------------------------------------------------------
150
+ async runFiles(files, reason) {
151
+ if (this.stopped)
152
+ return;
153
+ // Kill any already-running child process
154
+ if (this.currentProcess) {
155
+ try {
156
+ this.currentProcess.kill('SIGTERM');
157
+ }
158
+ catch { /* ignore */ }
159
+ this.currentProcess = null;
160
+ }
161
+ this.runCount++;
162
+ if (this.clearScreen && this.runCount > 1) {
163
+ process.stdout.write('\x1b[2J\x1b[H');
164
+ }
165
+ this.printRunHeader(files, reason);
166
+ for (const file of files) {
167
+ if (this.stopped)
168
+ break;
169
+ await this.spawnFile(file);
170
+ }
171
+ }
172
+ spawnFile(file) {
173
+ return new Promise((resolve) => {
174
+ const ext = path.extname(file).toLowerCase();
175
+ const isTs = ext === '.ts' || ext === '.tsx';
176
+ // For TypeScript files, prefer ts-node via npx (always available in devDeps).
177
+ // For JS, use the current Node binary directly.
178
+ const cmd = isTs ? 'npx' : process.execPath;
179
+ const args = isTs ? ['ts-node', '--transpile-only', file] : [file];
180
+ const proc = (0, child_process_1.spawn)(cmd, args, {
181
+ stdio: 'inherit',
182
+ shell: false,
183
+ env: { ...process.env },
184
+ });
185
+ this.currentProcess = proc;
186
+ proc.on('close', () => {
187
+ this.currentProcess = null;
188
+ resolve();
189
+ });
190
+ proc.on('error', (err) => {
191
+ if (isTs && err.message.includes('ENOENT')) {
192
+ console.error(`\nrhost-testkit: could not find ts-node. Install it: npm install ts-node --save-dev`);
193
+ }
194
+ else {
195
+ console.error(`\nrhost-testkit: failed to run ${path.basename(file)}: ${err.message}`);
196
+ }
197
+ this.currentProcess = null;
198
+ resolve();
199
+ });
200
+ });
201
+ }
202
+ // -------------------------------------------------------------------------
203
+ // Internal: output formatting
204
+ // -------------------------------------------------------------------------
205
+ printBanner(files) {
206
+ const cwd = process.cwd();
207
+ const rel = files.map((f) => path.relative(cwd, f));
208
+ console.log('\x1b[36m╔══════════════════════════════════════════════════╗\x1b[0m');
209
+ console.log('\x1b[36m║\x1b[0m rhost-testkit \x1b[33mwatch mode\x1b[0m' + ' '.repeat(20) + '\x1b[36m║\x1b[0m');
210
+ console.log('\x1b[36m╚══════════════════════════════════════════════════╝\x1b[0m');
211
+ console.log(`\nWatching ${files.length} file${files.length !== 1 ? 's' : ''}:`);
212
+ for (const f of rel) {
213
+ console.log(` \x1b[90m${f}\x1b[0m`);
214
+ }
215
+ console.log('\nPress \x1b[1mCtrl+C\x1b[0m to stop.\n');
216
+ }
217
+ printRunHeader(files, reason) {
218
+ const sep = '─'.repeat(50);
219
+ const cwd = process.cwd();
220
+ const rel = files.map((f) => path.relative(cwd, f)).join(', ');
221
+ if (reason === 'initial') {
222
+ console.log(`\x1b[36m${sep}\x1b[0m`);
223
+ console.log(` \x1b[1mInitial run\x1b[0m — ${files.length} file${files.length !== 1 ? 's' : ''}`);
224
+ console.log(`\x1b[36m${sep}\x1b[0m\n`);
225
+ }
226
+ else {
227
+ const now = new Date().toLocaleTimeString();
228
+ console.log(`\x1b[33m${sep}\x1b[0m`);
229
+ console.log(` \x1b[1mChanged\x1b[0m [${now}]: \x1b[33m${rel}\x1b[0m`);
230
+ console.log(`\x1b[33m${sep}\x1b[0m\n`);
231
+ }
232
+ }
233
+ // -------------------------------------------------------------------------
234
+ // Internal: utilities
235
+ // -------------------------------------------------------------------------
236
+ /**
237
+ * Find the longest common directory path shared by all given dirs.
238
+ * Falls back to '/' (or drive root on Windows) if nothing in common.
239
+ */
240
+ commonRoot(dirs) {
241
+ if (dirs.length === 0)
242
+ return process.cwd();
243
+ if (dirs.length === 1)
244
+ return dirs[0];
245
+ const sep = path.sep;
246
+ const parts = dirs.map((d) => path.resolve(d).split(sep));
247
+ const reference = parts[0];
248
+ const common = [];
249
+ for (let i = 0; i < reference.length; i++) {
250
+ if (parts.every((p) => p[i] === reference[i])) {
251
+ common.push(reference[i]);
252
+ }
253
+ else {
254
+ break;
255
+ }
256
+ }
257
+ const result = common.join(sep);
258
+ return result || sep;
259
+ }
260
+ }
261
+ exports.RhostWatcher = RhostWatcher;
262
+ // ---------------------------------------------------------------------------
263
+ // File discovery helper (used by the CLI)
264
+ // ---------------------------------------------------------------------------
265
+ /**
266
+ * Recursively walk `rootDir` and return all test files matching
267
+ * `*.test.ts`, `*.test.js`, `*.spec.ts`, `*.spec.js`.
268
+ * Skips `node_modules`, `dist`, `.git`, `.next`, `.turbo`.
269
+ */
270
+ function discoverTestFiles(rootDir) {
271
+ const files = [];
272
+ walkDir(path.resolve(rootDir), files);
273
+ return files;
274
+ }
275
+ const SKIP_DIRS = new Set(['node_modules', 'dist', '.git', '.next', '.turbo', 'coverage']);
276
+ const TEST_FILE_RE = /\.(test|spec)\.(ts|tsx|js|jsx)$/;
277
+ function walkDir(dir, out) {
278
+ if (SKIP_DIRS.has(path.basename(dir)))
279
+ return;
280
+ let entries;
281
+ try {
282
+ entries = fs.readdirSync(dir, { withFileTypes: true });
283
+ }
284
+ catch {
285
+ return;
286
+ }
287
+ for (const entry of entries) {
288
+ const full = path.join(dir, entry.name);
289
+ if (entry.isDirectory()) {
290
+ walkDir(full, out);
291
+ }
292
+ else if (entry.isFile() && TEST_FILE_RE.test(entry.name)) {
293
+ out.push(full);
294
+ }
295
+ }
296
+ }
297
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}