@noego/wood 0.4.5 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/bin/wood.js +9 -1
  2. package/dist/client/app_env.cjs +39 -0
  3. package/dist/client/app_env.cjs.map +1 -0
  4. package/dist/client/app_env.d.cts +7 -0
  5. package/dist/client/app_env.d.ts +7 -0
  6. package/dist/client/app_env.js +14 -0
  7. package/dist/client/app_env.js.map +1 -0
  8. package/dist/client/index.cjs +33 -9
  9. package/dist/client/index.cjs.map +1 -1
  10. package/dist/client/index.d.cts +5 -1
  11. package/dist/client/index.d.ts +5 -1
  12. package/dist/client/index.js +32 -9
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/codegen/channel_map_generator.cjs +102 -0
  15. package/dist/codegen/channel_map_generator.cjs.map +1 -0
  16. package/dist/codegen/channel_map_generator.d.cts +6 -0
  17. package/dist/codegen/channel_map_generator.d.ts +6 -0
  18. package/dist/codegen/channel_map_generator.js +78 -0
  19. package/dist/codegen/channel_map_generator.js.map +1 -0
  20. package/dist/codegen/controller_registration_generator.cjs +6 -1
  21. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  22. package/dist/codegen/controller_registration_generator.js +6 -1
  23. package/dist/codegen/controller_registration_generator.js.map +1 -1
  24. package/dist/codegen/generated_file_notice.cjs +40 -0
  25. package/dist/codegen/generated_file_notice.cjs.map +1 -0
  26. package/dist/codegen/generated_file_notice.d.cts +3 -0
  27. package/dist/codegen/generated_file_notice.d.ts +3 -0
  28. package/dist/codegen/generated_file_notice.js +16 -0
  29. package/dist/codegen/generated_file_notice.js.map +1 -0
  30. package/dist/codegen/index.cjs +3 -0
  31. package/dist/codegen/index.cjs.map +1 -1
  32. package/dist/codegen/index.d.cts +1 -0
  33. package/dist/codegen/index.d.ts +1 -0
  34. package/dist/codegen/index.js +2 -0
  35. package/dist/codegen/index.js.map +1 -1
  36. package/dist/codegen/preload_generator.cjs +97 -1
  37. package/dist/codegen/preload_generator.cjs.map +1 -1
  38. package/dist/codegen/preload_generator.js +97 -1
  39. package/dist/codegen/preload_generator.js.map +1 -1
  40. package/dist/codegen/renderer_app_generator.cjs +6 -1
  41. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  42. package/dist/codegen/renderer_app_generator.js +6 -1
  43. package/dist/codegen/renderer_app_generator.js.map +1 -1
  44. package/dist/codegen/renderer_controller_registration_generator.cjs +6 -1
  45. package/dist/codegen/renderer_controller_registration_generator.cjs.map +1 -1
  46. package/dist/codegen/renderer_controller_registration_generator.js +6 -1
  47. package/dist/codegen/renderer_controller_registration_generator.js.map +1 -1
  48. package/dist/codegen/renderer_view_manifest_generator.cjs +6 -1
  49. package/dist/codegen/renderer_view_manifest_generator.cjs.map +1 -1
  50. package/dist/codegen/renderer_view_manifest_generator.js +6 -1
  51. package/dist/codegen/renderer_view_manifest_generator.js.map +1 -1
  52. package/dist/codegen/runtime_generator.cjs +6 -1
  53. package/dist/codegen/runtime_generator.cjs.map +1 -1
  54. package/dist/codegen/runtime_generator.js +6 -1
  55. package/dist/codegen/runtime_generator.js.map +1 -1
  56. package/dist/codegen/test_mock_generator.cjs +5 -1
  57. package/dist/codegen/test_mock_generator.cjs.map +1 -1
  58. package/dist/codegen/test_mock_generator.js +5 -1
  59. package/dist/codegen/test_mock_generator.js.map +1 -1
  60. package/dist/codegen/type_generator.cjs +7 -1
  61. package/dist/codegen/type_generator.cjs.map +1 -1
  62. package/dist/codegen/type_generator.js +7 -1
  63. package/dist/codegen/type_generator.js.map +1 -1
  64. package/dist/index.cjs +19 -6
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.d.cts +7 -1
  67. package/dist/index.d.ts +7 -1
  68. package/dist/index.js +13 -1
  69. package/dist/index.js.map +1 -1
  70. package/dist/main/index.cjs +287 -62
  71. package/dist/main/index.cjs.map +1 -1
  72. package/dist/main/index.d.cts +57 -3
  73. package/dist/main/index.d.ts +57 -3
  74. package/dist/main/index.js +289 -62
  75. package/dist/main/index.js.map +1 -1
  76. package/dist/main/renderer_trace_drain_coordinator.cjs +127 -0
  77. package/dist/main/renderer_trace_drain_coordinator.cjs.map +1 -0
  78. package/dist/main/renderer_trace_drain_coordinator.d.cts +46 -0
  79. package/dist/main/renderer_trace_drain_coordinator.d.ts +46 -0
  80. package/dist/main/renderer_trace_drain_coordinator.js +101 -0
  81. package/dist/main/renderer_trace_drain_coordinator.js.map +1 -0
  82. package/dist/router/wood_router.cjs +9 -1
  83. package/dist/router/wood_router.cjs.map +1 -1
  84. package/dist/router/wood_router.d.cts +1 -1
  85. package/dist/router/wood_router.d.ts +1 -1
  86. package/dist/router/wood_router.js +9 -1
  87. package/dist/router/wood_router.js.map +1 -1
  88. package/dist/runtime/app_env.cjs +52 -0
  89. package/dist/runtime/app_env.cjs.map +1 -0
  90. package/dist/runtime/app_env.d.cts +10 -0
  91. package/dist/runtime/app_env.d.ts +10 -0
  92. package/dist/runtime/app_env.js +18 -0
  93. package/dist/runtime/app_env.js.map +1 -0
  94. package/dist/runtime/index.cjs +9 -2
  95. package/dist/runtime/index.cjs.map +1 -1
  96. package/dist/runtime/index.d.cts +5 -1
  97. package/dist/runtime/index.d.ts +5 -1
  98. package/dist/runtime/index.js +9 -1
  99. package/dist/runtime/index.js.map +1 -1
  100. package/dist/runtime/renderer_log_dispatcher.cjs.map +1 -1
  101. package/dist/runtime/renderer_log_dispatcher.d.cts +1 -1
  102. package/dist/runtime/renderer_log_dispatcher.d.ts +1 -1
  103. package/dist/runtime/renderer_log_dispatcher.js.map +1 -1
  104. package/dist/runtime/renderer_trace_batch_receiver_registry.cjs +50 -0
  105. package/dist/runtime/renderer_trace_batch_receiver_registry.cjs.map +1 -0
  106. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +10 -0
  107. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +10 -0
  108. package/dist/runtime/renderer_trace_batch_receiver_registry.js +24 -0
  109. package/dist/runtime/renderer_trace_batch_receiver_registry.js.map +1 -0
  110. package/dist/runtime/runtime.cjs +75 -57
  111. package/dist/runtime/runtime.cjs.map +1 -1
  112. package/dist/runtime/runtime.d.cts +8 -1
  113. package/dist/runtime/runtime.d.ts +8 -1
  114. package/dist/runtime/runtime.js +80 -58
  115. package/dist/runtime/runtime.js.map +1 -1
  116. package/dist/testing/browser.cjs +540 -11
  117. package/dist/testing/browser.cjs.map +1 -1
  118. package/dist/testing/browser.d.cts +219 -3
  119. package/dist/testing/browser.d.ts +219 -3
  120. package/dist/testing/browser.js +540 -11
  121. package/dist/testing/browser.js.map +1 -1
  122. package/dist/testing/create_controller_harness.d.cts +1 -1
  123. package/dist/testing/create_controller_harness.d.ts +1 -1
  124. package/dist/testing/index.cjs +13 -0
  125. package/dist/testing/index.cjs.map +1 -1
  126. package/dist/testing/index.d.cts +7 -2
  127. package/dist/testing/index.d.ts +7 -2
  128. package/dist/testing/index.js +14 -0
  129. package/dist/testing/index.js.map +1 -1
  130. package/dist/trace-testing/index.d.cts +1 -1
  131. package/dist/trace-testing/index.d.ts +1 -1
  132. package/dist/trace-testing/trace_recorder.d.cts +1 -1
  133. package/dist/trace-testing/trace_recorder.d.ts +1 -1
  134. package/dist/trace-transport/index.cjs +32 -0
  135. package/dist/trace-transport/index.cjs.map +1 -0
  136. package/dist/trace-transport/index.d.cts +6 -0
  137. package/dist/trace-transport/index.d.ts +6 -0
  138. package/dist/trace-transport/index.js +7 -0
  139. package/dist/trace-transport/index.js.map +1 -0
  140. package/dist/trace_hub-Cob54qRx.d.cts +56 -0
  141. package/dist/trace_hub-Cob54qRx.d.ts +56 -0
  142. package/dist/tracing/index.cjs +14 -0
  143. package/dist/tracing/index.cjs.map +1 -1
  144. package/dist/tracing/index.d.cts +7 -1
  145. package/dist/tracing/index.d.ts +7 -1
  146. package/dist/tracing/index.js +12 -0
  147. package/dist/tracing/index.js.map +1 -1
  148. package/dist/tracing/renderer_trace_batch_host.cjs +80 -0
  149. package/dist/tracing/renderer_trace_batch_host.cjs.map +1 -0
  150. package/dist/tracing/renderer_trace_batch_host.d.cts +16 -0
  151. package/dist/tracing/renderer_trace_batch_host.d.ts +16 -0
  152. package/dist/tracing/renderer_trace_batch_host.js +56 -0
  153. package/dist/tracing/renderer_trace_batch_host.js.map +1 -0
  154. package/dist/tracing/renderer_trace_batch_transport.cjs +313 -0
  155. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -0
  156. package/dist/tracing/renderer_trace_batch_transport.d.cts +53 -0
  157. package/dist/tracing/renderer_trace_batch_transport.d.ts +53 -0
  158. package/dist/tracing/renderer_trace_batch_transport.js +292 -0
  159. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -0
  160. package/dist/tracing/trace_commit_writer.cjs +159 -0
  161. package/dist/tracing/trace_commit_writer.cjs.map +1 -0
  162. package/dist/tracing/trace_commit_writer.d.cts +97 -0
  163. package/dist/tracing/trace_commit_writer.d.ts +97 -0
  164. package/dist/tracing/trace_commit_writer.js +135 -0
  165. package/dist/tracing/trace_commit_writer.js.map +1 -0
  166. package/dist/tracing/trace_hub.cjs +58 -3
  167. package/dist/tracing/trace_hub.cjs.map +1 -1
  168. package/dist/tracing/trace_hub.d.cts +2 -46
  169. package/dist/tracing/trace_hub.d.ts +2 -46
  170. package/dist/tracing/trace_hub.js +56 -3
  171. package/dist/tracing/trace_hub.js.map +1 -1
  172. package/dist/tracing/trace_provider.cjs +42 -12
  173. package/dist/tracing/trace_provider.cjs.map +1 -1
  174. package/dist/tracing/trace_provider.d.cts +15 -1
  175. package/dist/tracing/trace_provider.d.ts +15 -1
  176. package/dist/tracing/trace_provider.js +43 -12
  177. package/dist/tracing/trace_provider.js.map +1 -1
  178. package/dist/tracing/types/wood_trace_batch.types.cjs +17 -0
  179. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -0
  180. package/dist/tracing/types/wood_trace_batch.types.d.cts +124 -0
  181. package/dist/tracing/types/wood_trace_batch.types.d.ts +124 -0
  182. package/dist/tracing/types/wood_trace_batch.types.js +1 -0
  183. package/dist/tracing/types/wood_trace_batch.types.js.map +1 -0
  184. package/dist/tracing/types/wood_trace_sink.types.cjs +17 -0
  185. package/dist/tracing/types/wood_trace_sink.types.cjs.map +1 -0
  186. package/dist/tracing/types/wood_trace_sink.types.d.cts +2 -0
  187. package/dist/tracing/types/wood_trace_sink.types.d.ts +2 -0
  188. package/dist/tracing/types/wood_trace_sink.types.js +1 -0
  189. package/dist/tracing/types/wood_trace_sink.types.js.map +1 -0
  190. package/dist/tracing/wood_trace_batch_contract.cjs +229 -0
  191. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -0
  192. package/dist/tracing/wood_trace_batch_contract.d.cts +23 -0
  193. package/dist/tracing/wood_trace_batch_contract.d.ts +23 -0
  194. package/dist/tracing/wood_trace_batch_contract.js +205 -0
  195. package/dist/tracing/wood_trace_batch_contract.js.map +1 -0
  196. package/dist/transport/build_transport_bridge.cjs +62 -0
  197. package/dist/transport/build_transport_bridge.cjs.map +1 -0
  198. package/dist/transport/build_transport_bridge.d.cts +29 -0
  199. package/dist/transport/build_transport_bridge.d.ts +29 -0
  200. package/dist/transport/build_transport_bridge.js +38 -0
  201. package/dist/transport/build_transport_bridge.js.map +1 -0
  202. package/dist/transport/in_process_router_transport.cjs +41 -0
  203. package/dist/transport/in_process_router_transport.cjs.map +1 -0
  204. package/dist/transport/in_process_router_transport.d.cts +31 -0
  205. package/dist/transport/in_process_router_transport.d.ts +31 -0
  206. package/dist/transport/in_process_router_transport.js +17 -0
  207. package/dist/transport/in_process_router_transport.js.map +1 -0
  208. package/dist/transport/index.cjs +42 -0
  209. package/dist/transport/index.cjs.map +1 -0
  210. package/dist/transport/index.d.cts +8 -0
  211. package/dist/transport/index.d.ts +8 -0
  212. package/dist/transport/index.js +19 -0
  213. package/dist/transport/index.js.map +1 -0
  214. package/dist/transport/loopback_remote_transport.cjs +270 -0
  215. package/dist/transport/loopback_remote_transport.cjs.map +1 -0
  216. package/dist/transport/loopback_remote_transport.d.cts +49 -0
  217. package/dist/transport/loopback_remote_transport.d.ts +49 -0
  218. package/dist/transport/loopback_remote_transport.js +237 -0
  219. package/dist/transport/loopback_remote_transport.js.map +1 -0
  220. package/dist/transport/loopback_serialization.cjs +116 -0
  221. package/dist/transport/loopback_serialization.cjs.map +1 -0
  222. package/dist/transport/loopback_serialization.d.cts +28 -0
  223. package/dist/transport/loopback_serialization.d.ts +28 -0
  224. package/dist/transport/loopback_serialization.js +91 -0
  225. package/dist/transport/loopback_serialization.js.map +1 -0
  226. package/dist/transport/transport_contract_suite.cjs +110 -0
  227. package/dist/transport/transport_contract_suite.cjs.map +1 -0
  228. package/dist/transport/transport_contract_suite.d.cts +23 -0
  229. package/dist/transport/transport_contract_suite.d.ts +23 -0
  230. package/dist/transport/transport_contract_suite.js +85 -0
  231. package/dist/transport/transport_contract_suite.js.map +1 -0
  232. package/dist/transport/wood_rpc_transport.cjs +17 -0
  233. package/dist/transport/wood_rpc_transport.cjs.map +1 -0
  234. package/dist/transport/wood_rpc_transport.d.cts +44 -0
  235. package/dist/transport/wood_rpc_transport.d.ts +44 -0
  236. package/dist/transport/wood_rpc_transport.js +1 -0
  237. package/dist/transport/wood_rpc_transport.js.map +1 -0
  238. package/dist/types/config.cjs.map +1 -1
  239. package/dist/types/config.d.cts +12 -0
  240. package/dist/types/config.d.ts +12 -0
  241. package/dist/window/window_manager.cjs +3 -0
  242. package/dist/window/window_manager.cjs.map +1 -1
  243. package/dist/window/window_manager.js +3 -0
  244. package/dist/window/window_manager.js.map +1 -1
  245. package/docs/browser-testing.md +139 -1
  246. package/package.json +22 -3
  247. package/src/components/NavigationShell.browser.test.ts +236 -0
  248. package/src/components/NavigationShell.svelte +162 -49
@@ -0,0 +1,205 @@
1
+ const MAX_BATCH_EVENTS = 256;
2
+ class WoodTraceBatchContract {
3
+ create(producerId, sequenceStart, events) {
4
+ const snapshots = events.map((event) => this.snapshotEvent(event));
5
+ const last = snapshots[snapshots.length - 1];
6
+ const sequenceEnd = last ? last.traceSeq - 1 : sequenceStart - 1;
7
+ return Object.freeze({
8
+ kind: "wood.trace.batch",
9
+ protocolVersion: 1,
10
+ producerId,
11
+ batchId: `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`,
12
+ sequenceStart,
13
+ sequenceEnd,
14
+ events: Object.freeze(snapshots)
15
+ });
16
+ }
17
+ parse(input) {
18
+ if (!this.isRecord(input) || input.kind !== "wood.trace.batch") {
19
+ return { kind: "not-batch" };
20
+ }
21
+ const batchId = typeof input.batchId === "string" ? input.batchId : null;
22
+ const identity = this.validateIdentity(input);
23
+ if (identity.kind === "invalid") {
24
+ return { kind: "invalid", batchId, reason: identity.reason };
25
+ }
26
+ const producerId = input.producerId;
27
+ if (typeof producerId !== "string") {
28
+ return { kind: "invalid", batchId, reason: "Trace batch producer identity is invalid" };
29
+ }
30
+ const parsedEvents = this.parseEvents(input.events);
31
+ if (parsedEvents.kind === "invalid") {
32
+ return { kind: "invalid", batchId, reason: parsedEvents.reason };
33
+ }
34
+ const events = parsedEvents.events;
35
+ const parsedSequenceRange = this.parseSequenceRange(input, events);
36
+ if (parsedSequenceRange.kind === "invalid") {
37
+ return { kind: "invalid", batchId, reason: parsedSequenceRange.reason };
38
+ }
39
+ const { sequenceStart, sequenceEnd } = parsedSequenceRange;
40
+ const hasTraceSequenceMismatch = events.some((event, index) => {
41
+ const previous = events[index - 1];
42
+ return previous !== void 0 && event.traceSeq <= previous.traceSeq;
43
+ });
44
+ if (hasTraceSequenceMismatch) {
45
+ return { kind: "invalid", batchId, reason: "Trace event sequences are not strictly increasing" };
46
+ }
47
+ const expectedBatchId = `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`;
48
+ if (input.batchId !== expectedBatchId) {
49
+ return { kind: "invalid", batchId, reason: "Trace batch identity does not match its sequence range" };
50
+ }
51
+ return {
52
+ kind: "valid",
53
+ batch: this.create(producerId, sequenceStart, events)
54
+ };
55
+ }
56
+ parseAcknowledgement(input) {
57
+ if (!this.isRecord(input) || typeof input.kind !== "string" || typeof input.batchId !== "string") {
58
+ return { ok: false, reason: "Trace batch acknowledgement framing is invalid" };
59
+ }
60
+ if (input.kind === "committed") {
61
+ return this.parseCommittedAcknowledgement(input);
62
+ }
63
+ if (input.kind === "retryable") {
64
+ return this.parseRetryableAcknowledgement(input);
65
+ }
66
+ if (input.kind === "rejected" && typeof input.reason === "string") {
67
+ return {
68
+ ok: true,
69
+ acknowledgement: Object.freeze({
70
+ kind: "rejected",
71
+ batchId: input.batchId,
72
+ reason: input.reason
73
+ })
74
+ };
75
+ }
76
+ return { ok: false, reason: "Trace batch acknowledgement kind is invalid" };
77
+ }
78
+ parseCommittedAcknowledgement(input) {
79
+ const batchId = input.batchId;
80
+ const committedAtMs = input.committedAtMs;
81
+ const acceptedEvents = input.acceptedEvents;
82
+ const validNumbers = typeof batchId === "string" && typeof committedAtMs === "number" && Number.isFinite(committedAtMs) && typeof acceptedEvents === "number" && Number.isSafeInteger(acceptedEvents) && acceptedEvents >= 0;
83
+ if (!validNumbers) {
84
+ return { ok: false, reason: "Committed trace acknowledgement is invalid" };
85
+ }
86
+ return {
87
+ ok: true,
88
+ acknowledgement: Object.freeze({
89
+ kind: "committed",
90
+ batchId,
91
+ committedAtMs,
92
+ acceptedEvents
93
+ })
94
+ };
95
+ }
96
+ parseRetryableAcknowledgement(input) {
97
+ const batchId = input.batchId;
98
+ const retryAfterMs = input.retryAfterMs;
99
+ if (typeof batchId !== "string" || typeof input.reason !== "string" || typeof retryAfterMs !== "number" || !Number.isFinite(retryAfterMs) || retryAfterMs < 0) {
100
+ return { ok: false, reason: "Retryable trace acknowledgement is invalid" };
101
+ }
102
+ return {
103
+ ok: true,
104
+ acknowledgement: Object.freeze({
105
+ kind: "retryable",
106
+ batchId,
107
+ reason: input.reason,
108
+ retryAfterMs
109
+ })
110
+ };
111
+ }
112
+ parseEvent(input) {
113
+ if (!this.isRecord(input)) {
114
+ return { kind: "invalid", reason: "Trace event is not an object" };
115
+ }
116
+ const hasValidIdentity = this.hasValidEventIdentity(input);
117
+ const hasValidTiming = this.hasValidEventTiming(input);
118
+ if (!hasValidIdentity || !hasValidTiming) {
119
+ return { kind: "invalid", reason: "Trace event identity or timing is invalid" };
120
+ }
121
+ if (input.payload !== void 0 && !this.isRecord(input.payload)) {
122
+ return { kind: "invalid", reason: "Trace event payload is invalid" };
123
+ }
124
+ return {
125
+ kind: "valid",
126
+ event: this.snapshotEvent({
127
+ source: input.source,
128
+ type: input.type,
129
+ level: input.level,
130
+ process: "renderer",
131
+ timestamp: input.timestamp,
132
+ traceSeq: input.traceSeq,
133
+ ...typeof input.message === "string" ? { message: input.message } : {},
134
+ ...this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {},
135
+ ...input.payload ? { payload: input.payload } : {},
136
+ ...typeof input.windowId === "string" ? { windowId: input.windowId } : {},
137
+ ...typeof input.webContentsId === "number" && Number.isFinite(input.webContentsId) ? { webContentsId: input.webContentsId } : {},
138
+ ...typeof input.routeKey === "string" ? { routeKey: input.routeKey } : {},
139
+ ...typeof input.harnessId === "string" ? { harnessId: input.harnessId } : {}
140
+ })
141
+ };
142
+ }
143
+ hasValidEventIdentity(input) {
144
+ return typeof input.source === "string" && input.source.trim().length > 0 && typeof input.type === "string" && input.type.trim().length > 0 && typeof input.level === "string" && input.level.trim().length > 0 && input.process === "renderer";
145
+ }
146
+ hasValidEventTiming(input) {
147
+ return typeof input.timestamp === "string" && Number.isFinite(Date.parse(input.timestamp)) && typeof input.traceSeq === "number" && Number.isSafeInteger(input.traceSeq) && input.traceSeq >= 1;
148
+ }
149
+ parseEvents(input) {
150
+ if (!Array.isArray(input) || input.length === 0 || input.length > MAX_BATCH_EVENTS) {
151
+ return { kind: "invalid", reason: "Trace batch events are invalid" };
152
+ }
153
+ const events = [];
154
+ for (const rawEvent of input) {
155
+ const parsedEvent = this.parseEvent(rawEvent);
156
+ if (parsedEvent.kind === "invalid") {
157
+ return parsedEvent;
158
+ }
159
+ events.push(parsedEvent.event);
160
+ }
161
+ return { kind: "valid", events: Object.freeze(events) };
162
+ }
163
+ parseSequenceRange(input, events) {
164
+ const sequenceStart = input.sequenceStart;
165
+ const sequenceEnd = input.sequenceEnd;
166
+ if (typeof sequenceStart !== "number" || typeof sequenceEnd !== "number") {
167
+ return { kind: "invalid", reason: "Trace batch sequence range is invalid" };
168
+ }
169
+ const firstEvent = events[0];
170
+ const lastEvent = events[events.length - 1];
171
+ const hasInvalidRange = !Number.isSafeInteger(sequenceStart) || sequenceStart < 0 || !Number.isSafeInteger(sequenceEnd) || !firstEvent || !lastEvent || firstEvent.traceSeq !== sequenceStart + 1 || lastEvent.traceSeq !== sequenceEnd + 1;
172
+ if (hasInvalidRange) {
173
+ return { kind: "invalid", reason: "Trace batch sequence range does not match its events" };
174
+ }
175
+ return { kind: "valid", sequenceStart, sequenceEnd };
176
+ }
177
+ snapshotEvent(event) {
178
+ return Object.freeze({
179
+ ...event,
180
+ ...event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}
181
+ });
182
+ }
183
+ validateIdentity(input) {
184
+ if (input.protocolVersion !== 1) {
185
+ return { kind: "invalid", reason: "Trace batch protocol version is unsupported" };
186
+ }
187
+ if (typeof input.producerId !== "string" || input.producerId.trim().length === 0) {
188
+ return { kind: "invalid", reason: "Trace batch producer identity is invalid" };
189
+ }
190
+ if (typeof input.batchId !== "string" || input.batchId.trim().length === 0) {
191
+ return { kind: "invalid", reason: "Trace batch identity is invalid" };
192
+ }
193
+ return { kind: "valid" };
194
+ }
195
+ isConversationId(value) {
196
+ return typeof value === "string" || typeof value === "number" && Number.isFinite(value);
197
+ }
198
+ isRecord(value) {
199
+ return typeof value === "object" && value !== null && !Array.isArray(value);
200
+ }
201
+ }
202
+ export {
203
+ WoodTraceBatchContract
204
+ };
205
+ //# sourceMappingURL=wood_trace_batch_contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tracing/wood_trace_batch_contract.ts"],"sourcesContent":["import type {\n WoodRendererTraceEvent,\n WoodTraceAcknowledgementParseResult,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchParseResult,\n WoodTraceEventParseResult,\n WoodTraceEventsParseResult,\n WoodTraceIdentityValidationResult,\n} from './types/wood_trace_batch.types.js';\n\nconst MAX_BATCH_EVENTS = 256;\n\nexport class WoodTraceBatchContract {\n create(\n producerId: string,\n sequenceStart: number,\n events: readonly WoodRendererTraceEvent[],\n ): WoodTraceBatch {\n const snapshots = events.map((event) => this.snapshotEvent(event));\n const last = snapshots[snapshots.length - 1];\n const sequenceEnd = last ? last.traceSeq - 1 : sequenceStart - 1;\n return Object.freeze({\n kind: 'wood.trace.batch',\n protocolVersion: 1,\n producerId,\n batchId: `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`,\n sequenceStart,\n sequenceEnd,\n events: Object.freeze(snapshots),\n });\n }\n\n parse(input: unknown): WoodTraceBatchParseResult {\n if (!this.isRecord(input) || input.kind !== 'wood.trace.batch') {\n return { kind: 'not-batch' };\n }\n\n const batchId = typeof input.batchId === 'string' ? input.batchId : null;\n const identity = this.validateIdentity(input);\n if (identity.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: identity.reason };\n }\n const producerId = input.producerId;\n if (typeof producerId !== 'string') {\n return { kind: 'invalid', batchId, reason: 'Trace batch producer identity is invalid' };\n }\n\n const parsedEvents = this.parseEvents(input.events);\n if (parsedEvents.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedEvents.reason };\n }\n const events = parsedEvents.events;\n\n const parsedSequenceRange = this.parseSequenceRange(input, events);\n if (parsedSequenceRange.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedSequenceRange.reason };\n }\n const { sequenceStart, sequenceEnd } = parsedSequenceRange;\n const hasTraceSequenceMismatch = events.some((event, index) => {\n const previous = events[index - 1];\n return previous !== undefined && event.traceSeq <= previous.traceSeq;\n });\n if (hasTraceSequenceMismatch) {\n return { kind: 'invalid', batchId, reason: 'Trace event sequences are not strictly increasing' };\n }\n const expectedBatchId = `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`;\n if (input.batchId !== expectedBatchId) {\n return { kind: 'invalid', batchId, reason: 'Trace batch identity does not match its sequence range' };\n }\n\n return {\n kind: 'valid',\n batch: this.create(producerId, sequenceStart, events),\n };\n }\n\n parseAcknowledgement(input: unknown): WoodTraceAcknowledgementParseResult {\n if (!this.isRecord(input) || typeof input.kind !== 'string' || typeof input.batchId !== 'string') {\n return { ok: false, reason: 'Trace batch acknowledgement framing is invalid' };\n }\n\n if (input.kind === 'committed') {\n return this.parseCommittedAcknowledgement(input);\n }\n if (input.kind === 'retryable') {\n return this.parseRetryableAcknowledgement(input);\n }\n if (input.kind === 'rejected' && typeof input.reason === 'string') {\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'rejected',\n batchId: input.batchId,\n reason: input.reason,\n }),\n };\n }\n return { ok: false, reason: 'Trace batch acknowledgement kind is invalid' };\n }\n\n private parseCommittedAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const committedAtMs = input.committedAtMs;\n const acceptedEvents = input.acceptedEvents;\n const validNumbers = typeof batchId === 'string'\n && typeof committedAtMs === 'number'\n && Number.isFinite(committedAtMs)\n && typeof acceptedEvents === 'number'\n && Number.isSafeInteger(acceptedEvents)\n && acceptedEvents >= 0;\n if (!validNumbers) {\n return { ok: false, reason: 'Committed trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'committed',\n batchId,\n committedAtMs,\n acceptedEvents,\n }),\n };\n }\n\n private parseRetryableAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const retryAfterMs = input.retryAfterMs;\n if (typeof batchId !== 'string'\n || typeof input.reason !== 'string'\n || typeof retryAfterMs !== 'number'\n || !Number.isFinite(retryAfterMs)\n || retryAfterMs < 0) {\n return { ok: false, reason: 'Retryable trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'retryable',\n batchId,\n reason: input.reason,\n retryAfterMs,\n }),\n };\n }\n\n private parseEvent(input: unknown): WoodTraceEventParseResult {\n if (!this.isRecord(input)) {\n return { kind: 'invalid', reason: 'Trace event is not an object' };\n }\n const hasValidIdentity = this.hasValidEventIdentity(input);\n const hasValidTiming = this.hasValidEventTiming(input);\n if (!hasValidIdentity || !hasValidTiming) {\n return { kind: 'invalid', reason: 'Trace event identity or timing is invalid' };\n }\n if (input.payload !== undefined && !this.isRecord(input.payload)) {\n return { kind: 'invalid', reason: 'Trace event payload is invalid' };\n }\n return {\n kind: 'valid',\n event: this.snapshotEvent({\n source: input.source,\n type: input.type,\n level: input.level,\n process: 'renderer',\n timestamp: input.timestamp,\n traceSeq: input.traceSeq,\n ...(typeof input.message === 'string' ? { message: input.message } : {}),\n ...(this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {}),\n ...(input.payload ? { payload: input.payload } : {}),\n ...(typeof input.windowId === 'string' ? { windowId: input.windowId } : {}),\n ...(typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? { webContentsId: input.webContentsId }\n : {}),\n ...(typeof input.routeKey === 'string' ? { routeKey: input.routeKey } : {}),\n ...(typeof input.harnessId === 'string' ? { harnessId: input.harnessId } : {}),\n }),\n };\n }\n\n private hasValidEventIdentity(input: Record<string, unknown>): input is Record<string, unknown> & {\n source: string;\n type: string;\n level: string;\n process: 'renderer';\n } {\n return typeof input.source === 'string'\n && input.source.trim().length > 0\n && typeof input.type === 'string'\n && input.type.trim().length > 0\n && typeof input.level === 'string'\n && input.level.trim().length > 0\n && input.process === 'renderer';\n }\n\n private hasValidEventTiming(input: Record<string, unknown>): input is Record<string, unknown> & {\n timestamp: string;\n traceSeq: number;\n } {\n return typeof input.timestamp === 'string'\n && Number.isFinite(Date.parse(input.timestamp))\n && typeof input.traceSeq === 'number'\n && Number.isSafeInteger(input.traceSeq)\n && input.traceSeq >= 1;\n }\n\n private parseEvents(input: unknown): WoodTraceEventsParseResult {\n if (!Array.isArray(input) || input.length === 0 || input.length > MAX_BATCH_EVENTS) {\n return { kind: 'invalid', reason: 'Trace batch events are invalid' };\n }\n const events: WoodRendererTraceEvent[] = [];\n for (const rawEvent of input) {\n const parsedEvent = this.parseEvent(rawEvent);\n if (parsedEvent.kind === 'invalid') {\n return parsedEvent;\n }\n events.push(parsedEvent.event);\n }\n return { kind: 'valid', events: Object.freeze(events) };\n }\n\n private parseSequenceRange(\n input: Record<string, unknown>,\n events: readonly WoodRendererTraceEvent[],\n ): { kind: 'invalid'; reason: string } | { kind: 'valid'; sequenceStart: number; sequenceEnd: number } {\n const sequenceStart = input.sequenceStart;\n const sequenceEnd = input.sequenceEnd;\n if (typeof sequenceStart !== 'number' || typeof sequenceEnd !== 'number') {\n return { kind: 'invalid', reason: 'Trace batch sequence range is invalid' };\n }\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n const hasInvalidRange = !Number.isSafeInteger(sequenceStart)\n || sequenceStart < 0\n || !Number.isSafeInteger(sequenceEnd)\n || !firstEvent\n || !lastEvent\n || firstEvent.traceSeq !== sequenceStart + 1\n || lastEvent.traceSeq !== sequenceEnd + 1;\n if (hasInvalidRange) {\n return { kind: 'invalid', reason: 'Trace batch sequence range does not match its events' };\n }\n return { kind: 'valid', sequenceStart, sequenceEnd };\n }\n\n private snapshotEvent(event: WoodRendererTraceEvent): WoodRendererTraceEvent {\n return Object.freeze({\n ...event,\n ...(event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}),\n });\n }\n\n private validateIdentity(input: Record<string, unknown>): WoodTraceIdentityValidationResult {\n if (input.protocolVersion !== 1) {\n return { kind: 'invalid', reason: 'Trace batch protocol version is unsupported' };\n }\n if (typeof input.producerId !== 'string' || input.producerId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch producer identity is invalid' };\n }\n if (typeof input.batchId !== 'string' || input.batchId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch identity is invalid' };\n }\n return { kind: 'valid' };\n }\n\n private isConversationId(value: unknown): value is string | number {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var build_transport_bridge_exports = {};
20
+ __export(build_transport_bridge_exports, {
21
+ buildTransportBridge: () => buildTransportBridge
22
+ });
23
+ module.exports = __toCommonJS(build_transport_bridge_exports);
24
+ function operationHasInput(op) {
25
+ return Boolean(
26
+ op.inputSchema && op.inputSchema.type === "object" && Object.keys(
27
+ op.inputSchema.properties ?? {}
28
+ ).length > 0
29
+ );
30
+ }
31
+ function buildManifest(operations) {
32
+ return Array.from(operations.values()).map((op) => ({
33
+ channel: op.channel,
34
+ controller: op.controller,
35
+ action: op.action,
36
+ path: op.channel.split("."),
37
+ hasInput: operationHasInput(op)
38
+ }));
39
+ }
40
+ function buildTransportBridge(operations, transport) {
41
+ const tree = {};
42
+ for (const channel of operations.keys()) {
43
+ const parts = channel.split(".");
44
+ let current = tree;
45
+ for (let i = 0; i < parts.length - 1; i++) {
46
+ if (!current[parts[i]]) {
47
+ current[parts[i]] = {};
48
+ }
49
+ current = current[parts[i]];
50
+ }
51
+ const leaf = parts[parts.length - 1];
52
+ current[leaf] = (data) => transport.invoke(channel, data);
53
+ }
54
+ tree.on = (channel, callback) => transport.subscribe(channel, (payload) => callback(payload));
55
+ tree.__rpcManifest = buildManifest(operations);
56
+ return { bridge: tree };
57
+ }
58
+ // Annotate the CommonJS export names for ESM import in node:
59
+ 0 && (module.exports = {
60
+ buildTransportBridge
61
+ });
62
+ //# sourceMappingURL=build_transport_bridge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/transport/build_transport_bridge.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\nimport type { WoodRpcManifestEntry } from '../client/index.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)\n * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested method\n * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`\n * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the\n * same operations map used by codegen — so the existing `getApp()` renderer\n * client can be pointed at this bridge with zero changes.\n *\n * The production Electron preload path is untouched: it still exposes its own\n * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that\n * any `WoodRpcTransport` (in-process or loopback) plugs into.\n */\nexport interface TransportBridgeResult {\n bridge: Record<string, any>;\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys(\n (op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {},\n ).length > 0,\n );\n}\n\nfunction buildManifest(operations: Map<string, OperationDef>): WoodRpcManifestEntry[] {\n return Array.from(operations.values()).map((op) => ({\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n path: op.channel.split('.'),\n hasInput: operationHasInput(op),\n }));\n}\n\n/**\n * Build the nested bridge tree from the operations' dot-path channels.\n * Mirrors the nesting used by the preload generator and router bridge:\n * intermediate segments become namespace objects, leaf segments become\n * transport-backed invoke functions.\n */\nexport function buildTransportBridge(\n operations: Map<string, OperationDef>,\n transport: WoodRpcTransport,\n): TransportBridgeResult {\n const tree: Record<string, any> = {};\n\n for (const channel of operations.keys()) {\n const parts = channel.split('.');\n let current = tree;\n\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n current[parts[i]] = {};\n }\n current = current[parts[i]];\n }\n\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => transport.invoke(channel, data);\n }\n\n tree.on = (channel: string, callback: (...args: unknown[]) => void) =>\n transport.subscribe(channel, (payload) => callback(payload));\n\n tree.__rpcManifest = buildManifest(operations);\n\n return { bridge: tree };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBA,SAAS,kBAAkB,IAA2B;AACpD,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO;AAAA,MACJ,GAAG,YAAwD,cAAc,CAAC;AAAA,IAC7E,EAAE,SAAS;AAAA,EACf;AACF;AAEA,SAAS,cAAc,YAA+D;AACpF,SAAO,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ;AAAA,IAClD,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,IAC1B,UAAU,kBAAkB,EAAE;AAAA,EAChC,EAAE;AACJ;AAQO,SAAS,qBACd,YACA,WACuB;AACvB,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,WAAW,KAAK,GAAG;AACvC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,GAAG;AACtB,gBAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAAA,MACvB;AACA,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AAEA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,UAAU,OAAO,SAAS,IAAI;AAAA,EACpE;AAEA,OAAK,KAAK,CAAC,SAAiB,aAC1B,UAAU,UAAU,SAAS,CAAC,YAAY,SAAS,OAAO,CAAC;AAE7D,OAAK,gBAAgB,cAAc,UAAU;AAE7C,SAAO,EAAE,QAAQ,KAAK;AACxB;","names":[]}
@@ -0,0 +1,29 @@
1
+ import { OperationDef } from '../types/operations.cjs';
2
+ import { WoodRpcTransport } from './wood_rpc_transport.cjs';
3
+
4
+ /**
5
+ * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)
6
+ * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.
7
+ *
8
+ * Every operation channel (e.g. `chat.messages.send`) becomes a nested method
9
+ * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`
10
+ * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the
11
+ * same operations map used by codegen — so the existing `getApp()` renderer
12
+ * client can be pointed at this bridge with zero changes.
13
+ *
14
+ * The production Electron preload path is untouched: it still exposes its own
15
+ * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that
16
+ * any `WoodRpcTransport` (in-process or loopback) plugs into.
17
+ */
18
+ interface TransportBridgeResult {
19
+ bridge: Record<string, any>;
20
+ }
21
+ /**
22
+ * Build the nested bridge tree from the operations' dot-path channels.
23
+ * Mirrors the nesting used by the preload generator and router bridge:
24
+ * intermediate segments become namespace objects, leaf segments become
25
+ * transport-backed invoke functions.
26
+ */
27
+ declare function buildTransportBridge(operations: Map<string, OperationDef>, transport: WoodRpcTransport): TransportBridgeResult;
28
+
29
+ export { type TransportBridgeResult, buildTransportBridge };
@@ -0,0 +1,29 @@
1
+ import { OperationDef } from '../types/operations.js';
2
+ import { WoodRpcTransport } from './wood_rpc_transport.js';
3
+
4
+ /**
5
+ * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)
6
+ * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.
7
+ *
8
+ * Every operation channel (e.g. `chat.messages.send`) becomes a nested method
9
+ * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`
10
+ * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the
11
+ * same operations map used by codegen — so the existing `getApp()` renderer
12
+ * client can be pointed at this bridge with zero changes.
13
+ *
14
+ * The production Electron preload path is untouched: it still exposes its own
15
+ * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that
16
+ * any `WoodRpcTransport` (in-process or loopback) plugs into.
17
+ */
18
+ interface TransportBridgeResult {
19
+ bridge: Record<string, any>;
20
+ }
21
+ /**
22
+ * Build the nested bridge tree from the operations' dot-path channels.
23
+ * Mirrors the nesting used by the preload generator and router bridge:
24
+ * intermediate segments become namespace objects, leaf segments become
25
+ * transport-backed invoke functions.
26
+ */
27
+ declare function buildTransportBridge(operations: Map<string, OperationDef>, transport: WoodRpcTransport): TransportBridgeResult;
28
+
29
+ export { type TransportBridgeResult, buildTransportBridge };
@@ -0,0 +1,38 @@
1
+ function operationHasInput(op) {
2
+ return Boolean(
3
+ op.inputSchema && op.inputSchema.type === "object" && Object.keys(
4
+ op.inputSchema.properties ?? {}
5
+ ).length > 0
6
+ );
7
+ }
8
+ function buildManifest(operations) {
9
+ return Array.from(operations.values()).map((op) => ({
10
+ channel: op.channel,
11
+ controller: op.controller,
12
+ action: op.action,
13
+ path: op.channel.split("."),
14
+ hasInput: operationHasInput(op)
15
+ }));
16
+ }
17
+ function buildTransportBridge(operations, transport) {
18
+ const tree = {};
19
+ for (const channel of operations.keys()) {
20
+ const parts = channel.split(".");
21
+ let current = tree;
22
+ for (let i = 0; i < parts.length - 1; i++) {
23
+ if (!current[parts[i]]) {
24
+ current[parts[i]] = {};
25
+ }
26
+ current = current[parts[i]];
27
+ }
28
+ const leaf = parts[parts.length - 1];
29
+ current[leaf] = (data) => transport.invoke(channel, data);
30
+ }
31
+ tree.on = (channel, callback) => transport.subscribe(channel, (payload) => callback(payload));
32
+ tree.__rpcManifest = buildManifest(operations);
33
+ return { bridge: tree };
34
+ }
35
+ export {
36
+ buildTransportBridge
37
+ };
38
+ //# sourceMappingURL=build_transport_bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/transport/build_transport_bridge.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\nimport type { WoodRpcManifestEntry } from '../client/index.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)\n * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested method\n * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`\n * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the\n * same operations map used by codegen — so the existing `getApp()` renderer\n * client can be pointed at this bridge with zero changes.\n *\n * The production Electron preload path is untouched: it still exposes its own\n * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that\n * any `WoodRpcTransport` (in-process or loopback) plugs into.\n */\nexport interface TransportBridgeResult {\n bridge: Record<string, any>;\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys(\n (op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {},\n ).length > 0,\n );\n}\n\nfunction buildManifest(operations: Map<string, OperationDef>): WoodRpcManifestEntry[] {\n return Array.from(operations.values()).map((op) => ({\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n path: op.channel.split('.'),\n hasInput: operationHasInput(op),\n }));\n}\n\n/**\n * Build the nested bridge tree from the operations' dot-path channels.\n * Mirrors the nesting used by the preload generator and router bridge:\n * intermediate segments become namespace objects, leaf segments become\n * transport-backed invoke functions.\n */\nexport function buildTransportBridge(\n operations: Map<string, OperationDef>,\n transport: WoodRpcTransport,\n): TransportBridgeResult {\n const tree: Record<string, any> = {};\n\n for (const channel of operations.keys()) {\n const parts = channel.split('.');\n let current = tree;\n\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n current[parts[i]] = {};\n }\n current = current[parts[i]];\n }\n\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => transport.invoke(channel, data);\n }\n\n tree.on = (channel: string, callback: (...args: unknown[]) => void) =>\n transport.subscribe(channel, (payload) => callback(payload));\n\n tree.__rpcManifest = buildManifest(operations);\n\n return { bridge: tree };\n}\n"],"mappings":"AAsBA,SAAS,kBAAkB,IAA2B;AACpD,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO;AAAA,MACJ,GAAG,YAAwD,cAAc,CAAC;AAAA,IAC7E,EAAE,SAAS;AAAA,EACf;AACF;AAEA,SAAS,cAAc,YAA+D;AACpF,SAAO,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ;AAAA,IAClD,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,IAC1B,UAAU,kBAAkB,EAAE;AAAA,EAChC,EAAE;AACJ;AAQO,SAAS,qBACd,YACA,WACuB;AACvB,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,WAAW,KAAK,GAAG;AACvC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,GAAG;AACtB,gBAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAAA,MACvB;AACA,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AAEA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,UAAU,OAAO,SAAS,IAAI;AAAA,EACpE;AAEA,OAAK,KAAK,CAAC,SAAiB,aAC1B,UAAU,UAAU,SAAS,CAAC,YAAY,SAAS,OAAO,CAAC;AAE7D,OAAK,gBAAgB,cAAc,UAAU;AAE7C,SAAO,EAAE,QAAQ,KAAK;AACxB;","names":[]}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var in_process_router_transport_exports = {};
20
+ __export(in_process_router_transport_exports, {
21
+ InProcessRouterTransport: () => InProcessRouterTransport
22
+ });
23
+ module.exports = __toCommonJS(in_process_router_transport_exports);
24
+ var import_create_router_bridge = require("../testing/create_router_bridge.js");
25
+ class InProcessRouterTransport {
26
+ constructor(router, events = new import_create_router_bridge.RouterBridgeEvents()) {
27
+ this.router = router;
28
+ this.events = events;
29
+ }
30
+ invoke(channel, payload) {
31
+ return this.router.dispatch(channel, payload ?? {});
32
+ }
33
+ subscribe(channel, listener) {
34
+ return this.events.on(channel, (data) => listener(data));
35
+ }
36
+ }
37
+ // Annotate the CommonJS export names for ESM import in node:
38
+ 0 && (module.exports = {
39
+ InProcessRouterTransport
40
+ });
41
+ //# sourceMappingURL=in_process_router_transport.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/transport/in_process_router_transport.ts"],"sourcesContent":["import type { WoodRouter } from '../router/wood_router.cjs';\nimport { RouterBridgeEvents } from '../testing/create_router_bridge.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * A `WoodRpcTransport` that dispatches straight through a real `WoodRouter`\n * (full input-schema validation, scoped container, middleware, controller\n * resolution) and delivers push events through the same `RouterBridgeEvents`\n * emitter the router bridge uses.\n *\n * Wiring the push side (server -> subscriber):\n *\n * const transport = new InProcessRouterTransport(router);\n * const windowEvents = await container.get(WindowEventService);\n * windowEvents.configure((ch, data) => transport.events.emit(ch, data));\n *\n * `WindowEventService.send` prepends `__event:`; `RouterBridgeEvents.emit`\n * strips it — identical semantics to `create_router_bridge`.\n *\n * Fast-tier safe: imports no `electron` and no `playwright`.\n */\nexport class InProcessRouterTransport implements WoodRpcTransport {\n readonly events: RouterBridgeEvents;\n\n private readonly router: WoodRouter;\n\n constructor(router: WoodRouter, events: RouterBridgeEvents = new RouterBridgeEvents()) {\n this.router = router;\n this.events = events;\n }\n\n invoke(channel: string, payload?: unknown): Promise<unknown> {\n return this.router.dispatch(channel, payload ?? {});\n }\n\n subscribe(channel: string, listener: (payload: unknown) => void): () => void {\n return this.events.on(channel, (data) => listener(data));\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kCAAmC;AAoB5B,MAAM,yBAAqD;AAAA,EAKhE,YAAY,QAAoB,SAA6B,IAAI,+CAAmB,GAAG;AACrF,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,OAAO,SAAiB,SAAqC;AAC3D,WAAO,KAAK,OAAO,SAAS,SAAS,WAAW,CAAC,CAAC;AAAA,EACpD;AAAA,EAEA,UAAU,SAAiB,UAAkD;AAC3E,WAAO,KAAK,OAAO,GAAG,SAAS,CAAC,SAAS,SAAS,IAAI,CAAC;AAAA,EACzD;AACF;","names":[]}
@@ -0,0 +1,31 @@
1
+ import { WoodRouter } from '../router/wood_router.cjs';
2
+ import { RouterBridgeEvents } from '../testing/create_router_bridge.cjs';
3
+ import { WoodRpcTransport } from './wood_rpc_transport.cjs';
4
+ import '../types/operations.cjs';
5
+
6
+ /**
7
+ * A `WoodRpcTransport` that dispatches straight through a real `WoodRouter`
8
+ * (full input-schema validation, scoped container, middleware, controller
9
+ * resolution) and delivers push events through the same `RouterBridgeEvents`
10
+ * emitter the router bridge uses.
11
+ *
12
+ * Wiring the push side (server -> subscriber):
13
+ *
14
+ * const transport = new InProcessRouterTransport(router);
15
+ * const windowEvents = await container.get(WindowEventService);
16
+ * windowEvents.configure((ch, data) => transport.events.emit(ch, data));
17
+ *
18
+ * `WindowEventService.send` prepends `__event:`; `RouterBridgeEvents.emit`
19
+ * strips it — identical semantics to `create_router_bridge`.
20
+ *
21
+ * Fast-tier safe: imports no `electron` and no `playwright`.
22
+ */
23
+ declare class InProcessRouterTransport implements WoodRpcTransport {
24
+ readonly events: RouterBridgeEvents;
25
+ private readonly router;
26
+ constructor(router: WoodRouter, events?: RouterBridgeEvents);
27
+ invoke(channel: string, payload?: unknown): Promise<unknown>;
28
+ subscribe(channel: string, listener: (payload: unknown) => void): () => void;
29
+ }
30
+
31
+ export { InProcessRouterTransport };
@@ -0,0 +1,31 @@
1
+ import { WoodRouter } from '../router/wood_router.js';
2
+ import { RouterBridgeEvents } from '../testing/create_router_bridge.js';
3
+ import { WoodRpcTransport } from './wood_rpc_transport.js';
4
+ import '../types/operations.js';
5
+
6
+ /**
7
+ * A `WoodRpcTransport` that dispatches straight through a real `WoodRouter`
8
+ * (full input-schema validation, scoped container, middleware, controller
9
+ * resolution) and delivers push events through the same `RouterBridgeEvents`
10
+ * emitter the router bridge uses.
11
+ *
12
+ * Wiring the push side (server -> subscriber):
13
+ *
14
+ * const transport = new InProcessRouterTransport(router);
15
+ * const windowEvents = await container.get(WindowEventService);
16
+ * windowEvents.configure((ch, data) => transport.events.emit(ch, data));
17
+ *
18
+ * `WindowEventService.send` prepends `__event:`; `RouterBridgeEvents.emit`
19
+ * strips it — identical semantics to `create_router_bridge`.
20
+ *
21
+ * Fast-tier safe: imports no `electron` and no `playwright`.
22
+ */
23
+ declare class InProcessRouterTransport implements WoodRpcTransport {
24
+ readonly events: RouterBridgeEvents;
25
+ private readonly router;
26
+ constructor(router: WoodRouter, events?: RouterBridgeEvents);
27
+ invoke(channel: string, payload?: unknown): Promise<unknown>;
28
+ subscribe(channel: string, listener: (payload: unknown) => void): () => void;
29
+ }
30
+
31
+ export { InProcessRouterTransport };
@@ -0,0 +1,17 @@
1
+ import { RouterBridgeEvents } from "../testing/create_router_bridge.js";
2
+ class InProcessRouterTransport {
3
+ constructor(router, events = new RouterBridgeEvents()) {
4
+ this.router = router;
5
+ this.events = events;
6
+ }
7
+ invoke(channel, payload) {
8
+ return this.router.dispatch(channel, payload ?? {});
9
+ }
10
+ subscribe(channel, listener) {
11
+ return this.events.on(channel, (data) => listener(data));
12
+ }
13
+ }
14
+ export {
15
+ InProcessRouterTransport
16
+ };
17
+ //# sourceMappingURL=in_process_router_transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/transport/in_process_router_transport.ts"],"sourcesContent":["import type { WoodRouter } from '../router/wood_router.js';\nimport { RouterBridgeEvents } from '../testing/create_router_bridge.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * A `WoodRpcTransport` that dispatches straight through a real `WoodRouter`\n * (full input-schema validation, scoped container, middleware, controller\n * resolution) and delivers push events through the same `RouterBridgeEvents`\n * emitter the router bridge uses.\n *\n * Wiring the push side (server -> subscriber):\n *\n * const transport = new InProcessRouterTransport(router);\n * const windowEvents = await container.get(WindowEventService);\n * windowEvents.configure((ch, data) => transport.events.emit(ch, data));\n *\n * `WindowEventService.send` prepends `__event:`; `RouterBridgeEvents.emit`\n * strips it — identical semantics to `create_router_bridge`.\n *\n * Fast-tier safe: imports no `electron` and no `playwright`.\n */\nexport class InProcessRouterTransport implements WoodRpcTransport {\n readonly events: RouterBridgeEvents;\n\n private readonly router: WoodRouter;\n\n constructor(router: WoodRouter, events: RouterBridgeEvents = new RouterBridgeEvents()) {\n this.router = router;\n this.events = events;\n }\n\n invoke(channel: string, payload?: unknown): Promise<unknown> {\n return this.router.dispatch(channel, payload ?? {});\n }\n\n subscribe(channel: string, listener: (payload: unknown) => void): () => void {\n return this.events.on(channel, (data) => listener(data));\n }\n}\n"],"mappings":"AACA,SAAS,0BAA0B;AAoB5B,MAAM,yBAAqD;AAAA,EAKhE,YAAY,QAAoB,SAA6B,IAAI,mBAAmB,GAAG;AACrF,SAAK,SAAS;AACd,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,OAAO,SAAiB,SAAqC;AAC3D,WAAO,KAAK,OAAO,SAAS,SAAS,WAAW,CAAC,CAAC;AAAA,EACpD;AAAA,EAEA,UAAU,SAAiB,UAAkD;AAC3E,WAAO,KAAK,OAAO,GAAG,SAAS,CAAC,SAAS,SAAS,IAAI,CAAC;AAAA,EACzD;AACF;","names":[]}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var transport_exports = {};
20
+ __export(transport_exports, {
21
+ InProcessRouterTransport: () => import_in_process_router_transport.InProcessRouterTransport,
22
+ LoopbackRemoteTransport: () => import_loopback_remote_transport.LoopbackRemoteTransport,
23
+ LoopbackRemoteTransportServer: () => import_loopback_remote_transport.LoopbackRemoteTransportServer,
24
+ LoopbackSerializationError: () => import_loopback_serialization.LoopbackSerializationError,
25
+ assertLoopbackSerializable: () => import_loopback_serialization.assertLoopbackSerializable,
26
+ buildTransportBridge: () => import_build_transport_bridge.buildTransportBridge
27
+ });
28
+ module.exports = __toCommonJS(transport_exports);
29
+ var import_in_process_router_transport = require("./in_process_router_transport.js");
30
+ var import_loopback_remote_transport = require("./loopback_remote_transport.js");
31
+ var import_loopback_serialization = require("./loopback_serialization.js");
32
+ var import_build_transport_bridge = require("./build_transport_bridge.js");
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ InProcessRouterTransport,
36
+ LoopbackRemoteTransport,
37
+ LoopbackRemoteTransportServer,
38
+ LoopbackSerializationError,
39
+ assertLoopbackSerializable,
40
+ buildTransportBridge
41
+ });
42
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/transport/index.ts"],"sourcesContent":["export type {\n WoodRpcTransport,\n WoodChannelContract,\n WoodChannelMapLike,\n WoodChannelInput,\n WoodChannelOutput,\n TypedCall,\n} from './wood_rpc_transport.js';\nexport { InProcessRouterTransport } from './in_process_router_transport.js';\nexport {\n LoopbackRemoteTransport,\n LoopbackRemoteTransportServer,\n} from './loopback_remote_transport.js';\nexport {\n assertLoopbackSerializable,\n LoopbackSerializationError,\n} from './loopback_serialization.js';\nexport { buildTransportBridge, type TransportBridgeResult } from './build_transport_bridge.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,yCAAyC;AACzC,uCAGO;AACP,oCAGO;AACP,oCAAiE;","names":[]}
@@ -0,0 +1,8 @@
1
+ export { TypedCall, WoodChannelContract, WoodChannelInput, WoodChannelMapLike, WoodChannelOutput, WoodRpcTransport } from './wood_rpc_transport.cjs';
2
+ export { InProcessRouterTransport } from './in_process_router_transport.cjs';
3
+ export { LoopbackRemoteTransport, LoopbackRemoteTransportServer } from './loopback_remote_transport.cjs';
4
+ export { LoopbackSerializationError, assertLoopbackSerializable } from './loopback_serialization.cjs';
5
+ export { TransportBridgeResult, buildTransportBridge } from './build_transport_bridge.cjs';
6
+ import '../router/wood_router.cjs';
7
+ import '../types/operations.cjs';
8
+ import '../testing/create_router_bridge.cjs';
@@ -0,0 +1,8 @@
1
+ export { TypedCall, WoodChannelContract, WoodChannelInput, WoodChannelMapLike, WoodChannelOutput, WoodRpcTransport } from './wood_rpc_transport.js';
2
+ export { InProcessRouterTransport } from './in_process_router_transport.js';
3
+ export { LoopbackRemoteTransport, LoopbackRemoteTransportServer } from './loopback_remote_transport.js';
4
+ export { LoopbackSerializationError, assertLoopbackSerializable } from './loopback_serialization.js';
5
+ export { TransportBridgeResult, buildTransportBridge } from './build_transport_bridge.js';
6
+ import '../router/wood_router.js';
7
+ import '../types/operations.js';
8
+ import '../testing/create_router_bridge.js';