rivetkit 2.0.3 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/README.md +11 -0
  2. package/dist/schemas/actor-persist/v1.ts +21 -24
  3. package/dist/schemas/client-protocol/v1.ts +6 -0
  4. package/dist/tsup/actor/errors.cjs +10 -2
  5. package/dist/tsup/actor/errors.cjs.map +1 -1
  6. package/dist/tsup/actor/errors.d.cts +17 -4
  7. package/dist/tsup/actor/errors.d.ts +17 -4
  8. package/dist/tsup/actor/errors.js +11 -3
  9. package/dist/tsup/{chunk-4NSUQZ2H.js → chunk-2MD57QF4.js} +119 -115
  10. package/dist/tsup/chunk-2MD57QF4.js.map +1 -0
  11. package/dist/tsup/{chunk-GIR3AFFI.cjs → chunk-5QGQK44L.cjs} +103 -44
  12. package/dist/tsup/chunk-5QGQK44L.cjs.map +1 -0
  13. package/dist/tsup/chunk-5YTI25C3.cjs +250 -0
  14. package/dist/tsup/chunk-5YTI25C3.cjs.map +1 -0
  15. package/dist/tsup/chunk-B2QGJGZQ.js +338 -0
  16. package/dist/tsup/chunk-B2QGJGZQ.js.map +1 -0
  17. package/dist/tsup/{chunk-3H7O2A7I.js → chunk-CFFKMUYH.js} +61 -22
  18. package/dist/tsup/chunk-CFFKMUYH.js.map +1 -0
  19. package/dist/tsup/{chunk-FLMTTN27.js → chunk-CKA54YQN.js} +15 -8
  20. package/dist/tsup/chunk-CKA54YQN.js.map +1 -0
  21. package/dist/tsup/chunk-D7NWUCRK.cjs +20 -0
  22. package/dist/tsup/chunk-D7NWUCRK.cjs.map +1 -0
  23. package/dist/tsup/{chunk-FCCPJNMA.cjs → chunk-FGFT4FVX.cjs} +12 -27
  24. package/dist/tsup/chunk-FGFT4FVX.cjs.map +1 -0
  25. package/dist/tsup/chunk-I5VTWPHW.js +20 -0
  26. package/dist/tsup/chunk-I5VTWPHW.js.map +1 -0
  27. package/dist/tsup/{chunk-6WKQDDUD.cjs → chunk-IRMBWX36.cjs} +146 -142
  28. package/dist/tsup/chunk-IRMBWX36.cjs.map +1 -0
  29. package/dist/tsup/chunk-L7QRXNWP.js +6562 -0
  30. package/dist/tsup/chunk-L7QRXNWP.js.map +1 -0
  31. package/dist/tsup/{chunk-R2OPSKIV.cjs → chunk-LZIBTLEY.cjs} +20 -13
  32. package/dist/tsup/chunk-LZIBTLEY.cjs.map +1 -0
  33. package/dist/tsup/chunk-MRZS2J4X.cjs +6562 -0
  34. package/dist/tsup/chunk-MRZS2J4X.cjs.map +1 -0
  35. package/dist/tsup/{chunk-PO4VLDWA.js → chunk-PG3K2LI7.js} +3 -5
  36. package/dist/tsup/chunk-PG3K2LI7.js.map +1 -0
  37. package/dist/tsup/{chunk-TZJKSBUQ.cjs → chunk-PHSQJ6QI.cjs} +3 -5
  38. package/dist/tsup/chunk-PHSQJ6QI.cjs.map +1 -0
  39. package/dist/tsup/chunk-RM2SVURR.cjs +338 -0
  40. package/dist/tsup/chunk-RM2SVURR.cjs.map +1 -0
  41. package/dist/tsup/{chunk-OGAPU3UG.cjs → chunk-WADSS5X4.cjs} +66 -27
  42. package/dist/tsup/chunk-WADSS5X4.cjs.map +1 -0
  43. package/dist/tsup/chunk-WNGOBAA7.js +250 -0
  44. package/dist/tsup/chunk-WNGOBAA7.js.map +1 -0
  45. package/dist/tsup/{chunk-INGJP237.js → chunk-YPZFLUO6.js} +103 -44
  46. package/dist/tsup/chunk-YPZFLUO6.js.map +1 -0
  47. package/dist/tsup/{chunk-6PDXBYI5.js → chunk-YW6Y6VNE.js} +8 -23
  48. package/dist/tsup/chunk-YW6Y6VNE.js.map +1 -0
  49. package/dist/tsup/client/mod.cjs +10 -10
  50. package/dist/tsup/client/mod.d.cts +7 -13
  51. package/dist/tsup/client/mod.d.ts +7 -13
  52. package/dist/tsup/client/mod.js +9 -9
  53. package/dist/tsup/common/log.cjs +12 -4
  54. package/dist/tsup/common/log.cjs.map +1 -1
  55. package/dist/tsup/common/log.d.cts +23 -17
  56. package/dist/tsup/common/log.d.ts +23 -17
  57. package/dist/tsup/common/log.js +15 -7
  58. package/dist/tsup/common/websocket.cjs +5 -5
  59. package/dist/tsup/common/websocket.js +4 -4
  60. package/dist/tsup/{common-CpqORuCq.d.cts → common-CXCe7s6i.d.cts} +2 -2
  61. package/dist/tsup/{common-CpqORuCq.d.ts → common-CXCe7s6i.d.ts} +2 -2
  62. package/dist/tsup/{connection-BwUMoe6n.d.ts → connection-BvE-Oq7t.d.ts} +215 -234
  63. package/dist/tsup/{connection-BR_Ve4ku.d.cts → connection-DTzmWwU5.d.cts} +215 -234
  64. package/dist/tsup/driver-helpers/mod.cjs +6 -9
  65. package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
  66. package/dist/tsup/driver-helpers/mod.d.cts +5 -6
  67. package/dist/tsup/driver-helpers/mod.d.ts +5 -6
  68. package/dist/tsup/driver-helpers/mod.js +6 -9
  69. package/dist/tsup/driver-test-suite/mod.cjs +615 -1357
  70. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
  71. package/dist/tsup/driver-test-suite/mod.d.cts +12 -6
  72. package/dist/tsup/driver-test-suite/mod.d.ts +12 -6
  73. package/dist/tsup/driver-test-suite/mod.js +1334 -2076
  74. package/dist/tsup/driver-test-suite/mod.js.map +1 -1
  75. package/dist/tsup/inspector/mod.cjs +6 -8
  76. package/dist/tsup/inspector/mod.cjs.map +1 -1
  77. package/dist/tsup/inspector/mod.d.cts +3 -3
  78. package/dist/tsup/inspector/mod.d.ts +3 -3
  79. package/dist/tsup/inspector/mod.js +8 -10
  80. package/dist/tsup/mod.cjs +9 -15
  81. package/dist/tsup/mod.cjs.map +1 -1
  82. package/dist/tsup/mod.d.cts +47 -42
  83. package/dist/tsup/mod.d.ts +47 -42
  84. package/dist/tsup/mod.js +10 -16
  85. package/dist/tsup/{router-endpoints-DAbqVFx2.d.ts → router-endpoints-CctffZNL.d.cts} +2 -3
  86. package/dist/tsup/{router-endpoints-AYkXG8Tl.d.cts → router-endpoints-DFm1BglJ.d.ts} +2 -3
  87. package/dist/tsup/test/mod.cjs +10 -14
  88. package/dist/tsup/test/mod.cjs.map +1 -1
  89. package/dist/tsup/test/mod.d.cts +4 -5
  90. package/dist/tsup/test/mod.d.ts +4 -5
  91. package/dist/tsup/test/mod.js +9 -13
  92. package/dist/tsup/{utils-CT0cv4jd.d.ts → utils-fwx3o3K9.d.cts} +1 -0
  93. package/dist/tsup/{utils-CT0cv4jd.d.cts → utils-fwx3o3K9.d.ts} +1 -0
  94. package/dist/tsup/utils.cjs +5 -3
  95. package/dist/tsup/utils.cjs.map +1 -1
  96. package/dist/tsup/utils.d.cts +19 -2
  97. package/dist/tsup/utils.d.ts +19 -2
  98. package/dist/tsup/utils.js +4 -2
  99. package/package.json +6 -6
  100. package/src/actor/action.ts +1 -5
  101. package/src/actor/config.ts +27 -295
  102. package/src/actor/connection.ts +9 -12
  103. package/src/actor/context.ts +1 -4
  104. package/src/actor/definition.ts +7 -11
  105. package/src/actor/errors.ts +98 -36
  106. package/src/actor/generic-conn-driver.ts +28 -16
  107. package/src/actor/instance.ts +177 -133
  108. package/src/actor/log.ts +4 -13
  109. package/src/actor/mod.ts +0 -5
  110. package/src/actor/protocol/old.ts +42 -26
  111. package/src/actor/protocol/serde.ts +1 -1
  112. package/src/actor/router-endpoints.ts +47 -39
  113. package/src/actor/router.ts +22 -19
  114. package/src/actor/unstable-react.ts +1 -1
  115. package/src/actor/utils.ts +6 -2
  116. package/src/client/actor-common.ts +1 -1
  117. package/src/client/actor-conn.ts +152 -91
  118. package/src/client/actor-handle.ts +85 -25
  119. package/src/client/actor-query.ts +65 -0
  120. package/src/client/client.ts +29 -98
  121. package/src/client/config.ts +44 -0
  122. package/src/client/errors.ts +1 -0
  123. package/src/client/log.ts +2 -4
  124. package/src/client/mod.ts +16 -12
  125. package/src/client/raw-utils.ts +82 -25
  126. package/src/client/utils.ts +5 -3
  127. package/src/common/fake-event-source.ts +10 -9
  128. package/src/common/inline-websocket-adapter2.ts +39 -30
  129. package/src/common/log.ts +176 -101
  130. package/src/common/logfmt.ts +21 -30
  131. package/src/common/router.ts +12 -19
  132. package/src/common/utils.ts +27 -13
  133. package/src/common/websocket.ts +0 -1
  134. package/src/driver-helpers/mod.ts +1 -1
  135. package/src/driver-test-suite/log.ts +1 -3
  136. package/src/driver-test-suite/mod.ts +87 -61
  137. package/src/driver-test-suite/test-inline-client-driver.ts +441 -255
  138. package/src/driver-test-suite/tests/actor-error-handling.ts +4 -12
  139. package/src/driver-test-suite/tests/actor-handle.ts +33 -0
  140. package/src/driver-test-suite/tests/actor-inspector.ts +2 -1
  141. package/src/driver-test-suite/tests/manager-driver.ts +5 -3
  142. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -226
  143. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -392
  144. package/src/driver-test-suite/tests/request-access.ts +112 -126
  145. package/src/driver-test-suite/utils.ts +10 -6
  146. package/src/drivers/default.ts +7 -4
  147. package/src/drivers/engine/actor-driver.ts +22 -13
  148. package/src/drivers/engine/config.ts +2 -10
  149. package/src/drivers/engine/kv.ts +1 -1
  150. package/src/drivers/engine/log.ts +1 -3
  151. package/src/drivers/engine/mod.ts +2 -3
  152. package/src/drivers/file-system/actor.ts +1 -1
  153. package/src/drivers/file-system/global-state.ts +36 -21
  154. package/src/drivers/file-system/log.ts +1 -3
  155. package/src/drivers/file-system/manager.ts +33 -15
  156. package/src/inspector/config.ts +9 -4
  157. package/src/inspector/log.ts +1 -1
  158. package/src/inspector/manager.ts +2 -2
  159. package/src/inspector/utils.ts +1 -1
  160. package/src/manager/driver.ts +10 -2
  161. package/src/manager/hono-websocket-adapter.ts +21 -12
  162. package/src/manager/log.ts +2 -4
  163. package/src/manager/mod.ts +1 -1
  164. package/src/manager/router.ts +378 -1390
  165. package/src/manager-api/routes/actors-create.ts +16 -0
  166. package/src/manager-api/routes/actors-delete.ts +4 -0
  167. package/src/manager-api/routes/actors-get-by-id.ts +7 -0
  168. package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
  169. package/src/manager-api/routes/actors-get.ts +7 -0
  170. package/src/manager-api/routes/common.ts +18 -0
  171. package/src/mod.ts +0 -2
  172. package/src/registry/config.ts +1 -1
  173. package/src/registry/log.ts +2 -4
  174. package/src/registry/mod.ts +63 -34
  175. package/src/registry/run-config.ts +39 -26
  176. package/src/registry/serve.ts +4 -5
  177. package/src/remote-manager-driver/actor-http-client.ts +74 -0
  178. package/src/remote-manager-driver/actor-websocket-client.ts +64 -0
  179. package/src/remote-manager-driver/api-endpoints.ts +79 -0
  180. package/src/remote-manager-driver/api-utils.ts +46 -0
  181. package/src/remote-manager-driver/log.ts +5 -0
  182. package/src/remote-manager-driver/mod.ts +275 -0
  183. package/src/{drivers/engine → remote-manager-driver}/ws-proxy.ts +24 -14
  184. package/src/serde.ts +8 -2
  185. package/src/test/log.ts +1 -3
  186. package/src/test/mod.ts +17 -16
  187. package/src/utils.ts +53 -0
  188. package/dist/tsup/chunk-2CRLFV6Z.cjs +0 -202
  189. package/dist/tsup/chunk-2CRLFV6Z.cjs.map +0 -1
  190. package/dist/tsup/chunk-3H7O2A7I.js.map +0 -1
  191. package/dist/tsup/chunk-42I3OZ3Q.js +0 -15
  192. package/dist/tsup/chunk-42I3OZ3Q.js.map +0 -1
  193. package/dist/tsup/chunk-4NSUQZ2H.js.map +0 -1
  194. package/dist/tsup/chunk-6PDXBYI5.js.map +0 -1
  195. package/dist/tsup/chunk-6WKQDDUD.cjs.map +0 -1
  196. package/dist/tsup/chunk-CTBOSFUH.cjs +0 -116
  197. package/dist/tsup/chunk-CTBOSFUH.cjs.map +0 -1
  198. package/dist/tsup/chunk-EGVZZFE2.js +0 -2857
  199. package/dist/tsup/chunk-EGVZZFE2.js.map +0 -1
  200. package/dist/tsup/chunk-FCCPJNMA.cjs.map +0 -1
  201. package/dist/tsup/chunk-FLMTTN27.js.map +0 -1
  202. package/dist/tsup/chunk-GIR3AFFI.cjs.map +0 -1
  203. package/dist/tsup/chunk-INGJP237.js.map +0 -1
  204. package/dist/tsup/chunk-KJCJLKRM.js +0 -116
  205. package/dist/tsup/chunk-KJCJLKRM.js.map +0 -1
  206. package/dist/tsup/chunk-KUPQZYUQ.cjs +0 -15
  207. package/dist/tsup/chunk-KUPQZYUQ.cjs.map +0 -1
  208. package/dist/tsup/chunk-O2MBYIXO.cjs +0 -2857
  209. package/dist/tsup/chunk-O2MBYIXO.cjs.map +0 -1
  210. package/dist/tsup/chunk-OGAPU3UG.cjs.map +0 -1
  211. package/dist/tsup/chunk-OV6AYD4S.js +0 -4406
  212. package/dist/tsup/chunk-OV6AYD4S.js.map +0 -1
  213. package/dist/tsup/chunk-PO4VLDWA.js.map +0 -1
  214. package/dist/tsup/chunk-R2OPSKIV.cjs.map +0 -1
  215. package/dist/tsup/chunk-TZJKSBUQ.cjs.map +0 -1
  216. package/dist/tsup/chunk-UBUC5C3G.cjs +0 -189
  217. package/dist/tsup/chunk-UBUC5C3G.cjs.map +0 -1
  218. package/dist/tsup/chunk-UIM22YJL.cjs +0 -4406
  219. package/dist/tsup/chunk-UIM22YJL.cjs.map +0 -1
  220. package/dist/tsup/chunk-URVFQMYI.cjs +0 -230
  221. package/dist/tsup/chunk-URVFQMYI.cjs.map +0 -1
  222. package/dist/tsup/chunk-UVUPOS46.js +0 -230
  223. package/dist/tsup/chunk-UVUPOS46.js.map +0 -1
  224. package/dist/tsup/chunk-VRRHBNJC.js +0 -189
  225. package/dist/tsup/chunk-VRRHBNJC.js.map +0 -1
  226. package/dist/tsup/chunk-XFSS33EQ.js +0 -202
  227. package/dist/tsup/chunk-XFSS33EQ.js.map +0 -1
  228. package/src/client/http-client-driver.ts +0 -326
  229. package/src/driver-test-suite/tests/actor-auth.ts +0 -591
  230. package/src/drivers/engine/api-endpoints.ts +0 -128
  231. package/src/drivers/engine/api-utils.ts +0 -70
  232. package/src/drivers/engine/manager-driver.ts +0 -391
  233. package/src/inline-client-driver/log.ts +0 -7
  234. package/src/inline-client-driver/mod.ts +0 -385
  235. package/src/manager/auth.ts +0 -121
  236. /package/src/{drivers/engine → actor}/keys.test.ts +0 -0
  237. /package/src/{drivers/engine → actor}/keys.ts +0 -0
@@ -7,10 +7,8 @@ import type {
7
7
  } from "@/common/websocket-interface";
8
8
  import { getLogger } from "./log";
9
9
 
10
- export const LOGGER_NAME = "fake-event-source2";
11
-
12
10
  export function logger() {
13
- return getLogger(LOGGER_NAME);
11
+ return getLogger("fake-event-source2");
14
12
  }
15
13
 
16
14
  // TODO: Merge with ConnectWebSocketOutput interface
@@ -55,11 +53,11 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
55
53
  this.#wsContext = new WSContext({
56
54
  raw: this,
57
55
  send: (data: string | ArrayBuffer | Uint8Array) => {
58
- logger().debug("WSContext.send called");
56
+ logger().debug({ msg: "WSContext.send called" });
59
57
  this.#handleMessage(data);
60
58
  },
61
59
  close: (code?: number, reason?: string) => {
62
- logger().debug("WSContext.close called", { code, reason });
60
+ logger().debug({ msg: "WSContext.close called", code, reason });
63
61
  this.#handleClose(code || 1000, reason || "");
64
62
  },
65
63
  // Set readyState to 1 (OPEN) since handlers expect an open connection
@@ -99,11 +97,12 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
99
97
  }
100
98
 
101
99
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {
102
- logger().debug("send called", { readyState: this.readyState });
100
+ logger().debug({ msg: "send called", readyState: this.readyState });
103
101
 
104
102
  if (this.readyState !== this.OPEN) {
105
103
  const error = new Error("WebSocket is not open");
106
- logger().warn("cannot send message, websocket not open", {
104
+ logger().warn({
105
+ msg: "cannot send message, websocket not open",
107
106
  readyState: this.readyState,
108
107
  dataType: typeof data,
109
108
  dataLength: typeof data === "string" ? data.length : "binary",
@@ -124,7 +123,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
124
123
  return;
125
124
  }
126
125
 
127
- logger().debug("closing fake websocket", { code, reason });
126
+ logger().debug({ msg: "closing fake websocket", code, reason });
128
127
 
129
128
  this.#readyState = this.CLOSING;
130
129
 
@@ -132,7 +131,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
132
131
  try {
133
132
  this.#handler.onClose({ code, reason, wasClean: true }, this.#wsContext);
134
133
  } catch (err) {
135
- logger().error("error closing websocket", { error: err });
134
+ logger().error({ msg: "error closing websocket", error: err });
136
135
  } finally {
137
136
  this.#readyState = this.CLOSED;
138
137
 
@@ -156,15 +155,15 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
156
155
  */
157
156
  async #initialize(): Promise<void> {
158
157
  try {
159
- logger().debug("fake websocket initializing");
158
+ logger().debug({ msg: "fake websocket initializing" });
160
159
 
161
160
  // Call the handler's onOpen method
162
- logger().debug("calling handler.onOpen with WSContext");
161
+ logger().debug({ msg: "calling handler.onOpen with WSContext" });
163
162
  this.#handler.onOpen(undefined, this.#wsContext);
164
163
 
165
164
  // Update the ready state and fire events
166
165
  this.#readyState = this.OPEN;
167
- logger().debug("fake websocket initialized and now OPEN");
166
+ logger().debug({ msg: "fake websocket initialized and now OPEN" });
168
167
 
169
168
  // Fire the open event
170
169
  this.#fireOpen();
@@ -172,13 +171,15 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
172
171
  // Delay processing queued messages slightly to allow event handlers to be set up
173
172
  if (this.#queuedMessages.length > 0) {
174
173
  if (this.readyState !== this.OPEN) {
175
- logger().warn("socket no longer open, dropping queued messages");
174
+ logger().warn({
175
+ msg: "socket no longer open, dropping queued messages",
176
+ });
176
177
  return;
177
178
  }
178
179
 
179
- logger().debug(
180
- `now processing ${this.#queuedMessages.length} queued messages`,
181
- );
180
+ logger().debug({
181
+ msg: `now processing ${this.#queuedMessages.length} queued messages`,
182
+ });
182
183
 
183
184
  // Create a copy to avoid issues if new messages arrive during processing
184
185
  const messagesToProcess = [...this.#queuedMessages];
@@ -186,12 +187,13 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
186
187
 
187
188
  // Process each queued message
188
189
  for (const message of messagesToProcess) {
189
- logger().debug("processing queued message");
190
+ logger().debug({ msg: "processing queued message" });
190
191
  this.#handleMessage(message);
191
192
  }
192
193
  }
193
194
  } catch (err) {
194
- logger().error("error opening fake websocket", {
195
+ logger().error({
196
+ msg: "error opening fake websocket",
195
197
  error: err,
196
198
  errorMessage: err instanceof Error ? err.message : String(err),
197
199
  stack: err instanceof Error ? err.stack : undefined,
@@ -207,7 +209,8 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
207
209
  #handleMessage(data: string | ArrayBuffer | Uint8Array): void {
208
210
  // Store messages that arrive before the socket is fully initialized
209
211
  if (this.readyState !== this.OPEN) {
210
- logger().debug("message received before socket is OPEN, queuing", {
212
+ logger().debug({
213
+ msg: "message received before socket is OPEN, queuing",
211
214
  readyState: this.readyState,
212
215
  dataType: typeof data,
213
216
  dataLength:
@@ -226,7 +229,8 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
226
229
  }
227
230
 
228
231
  // Log message received from server
229
- logger().debug("fake websocket received message from server", {
232
+ logger().debug({
233
+ msg: "fake websocket received message from server",
230
234
  dataType: typeof data,
231
235
  dataLength:
232
236
  typeof data === "string"
@@ -299,11 +303,16 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
299
303
  try {
300
304
  listener(event);
301
305
  } catch (err) {
302
- logger().error(`error in ${type} event listener`, { error: err });
306
+ logger().error({
307
+ msg: `error in ${type} event listener`,
308
+ error: err,
309
+ });
303
310
  }
304
311
  }
305
312
  } else {
306
- logger().debug(`no ${type} listeners registered, buffering event`);
313
+ logger().debug({
314
+ msg: `no ${type} listeners registered, buffering event`,
315
+ });
307
316
  this.#bufferedEvents.push({ type, event });
308
317
  }
309
318
 
@@ -314,7 +323,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
314
323
  try {
315
324
  this.#onopen(event);
316
325
  } catch (error) {
317
- logger().error("error in onopen handler", { error });
326
+ logger().error({ msg: "error in onopen handler", error });
318
327
  }
319
328
  }
320
329
  break;
@@ -323,7 +332,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
323
332
  try {
324
333
  this.#onclose(event);
325
334
  } catch (error) {
326
- logger().error("error in onclose handler", { error });
335
+ logger().error({ msg: "error in onclose handler", error });
327
336
  }
328
337
  }
329
338
  break;
@@ -332,7 +341,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
332
341
  try {
333
342
  this.#onerror(event);
334
343
  } catch (error) {
335
- logger().error("error in onerror handler", { error });
344
+ logger().error({ msg: "error in onerror handler", error });
336
345
  }
337
346
  }
338
347
  break;
@@ -341,7 +350,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
341
350
  try {
342
351
  this.#onmessage(event);
343
352
  } catch (error) {
344
- logger().error("error in onmessage handler", { error });
353
+ logger().error({ msg: "error in onmessage handler", error });
345
354
  }
346
355
  }
347
356
  break;
@@ -377,7 +386,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
377
386
 
378
387
  this.#dispatchEvent("open", event);
379
388
  } catch (err) {
380
- logger().error("error in open event", { error: err });
389
+ logger().error({ msg: "error in open event", error: err });
381
390
  }
382
391
  }
383
392
 
@@ -385,7 +394,7 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
385
394
  try {
386
395
  this.#dispatchEvent("close", event);
387
396
  } catch (err) {
388
- logger().error("error in close event", { error: err });
397
+ logger().error({ msg: "error in close event", error: err });
389
398
  }
390
399
  }
391
400
 
@@ -402,11 +411,11 @@ export class InlineWebSocketAdapter2 implements UniversalWebSocket {
402
411
 
403
412
  this.#dispatchEvent("error", event);
404
413
  } catch (err) {
405
- logger().error("error in error event", { error: err });
414
+ logger().error({ msg: "error in error event", error: err });
406
415
  }
407
416
 
408
417
  // Log the error
409
- logger().error("websocket error", { error });
418
+ logger().error({ msg: "websocket error", error });
410
419
  }
411
420
 
412
421
  // Event handler properties with getters/setters
package/src/common/log.ts CHANGED
@@ -1,139 +1,214 @@
1
- import { getEnvUniversal } from "@/utils";
2
1
  import {
3
- type LevelIndex,
4
- LevelNameMap,
5
- type LogLevel,
6
- LogLevels,
7
- } from "./log-levels";
2
+ type LevelWithSilent,
3
+ type Logger,
4
+ pino,
5
+ stdTimeFunctions,
6
+ } from "pino";
7
+ import { z } from "zod";
8
+ import { getEnvUniversal } from "@/utils";
8
9
  import {
9
10
  castToLogValue,
10
11
  formatTimestamp,
11
- type LogEntry,
12
+ LOGGER_CONFIG,
12
13
  stringify,
13
14
  } from "./logfmt";
14
15
 
15
- interface LogRecord {
16
- args: unknown[];
17
- datetime: Date;
18
- level: number;
19
- levelName: string;
20
- loggerName: string;
21
- msg: string;
22
- }
16
+ export type { Logger } from "pino";
23
17
 
24
- export class Logger {
25
- name: string;
26
- level: LogLevel;
18
+ let baseLogger: Logger | undefined;
19
+ let configuredLogLevel: LogLevel | undefined;
27
20
 
28
- constructor(name: string, level: LogLevel) {
29
- this.name = name;
30
- this.level = level;
31
- }
21
+ /** Cache of child loggers by logger name. */
22
+ const loggerCache = new Map<string, Logger>();
32
23
 
33
- log(level: LevelIndex, message: string, ...args: unknown[]): void {
34
- const record: LogRecord = {
35
- msg: message,
36
- args,
37
- level,
38
- loggerName: this.name,
39
- datetime: new Date(),
40
- levelName: LevelNameMap[level],
41
- };
42
-
43
- if (this.#shouldLog(level)) {
44
- this.#logRecord(record);
45
- }
46
- }
24
+ export const LogLevelSchema = z.enum([
25
+ "trace",
26
+ "debug",
27
+ "info",
28
+ "warn",
29
+ "error",
30
+ "fatal",
31
+ "silent",
32
+ ]);
47
33
 
48
- #shouldLog(level: LevelIndex): boolean {
49
- return level >= LogLevels[this.level];
50
- }
34
+ export type LogLevel = z.infer<typeof LogLevelSchema>;
51
35
 
52
- #logRecord(record: LogRecord): void {
53
- console.log(formatter(record));
36
+ export function getPinoLevel(logLevel?: LogLevel): LevelWithSilent {
37
+ // Priority: provided > configured > env > default
38
+ if (logLevel) {
39
+ return logLevel;
54
40
  }
55
41
 
56
- trace(message: string, ...args: unknown[]): void {
57
- this.log(LogLevels.TRACE, message, ...args);
42
+ if (configuredLogLevel) {
43
+ return configuredLogLevel;
58
44
  }
59
45
 
60
- debug(message: string, ...args: unknown[]): void {
61
- this.log(LogLevels.DEBUG, message, ...args);
46
+ const raw = (getEnvUniversal("LOG_LEVEL") || "warn").toString().toLowerCase();
47
+
48
+ const parsed = LogLevelSchema.safeParse(raw);
49
+ if (parsed.success) {
50
+ return parsed.data;
62
51
  }
63
52
 
64
- info(message: string, ...args: unknown[]): void {
65
- this.log(LogLevels.INFO, message, ...args);
53
+ // Default to info if invalid
54
+ return "info";
55
+ }
56
+
57
+ export function getIncludeTarget(): boolean {
58
+ return getEnvUniversal("LOG_TARGET") === "1";
59
+ }
60
+
61
+ /**
62
+ * Configure a custom base logger.
63
+ */
64
+ export function configureBaseLogger(logger: Logger): void {
65
+ baseLogger = logger;
66
+ loggerCache.clear();
67
+ }
68
+
69
+ // TODO: This can be simplified in logfmt.ts
70
+ function customWrite(level: string, o: any) {
71
+ const entries: any = {};
72
+
73
+ // Add timestamp if enabled
74
+ if (getEnvUniversal("LOG_TIMESTAMP") === "1" && o.time) {
75
+ const date = typeof o.time === "number" ? new Date(o.time) : new Date();
76
+ entries.ts = formatTimestamp(date);
66
77
  }
67
78
 
68
- warn(message: string, ...args: unknown[]): void {
69
- this.log(LogLevels.WARN, message, ...args);
79
+ // Add level
80
+ entries.level = level.toUpperCase();
81
+
82
+ // Add target if present
83
+ if (o.target) {
84
+ entries.target = o.target;
70
85
  }
71
86
 
72
- error(message: string, ...args: unknown[]): void {
73
- this.log(LogLevels.ERROR, message, ...args);
87
+ // Add message
88
+ if (o.msg) {
89
+ entries.msg = o.msg;
74
90
  }
75
91
 
76
- critical(message: string, ...args: unknown[]): void {
77
- this.log(LogLevels.CRITICAL, message, ...args);
92
+ // Add other properties
93
+ for (const [key, value] of Object.entries(o)) {
94
+ if (
95
+ key !== "time" &&
96
+ key !== "level" &&
97
+ key !== "target" &&
98
+ key !== "msg" &&
99
+ key !== "pid" &&
100
+ key !== "hostname"
101
+ ) {
102
+ entries[key] = castToLogValue(value);
103
+ }
78
104
  }
105
+
106
+ const output = stringify(entries);
107
+ console.log(output);
79
108
  }
80
109
 
81
- const loggers: Record<string, Logger> = {};
110
+ /**
111
+ * Configure the default logger with optional log level.
112
+ */
113
+ export async function configureDefaultLogger(
114
+ logLevel?: LogLevel,
115
+ ): Promise<void> {
116
+ // Store the configured log level
117
+ if (logLevel) {
118
+ configuredLogLevel = logLevel;
119
+ }
82
120
 
83
- export function getLogger(name = "default"): Logger {
84
- const defaultLogLevelEnv: LogLevel | undefined = getEnvUniversal(
85
- "_LOG_LEVEL",
86
- ) as LogLevel | undefined;
121
+ baseLogger = pino({
122
+ level: getPinoLevel(logLevel),
123
+ messageKey: "msg",
124
+ // Do not include pid/hostname in output
125
+ base: {},
126
+ // Keep a string level in the output
127
+ formatters: {
128
+ level(_label: string, number: number) {
129
+ return { level: number };
130
+ },
131
+ },
132
+ timestamp:
133
+ getEnvUniversal("LOG_TIMESTAMP") === "1"
134
+ ? stdTimeFunctions.epochTime
135
+ : false,
136
+ browser: {
137
+ write: {
138
+ fatal: customWrite.bind(null, "fatal"),
139
+ error: customWrite.bind(null, "error"),
140
+ warn: customWrite.bind(null, "warn"),
141
+ info: customWrite.bind(null, "info"),
142
+ debug: customWrite.bind(null, "debug"),
143
+ trace: customWrite.bind(null, "trace"),
144
+ },
145
+ },
146
+ hooks: {
147
+ logMethod(inputArgs, _method, level) {
148
+ // TODO: This is a hack to not implement our own transport target. We can get better perf if we have our own transport target.
149
+
150
+ const levelMap: Record<number, string> = {
151
+ 10: "trace",
152
+ 20: "debug",
153
+ 30: "info",
154
+ 40: "warn",
155
+ 50: "error",
156
+ 60: "fatal",
157
+ };
158
+ const levelName = levelMap[level] || "info";
159
+ const time =
160
+ getEnvUniversal("LOG_TIMESTAMP") === "1" ? Date.now() : undefined;
161
+ // TODO: This can be simplified in logfmt.ts
162
+ if (inputArgs.length >= 2) {
163
+ const [objOrMsg, msg] = inputArgs;
164
+ if (typeof objOrMsg === "object" && objOrMsg !== null) {
165
+ customWrite(levelName, { ...objOrMsg, msg, time });
166
+ } else {
167
+ customWrite(levelName, { msg: String(objOrMsg), time });
168
+ }
169
+ } else if (inputArgs.length === 1) {
170
+ const [objOrMsg] = inputArgs;
171
+ if (typeof objOrMsg === "object" && objOrMsg !== null) {
172
+ customWrite(levelName, { ...objOrMsg, time });
173
+ } else {
174
+ customWrite(levelName, { msg: String(objOrMsg), time });
175
+ }
176
+ }
177
+ },
178
+ },
179
+ });
180
+
181
+ loggerCache.clear();
182
+ }
87
183
 
88
- const defaultLogLevel: LogLevel = defaultLogLevelEnv ?? "INFO";
89
- if (!loggers[name]) {
90
- loggers[name] = new Logger(name, defaultLogLevel);
184
+ /**
185
+ * Get or initialize the base logger.
186
+ */
187
+ export function getBaseLogger(): Logger {
188
+ if (!baseLogger) {
189
+ configureDefaultLogger();
91
190
  }
92
- return loggers[name];
191
+ return baseLogger!;
93
192
  }
94
193
 
95
- function formatter(log: LogRecord): string {
96
- const args: LogEntry[] = [];
97
- for (let i = 0; i < log.args.length; i++) {
98
- const logArg = log.args[i];
99
- if (logArg && typeof logArg === "object") {
100
- // Spread object
101
- for (const k in logArg) {
102
- // biome-ignore lint/suspicious/noExplicitAny: Unknown type
103
- const v = (logArg as any)[k];
104
-
105
- pushArg(k, v, args);
106
- }
107
- } else {
108
- pushArg(`arg${i}`, logArg, args);
109
- }
194
+ /**
195
+ * Returns a child logger with `target` bound for the given name.
196
+ */
197
+ export function getLogger(name = "default"): Logger {
198
+ // Check cache first
199
+ const cached = loggerCache.get(name);
200
+ if (cached) {
201
+ return cached;
110
202
  }
111
203
 
112
- const logTs = getEnvUniversal("_LOG_TIMESTAMP") === "1";
113
- const logTarget = getEnvUniversal("_LOG_TARGET") === "1";
204
+ // Create
205
+ const base = getBaseLogger();
114
206
 
115
- return stringify(
116
- ...(logTs ? [["ts", formatTimestamp(new Date())] as LogEntry] : []),
117
- ["level", LevelNameMap[log.level]],
118
- ...(logTarget ? [["target", log.loggerName] as LogEntry] : []),
119
- ["msg", log.msg],
120
- ...args,
121
- );
122
- }
207
+ // Add target to log if enabled
208
+ const child = getIncludeTarget() ? base.child({ target: name }) : base;
123
209
 
124
- function pushArg(k: string, v: unknown, args: LogEntry[]) {
125
- args.push([k, castToLogValue(v)]);
126
- }
210
+ // Cache the logger
211
+ loggerCache.set(name, child);
127
212
 
128
- // function getEnv(name: string): string | undefined {
129
- // if (typeof window !== "undefined" && window.localStorage) {
130
- // return window.localStorage.getItem(name) || undefined;
131
- // }
132
- // return undefined;
133
- // // TODO(ACTR-9): Add back env config once node compat layer works
134
- // //return crossGetEnv(name);
135
- // }
136
-
137
- export function setupLogging() {
138
- // Do nothing for now
213
+ return child;
139
214
  }
@@ -1,8 +1,5 @@
1
1
  import { type LogLevel, LogLevels } from "./log-levels";
2
2
 
3
- export type LogEntry = [string, LogValue];
4
- export type LogValue = string | number | bigint | boolean | null | undefined;
5
-
6
3
  const LOG_LEVEL_COLORS: Record<number, string> = {
7
4
  [LogLevels.CRITICAL]: "\x1b[31m", // Red
8
5
  [LogLevels.ERROR]: "\x1b[31m", // Red
@@ -15,9 +12,7 @@ const LOG_LEVEL_COLORS: Record<number, string> = {
15
12
  const RESET_COLOR = "\x1b[0m";
16
13
 
17
14
  /**
18
- * Serializes logfmt line using orderer parameters.
19
- *
20
- * We use varargs because it's ordered & it has less overhead than an object.
15
+ * Serializes logfmt line from an object.
21
16
  *
22
17
  * ## Styling Methodology
23
18
  *
@@ -31,11 +26,12 @@ const RESET_COLOR = "\x1b[0m";
31
26
  * name quickly then look closer to read the data associated with the
32
27
  * property.
33
28
  */
34
- export function stringify(...data: LogEntry[]) {
29
+ export function stringify(data: any) {
35
30
  let line = "";
31
+ const entries = Object.entries(data);
36
32
 
37
- for (let i = 0; i < data.length; i++) {
38
- const [key, valueRaw] = data[i];
33
+ for (let i = 0; i < entries.length; i++) {
34
+ const [key, valueRaw] = entries[i];
39
35
 
40
36
  let isNull = false;
41
37
  let valueString: string;
@@ -84,7 +80,7 @@ export function stringify(...data: LogEntry[]) {
84
80
  line += `${key}=${valueString}`;
85
81
  }
86
82
 
87
- if (i !== data.length - 1) {
83
+ if (i !== entries.length - 1) {
88
84
  line += " ";
89
85
  }
90
86
  }
@@ -104,7 +100,7 @@ export function formatTimestamp(date: Date): string {
104
100
  return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`;
105
101
  }
106
102
 
107
- export function castToLogValue(v: unknown): LogValue {
103
+ export function castToLogValue(v: unknown): any {
108
104
  if (
109
105
  typeof v === "string" ||
110
106
  typeof v === "number" ||
@@ -143,10 +139,7 @@ export const LOGGER_CONFIG: GlobalLoggerConfig = {
143
139
  /**
144
140
  * Converts an object in to an easier to read KV of entries.
145
141
  */
146
- export function spreadObjectToLogEntries(
147
- base: string,
148
- data: unknown,
149
- ): LogEntry[] {
142
+ export function spreadObjectToLogEntries(base: string, data: unknown): any {
150
143
  if (
151
144
  LOGGER_CONFIG.enableSpreadObject &&
152
145
  typeof data === "object" &&
@@ -155,12 +148,11 @@ export function spreadObjectToLogEntries(
155
148
  Object.keys(data).length !== 0 &&
156
149
  Object.keys(data).length < 16
157
150
  ) {
158
- const logData: LogEntry[] = [];
151
+ const logData: any = {};
159
152
  for (const key in data) {
160
- // logData.push([`${base}.${key}`, JSON.stringify((data as any)[key])]);
161
-
162
- logData.push(
163
- ...spreadObjectToLogEntries(
153
+ Object.assign(
154
+ logData,
155
+ spreadObjectToLogEntries(
164
156
  `${base}.${key}`,
165
157
  // biome-ignore lint/suspicious/noExplicitAny: FIXME
166
158
  (data as any)[key],
@@ -170,21 +162,20 @@ export function spreadObjectToLogEntries(
170
162
  return logData;
171
163
  }
172
164
 
173
- return [[base, JSON.stringify(data)]];
165
+ return { [base]: JSON.stringify(data) };
174
166
  }
175
167
 
176
- export function errorToLogEntries(base: string, error: unknown): LogEntry[] {
168
+ export function errorToLogEntries(base: string, error: unknown): any {
177
169
  if (error instanceof Error) {
178
- return [
179
- //[`${base}.name`, error.name],
180
- [`${base}.message`, error.message],
170
+ return {
171
+ [`${base}.message`]: error.message,
181
172
  ...(LOGGER_CONFIG.enableErrorStack && error.stack
182
- ? [[`${base}.stack`, formatStackTrace(error.stack)] as LogEntry]
183
- : []),
184
- ...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : []),
185
- ];
173
+ ? { [`${base}.stack`]: formatStackTrace(error.stack) }
174
+ : {}),
175
+ ...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : {}),
176
+ };
186
177
  }
187
- return [[base, `${error}`]];
178
+ return { [base]: `${error}` };
188
179
  }
189
180
 
190
181
  // export function errorToLogEntries(base: string, error: unknown): LogEntry[] {