@noego/wood 0.4.6 → 0.4.8
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/bin/wood.js +6 -1
- package/dist/client/app_env.cjs +39 -0
- package/dist/client/app_env.cjs.map +1 -0
- package/dist/client/app_env.d.cts +7 -0
- package/dist/client/app_env.d.ts +7 -0
- package/dist/client/app_env.js +14 -0
- package/dist/client/app_env.js.map +1 -0
- package/dist/client/index.cjs +33 -9
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +5 -1
- package/dist/client/index.d.ts +5 -1
- package/dist/client/index.js +32 -9
- package/dist/client/index.js.map +1 -1
- package/dist/codegen/channel_map_generator.cjs +102 -0
- package/dist/codegen/channel_map_generator.cjs.map +1 -0
- package/dist/codegen/channel_map_generator.d.cts +6 -0
- package/dist/codegen/channel_map_generator.d.ts +6 -0
- package/dist/codegen/channel_map_generator.js +78 -0
- package/dist/codegen/channel_map_generator.js.map +1 -0
- package/dist/codegen/controller_registration_generator.cjs +6 -1
- package/dist/codegen/controller_registration_generator.cjs.map +1 -1
- package/dist/codegen/controller_registration_generator.js +6 -1
- package/dist/codegen/controller_registration_generator.js.map +1 -1
- package/dist/codegen/generated_file_notice.cjs +40 -0
- package/dist/codegen/generated_file_notice.cjs.map +1 -0
- package/dist/codegen/generated_file_notice.d.cts +3 -0
- package/dist/codegen/generated_file_notice.d.ts +3 -0
- package/dist/codegen/generated_file_notice.js +16 -0
- package/dist/codegen/generated_file_notice.js.map +1 -0
- package/dist/codegen/index.cjs +3 -0
- package/dist/codegen/index.cjs.map +1 -1
- package/dist/codegen/index.d.cts +1 -0
- package/dist/codegen/index.d.ts +1 -0
- package/dist/codegen/index.js +2 -0
- package/dist/codegen/index.js.map +1 -1
- package/dist/codegen/preload_generator.cjs +97 -1
- package/dist/codegen/preload_generator.cjs.map +1 -1
- package/dist/codegen/preload_generator.js +97 -1
- package/dist/codegen/preload_generator.js.map +1 -1
- package/dist/codegen/renderer_app_generator.cjs +6 -1
- package/dist/codegen/renderer_app_generator.cjs.map +1 -1
- package/dist/codegen/renderer_app_generator.js +6 -1
- package/dist/codegen/renderer_app_generator.js.map +1 -1
- package/dist/codegen/renderer_controller_registration_generator.cjs +6 -1
- package/dist/codegen/renderer_controller_registration_generator.cjs.map +1 -1
- package/dist/codegen/renderer_controller_registration_generator.js +6 -1
- package/dist/codegen/renderer_controller_registration_generator.js.map +1 -1
- package/dist/codegen/renderer_view_manifest_generator.cjs +6 -1
- package/dist/codegen/renderer_view_manifest_generator.cjs.map +1 -1
- package/dist/codegen/renderer_view_manifest_generator.js +6 -1
- package/dist/codegen/renderer_view_manifest_generator.js.map +1 -1
- package/dist/codegen/runtime_generator.cjs +6 -1
- package/dist/codegen/runtime_generator.cjs.map +1 -1
- package/dist/codegen/runtime_generator.js +6 -1
- package/dist/codegen/runtime_generator.js.map +1 -1
- package/dist/codegen/test_mock_generator.cjs +5 -1
- package/dist/codegen/test_mock_generator.cjs.map +1 -1
- package/dist/codegen/test_mock_generator.js +5 -1
- package/dist/codegen/test_mock_generator.js.map +1 -1
- package/dist/codegen/type_generator.cjs +6 -1
- package/dist/codegen/type_generator.cjs.map +1 -1
- package/dist/codegen/type_generator.js +6 -1
- package/dist/codegen/type_generator.js.map +1 -1
- package/dist/index.cjs +19 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/main/index.cjs +133 -55
- package/dist/main/index.cjs.map +1 -1
- package/dist/main/index.d.cts +30 -2
- package/dist/main/index.d.ts +30 -2
- package/dist/main/index.js +134 -55
- package/dist/main/index.js.map +1 -1
- package/dist/main/renderer_trace_drain_coordinator.cjs +127 -0
- package/dist/main/renderer_trace_drain_coordinator.cjs.map +1 -0
- package/dist/main/renderer_trace_drain_coordinator.d.cts +46 -0
- package/dist/main/renderer_trace_drain_coordinator.d.ts +46 -0
- package/dist/main/renderer_trace_drain_coordinator.js +101 -0
- package/dist/main/renderer_trace_drain_coordinator.js.map +1 -0
- package/dist/router/wood_router.cjs +9 -1
- package/dist/router/wood_router.cjs.map +1 -1
- package/dist/router/wood_router.d.cts +1 -1
- package/dist/router/wood_router.d.ts +1 -1
- package/dist/router/wood_router.js +9 -1
- package/dist/router/wood_router.js.map +1 -1
- package/dist/runtime/app_env.cjs +52 -0
- package/dist/runtime/app_env.cjs.map +1 -0
- package/dist/runtime/app_env.d.cts +10 -0
- package/dist/runtime/app_env.d.ts +10 -0
- package/dist/runtime/app_env.js +18 -0
- package/dist/runtime/app_env.js.map +1 -0
- package/dist/runtime/index.cjs +9 -2
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +5 -1
- package/dist/runtime/index.d.ts +5 -1
- package/dist/runtime/index.js +9 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/renderer_log_dispatcher.cjs.map +1 -1
- package/dist/runtime/renderer_log_dispatcher.d.cts +1 -1
- package/dist/runtime/renderer_log_dispatcher.d.ts +1 -1
- package/dist/runtime/renderer_log_dispatcher.js.map +1 -1
- package/dist/runtime/renderer_trace_batch_receiver_registry.cjs +50 -0
- package/dist/runtime/renderer_trace_batch_receiver_registry.cjs.map +1 -0
- package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +10 -0
- package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +10 -0
- package/dist/runtime/renderer_trace_batch_receiver_registry.js +24 -0
- package/dist/runtime/renderer_trace_batch_receiver_registry.js.map +1 -0
- package/dist/runtime/runtime.cjs +75 -57
- package/dist/runtime/runtime.cjs.map +1 -1
- package/dist/runtime/runtime.d.cts +8 -1
- package/dist/runtime/runtime.d.ts +8 -1
- package/dist/runtime/runtime.js +80 -58
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/testing/browser.cjs +540 -11
- package/dist/testing/browser.cjs.map +1 -1
- package/dist/testing/browser.d.cts +219 -3
- package/dist/testing/browser.d.ts +219 -3
- package/dist/testing/browser.js +540 -11
- package/dist/testing/browser.js.map +1 -1
- package/dist/testing/create_controller_harness.d.cts +1 -1
- package/dist/testing/create_controller_harness.d.ts +1 -1
- package/dist/testing/index.cjs +13 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +7 -2
- package/dist/testing/index.d.ts +7 -2
- package/dist/testing/index.js +14 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/trace-testing/index.d.cts +1 -1
- package/dist/trace-testing/index.d.ts +1 -1
- package/dist/trace-testing/trace_recorder.d.cts +1 -1
- package/dist/trace-testing/trace_recorder.d.ts +1 -1
- package/dist/trace-transport/index.cjs +32 -0
- package/dist/trace-transport/index.cjs.map +1 -0
- package/dist/trace-transport/index.d.cts +6 -0
- package/dist/trace-transport/index.d.ts +6 -0
- package/dist/trace-transport/index.js +7 -0
- package/dist/trace-transport/index.js.map +1 -0
- package/dist/trace_hub-Cob54qRx.d.cts +56 -0
- package/dist/trace_hub-Cob54qRx.d.ts +56 -0
- package/dist/tracing/index.cjs +14 -0
- package/dist/tracing/index.cjs.map +1 -1
- package/dist/tracing/index.d.cts +7 -1
- package/dist/tracing/index.d.ts +7 -1
- package/dist/tracing/index.js +12 -0
- package/dist/tracing/index.js.map +1 -1
- package/dist/tracing/renderer_trace_batch_host.cjs +80 -0
- package/dist/tracing/renderer_trace_batch_host.cjs.map +1 -0
- package/dist/tracing/renderer_trace_batch_host.d.cts +16 -0
- package/dist/tracing/renderer_trace_batch_host.d.ts +16 -0
- package/dist/tracing/renderer_trace_batch_host.js +56 -0
- package/dist/tracing/renderer_trace_batch_host.js.map +1 -0
- package/dist/tracing/renderer_trace_batch_transport.cjs +313 -0
- package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -0
- package/dist/tracing/renderer_trace_batch_transport.d.cts +53 -0
- package/dist/tracing/renderer_trace_batch_transport.d.ts +53 -0
- package/dist/tracing/renderer_trace_batch_transport.js +292 -0
- package/dist/tracing/renderer_trace_batch_transport.js.map +1 -0
- package/dist/tracing/trace_commit_writer.cjs +159 -0
- package/dist/tracing/trace_commit_writer.cjs.map +1 -0
- package/dist/tracing/trace_commit_writer.d.cts +97 -0
- package/dist/tracing/trace_commit_writer.d.ts +97 -0
- package/dist/tracing/trace_commit_writer.js +135 -0
- package/dist/tracing/trace_commit_writer.js.map +1 -0
- package/dist/tracing/trace_hub.cjs +58 -3
- package/dist/tracing/trace_hub.cjs.map +1 -1
- package/dist/tracing/trace_hub.d.cts +2 -46
- package/dist/tracing/trace_hub.d.ts +2 -46
- package/dist/tracing/trace_hub.js +56 -3
- package/dist/tracing/trace_hub.js.map +1 -1
- package/dist/tracing/trace_provider.cjs +42 -12
- package/dist/tracing/trace_provider.cjs.map +1 -1
- package/dist/tracing/trace_provider.d.cts +15 -1
- package/dist/tracing/trace_provider.d.ts +15 -1
- package/dist/tracing/trace_provider.js +43 -12
- package/dist/tracing/trace_provider.js.map +1 -1
- package/dist/tracing/types/wood_trace_batch.types.cjs +17 -0
- package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -0
- package/dist/tracing/types/wood_trace_batch.types.d.cts +124 -0
- package/dist/tracing/types/wood_trace_batch.types.d.ts +124 -0
- package/dist/tracing/types/wood_trace_batch.types.js +1 -0
- package/dist/tracing/types/wood_trace_batch.types.js.map +1 -0
- package/dist/tracing/types/wood_trace_sink.types.cjs +17 -0
- package/dist/tracing/types/wood_trace_sink.types.cjs.map +1 -0
- package/dist/tracing/types/wood_trace_sink.types.d.cts +2 -0
- package/dist/tracing/types/wood_trace_sink.types.d.ts +2 -0
- package/dist/tracing/types/wood_trace_sink.types.js +1 -0
- package/dist/tracing/types/wood_trace_sink.types.js.map +1 -0
- package/dist/tracing/wood_trace_batch_contract.cjs +229 -0
- package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -0
- package/dist/tracing/wood_trace_batch_contract.d.cts +23 -0
- package/dist/tracing/wood_trace_batch_contract.d.ts +23 -0
- package/dist/tracing/wood_trace_batch_contract.js +205 -0
- package/dist/tracing/wood_trace_batch_contract.js.map +1 -0
- package/dist/transport/build_transport_bridge.cjs +62 -0
- package/dist/transport/build_transport_bridge.cjs.map +1 -0
- package/dist/transport/build_transport_bridge.d.cts +29 -0
- package/dist/transport/build_transport_bridge.d.ts +29 -0
- package/dist/transport/build_transport_bridge.js +38 -0
- package/dist/transport/build_transport_bridge.js.map +1 -0
- package/dist/transport/in_process_router_transport.cjs +41 -0
- package/dist/transport/in_process_router_transport.cjs.map +1 -0
- package/dist/transport/in_process_router_transport.d.cts +31 -0
- package/dist/transport/in_process_router_transport.d.ts +31 -0
- package/dist/transport/in_process_router_transport.js +17 -0
- package/dist/transport/in_process_router_transport.js.map +1 -0
- package/dist/transport/index.cjs +42 -0
- package/dist/transport/index.cjs.map +1 -0
- package/dist/transport/index.d.cts +8 -0
- package/dist/transport/index.d.ts +8 -0
- package/dist/transport/index.js +19 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/loopback_remote_transport.cjs +270 -0
- package/dist/transport/loopback_remote_transport.cjs.map +1 -0
- package/dist/transport/loopback_remote_transport.d.cts +49 -0
- package/dist/transport/loopback_remote_transport.d.ts +49 -0
- package/dist/transport/loopback_remote_transport.js +237 -0
- package/dist/transport/loopback_remote_transport.js.map +1 -0
- package/dist/transport/loopback_serialization.cjs +116 -0
- package/dist/transport/loopback_serialization.cjs.map +1 -0
- package/dist/transport/loopback_serialization.d.cts +28 -0
- package/dist/transport/loopback_serialization.d.ts +28 -0
- package/dist/transport/loopback_serialization.js +91 -0
- package/dist/transport/loopback_serialization.js.map +1 -0
- package/dist/transport/transport_contract_suite.cjs +110 -0
- package/dist/transport/transport_contract_suite.cjs.map +1 -0
- package/dist/transport/transport_contract_suite.d.cts +23 -0
- package/dist/transport/transport_contract_suite.d.ts +23 -0
- package/dist/transport/transport_contract_suite.js +85 -0
- package/dist/transport/transport_contract_suite.js.map +1 -0
- package/dist/transport/wood_rpc_transport.cjs +17 -0
- package/dist/transport/wood_rpc_transport.cjs.map +1 -0
- package/dist/transport/wood_rpc_transport.d.cts +44 -0
- package/dist/transport/wood_rpc_transport.d.ts +44 -0
- package/dist/transport/wood_rpc_transport.js +1 -0
- package/dist/transport/wood_rpc_transport.js.map +1 -0
- package/docs/browser-testing.md +139 -1
- package/package.json +25 -4
- package/src/client/app_env.ts +21 -0
- package/src/components/NavigationShell.browser.test.ts +236 -0
- package/src/components/NavigationShell.svelte +162 -49
- package/src/runtime/app_env.ts +27 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { d as TraceProcess, c as TraceLevel, g as WoodTraceEventSnapshot } from '../trace_hub-Cob54qRx.js';
|
|
2
|
+
import 'rxjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A committed trace row. Ordering is authoritative on `commitSeq` — the
|
|
6
|
+
* writer-assigned monotonic sequence stamped at the single ingestion/commit
|
|
7
|
+
* boundary. `producerId` + `producerSeq` identify the producer-side stream;
|
|
8
|
+
* `timestamp` is retained for display but is NEVER used for cross-producer
|
|
9
|
+
* ordering (clocks across main/renderer are not causal).
|
|
10
|
+
*/
|
|
11
|
+
interface TraceCommitRow {
|
|
12
|
+
readonly commitSeq: number;
|
|
13
|
+
readonly producerId: string;
|
|
14
|
+
readonly producerSeq: number;
|
|
15
|
+
readonly process: TraceProcess;
|
|
16
|
+
readonly level: TraceLevel;
|
|
17
|
+
readonly type: string;
|
|
18
|
+
readonly source: string;
|
|
19
|
+
readonly message?: string;
|
|
20
|
+
readonly conversationId?: number | string;
|
|
21
|
+
readonly timestamp: string;
|
|
22
|
+
readonly payload?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Storage boundary for committed trace rows. Implemented per-runtime: the app's
|
|
26
|
+
* test backend harness supplies a SQLite-backed adapter (better-sqlite3, which
|
|
27
|
+
* wood does not depend on). `persist` may be sync or async; the writer barrier
|
|
28
|
+
* awaits whatever it returns.
|
|
29
|
+
*/
|
|
30
|
+
interface WoodTracePersistencePort {
|
|
31
|
+
persist(row: TraceCommitRow): void | Promise<void>;
|
|
32
|
+
close?(): void | Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
interface TraceFlushOptions {
|
|
35
|
+
timeoutMs?: number;
|
|
36
|
+
}
|
|
37
|
+
interface TraceFlushResult {
|
|
38
|
+
/** Highest `commitSeq` durably persisted at flush completion. */
|
|
39
|
+
readonly committedHighWaterMark: number;
|
|
40
|
+
}
|
|
41
|
+
interface TraceCommitWriterOptions {
|
|
42
|
+
/** Stable id for the main-process producer stream (default `'main'`). */
|
|
43
|
+
readonly mainProducerId?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The single trace ingestion/commit boundary. Every trace event (main or, in
|
|
47
|
+
* later phases, renderer batches) is admitted here, assigned a monotonic
|
|
48
|
+
* `commitSeq`, and enqueued for persistence. `flush` drains the async write
|
|
49
|
+
* queue and returns the committed high-water mark — no sleeps, no polling.
|
|
50
|
+
*/
|
|
51
|
+
declare class TraceCommitWriter {
|
|
52
|
+
private readonly port;
|
|
53
|
+
private readonly mainProducerId;
|
|
54
|
+
private readonly seen;
|
|
55
|
+
private inflight;
|
|
56
|
+
private nextCommitSeq;
|
|
57
|
+
private committed;
|
|
58
|
+
private pendingError;
|
|
59
|
+
private rendererFlush;
|
|
60
|
+
constructor(port: WoodTracePersistencePort, options?: TraceCommitWriterOptions);
|
|
61
|
+
/**
|
|
62
|
+
* Admit one trace event. Returns the committed row (with its assigned
|
|
63
|
+
* `commitSeq`), or `null` if it is a duplicate of an already-admitted
|
|
64
|
+
* (producerId, producerSeq) pair — this is the batch-retry idempotency guard.
|
|
65
|
+
*/
|
|
66
|
+
admit(event: WoodTraceEventSnapshot): TraceCommitRow | null;
|
|
67
|
+
/** WoodTraceEventSink shape — register via `tracer.registerSink(writer.sink)`. */
|
|
68
|
+
readonly sink: (event: WoodTraceEventSnapshot) => void;
|
|
69
|
+
highWaterMark(): number;
|
|
70
|
+
/**
|
|
71
|
+
* Install the renderer-flush hook (Phase 4 browser mode). The browser harness
|
|
72
|
+
* supplies a function that drains the page's in-flight renderer `__trace`
|
|
73
|
+
* round-trips; `flush()` awaits it before the main-writer barrier so
|
|
74
|
+
* renderer-origin traces are persisted deterministically. Backend mode leaves
|
|
75
|
+
* this unset and `requestRendererFlush` resolves immediately.
|
|
76
|
+
*/
|
|
77
|
+
setRendererFlush(fn: (() => Promise<void>) | null): void;
|
|
78
|
+
/**
|
|
79
|
+
* Request that renderer producers flush their pending batches and await acks.
|
|
80
|
+
* In browser mode the installed hook (see {@link setRendererFlush}) round-trips
|
|
81
|
+
* the page to drain pending `__trace` deliveries. With no hook (backend mode,
|
|
82
|
+
* no renderer) this resolves immediately.
|
|
83
|
+
*/
|
|
84
|
+
requestRendererFlush(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Drain the write queue and return the committed high-water mark. Awaits a
|
|
87
|
+
* barrier over all in-flight persists; with `timeoutMs` it rejects on a
|
|
88
|
+
* timer race rather than polling. Rejects if any persist failed.
|
|
89
|
+
*/
|
|
90
|
+
flush(options?: TraceFlushOptions): Promise<TraceFlushResult>;
|
|
91
|
+
private awaitBarrier;
|
|
92
|
+
private enqueue;
|
|
93
|
+
private resolveProducerId;
|
|
94
|
+
private toRow;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { type TraceCommitRow, TraceCommitWriter, type TraceCommitWriterOptions, type TraceFlushOptions, type TraceFlushResult, type WoodTracePersistencePort };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
class TraceCommitWriter {
|
|
2
|
+
constructor(port, options = {}) {
|
|
3
|
+
this.seen = /* @__PURE__ */ new Set();
|
|
4
|
+
this.inflight = [];
|
|
5
|
+
this.nextCommitSeq = 1;
|
|
6
|
+
this.committed = 0;
|
|
7
|
+
this.pendingError = null;
|
|
8
|
+
this.rendererFlush = null;
|
|
9
|
+
/** WoodTraceEventSink shape — register via `tracer.registerSink(writer.sink)`. */
|
|
10
|
+
this.sink = (event) => {
|
|
11
|
+
this.admit(event);
|
|
12
|
+
};
|
|
13
|
+
this.port = port;
|
|
14
|
+
this.mainProducerId = options.mainProducerId ?? "main";
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Admit one trace event. Returns the committed row (with its assigned
|
|
18
|
+
* `commitSeq`), or `null` if it is a duplicate of an already-admitted
|
|
19
|
+
* (producerId, producerSeq) pair — this is the batch-retry idempotency guard.
|
|
20
|
+
*/
|
|
21
|
+
admit(event) {
|
|
22
|
+
const producerId = this.resolveProducerId(event);
|
|
23
|
+
const producerSeq = event.traceSeq;
|
|
24
|
+
const identity = `${producerId}#${producerSeq}`;
|
|
25
|
+
if (this.seen.has(identity)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
this.seen.add(identity);
|
|
29
|
+
const row = this.toRow(event, producerId, producerSeq);
|
|
30
|
+
this.enqueue(row);
|
|
31
|
+
return row;
|
|
32
|
+
}
|
|
33
|
+
highWaterMark() {
|
|
34
|
+
return this.committed;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Install the renderer-flush hook (Phase 4 browser mode). The browser harness
|
|
38
|
+
* supplies a function that drains the page's in-flight renderer `__trace`
|
|
39
|
+
* round-trips; `flush()` awaits it before the main-writer barrier so
|
|
40
|
+
* renderer-origin traces are persisted deterministically. Backend mode leaves
|
|
41
|
+
* this unset and `requestRendererFlush` resolves immediately.
|
|
42
|
+
*/
|
|
43
|
+
setRendererFlush(fn) {
|
|
44
|
+
this.rendererFlush = fn;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Request that renderer producers flush their pending batches and await acks.
|
|
48
|
+
* In browser mode the installed hook (see {@link setRendererFlush}) round-trips
|
|
49
|
+
* the page to drain pending `__trace` deliveries. With no hook (backend mode,
|
|
50
|
+
* no renderer) this resolves immediately.
|
|
51
|
+
*/
|
|
52
|
+
async requestRendererFlush() {
|
|
53
|
+
if (this.rendererFlush) {
|
|
54
|
+
await this.rendererFlush();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Drain the write queue and return the committed high-water mark. Awaits a
|
|
59
|
+
* barrier over all in-flight persists; with `timeoutMs` it rejects on a
|
|
60
|
+
* timer race rather than polling. Rejects if any persist failed.
|
|
61
|
+
*/
|
|
62
|
+
async flush(options = {}) {
|
|
63
|
+
await this.requestRendererFlush();
|
|
64
|
+
const barrier = Promise.allSettled(this.inflight.slice());
|
|
65
|
+
await this.awaitBarrier(barrier, options.timeoutMs);
|
|
66
|
+
if (this.pendingError !== null) {
|
|
67
|
+
const error = this.pendingError;
|
|
68
|
+
this.pendingError = null;
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
return { committedHighWaterMark: this.committed };
|
|
72
|
+
}
|
|
73
|
+
async awaitBarrier(barrier, timeoutMs) {
|
|
74
|
+
if (timeoutMs === void 0) {
|
|
75
|
+
await barrier;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
let timer = null;
|
|
79
|
+
const timeout = new Promise((_, reject) => {
|
|
80
|
+
timer = setTimeout(
|
|
81
|
+
() => reject(new Error(`trace flush barrier exceeded ${timeoutMs}ms`)),
|
|
82
|
+
timeoutMs
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
try {
|
|
86
|
+
await Promise.race([barrier.then(() => void 0), timeout]);
|
|
87
|
+
} finally {
|
|
88
|
+
if (timer !== null) {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
enqueue(row) {
|
|
94
|
+
const op = Promise.resolve().then(() => this.port.persist(row)).then(
|
|
95
|
+
() => {
|
|
96
|
+
if (row.commitSeq > this.committed) {
|
|
97
|
+
this.committed = row.commitSeq;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
(error) => {
|
|
101
|
+
this.pendingError = error;
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
this.inflight.push(op);
|
|
105
|
+
}
|
|
106
|
+
resolveProducerId(event) {
|
|
107
|
+
if (event.process === "renderer") {
|
|
108
|
+
const rendererId = event.payload?.woodRendererProducerId;
|
|
109
|
+
return typeof rendererId === "string" ? rendererId : "renderer";
|
|
110
|
+
}
|
|
111
|
+
if (event.process === "main") {
|
|
112
|
+
return this.mainProducerId;
|
|
113
|
+
}
|
|
114
|
+
return event.process;
|
|
115
|
+
}
|
|
116
|
+
toRow(event, producerId, producerSeq) {
|
|
117
|
+
return {
|
|
118
|
+
commitSeq: this.nextCommitSeq++,
|
|
119
|
+
producerId,
|
|
120
|
+
producerSeq,
|
|
121
|
+
process: event.process,
|
|
122
|
+
level: event.level,
|
|
123
|
+
type: event.type,
|
|
124
|
+
source: event.source,
|
|
125
|
+
...event.message !== void 0 ? { message: event.message } : {},
|
|
126
|
+
...event.conversationId !== void 0 ? { conversationId: event.conversationId } : {},
|
|
127
|
+
timestamp: event.timestamp,
|
|
128
|
+
...event.payload ? { payload: { ...event.payload } } : {}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export {
|
|
133
|
+
TraceCommitWriter
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=trace_commit_writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/tracing/trace_commit_writer.ts"],"sourcesContent":["import type { TraceLevel, TraceProcess } from './trace_hub.js';\nimport type { WoodTraceEventSnapshot } from './types/wood_trace_sink.types.js';\n\n/**\n * A committed trace row. Ordering is authoritative on `commitSeq` — the\n * writer-assigned monotonic sequence stamped at the single ingestion/commit\n * boundary. `producerId` + `producerSeq` identify the producer-side stream;\n * `timestamp` is retained for display but is NEVER used for cross-producer\n * ordering (clocks across main/renderer are not causal).\n */\nexport interface TraceCommitRow {\n readonly commitSeq: number;\n readonly producerId: string;\n readonly producerSeq: number;\n readonly process: TraceProcess;\n readonly level: TraceLevel;\n readonly type: string;\n readonly source: string;\n readonly message?: string;\n readonly conversationId?: number | string;\n readonly timestamp: string;\n readonly payload?: Record<string, unknown>;\n}\n\n/**\n * Storage boundary for committed trace rows. Implemented per-runtime: the app's\n * test backend harness supplies a SQLite-backed adapter (better-sqlite3, which\n * wood does not depend on). `persist` may be sync or async; the writer barrier\n * awaits whatever it returns.\n */\nexport interface WoodTracePersistencePort {\n persist(row: TraceCommitRow): void | Promise<void>;\n close?(): void | Promise<void>;\n}\n\nexport interface TraceFlushOptions {\n timeoutMs?: number;\n}\n\nexport interface TraceFlushResult {\n /** Highest `commitSeq` durably persisted at flush completion. */\n readonly committedHighWaterMark: number;\n}\n\nexport interface TraceCommitWriterOptions {\n /** Stable id for the main-process producer stream (default `'main'`). */\n readonly mainProducerId?: string;\n}\n\n/**\n * The single trace ingestion/commit boundary. Every trace event (main or, in\n * later phases, renderer batches) is admitted here, assigned a monotonic\n * `commitSeq`, and enqueued for persistence. `flush` drains the async write\n * queue and returns the committed high-water mark — no sleeps, no polling.\n */\nexport class TraceCommitWriter {\n private readonly port: WoodTracePersistencePort;\n private readonly mainProducerId: string;\n private readonly seen = new Set<string>();\n private inflight: Promise<void>[] = [];\n private nextCommitSeq = 1;\n private committed = 0;\n private pendingError: unknown = null;\n private rendererFlush: (() => Promise<void>) | null = null;\n\n constructor(port: WoodTracePersistencePort, options: TraceCommitWriterOptions = {}) {\n this.port = port;\n this.mainProducerId = options.mainProducerId ?? 'main';\n }\n\n /**\n * Admit one trace event. Returns the committed row (with its assigned\n * `commitSeq`), or `null` if it is a duplicate of an already-admitted\n * (producerId, producerSeq) pair — this is the batch-retry idempotency guard.\n */\n admit(event: WoodTraceEventSnapshot): TraceCommitRow | null {\n const producerId = this.resolveProducerId(event);\n const producerSeq = event.traceSeq;\n const identity = `${producerId}#${producerSeq}`;\n if (this.seen.has(identity)) {\n return null;\n }\n this.seen.add(identity);\n const row = this.toRow(event, producerId, producerSeq);\n this.enqueue(row);\n return row;\n }\n\n /** WoodTraceEventSink shape — register via `tracer.registerSink(writer.sink)`. */\n readonly sink = (event: WoodTraceEventSnapshot): void => {\n this.admit(event);\n };\n\n highWaterMark(): number {\n return this.committed;\n }\n\n /**\n * Install the renderer-flush hook (Phase 4 browser mode). The browser harness\n * supplies a function that drains the page's in-flight renderer `__trace`\n * round-trips; `flush()` awaits it before the main-writer barrier so\n * renderer-origin traces are persisted deterministically. Backend mode leaves\n * this unset and `requestRendererFlush` resolves immediately.\n */\n setRendererFlush(fn: (() => Promise<void>) | null): void {\n this.rendererFlush = fn;\n }\n\n /**\n * Request that renderer producers flush their pending batches and await acks.\n * In browser mode the installed hook (see {@link setRendererFlush}) round-trips\n * the page to drain pending `__trace` deliveries. With no hook (backend mode,\n * no renderer) this resolves immediately.\n */\n async requestRendererFlush(): Promise<void> {\n if (this.rendererFlush) {\n await this.rendererFlush();\n }\n }\n\n /**\n * Drain the write queue and return the committed high-water mark. Awaits a\n * barrier over all in-flight persists; with `timeoutMs` it rejects on a\n * timer race rather than polling. Rejects if any persist failed.\n */\n async flush(options: TraceFlushOptions = {}): Promise<TraceFlushResult> {\n await this.requestRendererFlush();\n const barrier = Promise.allSettled(this.inflight.slice());\n await this.awaitBarrier(barrier, options.timeoutMs);\n if (this.pendingError !== null) {\n const error = this.pendingError;\n this.pendingError = null;\n throw error;\n }\n return { committedHighWaterMark: this.committed };\n }\n\n private async awaitBarrier(\n barrier: Promise<unknown>,\n timeoutMs: number | undefined,\n ): Promise<void> {\n if (timeoutMs === undefined) {\n await barrier;\n return;\n }\n let timer: ReturnType<typeof setTimeout> | null = null;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`trace flush barrier exceeded ${timeoutMs}ms`)),\n timeoutMs,\n );\n });\n try {\n await Promise.race([barrier.then(() => undefined), timeout]);\n } finally {\n if (timer !== null) {\n clearTimeout(timer);\n }\n }\n }\n\n private enqueue(row: TraceCommitRow): void {\n const op = Promise.resolve()\n .then(() => this.port.persist(row))\n .then(\n () => {\n if (row.commitSeq > this.committed) {\n this.committed = row.commitSeq;\n }\n },\n (error: unknown) => {\n this.pendingError = error;\n },\n );\n this.inflight.push(op);\n }\n\n private resolveProducerId(event: WoodTraceEventSnapshot): string {\n if (event.process === 'renderer') {\n const rendererId = event.payload?.woodRendererProducerId;\n return typeof rendererId === 'string' ? rendererId : 'renderer';\n }\n if (event.process === 'main') {\n return this.mainProducerId;\n }\n return event.process;\n }\n\n private toRow(\n event: WoodTraceEventSnapshot,\n producerId: string,\n producerSeq: number,\n ): TraceCommitRow {\n return {\n commitSeq: this.nextCommitSeq++,\n producerId,\n producerSeq,\n process: event.process,\n level: event.level,\n type: event.type,\n source: event.source,\n ...(event.message !== undefined ? { message: event.message } : {}),\n ...(event.conversationId !== undefined ? { conversationId: event.conversationId } : {}),\n timestamp: event.timestamp,\n ...(event.payload ? { payload: { ...event.payload } } : {}),\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -22,8 +22,10 @@ __export(trace_hub_exports, {
|
|
|
22
22
|
dispatchRendererTracePayload: () => dispatchRendererTracePayload,
|
|
23
23
|
emitRendererTrace: () => emitRendererTrace,
|
|
24
24
|
getTraceEvents$: () => getTraceEvents$,
|
|
25
|
+
normalizeTraceLevel: () => normalizeTraceLevel,
|
|
25
26
|
publishMainTrace: () => publishMainTrace,
|
|
26
27
|
publishTestTrace: () => publishTestTrace,
|
|
28
|
+
registerTraceSink: () => registerTraceSink,
|
|
27
29
|
setMainTraceMinLevel: () => setMainTraceMinLevel,
|
|
28
30
|
setRendererTraceEnabled: () => setRendererTraceEnabled,
|
|
29
31
|
setRendererTraceMinLevel: () => setRendererTraceMinLevel,
|
|
@@ -39,6 +41,17 @@ const LEVEL_ORDER = {
|
|
|
39
41
|
warn: 2,
|
|
40
42
|
error: 3
|
|
41
43
|
};
|
|
44
|
+
const CUSTOM_LEVEL_ORDER = LEVEL_ORDER.info;
|
|
45
|
+
function normalizeTraceLevel(level, fallback = "info") {
|
|
46
|
+
if (typeof level !== "string") {
|
|
47
|
+
return fallback;
|
|
48
|
+
}
|
|
49
|
+
const normalized = level.trim().toLowerCase();
|
|
50
|
+
return normalized.length > 0 ? normalized : fallback;
|
|
51
|
+
}
|
|
52
|
+
function traceLevelOrder(level) {
|
|
53
|
+
return LEVEL_ORDER[level] ?? CUSTOM_LEVEL_ORDER;
|
|
54
|
+
}
|
|
42
55
|
let rendererMinLevel = "debug";
|
|
43
56
|
let rendererEnabled = false;
|
|
44
57
|
let customRendererTraceTransport = null;
|
|
@@ -89,6 +102,7 @@ class TraceHub {
|
|
|
89
102
|
constructor() {
|
|
90
103
|
this.subject = new import_rxjs.Subject();
|
|
91
104
|
this.shared$ = this.subject.asObservable().pipe((0, import_operators.share)());
|
|
105
|
+
this.sinks = /* @__PURE__ */ new Set();
|
|
92
106
|
this.nextTraceSeq = 1;
|
|
93
107
|
this.minLevels = {
|
|
94
108
|
main: "debug",
|
|
@@ -102,6 +116,12 @@ class TraceHub {
|
|
|
102
116
|
setMinLevel(process, level) {
|
|
103
117
|
this.minLevels[process] = level;
|
|
104
118
|
}
|
|
119
|
+
registerSink(sink) {
|
|
120
|
+
this.sinks.add(sink);
|
|
121
|
+
return () => {
|
|
122
|
+
this.sinks.delete(sink);
|
|
123
|
+
};
|
|
124
|
+
}
|
|
105
125
|
publish(process, level, input) {
|
|
106
126
|
const normalized = normalizeTraceInput(input);
|
|
107
127
|
const event = {
|
|
@@ -111,11 +131,40 @@ class TraceHub {
|
|
|
111
131
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
112
132
|
traceSeq: this.nextTraceSeq++
|
|
113
133
|
};
|
|
114
|
-
if (
|
|
134
|
+
if (traceLevelOrder(level) >= traceLevelOrder(this.minLevels[process])) {
|
|
135
|
+
this.publishToSinks(event);
|
|
115
136
|
this.subject.next(event);
|
|
116
137
|
}
|
|
117
138
|
return event;
|
|
118
139
|
}
|
|
140
|
+
publishRendererToSinks(level, input) {
|
|
141
|
+
if (this.sinks.size === 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const event = {
|
|
145
|
+
...input,
|
|
146
|
+
level,
|
|
147
|
+
process: "renderer",
|
|
148
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
149
|
+
traceSeq: this.nextTraceSeq++
|
|
150
|
+
};
|
|
151
|
+
this.publishToSinks(event);
|
|
152
|
+
}
|
|
153
|
+
publishToSinks(event) {
|
|
154
|
+
if (this.sinks.size === 0) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const snapshot = Object.freeze({
|
|
158
|
+
...event,
|
|
159
|
+
...event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}
|
|
160
|
+
});
|
|
161
|
+
for (const sink of this.sinks) {
|
|
162
|
+
try {
|
|
163
|
+
sink(snapshot);
|
|
164
|
+
} catch {
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
119
168
|
}
|
|
120
169
|
function getGlobalTraceHub() {
|
|
121
170
|
const globalObj = globalThis;
|
|
@@ -127,6 +176,9 @@ function getGlobalTraceHub() {
|
|
|
127
176
|
function getTraceEvents$() {
|
|
128
177
|
return getGlobalTraceHub().events$;
|
|
129
178
|
}
|
|
179
|
+
function registerTraceSink(sink) {
|
|
180
|
+
return getGlobalTraceHub().registerSink(sink);
|
|
181
|
+
}
|
|
130
182
|
function setMainTraceMinLevel(level) {
|
|
131
183
|
getGlobalTraceHub().setMinLevel("main", level);
|
|
132
184
|
}
|
|
@@ -145,7 +197,7 @@ function publishTestTrace(process, level, input) {
|
|
|
145
197
|
}
|
|
146
198
|
function dispatchRendererTracePayload(rawPayload, context) {
|
|
147
199
|
const payload = rawPayload ?? {};
|
|
148
|
-
const level = payload.level
|
|
200
|
+
const level = normalizeTraceLevel(payload.level);
|
|
149
201
|
getGlobalTraceHub().publish("renderer", level, mergeTraceRuntimeContext(payload, context));
|
|
150
202
|
return {
|
|
151
203
|
ok: true,
|
|
@@ -159,10 +211,11 @@ function emitRendererTrace(level, input) {
|
|
|
159
211
|
if (!rendererEnabled) {
|
|
160
212
|
return;
|
|
161
213
|
}
|
|
162
|
-
if (
|
|
214
|
+
if (traceLevelOrder(level) < traceLevelOrder(rendererMinLevel)) {
|
|
163
215
|
return;
|
|
164
216
|
}
|
|
165
217
|
const normalized = { ...normalizeTraceInput(input), level };
|
|
218
|
+
getGlobalTraceHub().publishRendererToSinks(level, normalized);
|
|
166
219
|
if (customRendererTraceTransport) {
|
|
167
220
|
try {
|
|
168
221
|
customRendererTraceTransport(normalized);
|
|
@@ -192,8 +245,10 @@ function clearTraceHubForTests() {
|
|
|
192
245
|
dispatchRendererTracePayload,
|
|
193
246
|
emitRendererTrace,
|
|
194
247
|
getTraceEvents$,
|
|
248
|
+
normalizeTraceLevel,
|
|
195
249
|
publishMainTrace,
|
|
196
250
|
publishTestTrace,
|
|
251
|
+
registerTraceSink,
|
|
197
252
|
setMainTraceMinLevel,
|
|
198
253
|
setRendererTraceEnabled,
|
|
199
254
|
setRendererTraceMinLevel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/tracing/trace_hub.ts"],"sourcesContent":["import { Observable, Subject } from 'rxjs';\nimport { share } from 'rxjs/operators';\n\nexport type TraceLevel = 'debug' | 'info' | 'warn' | 'error';\nexport type TraceProcess = 'main' | 'renderer' | 'test';\n\nexport type TraceInput = {\n source: string;\n type: string;\n message?: string;\n conversationId?: number | string;\n payload?: Record<string, unknown>;\n windowId?: string;\n webContentsId?: number;\n routeKey?: string;\n harnessId?: string;\n};\n\nexport type TraceEvent = TraceInput & {\n level: TraceLevel;\n process: TraceProcess;\n timestamp: string;\n traceSeq: number;\n};\n\nexport type TraceDispatchResult = {\n ok: boolean;\n forwarded: boolean;\n};\n\nexport type TraceRuntimeContext = {\n windowId?: string;\n webContentsId?: number;\n routeKey?: string;\n harnessId?: string;\n};\n\nexport type TraceWaitOptions = {\n timeoutMs?: number;\n};\n\nconst TRACE_HUB_SYMBOL = Symbol.for('@noego/wood.trace.hub');\n\nconst LEVEL_ORDER: Record<TraceLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nlet rendererMinLevel: TraceLevel = 'debug';\nlet rendererEnabled = false;\nlet customRendererTraceTransport: ((payload: unknown) => void) | null = null;\n\ntype GlobalWithTraceHub = typeof globalThis & {\n [TRACE_HUB_SYMBOL]?: TraceHub;\n};\n\ntype TraceBridgeLike = Record<string, unknown> & {\n __trace?: (payload: unknown) => void;\n};\n\ntype GlobalWithTraceBridge = typeof globalThis & {\n __NOEGO_WOOD_BRIDGE__?: unknown;\n wood?: unknown;\n window?: {\n __NOEGO_WOOD_BRIDGE__?: unknown;\n wood?: unknown;\n };\n};\n\nfunction normalizeTraceInput(raw: unknown): TraceInput {\n const input = (raw ?? {}) as Partial<TraceInput> & Record<string, unknown>;\n const source = typeof input.source === 'string' && input.source.trim().length > 0\n ? input.source\n : 'unknown';\n const type = typeof input.type === 'string' && input.type.trim().length > 0\n ? input.type\n : 'unknown';\n const message = typeof input.message === 'string' ? input.message : undefined;\n const conversationId = typeof input.conversationId === 'number' || typeof input.conversationId === 'string'\n ? input.conversationId\n : undefined;\n const windowId = typeof input.windowId === 'string' && input.windowId.trim().length > 0\n ? input.windowId\n : undefined;\n const webContentsId = typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? input.webContentsId\n : undefined;\n const routeKey = typeof input.routeKey === 'string' && input.routeKey.trim().length > 0\n ? input.routeKey\n : undefined;\n const harnessId = typeof input.harnessId === 'string' && input.harnessId.trim().length > 0\n ? input.harnessId\n : undefined;\n const payload = isRecord(input.payload) ? { ...input.payload } : undefined;\n\n return {\n source,\n type,\n ...(message ? { message } : {}),\n ...(conversationId !== undefined ? { conversationId } : {}),\n ...(windowId !== undefined ? { windowId } : {}),\n ...(webContentsId !== undefined ? { webContentsId } : {}),\n ...(routeKey !== undefined ? { routeKey } : {}),\n ...(harnessId !== undefined ? { harnessId } : {}),\n ...(payload ? { payload } : {}),\n };\n}\n\nfunction mergeTraceRuntimeContext(input: unknown, context: TraceRuntimeContext | undefined): TraceInput {\n if (!context) {\n return normalizeTraceInput(input);\n }\n return normalizeTraceInput({\n ...(isRecord(input) ? input : {}),\n ...context,\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction resolveTraceBridge(): TraceBridgeLike | null {\n const globalObj = globalThis as GlobalWithTraceBridge;\n const bridge = globalObj.__NOEGO_WOOD_BRIDGE__\n ?? globalObj.window?.__NOEGO_WOOD_BRIDGE__\n ?? globalObj.wood\n ?? globalObj.window?.wood;\n if (!bridge || typeof bridge !== 'object') {\n return null;\n }\n return bridge as TraceBridgeLike;\n}\n\nclass TraceHub {\n private readonly subject = new Subject<TraceEvent>();\n private readonly shared$ = this.subject.asObservable().pipe(share());\n private nextTraceSeq = 1;\n private minLevels: Record<TraceProcess, TraceLevel> = {\n main: 'debug',\n renderer: 'debug',\n test: 'debug',\n };\n\n get events$(): Observable<TraceEvent> {\n return this.shared$;\n }\n\n setMinLevel(process: TraceProcess, level: TraceLevel): void {\n this.minLevels[process] = level;\n }\n\n publish(process: TraceProcess, level: TraceLevel, input: unknown): TraceEvent {\n const normalized = normalizeTraceInput(input);\n const event: TraceEvent = {\n ...normalized,\n level,\n process,\n timestamp: new Date().toISOString(),\n traceSeq: this.nextTraceSeq++,\n };\n if (LEVEL_ORDER[level] >= LEVEL_ORDER[this.minLevels[process]]) {\n this.subject.next(event);\n }\n return event;\n }\n}\n\nfunction getGlobalTraceHub(): TraceHub {\n const globalObj = globalThis as GlobalWithTraceHub;\n if (!globalObj[TRACE_HUB_SYMBOL]) {\n globalObj[TRACE_HUB_SYMBOL] = new TraceHub();\n }\n return globalObj[TRACE_HUB_SYMBOL] as TraceHub;\n}\n\nexport function getTraceEvents$(): Observable<TraceEvent> {\n return getGlobalTraceHub().events$;\n}\n\nexport function setMainTraceMinLevel(level: TraceLevel): void {\n getGlobalTraceHub().setMinLevel('main', level);\n}\n\nexport function setRendererTraceMinLevel(level: TraceLevel): void {\n rendererMinLevel = level;\n getGlobalTraceHub().setMinLevel('renderer', level);\n}\n\nexport function setRendererTraceEnabled(enabled: boolean): void {\n rendererEnabled = enabled;\n}\n\nexport function publishMainTrace(level: TraceLevel, input: unknown): TraceEvent {\n return getGlobalTraceHub().publish('main', level, input);\n}\n\nexport function publishTestTrace(process: TraceProcess, level: TraceLevel, input: unknown): TraceEvent {\n return getGlobalTraceHub().publish(process, level, input);\n}\n\nexport function dispatchRendererTracePayload(\n rawPayload: unknown,\n context?: TraceRuntimeContext,\n): TraceDispatchResult {\n const payload = (rawPayload ?? {}) as Partial<TraceInput> & { level?: TraceLevel };\n const level = payload.level === 'debug' || payload.level === 'info' || payload.level === 'warn' || payload.level === 'error'\n ? payload.level\n : 'info';\n getGlobalTraceHub().publish('renderer', level, mergeTraceRuntimeContext(payload, context));\n return {\n ok: true,\n forwarded: true,\n };\n}\n\nexport function setRendererTraceTransport(fn: ((payload: unknown) => void) | null): void {\n customRendererTraceTransport = fn;\n}\n\nexport function emitRendererTrace(level: TraceLevel, input: TraceInput): void {\n if (!rendererEnabled) {\n return;\n }\n if (LEVEL_ORDER[level] < LEVEL_ORDER[rendererMinLevel]) {\n return;\n }\n const normalized = { ...normalizeTraceInput(input), level };\n\n if (customRendererTraceTransport) {\n try {\n customRendererTraceTransport(normalized);\n return;\n } catch {\n // Fall through to bridge.__trace\n }\n }\n\n const bridge = resolveTraceBridge();\n if (!bridge || typeof bridge.__trace !== 'function') {\n return;\n }\n try {\n bridge.__trace(normalized);\n } catch {\n // Tracing is observational and must never break the caller.\n }\n}\n\nexport function clearTraceHubForTests(): void {\n const globalObj = globalThis as GlobalWithTraceHub;\n delete globalObj[TRACE_HUB_SYMBOL];\n rendererMinLevel = 'debug';\n rendererEnabled = false;\n customRendererTraceTransport = null;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/tracing/trace_hub.ts"],"sourcesContent":["import { Observable, Subject } from 'rxjs';\nimport { share } from 'rxjs/operators';\nimport type {\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './types/wood_trace_sink.types.js';\n\nexport type StandardTraceLevel = 'debug' | 'info' | 'warn' | 'error';\nexport type TraceLevel = StandardTraceLevel | (string & {});\nexport type TraceProcess = 'main' | 'renderer' | 'test';\n\nexport type TraceInput = {\n source: string;\n type: string;\n message?: string;\n conversationId?: number | string;\n payload?: Record<string, unknown>;\n windowId?: string;\n webContentsId?: number;\n routeKey?: string;\n harnessId?: string;\n};\n\nexport type TraceEvent = TraceInput & {\n level: TraceLevel;\n process: TraceProcess;\n timestamp: string;\n traceSeq: number;\n};\n\nexport type TraceDispatchResult = {\n ok: boolean;\n forwarded: boolean;\n};\n\nexport type TraceRuntimeContext = {\n windowId?: string;\n webContentsId?: number;\n routeKey?: string;\n harnessId?: string;\n};\n\nexport type TraceWaitOptions = {\n timeoutMs?: number;\n};\n\nconst TRACE_HUB_SYMBOL = Symbol.for('@noego/wood.trace.hub');\n\nconst LEVEL_ORDER: Record<StandardTraceLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\nconst CUSTOM_LEVEL_ORDER = LEVEL_ORDER.info;\n\nexport function normalizeTraceLevel(level: unknown, fallback: TraceLevel = 'info'): TraceLevel {\n if (typeof level !== 'string') {\n return fallback;\n }\n\n const normalized = level.trim().toLowerCase();\n return normalized.length > 0 ? normalized : fallback;\n}\n\nfunction traceLevelOrder(level: TraceLevel): number {\n return LEVEL_ORDER[level as StandardTraceLevel] ?? CUSTOM_LEVEL_ORDER;\n}\n\nlet rendererMinLevel: TraceLevel = 'debug';\nlet rendererEnabled = false;\nlet customRendererTraceTransport: ((payload: unknown) => void) | null = null;\n\ntype GlobalWithTraceHub = typeof globalThis & {\n [TRACE_HUB_SYMBOL]?: TraceHub;\n};\n\ntype TraceBridgeLike = Record<string, unknown> & {\n __trace?: (payload: unknown) => void;\n};\n\ntype GlobalWithTraceBridge = typeof globalThis & {\n __NOEGO_WOOD_BRIDGE__?: unknown;\n wood?: unknown;\n window?: {\n __NOEGO_WOOD_BRIDGE__?: unknown;\n wood?: unknown;\n };\n};\n\nfunction normalizeTraceInput(raw: unknown): TraceInput {\n const input = (raw ?? {}) as Partial<TraceInput> & Record<string, unknown>;\n const source = typeof input.source === 'string' && input.source.trim().length > 0\n ? input.source\n : 'unknown';\n const type = typeof input.type === 'string' && input.type.trim().length > 0\n ? input.type\n : 'unknown';\n const message = typeof input.message === 'string' ? input.message : undefined;\n const conversationId = typeof input.conversationId === 'number' || typeof input.conversationId === 'string'\n ? input.conversationId\n : undefined;\n const windowId = typeof input.windowId === 'string' && input.windowId.trim().length > 0\n ? input.windowId\n : undefined;\n const webContentsId = typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? input.webContentsId\n : undefined;\n const routeKey = typeof input.routeKey === 'string' && input.routeKey.trim().length > 0\n ? input.routeKey\n : undefined;\n const harnessId = typeof input.harnessId === 'string' && input.harnessId.trim().length > 0\n ? input.harnessId\n : undefined;\n const payload = isRecord(input.payload) ? { ...input.payload } : undefined;\n\n return {\n source,\n type,\n ...(message ? { message } : {}),\n ...(conversationId !== undefined ? { conversationId } : {}),\n ...(windowId !== undefined ? { windowId } : {}),\n ...(webContentsId !== undefined ? { webContentsId } : {}),\n ...(routeKey !== undefined ? { routeKey } : {}),\n ...(harnessId !== undefined ? { harnessId } : {}),\n ...(payload ? { payload } : {}),\n };\n}\n\nfunction mergeTraceRuntimeContext(input: unknown, context: TraceRuntimeContext | undefined): TraceInput {\n if (!context) {\n return normalizeTraceInput(input);\n }\n return normalizeTraceInput({\n ...(isRecord(input) ? input : {}),\n ...context,\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction resolveTraceBridge(): TraceBridgeLike | null {\n const globalObj = globalThis as GlobalWithTraceBridge;\n const bridge = globalObj.__NOEGO_WOOD_BRIDGE__\n ?? globalObj.window?.__NOEGO_WOOD_BRIDGE__\n ?? globalObj.wood\n ?? globalObj.window?.wood;\n if (!bridge || typeof bridge !== 'object') {\n return null;\n }\n return bridge as TraceBridgeLike;\n}\n\nclass TraceHub {\n private readonly subject = new Subject<TraceEvent>();\n private readonly shared$ = this.subject.asObservable().pipe(share());\n private readonly sinks = new Set<WoodTraceEventSink>();\n private nextTraceSeq = 1;\n private minLevels: Record<TraceProcess, TraceLevel> = {\n main: 'debug',\n renderer: 'debug',\n test: 'debug',\n };\n\n get events$(): Observable<TraceEvent> {\n return this.shared$;\n }\n\n setMinLevel(process: TraceProcess, level: TraceLevel): void {\n this.minLevels[process] = level;\n }\n\n registerSink(sink: WoodTraceEventSink): WoodTraceSinkDisposer {\n this.sinks.add(sink);\n return () => {\n this.sinks.delete(sink);\n };\n }\n\n publish(process: TraceProcess, level: TraceLevel, input: unknown): TraceEvent {\n const normalized = normalizeTraceInput(input);\n const event: TraceEvent = {\n ...normalized,\n level,\n process,\n timestamp: new Date().toISOString(),\n traceSeq: this.nextTraceSeq++,\n };\n if (traceLevelOrder(level) >= traceLevelOrder(this.minLevels[process])) {\n this.publishToSinks(event);\n this.subject.next(event);\n }\n return event;\n }\n\n publishRendererToSinks(level: TraceLevel, input: TraceInput): void {\n if (this.sinks.size === 0) {\n return;\n }\n const event: TraceEvent = {\n ...input,\n level,\n process: 'renderer',\n timestamp: new Date().toISOString(),\n traceSeq: this.nextTraceSeq++,\n };\n this.publishToSinks(event);\n }\n\n private publishToSinks(event: TraceEvent): void {\n if (this.sinks.size === 0) {\n return;\n }\n const snapshot: WoodTraceEventSnapshot = Object.freeze({\n ...event,\n ...(event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}),\n });\n for (const sink of this.sinks) {\n try {\n sink(snapshot);\n } catch {\n // Trace sinks are observational and cannot fail trace callers or peers.\n }\n }\n }\n}\n\nfunction getGlobalTraceHub(): TraceHub {\n const globalObj = globalThis as GlobalWithTraceHub;\n if (!globalObj[TRACE_HUB_SYMBOL]) {\n globalObj[TRACE_HUB_SYMBOL] = new TraceHub();\n }\n return globalObj[TRACE_HUB_SYMBOL] as TraceHub;\n}\n\nexport function getTraceEvents$(): Observable<TraceEvent> {\n return getGlobalTraceHub().events$;\n}\n\nexport function registerTraceSink(sink: WoodTraceEventSink): WoodTraceSinkDisposer {\n return getGlobalTraceHub().registerSink(sink);\n}\n\nexport function setMainTraceMinLevel(level: TraceLevel): void {\n getGlobalTraceHub().setMinLevel('main', level);\n}\n\nexport function setRendererTraceMinLevel(level: TraceLevel): void {\n rendererMinLevel = level;\n getGlobalTraceHub().setMinLevel('renderer', level);\n}\n\nexport function setRendererTraceEnabled(enabled: boolean): void {\n rendererEnabled = enabled;\n}\n\nexport function publishMainTrace(level: TraceLevel, input: unknown): TraceEvent {\n return getGlobalTraceHub().publish('main', level, input);\n}\n\nexport function publishTestTrace(process: TraceProcess, level: TraceLevel, input: unknown): TraceEvent {\n return getGlobalTraceHub().publish(process, level, input);\n}\n\nexport function dispatchRendererTracePayload(\n rawPayload: unknown,\n context?: TraceRuntimeContext,\n): TraceDispatchResult {\n const payload = (rawPayload ?? {}) as Partial<TraceInput> & { level?: unknown };\n const level = normalizeTraceLevel(payload.level);\n getGlobalTraceHub().publish('renderer', level, mergeTraceRuntimeContext(payload, context));\n return {\n ok: true,\n forwarded: true,\n };\n}\n\nexport function setRendererTraceTransport(fn: ((payload: unknown) => void) | null): void {\n customRendererTraceTransport = fn;\n}\n\nexport function emitRendererTrace(level: TraceLevel, input: TraceInput): void {\n if (!rendererEnabled) {\n return;\n }\n if (traceLevelOrder(level) < traceLevelOrder(rendererMinLevel)) {\n return;\n }\n const normalized = { ...normalizeTraceInput(input), level };\n getGlobalTraceHub().publishRendererToSinks(level, normalized);\n\n if (customRendererTraceTransport) {\n try {\n customRendererTraceTransport(normalized);\n return;\n } catch {\n // Fall through to bridge.__trace\n }\n }\n\n const bridge = resolveTraceBridge();\n if (!bridge || typeof bridge.__trace !== 'function') {\n return;\n }\n try {\n bridge.__trace(normalized);\n } catch {\n // Tracing is observational and must never break the caller.\n }\n}\n\nexport function clearTraceHubForTests(): void {\n const globalObj = globalThis as GlobalWithTraceHub;\n delete globalObj[TRACE_HUB_SYMBOL];\n rendererMinLevel = 'debug';\n rendererEnabled = false;\n customRendererTraceTransport = null;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,46 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
type TraceLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
4
|
-
type TraceProcess = 'main' | 'renderer' | 'test';
|
|
5
|
-
type TraceInput = {
|
|
6
|
-
source: string;
|
|
7
|
-
type: string;
|
|
8
|
-
message?: string;
|
|
9
|
-
conversationId?: number | string;
|
|
10
|
-
payload?: Record<string, unknown>;
|
|
11
|
-
windowId?: string;
|
|
12
|
-
webContentsId?: number;
|
|
13
|
-
routeKey?: string;
|
|
14
|
-
harnessId?: string;
|
|
15
|
-
};
|
|
16
|
-
type TraceEvent = TraceInput & {
|
|
17
|
-
level: TraceLevel;
|
|
18
|
-
process: TraceProcess;
|
|
19
|
-
timestamp: string;
|
|
20
|
-
traceSeq: number;
|
|
21
|
-
};
|
|
22
|
-
type TraceDispatchResult = {
|
|
23
|
-
ok: boolean;
|
|
24
|
-
forwarded: boolean;
|
|
25
|
-
};
|
|
26
|
-
type TraceRuntimeContext = {
|
|
27
|
-
windowId?: string;
|
|
28
|
-
webContentsId?: number;
|
|
29
|
-
routeKey?: string;
|
|
30
|
-
harnessId?: string;
|
|
31
|
-
};
|
|
32
|
-
type TraceWaitOptions = {
|
|
33
|
-
timeoutMs?: number;
|
|
34
|
-
};
|
|
35
|
-
declare function getTraceEvents$(): Observable<TraceEvent>;
|
|
36
|
-
declare function setMainTraceMinLevel(level: TraceLevel): void;
|
|
37
|
-
declare function setRendererTraceMinLevel(level: TraceLevel): void;
|
|
38
|
-
declare function setRendererTraceEnabled(enabled: boolean): void;
|
|
39
|
-
declare function publishMainTrace(level: TraceLevel, input: unknown): TraceEvent;
|
|
40
|
-
declare function publishTestTrace(process: TraceProcess, level: TraceLevel, input: unknown): TraceEvent;
|
|
41
|
-
declare function dispatchRendererTracePayload(rawPayload: unknown, context?: TraceRuntimeContext): TraceDispatchResult;
|
|
42
|
-
declare function setRendererTraceTransport(fn: ((payload: unknown) => void) | null): void;
|
|
43
|
-
declare function emitRendererTrace(level: TraceLevel, input: TraceInput): void;
|
|
44
|
-
declare function clearTraceHubForTests(): void;
|
|
45
|
-
|
|
46
|
-
export { type TraceDispatchResult, type TraceEvent, type TraceInput, type TraceLevel, type TraceProcess, type TraceRuntimeContext, type TraceWaitOptions, clearTraceHubForTests, dispatchRendererTracePayload, emitRendererTrace, getTraceEvents$, publishMainTrace, publishTestTrace, setMainTraceMinLevel, setRendererTraceEnabled, setRendererTraceMinLevel, setRendererTraceTransport };
|
|
1
|
+
import 'rxjs';
|
|
2
|
+
export { S as StandardTraceLevel, T as TraceDispatchResult, a as TraceEvent, b as TraceInput, c as TraceLevel, d as TraceProcess, e as TraceRuntimeContext, f as TraceWaitOptions, i as clearTraceHubForTests, l as dispatchRendererTracePayload, m as emitRendererTrace, j as getTraceEvents$, t as normalizeTraceLevel, p as publishMainTrace, n as publishTestTrace, r as registerTraceSink, o as setMainTraceMinLevel, s as setRendererTraceEnabled, q as setRendererTraceMinLevel, k as setRendererTraceTransport } from '../trace_hub-Cob54qRx.cjs';
|
|
@@ -1,46 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
type TraceLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
4
|
-
type TraceProcess = 'main' | 'renderer' | 'test';
|
|
5
|
-
type TraceInput = {
|
|
6
|
-
source: string;
|
|
7
|
-
type: string;
|
|
8
|
-
message?: string;
|
|
9
|
-
conversationId?: number | string;
|
|
10
|
-
payload?: Record<string, unknown>;
|
|
11
|
-
windowId?: string;
|
|
12
|
-
webContentsId?: number;
|
|
13
|
-
routeKey?: string;
|
|
14
|
-
harnessId?: string;
|
|
15
|
-
};
|
|
16
|
-
type TraceEvent = TraceInput & {
|
|
17
|
-
level: TraceLevel;
|
|
18
|
-
process: TraceProcess;
|
|
19
|
-
timestamp: string;
|
|
20
|
-
traceSeq: number;
|
|
21
|
-
};
|
|
22
|
-
type TraceDispatchResult = {
|
|
23
|
-
ok: boolean;
|
|
24
|
-
forwarded: boolean;
|
|
25
|
-
};
|
|
26
|
-
type TraceRuntimeContext = {
|
|
27
|
-
windowId?: string;
|
|
28
|
-
webContentsId?: number;
|
|
29
|
-
routeKey?: string;
|
|
30
|
-
harnessId?: string;
|
|
31
|
-
};
|
|
32
|
-
type TraceWaitOptions = {
|
|
33
|
-
timeoutMs?: number;
|
|
34
|
-
};
|
|
35
|
-
declare function getTraceEvents$(): Observable<TraceEvent>;
|
|
36
|
-
declare function setMainTraceMinLevel(level: TraceLevel): void;
|
|
37
|
-
declare function setRendererTraceMinLevel(level: TraceLevel): void;
|
|
38
|
-
declare function setRendererTraceEnabled(enabled: boolean): void;
|
|
39
|
-
declare function publishMainTrace(level: TraceLevel, input: unknown): TraceEvent;
|
|
40
|
-
declare function publishTestTrace(process: TraceProcess, level: TraceLevel, input: unknown): TraceEvent;
|
|
41
|
-
declare function dispatchRendererTracePayload(rawPayload: unknown, context?: TraceRuntimeContext): TraceDispatchResult;
|
|
42
|
-
declare function setRendererTraceTransport(fn: ((payload: unknown) => void) | null): void;
|
|
43
|
-
declare function emitRendererTrace(level: TraceLevel, input: TraceInput): void;
|
|
44
|
-
declare function clearTraceHubForTests(): void;
|
|
45
|
-
|
|
46
|
-
export { type TraceDispatchResult, type TraceEvent, type TraceInput, type TraceLevel, type TraceProcess, type TraceRuntimeContext, type TraceWaitOptions, clearTraceHubForTests, dispatchRendererTracePayload, emitRendererTrace, getTraceEvents$, publishMainTrace, publishTestTrace, setMainTraceMinLevel, setRendererTraceEnabled, setRendererTraceMinLevel, setRendererTraceTransport };
|
|
1
|
+
import 'rxjs';
|
|
2
|
+
export { S as StandardTraceLevel, T as TraceDispatchResult, a as TraceEvent, b as TraceInput, c as TraceLevel, d as TraceProcess, e as TraceRuntimeContext, f as TraceWaitOptions, i as clearTraceHubForTests, l as dispatchRendererTracePayload, m as emitRendererTrace, j as getTraceEvents$, t as normalizeTraceLevel, p as publishMainTrace, n as publishTestTrace, r as registerTraceSink, o as setMainTraceMinLevel, s as setRendererTraceEnabled, q as setRendererTraceMinLevel, k as setRendererTraceTransport } from '../trace_hub-Cob54qRx.js';
|
|
@@ -7,6 +7,17 @@ const LEVEL_ORDER = {
|
|
|
7
7
|
warn: 2,
|
|
8
8
|
error: 3
|
|
9
9
|
};
|
|
10
|
+
const CUSTOM_LEVEL_ORDER = LEVEL_ORDER.info;
|
|
11
|
+
function normalizeTraceLevel(level, fallback = "info") {
|
|
12
|
+
if (typeof level !== "string") {
|
|
13
|
+
return fallback;
|
|
14
|
+
}
|
|
15
|
+
const normalized = level.trim().toLowerCase();
|
|
16
|
+
return normalized.length > 0 ? normalized : fallback;
|
|
17
|
+
}
|
|
18
|
+
function traceLevelOrder(level) {
|
|
19
|
+
return LEVEL_ORDER[level] ?? CUSTOM_LEVEL_ORDER;
|
|
20
|
+
}
|
|
10
21
|
let rendererMinLevel = "debug";
|
|
11
22
|
let rendererEnabled = false;
|
|
12
23
|
let customRendererTraceTransport = null;
|
|
@@ -57,6 +68,7 @@ class TraceHub {
|
|
|
57
68
|
constructor() {
|
|
58
69
|
this.subject = new Subject();
|
|
59
70
|
this.shared$ = this.subject.asObservable().pipe(share());
|
|
71
|
+
this.sinks = /* @__PURE__ */ new Set();
|
|
60
72
|
this.nextTraceSeq = 1;
|
|
61
73
|
this.minLevels = {
|
|
62
74
|
main: "debug",
|
|
@@ -70,6 +82,12 @@ class TraceHub {
|
|
|
70
82
|
setMinLevel(process, level) {
|
|
71
83
|
this.minLevels[process] = level;
|
|
72
84
|
}
|
|
85
|
+
registerSink(sink) {
|
|
86
|
+
this.sinks.add(sink);
|
|
87
|
+
return () => {
|
|
88
|
+
this.sinks.delete(sink);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
73
91
|
publish(process, level, input) {
|
|
74
92
|
const normalized = normalizeTraceInput(input);
|
|
75
93
|
const event = {
|
|
@@ -79,11 +97,40 @@ class TraceHub {
|
|
|
79
97
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80
98
|
traceSeq: this.nextTraceSeq++
|
|
81
99
|
};
|
|
82
|
-
if (
|
|
100
|
+
if (traceLevelOrder(level) >= traceLevelOrder(this.minLevels[process])) {
|
|
101
|
+
this.publishToSinks(event);
|
|
83
102
|
this.subject.next(event);
|
|
84
103
|
}
|
|
85
104
|
return event;
|
|
86
105
|
}
|
|
106
|
+
publishRendererToSinks(level, input) {
|
|
107
|
+
if (this.sinks.size === 0) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const event = {
|
|
111
|
+
...input,
|
|
112
|
+
level,
|
|
113
|
+
process: "renderer",
|
|
114
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
115
|
+
traceSeq: this.nextTraceSeq++
|
|
116
|
+
};
|
|
117
|
+
this.publishToSinks(event);
|
|
118
|
+
}
|
|
119
|
+
publishToSinks(event) {
|
|
120
|
+
if (this.sinks.size === 0) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const snapshot = Object.freeze({
|
|
124
|
+
...event,
|
|
125
|
+
...event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}
|
|
126
|
+
});
|
|
127
|
+
for (const sink of this.sinks) {
|
|
128
|
+
try {
|
|
129
|
+
sink(snapshot);
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
87
134
|
}
|
|
88
135
|
function getGlobalTraceHub() {
|
|
89
136
|
const globalObj = globalThis;
|
|
@@ -95,6 +142,9 @@ function getGlobalTraceHub() {
|
|
|
95
142
|
function getTraceEvents$() {
|
|
96
143
|
return getGlobalTraceHub().events$;
|
|
97
144
|
}
|
|
145
|
+
function registerTraceSink(sink) {
|
|
146
|
+
return getGlobalTraceHub().registerSink(sink);
|
|
147
|
+
}
|
|
98
148
|
function setMainTraceMinLevel(level) {
|
|
99
149
|
getGlobalTraceHub().setMinLevel("main", level);
|
|
100
150
|
}
|
|
@@ -113,7 +163,7 @@ function publishTestTrace(process, level, input) {
|
|
|
113
163
|
}
|
|
114
164
|
function dispatchRendererTracePayload(rawPayload, context) {
|
|
115
165
|
const payload = rawPayload ?? {};
|
|
116
|
-
const level = payload.level
|
|
166
|
+
const level = normalizeTraceLevel(payload.level);
|
|
117
167
|
getGlobalTraceHub().publish("renderer", level, mergeTraceRuntimeContext(payload, context));
|
|
118
168
|
return {
|
|
119
169
|
ok: true,
|
|
@@ -127,10 +177,11 @@ function emitRendererTrace(level, input) {
|
|
|
127
177
|
if (!rendererEnabled) {
|
|
128
178
|
return;
|
|
129
179
|
}
|
|
130
|
-
if (
|
|
180
|
+
if (traceLevelOrder(level) < traceLevelOrder(rendererMinLevel)) {
|
|
131
181
|
return;
|
|
132
182
|
}
|
|
133
183
|
const normalized = { ...normalizeTraceInput(input), level };
|
|
184
|
+
getGlobalTraceHub().publishRendererToSinks(level, normalized);
|
|
134
185
|
if (customRendererTraceTransport) {
|
|
135
186
|
try {
|
|
136
187
|
customRendererTraceTransport(normalized);
|
|
@@ -159,8 +210,10 @@ export {
|
|
|
159
210
|
dispatchRendererTracePayload,
|
|
160
211
|
emitRendererTrace,
|
|
161
212
|
getTraceEvents$,
|
|
213
|
+
normalizeTraceLevel,
|
|
162
214
|
publishMainTrace,
|
|
163
215
|
publishTestTrace,
|
|
216
|
+
registerTraceSink,
|
|
164
217
|
setMainTraceMinLevel,
|
|
165
218
|
setRendererTraceEnabled,
|
|
166
219
|
setRendererTraceMinLevel,
|