inspeffct 1.0.3 → 1.0.5
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/dist/bin.js +388 -210
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as NodeRuntime from '@effect/platform-node/NodeRuntime';
|
|
3
3
|
import * as NodeServices from '@effect/platform-node/NodeServices';
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
7
|
-
import * as
|
|
4
|
+
import * as Effect10 from 'effect/Effect';
|
|
5
|
+
import * as Command6 from 'effect/unstable/cli/Command';
|
|
6
|
+
import * as Argument3 from 'effect/unstable/cli/Argument';
|
|
7
|
+
import * as Context4 from 'effect/Context';
|
|
8
8
|
import * as Fiber from 'effect/Fiber';
|
|
9
9
|
import * as FileSystem from 'effect/FileSystem';
|
|
10
|
-
import * as
|
|
10
|
+
import * as Layer8 from 'effect/Layer';
|
|
11
11
|
import * as Schema from 'effect/Schema';
|
|
12
12
|
import * as Stream from 'effect/Stream';
|
|
13
13
|
import * as Formatter from 'effect/Formatter';
|
|
@@ -20,10 +20,11 @@ import * as Queue2 from 'effect/Queue';
|
|
|
20
20
|
import * as Socket from 'effect/unstable/socket/Socket';
|
|
21
21
|
import * as Chunk from 'effect/Chunk';
|
|
22
22
|
import * as Ref from 'effect/Ref';
|
|
23
|
+
import * as Random from 'effect/Random';
|
|
23
24
|
import * as SqliteClient from '@effect/sql-sqlite-node/SqliteClient';
|
|
24
25
|
import * as Struct5 from 'effect/Struct';
|
|
25
26
|
import * as Migrator from 'effect/unstable/sql/Migrator';
|
|
26
|
-
import * as
|
|
27
|
+
import * as SqlClient5 from 'effect/unstable/sql/SqlClient';
|
|
27
28
|
import * as SqlSchema from 'effect/unstable/sql/SqlSchema';
|
|
28
29
|
import * as SchemaGetter from 'effect/SchemaGetter';
|
|
29
30
|
import { flow } from 'effect/Function';
|
|
@@ -35,9 +36,9 @@ import * as crypto from 'crypto';
|
|
|
35
36
|
import * as fs from 'fs';
|
|
36
37
|
import * as os from 'os';
|
|
37
38
|
import * as path from 'path';
|
|
39
|
+
import * as Console2 from 'effect/Console';
|
|
38
40
|
import * as Option3 from 'effect/Option';
|
|
39
41
|
import * as ChildProcess from 'effect/unstable/process/ChildProcess';
|
|
40
|
-
import * as Console from 'effect/Console';
|
|
41
42
|
import * as Duration from 'effect/Duration';
|
|
42
43
|
import * as Graph from 'effect/Graph';
|
|
43
44
|
|
|
@@ -195,17 +196,17 @@ Schema.toCodecJson(
|
|
|
195
196
|
CaptureCurrentFibersRequest
|
|
196
197
|
]).annotate({ identifier: "InMessage" })
|
|
197
198
|
);
|
|
198
|
-
var BootloaderPath = class extends
|
|
199
|
+
var BootloaderPath = class extends Context4.Service()("inspeffct/BootloaderPath") {
|
|
199
200
|
};
|
|
200
|
-
var getPath =
|
|
201
|
-
var computeBootloaderPath =
|
|
201
|
+
var getPath = Effect10.map(BootloaderPath, (service) => service.path);
|
|
202
|
+
var computeBootloaderPath = Effect10.gen(function* () {
|
|
202
203
|
const path2 = yield* Path.Path;
|
|
203
204
|
const binDir = path2.dirname(import.meta.url.replace("file://", ""));
|
|
204
205
|
return path2.join(binDir, "bootloader.cjs");
|
|
205
206
|
});
|
|
206
|
-
var layer =
|
|
207
|
+
var layer = Layer8.effect(
|
|
207
208
|
BootloaderPath,
|
|
208
|
-
|
|
209
|
+
Effect10.map(computeBootloaderPath, (path2) => BootloaderPath.of({ path: path2 }))
|
|
209
210
|
);
|
|
210
211
|
var CdpRequest = Schema.Struct({
|
|
211
212
|
id: Schema.Number,
|
|
@@ -236,13 +237,13 @@ var CdpError = class extends Schema.TaggedErrorClass()("CdpError", {
|
|
|
236
237
|
code: Schema.optional(Schema.Number)
|
|
237
238
|
}) {
|
|
238
239
|
};
|
|
239
|
-
var CdpClient = class extends
|
|
240
|
+
var CdpClient = class extends Context4.Service()("inspeffct/CdpClient") {
|
|
240
241
|
};
|
|
241
242
|
var isCdpEvent = (msg) => typeof msg === "object" && msg !== null && "method" in msg && typeof msg.method === "string" && !("id" in msg);
|
|
242
243
|
var isCdpResponse = (msg) => typeof msg === "object" && msg !== null && "id" in msg && typeof msg.id === "number";
|
|
243
|
-
var makeConnection = (url) =>
|
|
244
|
+
var makeConnection = (url) => Effect10.gen(function* () {
|
|
244
245
|
const socket = yield* Socket.makeWebSocket(url).pipe(
|
|
245
|
-
|
|
246
|
+
Effect10.mapError((e) => new CdpError({ message: `Failed to connect to ${url}: ${e}` }))
|
|
246
247
|
);
|
|
247
248
|
const outgoing = yield* Queue2.unbounded();
|
|
248
249
|
const eventsPubSub = yield* PubSub2.unbounded();
|
|
@@ -256,14 +257,14 @@ var makeConnection = (url) => Effect8.gen(function* () {
|
|
|
256
257
|
})
|
|
257
258
|
),
|
|
258
259
|
Stream.runForEach(
|
|
259
|
-
(msg) =>
|
|
260
|
+
(msg) => Effect10.gen(function* () {
|
|
260
261
|
if (isCdpResponse(msg)) {
|
|
261
262
|
const resume = pendingRequests.get(msg.id);
|
|
262
263
|
if (resume) {
|
|
263
264
|
pendingRequests.delete(msg.id);
|
|
264
265
|
if (msg.error) {
|
|
265
266
|
resume(
|
|
266
|
-
|
|
267
|
+
Effect10.fail(
|
|
267
268
|
new CdpError({
|
|
268
269
|
message: msg.error.message,
|
|
269
270
|
code: msg.error.code
|
|
@@ -271,28 +272,28 @@ var makeConnection = (url) => Effect8.gen(function* () {
|
|
|
271
272
|
)
|
|
272
273
|
);
|
|
273
274
|
} else {
|
|
274
|
-
resume(
|
|
275
|
+
resume(Effect10.succeed(msg.result));
|
|
275
276
|
}
|
|
276
277
|
}
|
|
277
278
|
}
|
|
278
279
|
if (isCdpEvent(msg)) {
|
|
279
280
|
const decoded = yield* Schema.decodeUnknownEffect(CdpEvent)(msg).pipe(
|
|
280
|
-
|
|
281
|
+
Effect10.mapError((error) => new CdpError({ message: String(error) }))
|
|
281
282
|
);
|
|
282
283
|
yield* PubSub2.publish(eventsPubSub, decoded);
|
|
283
284
|
}
|
|
284
|
-
}).pipe(
|
|
285
|
+
}).pipe(Effect10.catchCause(Effect10.logDebug))
|
|
285
286
|
),
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
287
|
+
Effect10.ensuring(Queue2.shutdown(outgoing)),
|
|
288
|
+
Effect10.catchCause(Effect10.logDebug),
|
|
289
|
+
Effect10.forkScoped
|
|
289
290
|
);
|
|
290
291
|
const request = (method, params) => {
|
|
291
292
|
const id = nextId++;
|
|
292
|
-
return
|
|
293
|
+
return Effect10.callback((resume) => {
|
|
293
294
|
pendingRequests.set(id, resume);
|
|
294
295
|
Queue2.offerUnsafe(outgoing, { id, method, params });
|
|
295
|
-
return
|
|
296
|
+
return Effect10.sync(() => {
|
|
296
297
|
pendingRequests.delete(id);
|
|
297
298
|
});
|
|
298
299
|
});
|
|
@@ -304,19 +305,36 @@ var makeConnection = (url) => Effect8.gen(function* () {
|
|
|
304
305
|
events
|
|
305
306
|
};
|
|
306
307
|
});
|
|
307
|
-
var layer2 =
|
|
308
|
+
var layer2 = Layer8.effect(
|
|
308
309
|
CdpClient,
|
|
309
|
-
|
|
310
|
+
Effect10.gen(function* () {
|
|
310
311
|
const wsConstructor = yield* Socket.WebSocketConstructor;
|
|
311
312
|
return CdpClient.of({
|
|
312
313
|
connect: (url) => makeConnection(url).pipe(
|
|
313
|
-
|
|
314
|
+
Effect10.provideService(Socket.WebSocketConstructor, wsConstructor)
|
|
314
315
|
)
|
|
315
316
|
});
|
|
316
317
|
})
|
|
317
318
|
).pipe(
|
|
318
|
-
|
|
319
|
+
Layer8.provide(NodeSocket.layerWebSocketConstructor)
|
|
319
320
|
);
|
|
321
|
+
var randomByte = Random.nextIntBetween(0, 256, { halfOpen: true });
|
|
322
|
+
var randomUUID = Effect10.gen(function* () {
|
|
323
|
+
const bytes = yield* Effect10.all(Array.from({ length: 16 }, () => randomByte));
|
|
324
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
325
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
326
|
+
const hex = bytes.map((byte) => byte.toString(16).padStart(2, "0"));
|
|
327
|
+
return [
|
|
328
|
+
hex.slice(0, 4).join(""),
|
|
329
|
+
hex.slice(4, 6).join(""),
|
|
330
|
+
hex.slice(6, 8).join(""),
|
|
331
|
+
hex.slice(8, 10).join(""),
|
|
332
|
+
hex.slice(10, 16).join("")
|
|
333
|
+
].join("-");
|
|
334
|
+
});
|
|
335
|
+
var RunId = class extends Context4.Service()("inspeffct/RunId") {
|
|
336
|
+
};
|
|
337
|
+
var layer3 = Layer8.effect(RunId, randomUUID);
|
|
320
338
|
var isSchema = (u) => typeof u === "object" && u !== null && "ast" in u;
|
|
321
339
|
var getMembers = (schema) => "members" in schema && Array.isArray(schema.members) ? schema.members : "cases" in schema ? Object.values(schema.cases) : [schema];
|
|
322
340
|
var evolveNested = (schema, evolve2) => {
|
|
@@ -435,8 +453,8 @@ var encodeStruct = (config) => (self) => {
|
|
|
435
453
|
})
|
|
436
454
|
);
|
|
437
455
|
};
|
|
438
|
-
var create_otel_tables_default =
|
|
439
|
-
const sql = yield*
|
|
456
|
+
var create_otel_tables_default = Effect10.gen(function* () {
|
|
457
|
+
const sql = yield* SqlClient5.SqlClient;
|
|
440
458
|
yield* sql`
|
|
441
459
|
CREATE TABLE spans (
|
|
442
460
|
span_id TEXT PRIMARY KEY,
|
|
@@ -457,15 +475,15 @@ var create_otel_tables_default = Effect8.gen(function* () {
|
|
|
457
475
|
dropped_links_count INTEGER NOT NULL DEFAULT 0,
|
|
458
476
|
is_external INTEGER NOT NULL DEFAULT 0
|
|
459
477
|
)
|
|
460
|
-
`.pipe(
|
|
461
|
-
yield* sql`CREATE INDEX idx_spans_trace_id ON spans(trace_id)`.pipe(
|
|
478
|
+
`.pipe(Effect10.withSpan("create_spans_table"));
|
|
479
|
+
yield* sql`CREATE INDEX idx_spans_trace_id ON spans(trace_id)`.pipe(Effect10.withSpan("create_idx_spans_trace_id"));
|
|
462
480
|
yield* sql`CREATE INDEX idx_spans_start_time ON spans(start_time)`.pipe(
|
|
463
|
-
|
|
481
|
+
Effect10.withSpan("create_idx_spans_start_time")
|
|
464
482
|
);
|
|
465
|
-
yield* sql`CREATE INDEX idx_spans_name ON spans(name)`.pipe(
|
|
466
|
-
yield* sql`CREATE INDEX idx_spans_parent ON spans(parent_span_id)`.pipe(
|
|
483
|
+
yield* sql`CREATE INDEX idx_spans_name ON spans(name)`.pipe(Effect10.withSpan("create_idx_spans_name"));
|
|
484
|
+
yield* sql`CREATE INDEX idx_spans_parent ON spans(parent_span_id)`.pipe(Effect10.withSpan("create_idx_spans_parent"));
|
|
467
485
|
yield* sql`CREATE INDEX idx_spans_running ON spans(span_id) WHERE end_time IS NULL`.pipe(
|
|
468
|
-
|
|
486
|
+
Effect10.withSpan("create_idx_spans_running")
|
|
469
487
|
);
|
|
470
488
|
yield* sql`
|
|
471
489
|
CREATE TABLE span_events (
|
|
@@ -477,9 +495,9 @@ var create_otel_tables_default = Effect8.gen(function* () {
|
|
|
477
495
|
attributes TEXT NOT NULL DEFAULT '{}',
|
|
478
496
|
dropped_attributes_count INTEGER NOT NULL DEFAULT 0
|
|
479
497
|
)
|
|
480
|
-
`.pipe(
|
|
498
|
+
`.pipe(Effect10.withSpan("create_span_events_table"));
|
|
481
499
|
yield* sql`CREATE INDEX idx_span_events_span ON span_events(span_id)`.pipe(
|
|
482
|
-
|
|
500
|
+
Effect10.withSpan("create_idx_span_events_span")
|
|
483
501
|
);
|
|
484
502
|
yield* sql`
|
|
485
503
|
CREATE TABLE span_links (
|
|
@@ -491,13 +509,22 @@ var create_otel_tables_default = Effect8.gen(function* () {
|
|
|
491
509
|
attributes TEXT NOT NULL DEFAULT '{}',
|
|
492
510
|
dropped_attributes_count INTEGER NOT NULL DEFAULT 0
|
|
493
511
|
)
|
|
494
|
-
`.pipe(
|
|
512
|
+
`.pipe(Effect10.withSpan("create_span_links_table"));
|
|
495
513
|
yield* sql`CREATE INDEX idx_span_links_span ON span_links(span_id)`.pipe(
|
|
496
|
-
|
|
514
|
+
Effect10.withSpan("create_idx_span_links_span")
|
|
515
|
+
);
|
|
516
|
+
});
|
|
517
|
+
var create_span_exits_table_default = Effect10.void;
|
|
518
|
+
var simplify_span_exits_default = Effect10.void;
|
|
519
|
+
var add_run_id_default = Effect10.gen(function* () {
|
|
520
|
+
const sql = yield* SqlClient5.SqlClient;
|
|
521
|
+
yield* sql`ALTER TABLE spans ADD COLUMN run_id TEXT NOT NULL DEFAULT ''`.pipe(
|
|
522
|
+
Effect10.withSpan("add_spans_run_id")
|
|
523
|
+
);
|
|
524
|
+
yield* sql`CREATE INDEX idx_spans_run_id ON spans(run_id)`.pipe(
|
|
525
|
+
Effect10.withSpan("create_idx_spans_run_id")
|
|
497
526
|
);
|
|
498
527
|
});
|
|
499
|
-
var create_span_exits_table_default = Effect8.void;
|
|
500
|
-
var simplify_span_exits_default = Effect8.void;
|
|
501
528
|
|
|
502
529
|
// src/services/Storage.ts
|
|
503
530
|
var SpanExitJson = Schema.toCodecJson(SpanExit);
|
|
@@ -567,6 +594,7 @@ var DbExternalSpan = ExternalSpan.pipe(
|
|
|
567
594
|
);
|
|
568
595
|
var DbAnySpan = Schema.Union([DbSpan, DbExternalSpan]);
|
|
569
596
|
var TraceSummary = Schema.Struct({
|
|
597
|
+
run_id: Schema.String,
|
|
570
598
|
trace_id: Schema.String,
|
|
571
599
|
span_count: NumberFromBigInt,
|
|
572
600
|
root_span_name: Schema.NullOr(Schema.String),
|
|
@@ -586,40 +614,44 @@ var DbSpanLink = SpanLink.mapFields(
|
|
|
586
614
|
linkedTraceId: "linked_trace_id"
|
|
587
615
|
})
|
|
588
616
|
);
|
|
589
|
-
var Storage = class extends
|
|
617
|
+
var Storage = class extends Context4.Service()("inspeffct/Storage") {
|
|
590
618
|
};
|
|
591
619
|
var MigrationsLoader = Migrator.fromRecord({
|
|
592
620
|
"0001_create_otel_tables": create_otel_tables_default,
|
|
593
621
|
"0002_create_span_exits_table": create_span_exits_table_default,
|
|
594
|
-
"0003_simplify_span_exits": simplify_span_exits_default
|
|
622
|
+
"0003_simplify_span_exits": simplify_span_exits_default,
|
|
623
|
+
"0004_add_run_id": add_run_id_default
|
|
595
624
|
});
|
|
596
625
|
var runMigrations = Migrator.make({})({
|
|
597
626
|
loader: MigrationsLoader
|
|
598
627
|
});
|
|
599
|
-
var
|
|
600
|
-
|
|
628
|
+
var layer5 = (config) => Layer8.effectContext(
|
|
629
|
+
Effect10.gen(function* () {
|
|
601
630
|
const sql = yield* SqliteClient.SqliteClient;
|
|
602
631
|
yield* runMigrations;
|
|
603
632
|
const storage = Storage.of({
|
|
604
|
-
persistSpan: (span) =>
|
|
633
|
+
persistSpan: (span, runId) => Effect10.gen(function* () {
|
|
605
634
|
const changed = yield* (
|
|
606
635
|
// @ts-ignore TS28 false positive from SqlSchema service inference
|
|
607
636
|
SqlSchema.findOne({
|
|
608
637
|
Request: DbAnySpan,
|
|
609
638
|
Result: Schema.Struct({ span_id: Schema.String }),
|
|
610
|
-
execute: (db) =>
|
|
611
|
-
|
|
639
|
+
execute: (db) => {
|
|
640
|
+
const row = { ...db, run_id: runId };
|
|
641
|
+
return sql`
|
|
642
|
+
INSERT INTO spans ${sql.insert(row)}
|
|
612
643
|
ON CONFLICT(span_id) DO UPDATE SET
|
|
613
|
-
${sql.update(
|
|
644
|
+
${sql.update(row, ["span_id"])}
|
|
614
645
|
WHERE
|
|
615
646
|
is_external = 1 OR
|
|
616
647
|
(end_time IS NULL AND excluded.is_external = 0)
|
|
617
648
|
RETURNING span_id
|
|
618
|
-
|
|
649
|
+
`;
|
|
650
|
+
}
|
|
619
651
|
})(span).pipe(
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
652
|
+
Effect10.as(true),
|
|
653
|
+
Effect10.catch(() => Effect10.succeed(false)),
|
|
654
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
623
655
|
)
|
|
624
656
|
);
|
|
625
657
|
return changed;
|
|
@@ -644,7 +676,7 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
644
676
|
)
|
|
645
677
|
`
|
|
646
678
|
}),
|
|
647
|
-
|
|
679
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
648
680
|
),
|
|
649
681
|
getSpansByTraceId: (traceId) => (
|
|
650
682
|
// @ts-ignore TS28 false positive from SqlSchema service inference
|
|
@@ -658,7 +690,7 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
658
690
|
ORDER BY s.start_time ASC
|
|
659
691
|
`
|
|
660
692
|
})(traceId).pipe(
|
|
661
|
-
|
|
693
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
662
694
|
)
|
|
663
695
|
),
|
|
664
696
|
getRecentSpans: (limit = 100) => (
|
|
@@ -673,7 +705,7 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
673
705
|
LIMIT ${l}
|
|
674
706
|
`
|
|
675
707
|
})(limit).pipe(
|
|
676
|
-
|
|
708
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
677
709
|
)
|
|
678
710
|
),
|
|
679
711
|
getSpanEvents: flow(
|
|
@@ -696,7 +728,7 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
696
728
|
ORDER BY time ASC
|
|
697
729
|
`
|
|
698
730
|
}),
|
|
699
|
-
|
|
731
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
700
732
|
),
|
|
701
733
|
persistSpanLink: SqlSchema.void({
|
|
702
734
|
Request: DbSpanLink,
|
|
@@ -725,15 +757,24 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
725
757
|
getTraces: (filters = {}) => SqlSchema.findAll({
|
|
726
758
|
Request: Schema.Struct({
|
|
727
759
|
limit: Schema.optional(Schema.Number),
|
|
760
|
+
runId: Schema.optional(Schema.String),
|
|
728
761
|
since: Schema.optional(Schema.BigInt),
|
|
729
762
|
status: Schema.optional(Schema.Number)
|
|
730
763
|
}),
|
|
731
764
|
Result: TraceSummary,
|
|
732
765
|
execute: (req) => sql`
|
|
733
766
|
SELECT
|
|
767
|
+
s.run_id,
|
|
734
768
|
s.trace_id,
|
|
735
769
|
COUNT(*) as span_count,
|
|
736
|
-
(
|
|
770
|
+
(
|
|
771
|
+
SELECT name
|
|
772
|
+
FROM spans
|
|
773
|
+
WHERE trace_id = s.trace_id
|
|
774
|
+
AND run_id = s.run_id
|
|
775
|
+
AND parent_span_id IS NULL
|
|
776
|
+
LIMIT 1
|
|
777
|
+
) as root_span_name,
|
|
737
778
|
MIN(s.start_time) as start_time,
|
|
738
779
|
MAX(s.end_time) as end_time,
|
|
739
780
|
MAX(
|
|
@@ -745,6 +786,7 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
745
786
|
) as status
|
|
746
787
|
FROM spans s
|
|
747
788
|
WHERE ${sql.and([
|
|
789
|
+
req.runId !== void 0 ? sql`s.run_id = ${req.runId}` : sql`1=1`,
|
|
748
790
|
req.since !== void 0 ? sql`s.start_time >= ${req.since}` : sql`1=1`,
|
|
749
791
|
req.status !== void 0 ? sql`
|
|
750
792
|
CASE
|
|
@@ -754,12 +796,12 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
754
796
|
END = ${req.status}
|
|
755
797
|
` : sql`1=1`
|
|
756
798
|
])}
|
|
757
|
-
GROUP BY s.trace_id
|
|
799
|
+
GROUP BY s.run_id, s.trace_id
|
|
758
800
|
ORDER BY start_time DESC
|
|
759
801
|
${req.limit !== void 0 ? sql`LIMIT ${req.limit}` : sql``}
|
|
760
802
|
`
|
|
761
803
|
})(filters).pipe(
|
|
762
|
-
|
|
804
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
763
805
|
),
|
|
764
806
|
getSpans: (filters = {}) => (
|
|
765
807
|
// @ts-ignore TS28 false positive from SqlSchema service inference
|
|
@@ -768,6 +810,8 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
768
810
|
limit: Schema.optional(Schema.Number),
|
|
769
811
|
minDuration: Schema.optional(Schema.BigInt),
|
|
770
812
|
name: Schema.optional(Schema.String),
|
|
813
|
+
runId: Schema.optional(Schema.String),
|
|
814
|
+
spanId: Schema.optional(Schema.String),
|
|
771
815
|
status: Schema.optional(Schema.Number),
|
|
772
816
|
traceId: Schema.optional(Schema.String)
|
|
773
817
|
}),
|
|
@@ -776,6 +820,8 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
776
820
|
SELECT s.*
|
|
777
821
|
FROM spans s
|
|
778
822
|
WHERE ${sql.and([
|
|
823
|
+
req.runId !== void 0 ? sql`s.run_id = ${req.runId}` : sql`1=1`,
|
|
824
|
+
req.spanId !== void 0 ? sql`s.span_id = ${req.spanId}` : sql`1=1`,
|
|
779
825
|
req.traceId !== void 0 ? sql`s.trace_id = ${req.traceId}` : sql`1=1`,
|
|
780
826
|
req.name !== void 0 ? req.name.includes("%") ? sql`s.name LIKE ${req.name}` : sql`s.name = ${req.name}` : sql`1=1`,
|
|
781
827
|
req.minDuration !== void 0 ? sql`(s.end_time - s.start_time) >= ${req.minDuration}` : sql`1=1`,
|
|
@@ -791,44 +837,43 @@ var layer4 = (config) => Layer7.effectContext(
|
|
|
791
837
|
${req.limit !== void 0 ? sql`LIMIT ${req.limit}` : sql``}
|
|
792
838
|
`
|
|
793
839
|
})(filters).pipe(
|
|
794
|
-
|
|
840
|
+
Effect10.provideService(SqlClient5.SafeIntegers, true)
|
|
795
841
|
)
|
|
796
842
|
)
|
|
797
843
|
});
|
|
798
|
-
return
|
|
844
|
+
return Context4.make(Storage, storage);
|
|
799
845
|
})
|
|
800
|
-
).pipe(
|
|
846
|
+
).pipe(Layer8.provide(SqliteClient.layer(config)));
|
|
801
847
|
|
|
802
848
|
// src/services/EventCollector.ts
|
|
803
|
-
var EventCollector = class extends
|
|
849
|
+
var EventCollector = class extends Context4.Service()("inspeffct/EventCollector") {
|
|
804
850
|
};
|
|
805
|
-
var
|
|
851
|
+
var layer6 = Layer8.effect(
|
|
806
852
|
EventCollector,
|
|
807
|
-
|
|
853
|
+
Effect10.gen(function* () {
|
|
854
|
+
const runId = yield* RunId;
|
|
808
855
|
const storage = yield* Storage;
|
|
809
856
|
return EventCollector.of({
|
|
810
|
-
collect: (message) =>
|
|
857
|
+
collect: (message) => Effect10.gen(function* () {
|
|
811
858
|
switch (message._tag) {
|
|
812
859
|
case "InitNotification": {
|
|
813
|
-
yield*
|
|
860
|
+
yield* Effect10.logDebug(
|
|
814
861
|
`${message._tag} from ${message.instrumentationId} (inspectorURL: ${message.inspectorURL ?? "none"}, waitingForDebugger: ${message.waitingForDebugger})`
|
|
815
862
|
);
|
|
816
863
|
break;
|
|
817
864
|
}
|
|
818
865
|
case "TracerSpanNotification": {
|
|
819
866
|
const { instrumentationId, span } = message;
|
|
820
|
-
yield*
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
);
|
|
826
|
-
}
|
|
867
|
+
yield* Effect10.logDebug(`${message._tag} from ${instrumentationId}`);
|
|
868
|
+
yield* storage.persistSpan(span, runId);
|
|
869
|
+
yield* Effect10.logDebug(
|
|
870
|
+
`Persisted span (${span.traceId}, ${span.spanId}) to storage`
|
|
871
|
+
);
|
|
827
872
|
break;
|
|
828
873
|
}
|
|
829
874
|
case "TracerSpanEventNotification": {
|
|
830
875
|
const { event } = message;
|
|
831
|
-
yield*
|
|
876
|
+
yield* Effect10.logDebug(`${message._tag} from ${message.instrumentationId}`);
|
|
832
877
|
yield* storage.persistSpanEvent({
|
|
833
878
|
spanId: event.spanId,
|
|
834
879
|
traceId: event.traceId,
|
|
@@ -836,14 +881,14 @@ var layer5 = Layer7.effect(
|
|
|
836
881
|
time: event.time,
|
|
837
882
|
attributes: event.attributes
|
|
838
883
|
});
|
|
839
|
-
yield*
|
|
884
|
+
yield* Effect10.logDebug(
|
|
840
885
|
`Persisted span event ${event.name} for span ${event.spanId}`
|
|
841
886
|
);
|
|
842
887
|
break;
|
|
843
888
|
}
|
|
844
889
|
case "TracerSpanLinkNotification": {
|
|
845
890
|
const { link } = message;
|
|
846
|
-
yield*
|
|
891
|
+
yield* Effect10.logDebug(`${message._tag} from ${message.instrumentationId}`);
|
|
847
892
|
yield* storage.persistSpanLink({
|
|
848
893
|
spanId: link.spanId,
|
|
849
894
|
traceId: link.traceId,
|
|
@@ -851,7 +896,7 @@ var layer5 = Layer7.effect(
|
|
|
851
896
|
linkedTraceId: link.linkedTraceId,
|
|
852
897
|
attributes: link.attributes
|
|
853
898
|
});
|
|
854
|
-
yield*
|
|
899
|
+
yield* Effect10.logDebug(
|
|
855
900
|
`Persisted span link from ${link.spanId} to ${link.linkedSpanId}`
|
|
856
901
|
);
|
|
857
902
|
break;
|
|
@@ -860,48 +905,48 @@ var layer5 = Layer7.effect(
|
|
|
860
905
|
case "VariableReferenceInfo":
|
|
861
906
|
case "ResourcesForRequestReleased":
|
|
862
907
|
case "CurrentFibersInfo": {
|
|
863
|
-
yield*
|
|
908
|
+
yield* Effect10.logDebug(`${message._tag} from ${message.instrumentationId}`);
|
|
864
909
|
break;
|
|
865
910
|
}
|
|
866
911
|
}
|
|
867
|
-
}).pipe(
|
|
912
|
+
}).pipe(Effect10.catch((error) => Effect10.logWarning(`Failed to persist event: ${error}`)))
|
|
868
913
|
});
|
|
869
914
|
})
|
|
870
915
|
);
|
|
871
|
-
|
|
916
|
+
Layer8.succeed(
|
|
872
917
|
EventCollector,
|
|
873
918
|
EventCollector.of({
|
|
874
919
|
collect: (message) => {
|
|
875
920
|
if (message._tag === "InitNotification") {
|
|
876
|
-
return
|
|
921
|
+
return Effect10.logDebug(
|
|
877
922
|
`${message._tag} from ${message.instrumentationId} (inspectorURL: ${message.inspectorURL ?? "none"}, waitingForDebugger: ${message.waitingForDebugger})`
|
|
878
923
|
);
|
|
879
924
|
}
|
|
880
|
-
return
|
|
925
|
+
return Effect10.logDebug(`${message._tag} from ${message.instrumentationId}`);
|
|
881
926
|
}
|
|
882
927
|
})
|
|
883
928
|
);
|
|
884
|
-
|
|
929
|
+
Layer8.effect(
|
|
885
930
|
EventCollector,
|
|
886
|
-
|
|
931
|
+
Effect10.gen(function* () {
|
|
887
932
|
const messagesRef = yield* Ref.make(Chunk.empty());
|
|
888
933
|
return EventCollector.of({
|
|
889
934
|
collect: (message) => Ref.update(messagesRef, Chunk.append(message)),
|
|
890
|
-
getMessages: Ref.get(messagesRef).pipe(
|
|
935
|
+
getMessages: Ref.get(messagesRef).pipe(Effect10.map(Chunk.toReadonlyArray))
|
|
891
936
|
});
|
|
892
937
|
})
|
|
893
938
|
);
|
|
894
939
|
|
|
895
940
|
// src/services/CdpManager.ts
|
|
896
941
|
var BINDING_NAME = "__inspeffct_bridge__";
|
|
897
|
-
var CdpManager = class extends
|
|
942
|
+
var CdpManager = class extends Context4.Service()("inspeffct/CdpManager") {
|
|
898
943
|
};
|
|
899
|
-
var getBootloaderScript =
|
|
944
|
+
var getBootloaderScript = Effect10.gen(function* () {
|
|
900
945
|
const fs2 = yield* FileSystem.FileSystem;
|
|
901
946
|
const bootloaderPath = yield* getPath;
|
|
902
947
|
return yield* fs2.readFileString(bootloaderPath);
|
|
903
948
|
});
|
|
904
|
-
var connectAndListen = (url, bootloaderScript) =>
|
|
949
|
+
var connectAndListen = (url, bootloaderScript) => Effect10.gen(function* () {
|
|
905
950
|
const cdp = yield* CdpClient;
|
|
906
951
|
const collector = yield* EventCollector;
|
|
907
952
|
const connection = yield* cdp.connect(url);
|
|
@@ -909,21 +954,21 @@ var connectAndListen = (url, bootloaderScript) => Effect8.gen(function* () {
|
|
|
909
954
|
expression: bootloaderScript,
|
|
910
955
|
contextId,
|
|
911
956
|
silent: true
|
|
912
|
-
}).pipe(
|
|
957
|
+
}).pipe(Effect10.ensuring(connection.request("Runtime.runIfWaitingForDebugger").pipe(Effect10.ignore({ log: true }))));
|
|
913
958
|
const eventFiber = yield* connection.events.pipe(
|
|
914
959
|
Stream.takeUntil(
|
|
915
960
|
(event) => event.method === "Runtime.executionContextDestroyed" || event.method === "Runtime.executionContextsCleared" || event.method === "Inspector.detached"
|
|
916
961
|
),
|
|
917
962
|
Stream.runForEach(
|
|
918
|
-
(event) =>
|
|
963
|
+
(event) => Effect10.gen(function* () {
|
|
919
964
|
if (event.method === "Runtime.bindingCalled") {
|
|
920
965
|
const params = event.params;
|
|
921
966
|
if (params.name === BINDING_NAME) {
|
|
922
967
|
yield* Schema.decodeUnknownEffect(Schema.fromJsonString(OutMessage))(
|
|
923
968
|
params.payload
|
|
924
969
|
).pipe(
|
|
925
|
-
|
|
926
|
-
|
|
970
|
+
Effect10.flatMap((decoded) => collector.collect(decoded)),
|
|
971
|
+
Effect10.catch(() => Effect10.logError(`Failed to decode CDP message: ${params.payload}`))
|
|
927
972
|
);
|
|
928
973
|
}
|
|
929
974
|
}
|
|
@@ -933,44 +978,44 @@ var connectAndListen = (url, bootloaderScript) => Effect8.gen(function* () {
|
|
|
933
978
|
}
|
|
934
979
|
})
|
|
935
980
|
),
|
|
936
|
-
|
|
981
|
+
Effect10.forkScoped
|
|
937
982
|
);
|
|
938
|
-
yield*
|
|
983
|
+
yield* Effect10.yieldNow;
|
|
939
984
|
yield* connection.request("Runtime.addBinding", { name: BINDING_NAME });
|
|
940
985
|
yield* connection.request("Runtime.enable");
|
|
941
986
|
yield* connection.request("Runtime.runIfWaitingForDebugger");
|
|
942
|
-
yield*
|
|
987
|
+
yield* Effect10.logDebug(`CDP connected: ${url}`);
|
|
943
988
|
yield* Fiber.join(eventFiber);
|
|
944
989
|
});
|
|
945
|
-
var
|
|
990
|
+
var layer7 = Layer8.effect(
|
|
946
991
|
CdpManager,
|
|
947
|
-
|
|
992
|
+
Effect10.gen(function* () {
|
|
948
993
|
const bootloaderScript = yield* getBootloaderScript;
|
|
949
994
|
const cdpClient = yield* CdpClient;
|
|
950
995
|
const collector = yield* EventCollector;
|
|
951
|
-
const managerScope = yield*
|
|
996
|
+
const managerScope = yield* Effect10.scope;
|
|
952
997
|
const activeConnections = /* @__PURE__ */ new Map();
|
|
953
998
|
return CdpManager.of({
|
|
954
|
-
connect: (url) =>
|
|
999
|
+
connect: (url) => Effect10.gen(function* () {
|
|
955
1000
|
if (activeConnections.has(url)) {
|
|
956
1001
|
return;
|
|
957
1002
|
}
|
|
958
1003
|
activeConnections.set(url, true);
|
|
959
|
-
yield*
|
|
1004
|
+
yield* Effect10.logDebug(`Connecting to CDP: ${url}`);
|
|
960
1005
|
yield* connectAndListen(url, bootloaderScript).pipe(
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1006
|
+
Effect10.provideService(CdpClient, cdpClient),
|
|
1007
|
+
Effect10.provideService(EventCollector, collector),
|
|
1008
|
+
Effect10.scoped,
|
|
1009
|
+
Effect10.catchCause((cause) => Effect10.logError(`CDP connection failed for ${url}: ${cause}`)),
|
|
965
1010
|
// Always remove from tracking when done (success, failure, or interruption)
|
|
966
|
-
|
|
967
|
-
|
|
1011
|
+
Effect10.ensuring(
|
|
1012
|
+
Effect10.sync(() => {
|
|
968
1013
|
activeConnections.delete(url);
|
|
969
1014
|
}).pipe(
|
|
970
|
-
|
|
1015
|
+
Effect10.tap(() => Effect10.logDebug(`CDP disconnected: ${url}`))
|
|
971
1016
|
)
|
|
972
1017
|
),
|
|
973
|
-
|
|
1018
|
+
Effect10.forkIn(managerScope)
|
|
974
1019
|
);
|
|
975
1020
|
})
|
|
976
1021
|
});
|
|
@@ -978,12 +1023,12 @@ var layer6 = Layer7.effect(
|
|
|
978
1023
|
);
|
|
979
1024
|
var namedSocketDirectory = os.platform() === "win32" ? "\\\\.\\pipe\\" : os.tmpdir();
|
|
980
1025
|
var pipeCounter = 0;
|
|
981
|
-
var generateIpcPath =
|
|
1026
|
+
var generateIpcPath = Effect10.sync(() => {
|
|
982
1027
|
const randomHex = crypto.randomBytes(4).toString("hex");
|
|
983
1028
|
const pipeName = `inspeffct.${process.pid}-${randomHex}-${pipeCounter++}.sock`;
|
|
984
1029
|
return path.join(namedSocketDirectory, pipeName);
|
|
985
1030
|
});
|
|
986
|
-
var cleanupSocketFile = (socketPath) =>
|
|
1031
|
+
var cleanupSocketFile = (socketPath) => Effect10.sync(() => {
|
|
987
1032
|
if (os.platform() !== "win32") {
|
|
988
1033
|
try {
|
|
989
1034
|
fs.unlinkSync(socketPath);
|
|
@@ -991,7 +1036,7 @@ var cleanupSocketFile = (socketPath) => Effect8.sync(() => {
|
|
|
991
1036
|
}
|
|
992
1037
|
}
|
|
993
1038
|
});
|
|
994
|
-
var IpcServer = class extends
|
|
1039
|
+
var IpcServer = class extends Context4.Service()("inspeffct/IpcServer") {
|
|
995
1040
|
};
|
|
996
1041
|
var tryParseMessage = (message) => {
|
|
997
1042
|
try {
|
|
@@ -1003,13 +1048,13 @@ var tryParseMessage = (message) => {
|
|
|
1003
1048
|
};
|
|
1004
1049
|
var ACK_SUCCESS = new Uint8Array([0]);
|
|
1005
1050
|
var parseMessages = (socket) => Stream.unwrap(
|
|
1006
|
-
|
|
1051
|
+
Effect10.gen(function* () {
|
|
1007
1052
|
const write = yield* socket.writer;
|
|
1008
1053
|
const decoder = new TextDecoder();
|
|
1009
1054
|
let buffer = "";
|
|
1010
1055
|
return Stream.callback(
|
|
1011
1056
|
(queue) => socket.run(
|
|
1012
|
-
(data) =>
|
|
1057
|
+
(data) => Effect10.gen(function* () {
|
|
1013
1058
|
buffer += decoder.decode(data);
|
|
1014
1059
|
let nullIndex;
|
|
1015
1060
|
while ((nullIndex = buffer.indexOf("\0")) !== -1) {
|
|
@@ -1024,13 +1069,13 @@ var parseMessages = (socket) => Stream.unwrap(
|
|
|
1024
1069
|
}
|
|
1025
1070
|
}
|
|
1026
1071
|
}),
|
|
1027
|
-
{ onOpen:
|
|
1072
|
+
{ onOpen: Effect10.void }
|
|
1028
1073
|
).pipe(
|
|
1029
|
-
|
|
1074
|
+
Effect10.andThen(() => {
|
|
1030
1075
|
if (buffer.length > 0) {
|
|
1031
1076
|
const decoded = tryParseMessage(buffer);
|
|
1032
1077
|
if (decoded) {
|
|
1033
|
-
return Queue2.offer(queue, decoded).pipe(
|
|
1078
|
+
return Queue2.offer(queue, decoded).pipe(Effect10.andThen(Queue2.end(queue)));
|
|
1034
1079
|
}
|
|
1035
1080
|
}
|
|
1036
1081
|
return Queue2.end(queue);
|
|
@@ -1039,18 +1084,18 @@ var parseMessages = (socket) => Stream.unwrap(
|
|
|
1039
1084
|
);
|
|
1040
1085
|
})
|
|
1041
1086
|
);
|
|
1042
|
-
var
|
|
1087
|
+
var layer8 = Layer8.effect(
|
|
1043
1088
|
IpcServer,
|
|
1044
|
-
|
|
1089
|
+
Effect10.gen(function* () {
|
|
1045
1090
|
const ipcPath = yield* generateIpcPath;
|
|
1046
|
-
yield*
|
|
1091
|
+
yield* Effect10.addFinalizer(() => cleanupSocketFile(ipcPath));
|
|
1047
1092
|
const server = yield* NodeSocketServer.make({ path: ipcPath });
|
|
1048
1093
|
const pubsub = yield* PubSub2.unbounded();
|
|
1049
1094
|
yield* server.run(
|
|
1050
1095
|
(socket) => parseMessages(socket).pipe(
|
|
1051
1096
|
Stream.runForEach((message) => PubSub2.publish(pubsub, message))
|
|
1052
1097
|
)
|
|
1053
|
-
).pipe(
|
|
1098
|
+
).pipe(Effect10.catchCause(Effect10.logDebug), Effect10.forkScoped);
|
|
1054
1099
|
const messages = Stream.fromPubSub(pubsub);
|
|
1055
1100
|
const subscribe3 = PubSub2.subscribe(pubsub);
|
|
1056
1101
|
return IpcServer.of({
|
|
@@ -1060,9 +1105,9 @@ var layer7 = Layer7.effect(
|
|
|
1060
1105
|
});
|
|
1061
1106
|
})
|
|
1062
1107
|
);
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1108
|
+
Effect10.map(IpcServer, (server) => server.path);
|
|
1109
|
+
Effect10.map(IpcServer, (server) => server.messages);
|
|
1110
|
+
Effect10.flatMap(IpcServer, (server) => server.subscribe);
|
|
1066
1111
|
|
|
1067
1112
|
// src/cli/options.ts
|
|
1068
1113
|
var dataOption = Flag3.string("data").pipe(
|
|
@@ -1094,45 +1139,50 @@ var buildEnv = (bootloaderPath, ipcPath) => {
|
|
|
1094
1139
|
};
|
|
1095
1140
|
};
|
|
1096
1141
|
var makeServicesLayer = (dataPath) => {
|
|
1097
|
-
const
|
|
1098
|
-
const
|
|
1099
|
-
const
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1142
|
+
const runIdLayer = layer3;
|
|
1143
|
+
const storageLayer = layer5({ filename: dataPath });
|
|
1144
|
+
const eventCollectorLayer = layer6.pipe(
|
|
1145
|
+
Layer8.provide(runIdLayer),
|
|
1146
|
+
Layer8.provide(storageLayer)
|
|
1147
|
+
);
|
|
1148
|
+
const bootloaderPathLayer = layer.pipe(Layer8.provide(NodePath.layer));
|
|
1149
|
+
return Layer8.mergeAll(
|
|
1150
|
+
layer8,
|
|
1151
|
+
runIdLayer,
|
|
1103
1152
|
bootloaderPathLayer,
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
Layer7.provide(NodePath.layer)
|
|
1153
|
+
layer7.pipe(
|
|
1154
|
+
Layer8.provide(layer2),
|
|
1155
|
+
Layer8.provide(bootloaderPathLayer),
|
|
1156
|
+
Layer8.provide(NodeFileSystem.layer),
|
|
1157
|
+
Layer8.provide(NodePath.layer)
|
|
1110
1158
|
)
|
|
1159
|
+
).pipe(
|
|
1160
|
+
Layer8.provideMerge(eventCollectorLayer)
|
|
1111
1161
|
);
|
|
1112
1162
|
};
|
|
1113
|
-
var makeReadOnlyLayer = (dataPath) =>
|
|
1163
|
+
var makeReadOnlyLayer = (dataPath) => layer5({ filename: dataPath });
|
|
1114
1164
|
|
|
1115
1165
|
// src/cli/connect.ts
|
|
1116
|
-
var command =
|
|
1166
|
+
var command = Command6.make(
|
|
1117
1167
|
"connect",
|
|
1118
1168
|
{
|
|
1119
1169
|
data: dataOption,
|
|
1120
|
-
url:
|
|
1121
|
-
|
|
1170
|
+
url: Argument3.string("url").pipe(
|
|
1171
|
+
Argument3.withDescription("WebSocket URL of the inspector (ws://...)")
|
|
1122
1172
|
)
|
|
1123
1173
|
},
|
|
1124
|
-
({ data, url }) =>
|
|
1125
|
-
yield*
|
|
1126
|
-
yield*
|
|
1174
|
+
({ data, url }) => Effect10.gen(function* () {
|
|
1175
|
+
yield* Effect10.logDebug(`Connecting to URL: ${url}`);
|
|
1176
|
+
yield* Effect10.logDebug(`Data file: ${data}`);
|
|
1127
1177
|
const cdpManager = yield* CdpManager;
|
|
1128
1178
|
yield* cdpManager.connect(url);
|
|
1129
|
-
yield*
|
|
1130
|
-
return yield*
|
|
1179
|
+
yield* Effect10.logInfo(`Connected to ${url}`);
|
|
1180
|
+
return yield* Effect10.never;
|
|
1131
1181
|
}).pipe(
|
|
1132
|
-
|
|
1133
|
-
|
|
1182
|
+
Effect10.scoped,
|
|
1183
|
+
Effect10.provide(makeServicesLayer(data))
|
|
1134
1184
|
)
|
|
1135
|
-
).pipe(
|
|
1185
|
+
).pipe(Command6.withDescription("Connect to an existing CDP inspector endpoint"));
|
|
1136
1186
|
var NODE_INSPECTOR_REGEX = /Debugger listening on (ws:\/\/[^\s]+)/;
|
|
1137
1187
|
var BUN_INSPECTOR_REGEX = /https:\/\/debug\.bun\.sh\/#([^\s]+)/;
|
|
1138
1188
|
var parseInspectorUrl = (chunk, decoder) => {
|
|
@@ -1147,7 +1197,7 @@ var parseInspectorUrl = (chunk, decoder) => {
|
|
|
1147
1197
|
}
|
|
1148
1198
|
return void 0;
|
|
1149
1199
|
};
|
|
1150
|
-
var command2 =
|
|
1200
|
+
var command2 = Command6.make(
|
|
1151
1201
|
"run",
|
|
1152
1202
|
{
|
|
1153
1203
|
data: dataOption,
|
|
@@ -1155,31 +1205,33 @@ var command2 = Command5.make(
|
|
|
1155
1205
|
Flag3.optional,
|
|
1156
1206
|
Flag3.withHidden
|
|
1157
1207
|
),
|
|
1158
|
-
args:
|
|
1159
|
-
|
|
1160
|
-
|
|
1208
|
+
args: Argument3.string("command").pipe(
|
|
1209
|
+
Argument3.withDescription("The command to run"),
|
|
1210
|
+
Argument3.variadic({ min: 0 })
|
|
1161
1211
|
)
|
|
1162
1212
|
},
|
|
1163
|
-
({ args, data, encodedCommand }) =>
|
|
1213
|
+
({ args, data, encodedCommand }) => Effect10.gen(function* () {
|
|
1164
1214
|
const resolvedArgs = Option3.isSome(encodedCommand) ? JSON.parse(Buffer.from(encodedCommand.value, "base64url").toString("utf8")) : args;
|
|
1165
1215
|
const [rawExecutable, ...commandArgs] = resolvedArgs;
|
|
1166
1216
|
const executable = rawExecutable === "node" ? process.execPath : rawExecutable;
|
|
1167
|
-
|
|
1168
|
-
yield*
|
|
1217
|
+
const runId = yield* RunId;
|
|
1218
|
+
yield* Console2.log(`Run ID: ${runId}`);
|
|
1219
|
+
yield* Effect10.logDebug(`Running: ${executable} ${commandArgs.join(" ")}`);
|
|
1220
|
+
yield* Effect10.logDebug(`Data file: ${data}`);
|
|
1169
1221
|
const bootloaderPath = yield* getPath;
|
|
1170
|
-
yield*
|
|
1222
|
+
yield* Effect10.logDebug(`Bootloader: ${bootloaderPath}`);
|
|
1171
1223
|
const ipcServer = yield* IpcServer;
|
|
1172
|
-
yield*
|
|
1224
|
+
yield* Effect10.logDebug(`IPC socket: ${ipcServer.path}`);
|
|
1173
1225
|
const collector = yield* EventCollector;
|
|
1174
1226
|
const cdpManager = yield* CdpManager;
|
|
1175
1227
|
const env = buildEnv(bootloaderPath, ipcServer.path);
|
|
1176
|
-
yield*
|
|
1177
|
-
yield* Stream.runForEach(ipcServer.messages, (message) =>
|
|
1228
|
+
yield* Effect10.logDebug(`NODE_OPTIONS: ${env.NODE_OPTIONS}`);
|
|
1229
|
+
yield* Stream.runForEach(ipcServer.messages, (message) => Effect10.gen(function* () {
|
|
1178
1230
|
yield* collector.collect(message);
|
|
1179
1231
|
if (message._tag === "InitNotification" && message.inspectorURL) {
|
|
1180
1232
|
yield* cdpManager.connect(message.inspectorURL);
|
|
1181
1233
|
}
|
|
1182
|
-
})).pipe(
|
|
1234
|
+
})).pipe(Effect10.forkScoped);
|
|
1183
1235
|
const cmd = ChildProcess.make(executable, commandArgs, {
|
|
1184
1236
|
env,
|
|
1185
1237
|
extendEnv: true,
|
|
@@ -1188,35 +1240,35 @@ var command2 = Command5.make(
|
|
|
1188
1240
|
stdout: "inherit"
|
|
1189
1241
|
});
|
|
1190
1242
|
const childProcess = yield* cmd;
|
|
1191
|
-
yield*
|
|
1243
|
+
yield* Effect10.logDebug(`Started process with PID: ${childProcess.pid}`);
|
|
1192
1244
|
const textDecoder = new TextDecoder();
|
|
1193
1245
|
yield* Stream.runForEach(
|
|
1194
1246
|
childProcess.stderr,
|
|
1195
|
-
(chunk) =>
|
|
1196
|
-
yield*
|
|
1247
|
+
(chunk) => Effect10.gen(function* () {
|
|
1248
|
+
yield* Effect10.sync(() => process.stderr.write(chunk));
|
|
1197
1249
|
const inspectorUrl = parseInspectorUrl(chunk, textDecoder);
|
|
1198
1250
|
if (inspectorUrl) {
|
|
1199
|
-
yield*
|
|
1251
|
+
yield* Effect10.logDebug(`Detected inspector URL from stderr: ${inspectorUrl}`);
|
|
1200
1252
|
yield* cdpManager.connect(inspectorUrl);
|
|
1201
1253
|
}
|
|
1202
1254
|
})
|
|
1203
|
-
).pipe(
|
|
1204
|
-
const forwardSignal = (signal) =>
|
|
1255
|
+
).pipe(Effect10.forkScoped);
|
|
1256
|
+
const forwardSignal = (signal) => Effect10.sync(() => {
|
|
1205
1257
|
process.on(signal, () => {
|
|
1206
|
-
|
|
1258
|
+
Effect10.runPromise(childProcess.kill({ killSignal: signal }).pipe(Effect10.ignore));
|
|
1207
1259
|
});
|
|
1208
1260
|
});
|
|
1209
1261
|
yield* forwardSignal("SIGTERM");
|
|
1210
1262
|
yield* forwardSignal("SIGINT");
|
|
1211
1263
|
yield* forwardSignal("SIGHUP");
|
|
1212
1264
|
const exitCode = yield* childProcess.exitCode;
|
|
1213
|
-
yield*
|
|
1214
|
-
yield*
|
|
1265
|
+
yield* Effect10.logDebug(`Process exited with code: ${exitCode}`);
|
|
1266
|
+
yield* Effect10.sync(() => process.exitCode = exitCode);
|
|
1215
1267
|
}).pipe(
|
|
1216
|
-
|
|
1217
|
-
|
|
1268
|
+
Effect10.scoped,
|
|
1269
|
+
Effect10.provide(makeServicesLayer(data))
|
|
1218
1270
|
)
|
|
1219
|
-
).pipe(
|
|
1271
|
+
).pipe(Command6.withDescription("Run a command with Effect instrumentation"));
|
|
1220
1272
|
var getSpanId = (span) => span.spanId;
|
|
1221
1273
|
var getTraceId = (span) => span.traceId;
|
|
1222
1274
|
var getParentSpanId = (span) => span._tag === "Span" ? span.parentSpanId : null;
|
|
@@ -1341,11 +1393,123 @@ var renderSpanGraph = (graph) => {
|
|
|
1341
1393
|
return rootDocs.filter((doc) => doc.length > 0).join("\n");
|
|
1342
1394
|
};
|
|
1343
1395
|
|
|
1344
|
-
// src/cli/
|
|
1345
|
-
var
|
|
1396
|
+
// src/cli/span.ts
|
|
1397
|
+
var attributesToObject = (attributes) => Object.fromEntries(attributes);
|
|
1398
|
+
var command3 = Command6.make(
|
|
1399
|
+
"span",
|
|
1400
|
+
{
|
|
1401
|
+
data: dataOption,
|
|
1402
|
+
json: jsonOption,
|
|
1403
|
+
traceId: Argument3.string("trace-id").pipe(
|
|
1404
|
+
Argument3.withDescription("The trace ID containing the span")
|
|
1405
|
+
),
|
|
1406
|
+
spanId: Argument3.string("span-id").pipe(
|
|
1407
|
+
Argument3.withDescription("The span ID to display")
|
|
1408
|
+
)
|
|
1409
|
+
},
|
|
1410
|
+
({ data, json, spanId, traceId }) => Effect10.gen(function* () {
|
|
1411
|
+
const storage = yield* Storage;
|
|
1412
|
+
const spans = yield* storage.getSpans({ spanId, traceId });
|
|
1413
|
+
const span = spans[0];
|
|
1414
|
+
if (span === void 0) {
|
|
1415
|
+
yield* Console2.log(`No span found for trace: ${traceId}, span: ${spanId}`);
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
const events = yield* storage.getSpanEvents({ traceId, spanId });
|
|
1419
|
+
const links = yield* storage.getSpanLinks({ traceId, spanId });
|
|
1420
|
+
const startTime = getStartTime(span);
|
|
1421
|
+
const endTime = getEndTime(span);
|
|
1422
|
+
const durationNanos = endTime !== null ? endTime - startTime : null;
|
|
1423
|
+
if (json) {
|
|
1424
|
+
const output = {
|
|
1425
|
+
span: {
|
|
1426
|
+
spanId: getSpanId(span),
|
|
1427
|
+
traceId: getTraceId(span),
|
|
1428
|
+
parentSpanId: getParentSpanId(span),
|
|
1429
|
+
name: getSpanName(span),
|
|
1430
|
+
kind: getSpanKind(span),
|
|
1431
|
+
statusCode: getStatusCode(span),
|
|
1432
|
+
statusMessage: getStatusMessage(span),
|
|
1433
|
+
startTime: formatTimestamp(startTime),
|
|
1434
|
+
endTime: endTime !== null ? formatTimestamp(endTime) : null,
|
|
1435
|
+
durationMs: durationNanos !== null ? Number(durationNanos / 1000000n) : null,
|
|
1436
|
+
attributes: getAttributes(span),
|
|
1437
|
+
isExternal: isExternalSpan(span)
|
|
1438
|
+
},
|
|
1439
|
+
events: events.map((event) => ({
|
|
1440
|
+
name: event.name,
|
|
1441
|
+
time: formatTimestamp(event.time),
|
|
1442
|
+
attributes: attributesToObject(event.attributes)
|
|
1443
|
+
})),
|
|
1444
|
+
links: links.map((link) => ({
|
|
1445
|
+
linkedSpanId: link.linkedSpanId,
|
|
1446
|
+
linkedTraceId: link.linkedTraceId,
|
|
1447
|
+
attributes: attributesToObject(link.attributes)
|
|
1448
|
+
}))
|
|
1449
|
+
};
|
|
1450
|
+
yield* Console2.log(JSON.stringify(output, null, 2));
|
|
1451
|
+
} else {
|
|
1452
|
+
const fields = [
|
|
1453
|
+
field("Span", getSpanId(span)),
|
|
1454
|
+
field("Name", getSpanName(span)),
|
|
1455
|
+
field("Trace", getTraceId(span)),
|
|
1456
|
+
field("Kind", String(getSpanKind(span))),
|
|
1457
|
+
field("Status", formatStatusDoc(getStatusCode(span))),
|
|
1458
|
+
field("Started", formatTimestamp(startTime)),
|
|
1459
|
+
field("Duration", durationNanos !== null ? formatDuration(durationNanos) : "running")
|
|
1460
|
+
];
|
|
1461
|
+
const parentSpanId = getParentSpanId(span);
|
|
1462
|
+
if (parentSpanId !== null) {
|
|
1463
|
+
fields.push(field("Parent", parentSpanId));
|
|
1464
|
+
}
|
|
1465
|
+
if (endTime !== null) {
|
|
1466
|
+
fields.push(field("Ended", formatTimestamp(endTime)));
|
|
1467
|
+
}
|
|
1468
|
+
const statusMessage = getStatusMessage(span);
|
|
1469
|
+
if (statusMessage !== null) {
|
|
1470
|
+
fields.push(field("Status Message", statusMessage));
|
|
1471
|
+
}
|
|
1472
|
+
const attrs = getAttributes(span);
|
|
1473
|
+
if (Object.keys(attrs).length > 0) {
|
|
1474
|
+
fields.push(field("Attrs", JSON.stringify(attrs)));
|
|
1475
|
+
}
|
|
1476
|
+
const eventDocs = events.length === 0 ? ["Events: none"] : [
|
|
1477
|
+
`Events (${events.length}):`,
|
|
1478
|
+
...events.map((event) => {
|
|
1479
|
+
const attrs2 = attributesToObject(event.attributes);
|
|
1480
|
+
const lines = [` ${event.name} @ ${formatTimestamp(event.time)}`];
|
|
1481
|
+
if (Object.keys(attrs2).length > 0) {
|
|
1482
|
+
lines.push(` ${field("Attrs", JSON.stringify(attrs2))}`);
|
|
1483
|
+
}
|
|
1484
|
+
return lines.join("\n");
|
|
1485
|
+
})
|
|
1486
|
+
];
|
|
1487
|
+
const linkDocs = links.length === 0 ? ["Links: none"] : [
|
|
1488
|
+
`Links (${links.length}):`,
|
|
1489
|
+
...links.map((link) => {
|
|
1490
|
+
const attrs2 = attributesToObject(link.attributes);
|
|
1491
|
+
const lines = [` ${link.linkedTraceId}/${link.linkedSpanId}`];
|
|
1492
|
+
if (Object.keys(attrs2).length > 0) {
|
|
1493
|
+
lines.push(` ${field("Attrs", JSON.stringify(attrs2))}`);
|
|
1494
|
+
}
|
|
1495
|
+
return lines.join("\n");
|
|
1496
|
+
})
|
|
1497
|
+
];
|
|
1498
|
+
yield* Console2.log(renderDoc([...fields, "", ...eventDocs, "", ...linkDocs].join("\n")));
|
|
1499
|
+
}
|
|
1500
|
+
}).pipe(
|
|
1501
|
+
Effect10.scoped,
|
|
1502
|
+
Effect10.provide(makeReadOnlyLayer(data))
|
|
1503
|
+
)
|
|
1504
|
+
).pipe(Command6.withDescription("Show detailed span information"));
|
|
1505
|
+
var command4 = Command6.make(
|
|
1346
1506
|
"spans",
|
|
1347
1507
|
{
|
|
1348
1508
|
data: dataOption,
|
|
1509
|
+
runId: Flag3.string("run-id").pipe(
|
|
1510
|
+
Flag3.withDescription("Filter by run ID"),
|
|
1511
|
+
Flag3.optional
|
|
1512
|
+
),
|
|
1349
1513
|
json: jsonOption,
|
|
1350
1514
|
limit: limitOption,
|
|
1351
1515
|
minDuration: Flag3.string("min-duration").pipe(
|
|
@@ -1356,17 +1520,21 @@ var command3 = Command5.make(
|
|
|
1356
1520
|
Flag3.withDescription("Filter by span name (use % for wildcards)"),
|
|
1357
1521
|
Flag3.optional
|
|
1358
1522
|
),
|
|
1523
|
+
spanId: Flag3.string("span-id").pipe(
|
|
1524
|
+
Flag3.withDescription("Filter by span ID"),
|
|
1525
|
+
Flag3.optional
|
|
1526
|
+
),
|
|
1359
1527
|
status: Flag3.string("status").pipe(
|
|
1360
1528
|
Flag3.withDescription("Filter by status: ok, error, unset"),
|
|
1361
1529
|
Flag3.optional
|
|
1362
1530
|
),
|
|
1363
|
-
trace: Flag3.string("trace").pipe(
|
|
1531
|
+
trace: Flag3.string("trace-id").pipe(
|
|
1364
1532
|
Flag3.withAlias("t"),
|
|
1365
1533
|
Flag3.withDescription("Filter by trace ID"),
|
|
1366
1534
|
Flag3.optional
|
|
1367
1535
|
)
|
|
1368
1536
|
},
|
|
1369
|
-
({ data, json, limit, minDuration, name, status, trace }) =>
|
|
1537
|
+
({ data, json, limit, minDuration, name, runId, spanId, status, trace }) => Effect10.gen(function* () {
|
|
1370
1538
|
const storage = yield* Storage;
|
|
1371
1539
|
let statusCode;
|
|
1372
1540
|
if (Option3.isSome(status)) {
|
|
@@ -1381,10 +1549,12 @@ var command3 = Command5.make(
|
|
|
1381
1549
|
statusCode = 0;
|
|
1382
1550
|
break;
|
|
1383
1551
|
default:
|
|
1384
|
-
yield*
|
|
1552
|
+
yield* Effect10.logWarning(`Unknown status: ${status.value}, ignoring filter`);
|
|
1385
1553
|
}
|
|
1386
1554
|
}
|
|
1387
1555
|
const filters = {
|
|
1556
|
+
...Option3.isSome(runId) ? { runId: runId.value } : {},
|
|
1557
|
+
...Option3.isSome(spanId) ? { spanId: spanId.value } : {},
|
|
1388
1558
|
...Option3.isSome(trace) ? { traceId: trace.value } : {},
|
|
1389
1559
|
...Option3.isSome(name) ? { name: name.value } : {},
|
|
1390
1560
|
...statusCode !== void 0 ? { status: statusCode } : {},
|
|
@@ -1411,10 +1581,10 @@ var command3 = Command5.make(
|
|
|
1411
1581
|
isExternal: isExternalSpan(s)
|
|
1412
1582
|
};
|
|
1413
1583
|
});
|
|
1414
|
-
yield*
|
|
1584
|
+
yield* Console2.log(JSON.stringify(output, null, 2));
|
|
1415
1585
|
} else {
|
|
1416
1586
|
if (spans.length === 0) {
|
|
1417
|
-
yield*
|
|
1587
|
+
yield* Console2.log("No spans found.");
|
|
1418
1588
|
} else {
|
|
1419
1589
|
const spanItems = spans.map((s) => {
|
|
1420
1590
|
const endTime = getEndTime(s);
|
|
@@ -1444,28 +1614,28 @@ var command3 = Command5.make(
|
|
|
1444
1614
|
"",
|
|
1445
1615
|
...spanItems
|
|
1446
1616
|
].join("\n");
|
|
1447
|
-
yield*
|
|
1617
|
+
yield* Console2.log(renderDoc(doc));
|
|
1448
1618
|
}
|
|
1449
1619
|
}
|
|
1450
1620
|
}).pipe(
|
|
1451
|
-
|
|
1452
|
-
|
|
1621
|
+
Effect10.scoped,
|
|
1622
|
+
Effect10.provide(makeReadOnlyLayer(data))
|
|
1453
1623
|
)
|
|
1454
|
-
).pipe(
|
|
1455
|
-
var
|
|
1624
|
+
).pipe(Command6.withDescription("List spans with optional filters"));
|
|
1625
|
+
var command5 = Command6.make(
|
|
1456
1626
|
"trace",
|
|
1457
1627
|
{
|
|
1458
1628
|
data: dataOption,
|
|
1459
1629
|
json: jsonOption,
|
|
1460
|
-
traceId:
|
|
1461
|
-
|
|
1630
|
+
traceId: Argument3.string("trace-id").pipe(
|
|
1631
|
+
Argument3.withDescription("The trace ID to display")
|
|
1462
1632
|
)
|
|
1463
1633
|
},
|
|
1464
|
-
({ data, json, traceId }) =>
|
|
1634
|
+
({ data, json, traceId }) => Effect10.gen(function* () {
|
|
1465
1635
|
const storage = yield* Storage;
|
|
1466
1636
|
const spans = yield* storage.getSpans({ traceId });
|
|
1467
1637
|
if (spans.length === 0) {
|
|
1468
|
-
yield*
|
|
1638
|
+
yield* Console2.log(`No spans found for trace: ${traceId}`);
|
|
1469
1639
|
return;
|
|
1470
1640
|
}
|
|
1471
1641
|
const traces = yield* storage.getTraces({ limit: 1 });
|
|
@@ -1507,7 +1677,7 @@ var command4 = Command5.make(
|
|
|
1507
1677
|
spanCount: spans.length,
|
|
1508
1678
|
spans: roots.map((r) => buildJsonTree(graph, r.index))
|
|
1509
1679
|
};
|
|
1510
|
-
yield*
|
|
1680
|
+
yield* Console2.log(JSON.stringify(output, null, 2));
|
|
1511
1681
|
} else {
|
|
1512
1682
|
const header = [
|
|
1513
1683
|
field("Trace", traceId),
|
|
@@ -1515,18 +1685,22 @@ var command4 = Command5.make(
|
|
|
1515
1685
|
""
|
|
1516
1686
|
].join("\n");
|
|
1517
1687
|
const treeDoc = renderSpanGraph(graph);
|
|
1518
|
-
yield*
|
|
1688
|
+
yield* Console2.log(renderDoc([header, treeDoc].filter((line) => line.length > 0).join("\n")));
|
|
1519
1689
|
}
|
|
1520
1690
|
}).pipe(
|
|
1521
|
-
|
|
1522
|
-
|
|
1691
|
+
Effect10.scoped,
|
|
1692
|
+
Effect10.provide(makeReadOnlyLayer(data))
|
|
1523
1693
|
)
|
|
1524
|
-
).pipe(
|
|
1525
|
-
var
|
|
1694
|
+
).pipe(Command6.withDescription("Show a trace as a tree view"));
|
|
1695
|
+
var command6 = Command6.make(
|
|
1526
1696
|
"traces",
|
|
1527
1697
|
{
|
|
1528
1698
|
data: dataOption,
|
|
1529
1699
|
json: jsonOption,
|
|
1700
|
+
runId: Flag3.string("run-id").pipe(
|
|
1701
|
+
Flag3.withDescription("Filter by run ID"),
|
|
1702
|
+
Flag3.optional
|
|
1703
|
+
),
|
|
1530
1704
|
limit: limitOption,
|
|
1531
1705
|
since: Flag3.string("since").pipe(
|
|
1532
1706
|
Flag3.withDescription("Filter by time range (e.g., '1h', '30m')"),
|
|
@@ -1537,7 +1711,7 @@ var command5 = Command5.make(
|
|
|
1537
1711
|
Flag3.optional
|
|
1538
1712
|
)
|
|
1539
1713
|
},
|
|
1540
|
-
({ data, json, limit, since, status }) =>
|
|
1714
|
+
({ data, json, limit, runId, since, status }) => Effect10.gen(function* () {
|
|
1541
1715
|
const storage = yield* Storage;
|
|
1542
1716
|
let statusCode;
|
|
1543
1717
|
if (Option3.isSome(status)) {
|
|
@@ -1552,7 +1726,7 @@ var command5 = Command5.make(
|
|
|
1552
1726
|
statusCode = 0;
|
|
1553
1727
|
break;
|
|
1554
1728
|
default:
|
|
1555
|
-
yield*
|
|
1729
|
+
yield* Effect10.logWarning(`Unknown status: ${status.value}, ignoring filter`);
|
|
1556
1730
|
}
|
|
1557
1731
|
}
|
|
1558
1732
|
let sinceNanos;
|
|
@@ -1562,6 +1736,7 @@ var command5 = Command5.make(
|
|
|
1562
1736
|
sinceNanos = nowNanos - durationNanos;
|
|
1563
1737
|
}
|
|
1564
1738
|
const filters = {
|
|
1739
|
+
...Option3.isSome(runId) ? { runId: runId.value } : {},
|
|
1565
1740
|
...statusCode !== void 0 ? { status: statusCode } : {},
|
|
1566
1741
|
...sinceNanos !== void 0 ? { since: sinceNanos } : {},
|
|
1567
1742
|
...Option3.isSome(limit) ? { limit: limit.value } : {}
|
|
@@ -1577,10 +1752,10 @@ var command5 = Command5.make(
|
|
|
1577
1752
|
endTime: t.end_time ? formatTimestamp(t.end_time) : null,
|
|
1578
1753
|
durationMs: t.end_time ? Number((t.end_time - t.start_time) / 1000000n) : null
|
|
1579
1754
|
}));
|
|
1580
|
-
yield*
|
|
1755
|
+
yield* Console2.log(JSON.stringify(output, null, 2));
|
|
1581
1756
|
} else {
|
|
1582
1757
|
if (traces.length === 0) {
|
|
1583
|
-
yield*
|
|
1758
|
+
yield* Console2.log("No traces found.");
|
|
1584
1759
|
} else {
|
|
1585
1760
|
const traceItems = traces.map((t) => {
|
|
1586
1761
|
const duration = t.end_time ? formatDuration(t.end_time - t.start_time) : "running";
|
|
@@ -1598,21 +1773,24 @@ var command5 = Command5.make(
|
|
|
1598
1773
|
"",
|
|
1599
1774
|
...traceItems
|
|
1600
1775
|
].join("\n");
|
|
1601
|
-
yield*
|
|
1776
|
+
yield* Console2.log(renderDoc(doc));
|
|
1602
1777
|
}
|
|
1603
1778
|
}
|
|
1604
1779
|
}).pipe(
|
|
1605
|
-
|
|
1606
|
-
|
|
1780
|
+
Effect10.scoped,
|
|
1781
|
+
Effect10.provide(makeReadOnlyLayer(data))
|
|
1607
1782
|
)
|
|
1608
|
-
).pipe(
|
|
1783
|
+
).pipe(Command6.withDescription("List traces with optional filters"));
|
|
1609
1784
|
|
|
1610
1785
|
// src/cli.ts
|
|
1611
|
-
var
|
|
1612
|
-
|
|
1613
|
-
|
|
1786
|
+
var command7 = Command6.make("inspeffct").pipe(
|
|
1787
|
+
Command6.withDescription("Inspect Effect applications without code changes"),
|
|
1788
|
+
Command6.withSubcommands([
|
|
1789
|
+
{ group: "Capture", commands: [command2, command] },
|
|
1790
|
+
{ group: "Inspect", commands: [command6, command5, command4, command3] }
|
|
1791
|
+
])
|
|
1614
1792
|
);
|
|
1615
|
-
var cli =
|
|
1793
|
+
var cli = Command6.runWith(command7, {
|
|
1616
1794
|
version: "0.0.1"
|
|
1617
1795
|
});
|
|
1618
1796
|
var encodeRunSeparator = (args) => {
|
|
@@ -1629,6 +1807,6 @@ var run = (args) => cli(encodeRunSeparator(args));
|
|
|
1629
1807
|
|
|
1630
1808
|
// src/bin.ts
|
|
1631
1809
|
run(process.argv.slice(2)).pipe(
|
|
1632
|
-
|
|
1810
|
+
Effect10.provide(NodeServices.layer),
|
|
1633
1811
|
NodeRuntime.runMain
|
|
1634
1812
|
);
|