@nsxbet/playwright-orchestrator 0.2.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 +161 -0
- package/bin/run.js +5 -0
- package/dist/commands/assign.d.ts +23 -0
- package/dist/commands/assign.d.ts.map +1 -0
- package/dist/commands/assign.js +256 -0
- package/dist/commands/assign.js.map +1 -0
- package/dist/commands/extract-timing.d.ts +40 -0
- package/dist/commands/extract-timing.d.ts.map +1 -0
- package/dist/commands/extract-timing.js +196 -0
- package/dist/commands/extract-timing.js.map +1 -0
- package/dist/commands/list-tests.d.ts +16 -0
- package/dist/commands/list-tests.d.ts.map +1 -0
- package/dist/commands/list-tests.js +98 -0
- package/dist/commands/list-tests.js.map +1 -0
- package/dist/commands/merge-timing.d.ts +19 -0
- package/dist/commands/merge-timing.d.ts.map +1 -0
- package/dist/commands/merge-timing.js +217 -0
- package/dist/commands/merge-timing.js.map +1 -0
- package/dist/core/ckk-algorithm.d.ts +38 -0
- package/dist/core/ckk-algorithm.d.ts.map +1 -0
- package/dist/core/ckk-algorithm.js +192 -0
- package/dist/core/ckk-algorithm.js.map +1 -0
- package/dist/core/estimate.d.ts +72 -0
- package/dist/core/estimate.d.ts.map +1 -0
- package/dist/core/estimate.js +142 -0
- package/dist/core/estimate.js.map +1 -0
- package/dist/core/grep-pattern.d.ts +61 -0
- package/dist/core/grep-pattern.d.ts.map +1 -0
- package/dist/core/grep-pattern.js +104 -0
- package/dist/core/grep-pattern.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lpt-algorithm.d.ts +28 -0
- package/dist/core/lpt-algorithm.d.ts.map +1 -0
- package/dist/core/lpt-algorithm.js +80 -0
- package/dist/core/lpt-algorithm.js.map +1 -0
- package/dist/core/slugify.d.ts +13 -0
- package/dist/core/slugify.d.ts.map +1 -0
- package/dist/core/slugify.js +19 -0
- package/dist/core/slugify.js.map +1 -0
- package/dist/core/test-discovery.d.ts +46 -0
- package/dist/core/test-discovery.d.ts.map +1 -0
- package/dist/core/test-discovery.js +192 -0
- package/dist/core/test-discovery.js.map +1 -0
- package/dist/core/timing-store.d.ts +90 -0
- package/dist/core/timing-store.d.ts.map +1 -0
- package/dist/core/timing-store.js +280 -0
- package/dist/core/timing-store.js.map +1 -0
- package/dist/core/types.d.ts +241 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +54 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import { createEmptyTimingData, isTimingDataV1, isTimingDataV2, TIMING_DATA_VERSION, TIMING_DATA_VERSION_V1, } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Default EMA smoothing factor (alpha)
|
|
5
|
+
* Higher values give more weight to recent measurements
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_EMA_ALPHA = 0.3;
|
|
8
|
+
/**
|
|
9
|
+
* Default number of days after which to prune old entries
|
|
10
|
+
*/
|
|
11
|
+
export const DEFAULT_PRUNE_DAYS = 30;
|
|
12
|
+
/**
|
|
13
|
+
* Load timing data from a JSON file
|
|
14
|
+
*
|
|
15
|
+
* Supports both v1 (file-level) and v2 (test-level) formats.
|
|
16
|
+
*
|
|
17
|
+
* @param filePath - Path to the timing data JSON file
|
|
18
|
+
* @returns Timing data, or empty data if file doesn't exist
|
|
19
|
+
*/
|
|
20
|
+
export function loadTimingData(filePath) {
|
|
21
|
+
try {
|
|
22
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
23
|
+
const data = JSON.parse(content);
|
|
24
|
+
// Handle v1 format
|
|
25
|
+
if (data.version === TIMING_DATA_VERSION_V1) {
|
|
26
|
+
// Return as-is for backwards compatibility
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
// Handle v2 format
|
|
30
|
+
if (data.version === TIMING_DATA_VERSION) {
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
// Unknown version - return empty v2 data
|
|
34
|
+
console.warn(`Timing data version mismatch: expected ${TIMING_DATA_VERSION}, got ${data.version}. Using empty data.`);
|
|
35
|
+
return createEmptyTimingData();
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// File doesn't exist or is invalid - return empty data
|
|
39
|
+
return createEmptyTimingData();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Save timing data to a JSON file
|
|
44
|
+
*/
|
|
45
|
+
export function saveTimingData(filePath, data) {
|
|
46
|
+
const content = JSON.stringify(data, null, 2);
|
|
47
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Calculate Exponential Moving Average for duration
|
|
51
|
+
*
|
|
52
|
+
* Formula: newDuration = α * measuredDuration + (1 - α) * oldDuration
|
|
53
|
+
*
|
|
54
|
+
* @param oldDuration - Previous duration value
|
|
55
|
+
* @param newDuration - New measured duration
|
|
56
|
+
* @param alpha - Smoothing factor (0-1), higher = more weight on new value
|
|
57
|
+
*/
|
|
58
|
+
export function calculateEMA(oldDuration, newDuration, alpha = DEFAULT_EMA_ALPHA) {
|
|
59
|
+
return Math.round(alpha * newDuration + (1 - alpha) * oldDuration);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Merge new timing measurements into existing timing data using EMA (v1 - file-level)
|
|
63
|
+
*
|
|
64
|
+
* @param existing - Existing timing data (v1)
|
|
65
|
+
* @param newMeasurements - New measurements from shard artifacts
|
|
66
|
+
* @param alpha - EMA smoothing factor
|
|
67
|
+
* @returns Updated timing data
|
|
68
|
+
*/
|
|
69
|
+
export function mergeTimingData(existing, newMeasurements, alpha = DEFAULT_EMA_ALPHA) {
|
|
70
|
+
const now = new Date().toISOString();
|
|
71
|
+
// Convert v2 to v1 if needed (lossy - just take file names)
|
|
72
|
+
const existingFiles = isTimingDataV1(existing)
|
|
73
|
+
? existing.files
|
|
74
|
+
: aggregateTestsToFiles(existing);
|
|
75
|
+
const merged = {
|
|
76
|
+
version: TIMING_DATA_VERSION_V1,
|
|
77
|
+
updatedAt: now,
|
|
78
|
+
files: { ...existingFiles },
|
|
79
|
+
};
|
|
80
|
+
for (const artifact of newMeasurements) {
|
|
81
|
+
for (const [file, duration] of Object.entries(artifact.files)) {
|
|
82
|
+
const existingData = merged.files[file];
|
|
83
|
+
if (existingData) {
|
|
84
|
+
// Apply EMA to existing data
|
|
85
|
+
merged.files[file] = {
|
|
86
|
+
duration: calculateEMA(existingData.duration, duration, alpha),
|
|
87
|
+
runs: existingData.runs + 1,
|
|
88
|
+
lastRun: now,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// First measurement for this file
|
|
93
|
+
merged.files[file] = {
|
|
94
|
+
duration,
|
|
95
|
+
runs: 1,
|
|
96
|
+
lastRun: now,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return merged;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Merge new timing measurements into existing timing data using EMA (v2 - test-level)
|
|
105
|
+
*
|
|
106
|
+
* @param existing - Existing timing data (v2)
|
|
107
|
+
* @param newMeasurements - New measurements from shard artifacts
|
|
108
|
+
* @param alpha - EMA smoothing factor
|
|
109
|
+
* @returns Updated timing data
|
|
110
|
+
*/
|
|
111
|
+
export function mergeTestTimingData(existing, newMeasurements, alpha = DEFAULT_EMA_ALPHA) {
|
|
112
|
+
const now = new Date().toISOString();
|
|
113
|
+
const merged = {
|
|
114
|
+
version: TIMING_DATA_VERSION,
|
|
115
|
+
updatedAt: now,
|
|
116
|
+
tests: existing ? { ...existing.tests } : {},
|
|
117
|
+
};
|
|
118
|
+
for (const artifact of newMeasurements) {
|
|
119
|
+
for (const [testId, duration] of Object.entries(artifact.tests)) {
|
|
120
|
+
const existingData = merged.tests[testId];
|
|
121
|
+
const file = extractFileFromTestId(testId);
|
|
122
|
+
if (existingData) {
|
|
123
|
+
// Apply EMA to existing data
|
|
124
|
+
merged.tests[testId] = {
|
|
125
|
+
file: existingData.file,
|
|
126
|
+
duration: calculateEMA(existingData.duration, duration, alpha),
|
|
127
|
+
runs: existingData.runs + 1,
|
|
128
|
+
lastRun: now,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// First measurement for this test
|
|
133
|
+
merged.tests[testId] = {
|
|
134
|
+
file,
|
|
135
|
+
duration,
|
|
136
|
+
runs: 1,
|
|
137
|
+
lastRun: now,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return merged;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Extract file name from test ID
|
|
146
|
+
*/
|
|
147
|
+
function extractFileFromTestId(testId) {
|
|
148
|
+
const parts = testId.split('::');
|
|
149
|
+
return parts[0] ?? '';
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Aggregate test-level timing to file-level (for backwards compatibility)
|
|
153
|
+
*/
|
|
154
|
+
function aggregateTestsToFiles(data) {
|
|
155
|
+
const fileMap = new Map();
|
|
156
|
+
for (const testData of Object.values(data.tests)) {
|
|
157
|
+
const existing = fileMap.get(testData.file);
|
|
158
|
+
if (existing) {
|
|
159
|
+
existing.totalDuration += testData.duration;
|
|
160
|
+
existing.count += 1;
|
|
161
|
+
if (testData.lastRun > existing.lastRun) {
|
|
162
|
+
existing.lastRun = testData.lastRun;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
fileMap.set(testData.file, {
|
|
167
|
+
totalDuration: testData.duration,
|
|
168
|
+
count: 1,
|
|
169
|
+
lastRun: testData.lastRun,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const result = {};
|
|
174
|
+
for (const [file, stats] of fileMap) {
|
|
175
|
+
result[file] = {
|
|
176
|
+
duration: stats.totalDuration,
|
|
177
|
+
runs: stats.count,
|
|
178
|
+
lastRun: stats.lastRun,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Prune old entries from timing data (v1 - file-level)
|
|
185
|
+
*
|
|
186
|
+
* Removes entries that:
|
|
187
|
+
* 1. Haven't been run in more than `days` days
|
|
188
|
+
* 2. No longer exist in the current test files (if provided)
|
|
189
|
+
*
|
|
190
|
+
* @param data - Timing data to prune
|
|
191
|
+
* @param days - Number of days after which to remove entries
|
|
192
|
+
* @param currentFiles - Optional list of current test files (to remove deleted tests)
|
|
193
|
+
* @returns Pruned timing data
|
|
194
|
+
*/
|
|
195
|
+
export function pruneTimingData(data, days = DEFAULT_PRUNE_DAYS, currentFiles) {
|
|
196
|
+
if (isTimingDataV2(data)) {
|
|
197
|
+
return pruneTestTimingData(data, days, currentFiles);
|
|
198
|
+
}
|
|
199
|
+
const now = new Date();
|
|
200
|
+
const cutoffDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
|
|
201
|
+
const currentFileSet = currentFiles ? new Set(currentFiles) : null;
|
|
202
|
+
const prunedFiles = {};
|
|
203
|
+
for (const [file, timing] of Object.entries(data.files)) {
|
|
204
|
+
const lastRun = new Date(timing.lastRun);
|
|
205
|
+
// Skip if too old
|
|
206
|
+
if (lastRun < cutoffDate) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
// Skip if file no longer exists (when currentFiles is provided)
|
|
210
|
+
if (currentFileSet && !currentFileSet.has(file)) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
prunedFiles[file] = timing;
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
...data,
|
|
217
|
+
updatedAt: new Date().toISOString(),
|
|
218
|
+
files: prunedFiles,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Prune old entries from timing data (v2 - test-level)
|
|
223
|
+
*
|
|
224
|
+
* @param data - Timing data to prune
|
|
225
|
+
* @param days - Number of days after which to remove entries
|
|
226
|
+
* @param currentTestIds - Optional list of current test IDs (to remove deleted tests)
|
|
227
|
+
* @returns Pruned timing data
|
|
228
|
+
*/
|
|
229
|
+
export function pruneTestTimingData(data, days = DEFAULT_PRUNE_DAYS, currentTestIds) {
|
|
230
|
+
const now = new Date();
|
|
231
|
+
const cutoffDate = new Date(now.getTime() - days * 24 * 60 * 60 * 1000);
|
|
232
|
+
const currentTestSet = currentTestIds ? new Set(currentTestIds) : null;
|
|
233
|
+
const prunedTests = {};
|
|
234
|
+
for (const [testId, timing] of Object.entries(data.tests)) {
|
|
235
|
+
const lastRun = new Date(timing.lastRun);
|
|
236
|
+
// Skip if too old
|
|
237
|
+
if (lastRun < cutoffDate) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
// Skip if test no longer exists (when currentTestIds is provided)
|
|
241
|
+
if (currentTestSet && !currentTestSet.has(testId)) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
prunedTests[testId] = timing;
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
...data,
|
|
248
|
+
updatedAt: new Date().toISOString(),
|
|
249
|
+
tests: prunedTests,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get duration for a file from timing data (v1)
|
|
254
|
+
*
|
|
255
|
+
* @param data - Timing data
|
|
256
|
+
* @param file - File name
|
|
257
|
+
* @returns Duration in ms, or undefined if not found
|
|
258
|
+
*/
|
|
259
|
+
export function getFileDuration(data, file) {
|
|
260
|
+
if (isTimingDataV1(data)) {
|
|
261
|
+
return data.files[file]?.duration;
|
|
262
|
+
}
|
|
263
|
+
// For v2 data, aggregate tests in this file
|
|
264
|
+
const fileTests = Object.entries(data.tests).filter(([, t]) => t.file === file);
|
|
265
|
+
if (fileTests.length === 0) {
|
|
266
|
+
return undefined;
|
|
267
|
+
}
|
|
268
|
+
return fileTests.reduce((sum, [, t]) => sum + t.duration, 0);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Get duration for a test from timing data (v2)
|
|
272
|
+
*
|
|
273
|
+
* @param data - Timing data (v2)
|
|
274
|
+
* @param testId - Test ID
|
|
275
|
+
* @returns Duration in ms, or undefined if not found
|
|
276
|
+
*/
|
|
277
|
+
export function getTestDuration(data, testId) {
|
|
278
|
+
return data.tests[testId]?.duration;
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=timing-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timing-store.js","sourceRoot":"","sources":["../../src/core/timing-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAU9B,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAG9B,CAAC;QAEF,mBAAmB;QACnB,IAAI,IAAI,CAAC,OAAO,KAAK,sBAAsB,EAAE,CAAC;YAC5C,2CAA2C;YAC3C,OAAO,IAA+B,CAAC;QACzC,CAAC;QAED,mBAAmB;QACnB,IAAI,IAAI,CAAC,OAAO,KAAK,mBAAmB,EAAE,CAAC;YACzC,OAAO,IAA+B,CAAC;QACzC,CAAC;QAED,yCAAyC;QACzC,OAAO,CAAC,IAAI,CACV,0CAA0C,mBAAmB,SAAS,IAAI,CAAC,OAAO,qBAAqB,CACxG,CAAC;QACF,OAAO,qBAAqB,EAAE,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;QACvD,OAAO,qBAAqB,EAAE,CAAC;IACjC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,IAAgB;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,WAAmB,EACnB,WAAmB,EACnB,QAAgB,iBAAiB;IAEjC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAoB,EACpB,eAAsC,EACtC,QAAgB,iBAAiB;IAEjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,4DAA4D;IAC5D,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC;QAC5C,CAAC,CAAC,QAAQ,CAAC,KAAK;QAChB,CAAC,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAiB;QAC3B,OAAO,EAAE,sBAAsB;QAC/B,SAAS,EAAE,GAAG;QACd,KAAK,EAAE,EAAE,GAAG,aAAa,EAAE;KAC5B,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAExC,IAAI,YAAY,EAAE,CAAC;gBACjB,6BAA6B;gBAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;oBACnB,QAAQ,EAAE,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC;oBAC9D,IAAI,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC;oBAC3B,OAAO,EAAE,GAAG;iBACb,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,kCAAkC;gBAClC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;oBACnB,QAAQ;oBACR,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,GAAG;iBACb,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,QAA6B,EAC7B,eAA0C,EAC1C,QAAgB,iBAAiB;IAEjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,MAAM,MAAM,GAAiB;QAC3B,OAAO,EAAE,mBAAmB;QAC5B,SAAS,EAAE,GAAG;QACd,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;KAC7C,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,eAAe,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,IAAI,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;YAE3C,IAAI,YAAY,EAAE,CAAC;gBACjB,6BAA6B;gBAC7B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;oBACrB,IAAI,EAAE,YAAY,CAAC,IAAI;oBACvB,QAAQ,EAAE,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC;oBAC9D,IAAI,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC;oBAC3B,OAAO,EAAE,GAAG;iBACb,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,kCAAkC;gBAClC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG;oBACrB,IAAI;oBACJ,QAAQ;oBACR,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,GAAG;iBACb,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,MAAc;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAC5B,IAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,GAAG,EAGpB,CAAC;IAEJ,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,QAAQ,CAAC;YAC5C,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;YACpB,IAAI,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACxC,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACtC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;gBACzB,aAAa,EAAE,QAAQ,CAAC,QAAQ;gBAChC,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,QAAQ,CAAC,OAAO;aAC1B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAmC,EAAE,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,GAAG;YACb,QAAQ,EAAE,KAAK,CAAC,aAAa;YAC7B,IAAI,EAAE,KAAK,CAAC,KAAK;YACjB,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAgB,EAChB,OAAe,kBAAkB,EACjC,YAAuB;IAEvB,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEnE,MAAM,WAAW,GAAmC,EAAE,CAAC;IAEvD,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzC,kBAAkB;QAClB,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;YACzB,SAAS;QACX,CAAC;QAED,gEAAgE;QAChE,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,SAAS;QACX,CAAC;QAED,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED,OAAO;QACL,GAAG,IAAI;QACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,WAAW;KACnB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAkB,EAClB,OAAe,kBAAkB,EACjC,cAAyB;IAEzB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACxE,MAAM,cAAc,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,MAAM,WAAW,GAAmC,EAAE,CAAC;IAEvD,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzC,kBAAkB;QAClB,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;YACzB,SAAS;QACX,CAAC;QAED,kEAAkE;QAClE,IAAI,cAAc,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,SAAS;QACX,CAAC;QAED,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,GAAG,IAAI;QACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,WAAW;KACnB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAgB,EAChB,IAAY;IAEZ,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IACpC,CAAC;IAED,4CAA4C;IAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CACjD,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAC3B,CAAC;IACF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAkB,EAClB,MAAc;IAEd,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Timing data for a single test file (legacy v1 format)
|
|
3
|
+
*/
|
|
4
|
+
export interface FileTimingData {
|
|
5
|
+
/** Duration in milliseconds */
|
|
6
|
+
duration: number;
|
|
7
|
+
/** Number of times this file has been measured */
|
|
8
|
+
runs: number;
|
|
9
|
+
/** ISO timestamp of last measurement */
|
|
10
|
+
lastRun: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Timing data for a single test (v2 format - test-level)
|
|
14
|
+
*/
|
|
15
|
+
export interface TestTimingData {
|
|
16
|
+
/** Source file containing this test */
|
|
17
|
+
file: string;
|
|
18
|
+
/** Duration in milliseconds */
|
|
19
|
+
duration: number;
|
|
20
|
+
/** Number of times this test has been measured */
|
|
21
|
+
runs: number;
|
|
22
|
+
/** ISO timestamp of last measurement */
|
|
23
|
+
lastRun: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Complete timing data structure stored in cache (v1 - file-level)
|
|
27
|
+
*/
|
|
28
|
+
export interface TimingDataV1 {
|
|
29
|
+
/** Schema version (1) */
|
|
30
|
+
version: 1;
|
|
31
|
+
/** ISO timestamp of last update */
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
/** Map of file names to their timing data */
|
|
34
|
+
files: Record<string, FileTimingData>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Complete timing data structure stored in cache (v2 - test-level)
|
|
38
|
+
*/
|
|
39
|
+
export interface TimingDataV2 {
|
|
40
|
+
/** Schema version (2) */
|
|
41
|
+
version: 2;
|
|
42
|
+
/** ISO timestamp of last update */
|
|
43
|
+
updatedAt: string;
|
|
44
|
+
/** Map of test IDs to their timing data */
|
|
45
|
+
tests: Record<string, TestTimingData>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Union type for timing data (supports both versions)
|
|
49
|
+
*/
|
|
50
|
+
export type TimingData = TimingDataV1 | TimingDataV2;
|
|
51
|
+
/**
|
|
52
|
+
* Input for the shard assignment algorithm (file-level)
|
|
53
|
+
*/
|
|
54
|
+
export interface FileWithDuration {
|
|
55
|
+
/** File path (relative to test directory) */
|
|
56
|
+
file: string;
|
|
57
|
+
/** Duration in milliseconds */
|
|
58
|
+
duration: number;
|
|
59
|
+
/** Whether the duration was estimated (no historical data) */
|
|
60
|
+
estimated: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Input for the shard assignment algorithm (test-level)
|
|
64
|
+
*/
|
|
65
|
+
export interface TestWithDuration {
|
|
66
|
+
/** Test ID in format: file::describe::testTitle */
|
|
67
|
+
testId: string;
|
|
68
|
+
/** Source file */
|
|
69
|
+
file: string;
|
|
70
|
+
/** Duration in milliseconds */
|
|
71
|
+
duration: number;
|
|
72
|
+
/** Whether the duration was estimated (no historical data) */
|
|
73
|
+
estimated: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Output of the shard assignment algorithm (file-level)
|
|
77
|
+
*/
|
|
78
|
+
export interface ShardAssignment {
|
|
79
|
+
/** Shard index (1-based) */
|
|
80
|
+
shardIndex: number;
|
|
81
|
+
/** List of test files assigned to this shard */
|
|
82
|
+
files: string[];
|
|
83
|
+
/** Expected total duration in milliseconds */
|
|
84
|
+
expectedDuration: number;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Output of the shard assignment algorithm (test-level)
|
|
88
|
+
*/
|
|
89
|
+
export interface TestShardAssignment {
|
|
90
|
+
/** Shard index (1-based) */
|
|
91
|
+
shardIndex: number;
|
|
92
|
+
/** List of test IDs assigned to this shard */
|
|
93
|
+
tests: string[];
|
|
94
|
+
/** Expected total duration in milliseconds */
|
|
95
|
+
expectedDuration: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Complete result from the assign command (file-level)
|
|
99
|
+
*/
|
|
100
|
+
export interface AssignResult {
|
|
101
|
+
/** Map of shard index to list of files */
|
|
102
|
+
shards: Record<number, string[]>;
|
|
103
|
+
/** Expected duration per shard */
|
|
104
|
+
expectedDurations: Record<number, number>;
|
|
105
|
+
/** Total number of files */
|
|
106
|
+
totalFiles: number;
|
|
107
|
+
/** Files that had no timing data (estimated) */
|
|
108
|
+
estimatedFiles: string[];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Complete result from the assign command (test-level)
|
|
112
|
+
*/
|
|
113
|
+
export interface TestAssignResult {
|
|
114
|
+
/** Map of shard index to list of test IDs */
|
|
115
|
+
shards: Record<number, string[]>;
|
|
116
|
+
/** Map of shard index to grep pattern */
|
|
117
|
+
grepPatterns: Record<number, string>;
|
|
118
|
+
/** Expected duration per shard */
|
|
119
|
+
expectedDurations: Record<number, number>;
|
|
120
|
+
/** Total number of tests */
|
|
121
|
+
totalTests: number;
|
|
122
|
+
/** Tests that had no timing data (estimated) */
|
|
123
|
+
estimatedTests: string[];
|
|
124
|
+
/** Whether CKK found optimal solution (false = fell back to LPT) */
|
|
125
|
+
isOptimal: boolean;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Per-shard timing artifact uploaded after test run (file-level, v1)
|
|
129
|
+
*/
|
|
130
|
+
export interface ShardTimingArtifact {
|
|
131
|
+
/** Shard index (1-based) */
|
|
132
|
+
shard: number;
|
|
133
|
+
/** Browser project name */
|
|
134
|
+
project: string;
|
|
135
|
+
/** Map of file names to duration in ms */
|
|
136
|
+
files: Record<string, number>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Per-shard timing artifact uploaded after test run (test-level, v2)
|
|
140
|
+
*/
|
|
141
|
+
export interface TestShardTimingArtifact {
|
|
142
|
+
/** Shard index (1-based) */
|
|
143
|
+
shard: number;
|
|
144
|
+
/** Browser project name */
|
|
145
|
+
project: string;
|
|
146
|
+
/** Map of test IDs to duration in ms */
|
|
147
|
+
tests: Record<string, number>;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Information about a discovered test
|
|
151
|
+
*/
|
|
152
|
+
export interface DiscoveredTest {
|
|
153
|
+
/** Source file path */
|
|
154
|
+
file: string;
|
|
155
|
+
/** Test title */
|
|
156
|
+
title: string;
|
|
157
|
+
/** Full title path (describe blocks + test title) */
|
|
158
|
+
titlePath: string[];
|
|
159
|
+
/** Unique test ID: file::describe::testTitle */
|
|
160
|
+
testId: string;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Playwright JSON report structure (relevant fields only)
|
|
164
|
+
*/
|
|
165
|
+
export interface PlaywrightReport {
|
|
166
|
+
suites: PlaywrightSuite[];
|
|
167
|
+
}
|
|
168
|
+
export interface PlaywrightSuite {
|
|
169
|
+
title: string;
|
|
170
|
+
file: string;
|
|
171
|
+
suites?: PlaywrightSuite[];
|
|
172
|
+
specs?: PlaywrightSpec[];
|
|
173
|
+
}
|
|
174
|
+
export interface PlaywrightSpec {
|
|
175
|
+
title: string;
|
|
176
|
+
tests: PlaywrightTest[];
|
|
177
|
+
}
|
|
178
|
+
export interface PlaywrightTest {
|
|
179
|
+
results: PlaywrightTestResult[];
|
|
180
|
+
}
|
|
181
|
+
export interface PlaywrightTestResult {
|
|
182
|
+
duration: number;
|
|
183
|
+
status: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Playwright --list JSON output structure
|
|
187
|
+
*/
|
|
188
|
+
export interface PlaywrightListOutput {
|
|
189
|
+
config: {
|
|
190
|
+
projects: Array<{
|
|
191
|
+
name: string;
|
|
192
|
+
testDir: string;
|
|
193
|
+
}>;
|
|
194
|
+
};
|
|
195
|
+
suites: PlaywrightListSuite[];
|
|
196
|
+
}
|
|
197
|
+
export interface PlaywrightListSuite {
|
|
198
|
+
title: string;
|
|
199
|
+
file: string;
|
|
200
|
+
suites?: PlaywrightListSuite[];
|
|
201
|
+
specs?: PlaywrightListSpec[];
|
|
202
|
+
}
|
|
203
|
+
export interface PlaywrightListSpec {
|
|
204
|
+
title: string;
|
|
205
|
+
file: string;
|
|
206
|
+
line: number;
|
|
207
|
+
column: number;
|
|
208
|
+
}
|
|
209
|
+
/** Current schema version for timing data */
|
|
210
|
+
export declare const TIMING_DATA_VERSION = 2;
|
|
211
|
+
/** Legacy schema version */
|
|
212
|
+
export declare const TIMING_DATA_VERSION_V1 = 1;
|
|
213
|
+
/**
|
|
214
|
+
* Create an empty timing data structure (v2 - test-level)
|
|
215
|
+
*/
|
|
216
|
+
export declare function createEmptyTimingData(): TimingDataV2;
|
|
217
|
+
/**
|
|
218
|
+
* Create an empty timing data structure (v1 - file-level, for backwards compatibility)
|
|
219
|
+
*/
|
|
220
|
+
export declare function createEmptyTimingDataV1(): TimingDataV1;
|
|
221
|
+
/**
|
|
222
|
+
* Build a test ID from file and title path
|
|
223
|
+
* Format: file::describe1::describe2::testTitle
|
|
224
|
+
*/
|
|
225
|
+
export declare function buildTestId(file: string, titlePath: string[]): string;
|
|
226
|
+
/**
|
|
227
|
+
* Parse a test ID back to file and title path
|
|
228
|
+
*/
|
|
229
|
+
export declare function parseTestId(testId: string): {
|
|
230
|
+
file: string;
|
|
231
|
+
titlePath: string[];
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Check if timing data is v2 (test-level)
|
|
235
|
+
*/
|
|
236
|
+
export declare function isTimingDataV2(data: TimingData): data is TimingDataV2;
|
|
237
|
+
/**
|
|
238
|
+
* Check if timing data is v1 (file-level)
|
|
239
|
+
*/
|
|
240
|
+
export declare function isTimingDataV1(data: TimingData): data is TimingDataV1;
|
|
241
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Current schema version for timing data */
|
|
2
|
+
export const TIMING_DATA_VERSION = 2;
|
|
3
|
+
/** Legacy schema version */
|
|
4
|
+
export const TIMING_DATA_VERSION_V1 = 1;
|
|
5
|
+
/**
|
|
6
|
+
* Create an empty timing data structure (v2 - test-level)
|
|
7
|
+
*/
|
|
8
|
+
export function createEmptyTimingData() {
|
|
9
|
+
return {
|
|
10
|
+
version: TIMING_DATA_VERSION,
|
|
11
|
+
updatedAt: new Date().toISOString(),
|
|
12
|
+
tests: {},
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create an empty timing data structure (v1 - file-level, for backwards compatibility)
|
|
17
|
+
*/
|
|
18
|
+
export function createEmptyTimingDataV1() {
|
|
19
|
+
return {
|
|
20
|
+
version: TIMING_DATA_VERSION_V1,
|
|
21
|
+
updatedAt: new Date().toISOString(),
|
|
22
|
+
files: {},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build a test ID from file and title path
|
|
27
|
+
* Format: file::describe1::describe2::testTitle
|
|
28
|
+
*/
|
|
29
|
+
export function buildTestId(file, titlePath) {
|
|
30
|
+
return [file, ...titlePath].join('::');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse a test ID back to file and title path
|
|
34
|
+
*/
|
|
35
|
+
export function parseTestId(testId) {
|
|
36
|
+
const parts = testId.split('::');
|
|
37
|
+
return {
|
|
38
|
+
file: parts[0] ?? '',
|
|
39
|
+
titlePath: parts.slice(1),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Check if timing data is v2 (test-level)
|
|
44
|
+
*/
|
|
45
|
+
export function isTimingDataV2(data) {
|
|
46
|
+
return data.version === 2;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Check if timing data is v1 (file-level)
|
|
50
|
+
*/
|
|
51
|
+
export function isTimingDataV1(data) {
|
|
52
|
+
return data.version === 1;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAsOA,6CAA6C;AAC7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,4BAA4B;AAC5B,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,OAAO,EAAE,mBAAmB;QAC5B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,OAAO,EAAE,sBAAsB;QAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,EAAE;KACV,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,SAAmB;IAC3D,OAAO,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IAIxC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;QACpB,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,OAAO,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAgB;IAC7C,OAAO,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC;AAC5B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAChC,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAChC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|