Setting the file. One moment.
Lib · Browser Trace · browserbase/skills · Skills Docs
ContentsBack to the top of the page 87
export function sleepMs
— line 87
This file
Number 4.4
Position 4 of 12
Type JavaScript
Size 4 KB
Lines 118 scripts/ lib.mjs
JavaScript · 118 lines · 4 KB
O11Y_ROOT
||
'.o11y'
;
12 }
13
14 export function runDir ( runId ) {
15 return path. join ( runRoot (), runId);
16 }
17
18 export function ensureDir ( p ) {
19 fs. mkdirSync (p, { recursive: true });
20 }
21
22 // Wall-clock ISO seconds, no fractional part — same shape as `date -u +%Y-%m-%dT%H:%M:%SZ`.
23 export function isoUtcSeconds ( d = new Date ()) {
24 return d. toISOString (). replace ( / \. \d + / , '' );
25 }
26
27 // Compact UTC stamp suitable for filenames: 20260427T175533Z (no separators).
28 export function isoStampForFilename ( d = new Date ()) {
29 return d. toISOString (). replace ( / [-:] / g , '' ). replace ( / \. \d + / , '' );
30 }
31
32 export function readJson ( p , fallback = null ) {
33 if ( ! fs. existsSync (p)) return fallback;
34 try { return JSON . parse (fs. readFileSync (p, 'utf8' )); }
35 catch { return fallback; }
36 }
37
38 export function writeJson ( p , obj ) {
39 ensureDir (path. dirname (p));
40 fs. writeFileSync (p, JSON . stringify (obj, null , 2 ) + ' \n ' );
41 }
42
43 // Stream a JSONL file line-by-line. Returns parsed objects, skipping bad lines.
44 export function readJsonl ( p ) {
45 if ( ! fs. existsSync (p)) return [];
46 const out = [];
47 for ( const line of fs. readFileSync (p, 'utf8' ). split ( ' \n ' )) {
48 if ( ! line) continue ;
49 try { out. push ( JSON . parse (line)); } catch { /* skip */ }
50 }
51 return out;
52 }
53
54 // Atomic-ish JSONL write: caller has already mutated the array as desired.
55 // `skipEmpty: true` removes the file if there's nothing to write — used by per-page bucketing.
56 export function writeJsonl ( p , items , { skipEmpty = false } = {}) {
57 if (skipEmpty && items. length === 0 ) {
58 if (fs. existsSync (p)) fs. unlinkSync (p);
59 return ;
60 }
61 ensureDir (path. dirname (p));
62 const body = items. length ? items. map ( o => JSON . stringify (o)). join ( ' \n ' ) + ' \n ' : '' ;
63 fs. writeFileSync (p, body);
64 }
65
66 export function isAlive ( pid ) {
67 if ( ! Number. isInteger (pid)) return false ;
68 try { process. kill (pid, 0 ); return true ; } catch { return false ; }
69 }
70
71 // Wrap execFileSync so transient "exit non-zero" doesn't kill the caller.
72 // Returns { ok, stdout, stderr, status }.
73 export function runCmd ( cmd , args , opts = {}) {
74 try {
75 const stdout = execFileSync (cmd, args, { encoding: 'utf8' , stdio: [ 'ignore' , 'pipe' , 'pipe' ], ... opts });
76 return { ok: true , stdout, stderr: '' , status: 0 };
77 } catch (err) {
78 return {
79 ok: false ,
80 stdout: err.stdout?. toString ?.() ?? '' ,
81 stderr: err.stderr?. toString ?.() ?? String (err.message || err),
82 status: err.status ?? 1 ,
83 };
84 }
85 }
86
87 export function sleepMs ( ms ) {
88 return new Promise ( r => setTimeout (r, ms));
89 }
90
91 // Bucket map shared by bisect (session-wide + per-page) and query helpers.
92 // Format: [bucketRelativePath, predicate(method)].
93 export const BUCKETS = [
94 [ 'network/requests' , m => m === 'Network.requestWillBeSent' ],
95 [ 'network/responses' , m => m === 'Network.responseReceived' ],
96 [ 'network/finished' , m => m === 'Network.loadingFinished' ],
97 [ 'network/failed' , m => m === 'Network.loadingFailed' ],
98 [ 'network/websocket' , m => m. startsWith ( 'Network.webSocket' )],
99 [ 'console/logs' , m => m === 'Runtime.consoleAPICalled' ],
100 [ 'console/exceptions' , m => m === 'Runtime.exceptionThrown' ],
101 [ 'runtime/all' , m => m. startsWith ( 'Runtime.' )],
102 [ 'log/entries' , m => m === 'Log.entryAdded' ],
103 [ 'page/navigations' , m => m === 'Page.frameNavigated' ],
104 [ 'page/lifecycle' , m => m === 'Page.lifecycleEvent' ],
105 [ 'page/dialogs' , m => m. startsWith ( 'Page.javascriptDialog' )],
106 [ 'page/frames' , m => m. startsWith ( 'Page.frame' )],
107 [ 'page/all' , m => m. startsWith ( 'Page.' )],
108 [ 'dom/all' , m => m. startsWith ( 'DOM.' )],
109 [ 'target/attached' , m => m === 'Target.attachedToTarget' ],
110 [ 'target/detached' , m => m === 'Target.detachedFromTarget' ],
111 ];
112
113 // Top-level frameNavigated detector (parentId null/empty == top frame).
114 export function isTopNav ( ev ) {
115 if (ev?.method !== 'Page.frameNavigated' ) return false ;
116 const parent = ev?.params?.frame?.parentId ?? null ;
117 return parent === null || parent === '' ;
118 }