rivetkit 2.0.2 → 2.0.4

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 (246) hide show
  1. package/README.md +3 -5
  2. package/dist/schemas/actor-persist/v1.ts +225 -0
  3. package/dist/schemas/client-protocol/v1.ts +435 -0
  4. package/dist/schemas/file-system-driver/v1.ts +102 -0
  5. package/dist/tsup/actor/errors.cjs +77 -0
  6. package/dist/tsup/actor/errors.cjs.map +1 -0
  7. package/dist/tsup/actor/errors.d.cts +156 -0
  8. package/dist/tsup/actor/errors.d.ts +156 -0
  9. package/dist/tsup/actor/errors.js +77 -0
  10. package/dist/tsup/actor/errors.js.map +1 -0
  11. package/dist/tsup/chunk-3F2YSRJL.js +117 -0
  12. package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
  13. package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
  14. package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
  15. package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
  16. package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
  17. package/dist/tsup/chunk-6LJT3QRL.cjs +539 -0
  18. package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
  19. package/dist/tsup/chunk-GICQ3YCU.cjs +1792 -0
  20. package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
  21. package/dist/tsup/chunk-H26RP6GD.js +251 -0
  22. package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
  23. package/dist/tsup/chunk-HI3HWJRC.js +20 -0
  24. package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
  25. package/dist/tsup/chunk-HLLF4B4Q.js +1792 -0
  26. package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
  27. package/dist/tsup/chunk-IH6CKNDW.cjs +117 -0
  28. package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
  29. package/dist/tsup/chunk-LV2S3OU3.js +250 -0
  30. package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
  31. package/dist/tsup/chunk-LWNKVZG5.cjs +251 -0
  32. package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
  33. package/dist/tsup/chunk-NFU2BBT5.js +374 -0
  34. package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
  35. package/dist/tsup/chunk-PQY7KKTL.js +539 -0
  36. package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
  37. package/dist/tsup/chunk-QK72M5JB.js +45 -0
  38. package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
  39. package/dist/tsup/chunk-QNNXFOQV.cjs +45 -0
  40. package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
  41. package/dist/tsup/chunk-SBHHJ6QS.cjs +374 -0
  42. package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
  43. package/dist/tsup/chunk-TQ62L3X7.js +325 -0
  44. package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
  45. package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
  46. package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
  47. package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
  48. package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
  49. package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
  50. package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
  51. package/dist/tsup/client/mod.cjs +32 -0
  52. package/dist/tsup/client/mod.cjs.map +1 -0
  53. package/dist/tsup/client/mod.d.cts +20 -0
  54. package/dist/tsup/client/mod.d.ts +20 -0
  55. package/dist/tsup/client/mod.js +32 -0
  56. package/dist/tsup/client/mod.js.map +1 -0
  57. package/dist/tsup/common/log.cjs +21 -0
  58. package/dist/tsup/common/log.cjs.map +1 -0
  59. package/dist/tsup/common/log.d.cts +26 -0
  60. package/dist/tsup/common/log.d.ts +26 -0
  61. package/dist/tsup/common/log.js +21 -0
  62. package/dist/tsup/common/log.js.map +1 -0
  63. package/dist/tsup/common/websocket.cjs +10 -0
  64. package/dist/tsup/common/websocket.cjs.map +1 -0
  65. package/dist/tsup/common/websocket.d.cts +3 -0
  66. package/dist/tsup/common/websocket.d.ts +3 -0
  67. package/dist/tsup/common/websocket.js +10 -0
  68. package/dist/tsup/common/websocket.js.map +1 -0
  69. package/dist/tsup/common-CXCe7s6i.d.cts +218 -0
  70. package/dist/tsup/common-CXCe7s6i.d.ts +218 -0
  71. package/dist/tsup/connection-BI-6UIBJ.d.ts +2087 -0
  72. package/dist/tsup/connection-Dyd4NLGW.d.cts +2087 -0
  73. package/dist/tsup/driver-helpers/mod.cjs +30 -0
  74. package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
  75. package/dist/tsup/driver-helpers/mod.d.cts +17 -0
  76. package/dist/tsup/driver-helpers/mod.d.ts +17 -0
  77. package/dist/tsup/driver-helpers/mod.js +30 -0
  78. package/dist/tsup/driver-helpers/mod.js.map +1 -0
  79. package/dist/tsup/driver-test-suite/mod.cjs +3411 -0
  80. package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
  81. package/dist/tsup/driver-test-suite/mod.d.cts +63 -0
  82. package/dist/tsup/driver-test-suite/mod.d.ts +63 -0
  83. package/dist/tsup/driver-test-suite/mod.js +3411 -0
  84. package/dist/tsup/driver-test-suite/mod.js.map +1 -0
  85. package/dist/tsup/inspector/mod.cjs +51 -0
  86. package/dist/tsup/inspector/mod.cjs.map +1 -0
  87. package/dist/tsup/inspector/mod.d.cts +408 -0
  88. package/dist/tsup/inspector/mod.d.ts +408 -0
  89. package/dist/tsup/inspector/mod.js +51 -0
  90. package/dist/tsup/inspector/mod.js.map +1 -0
  91. package/dist/tsup/mod.cjs +67 -0
  92. package/dist/tsup/mod.cjs.map +1 -0
  93. package/dist/tsup/mod.d.cts +105 -0
  94. package/dist/tsup/mod.d.ts +105 -0
  95. package/dist/tsup/mod.js +67 -0
  96. package/dist/tsup/mod.js.map +1 -0
  97. package/dist/tsup/router-endpoints-BTe_Rsdn.d.cts +65 -0
  98. package/dist/tsup/router-endpoints-CBSrKHmo.d.ts +65 -0
  99. package/dist/tsup/test/mod.cjs +17 -0
  100. package/dist/tsup/test/mod.cjs.map +1 -0
  101. package/dist/tsup/test/mod.d.cts +26 -0
  102. package/dist/tsup/test/mod.d.ts +26 -0
  103. package/dist/tsup/test/mod.js +17 -0
  104. package/dist/tsup/test/mod.js.map +1 -0
  105. package/dist/tsup/utils-fwx3o3K9.d.cts +18 -0
  106. package/dist/tsup/utils-fwx3o3K9.d.ts +18 -0
  107. package/dist/tsup/utils.cjs +26 -0
  108. package/dist/tsup/utils.cjs.map +1 -0
  109. package/dist/tsup/utils.d.cts +36 -0
  110. package/dist/tsup/utils.d.ts +36 -0
  111. package/dist/tsup/utils.js +26 -0
  112. package/dist/tsup/utils.js.map +1 -0
  113. package/package.json +208 -5
  114. package/src/actor/action.ts +178 -0
  115. package/src/actor/config.ts +497 -0
  116. package/src/actor/connection.ts +257 -0
  117. package/src/actor/context.ts +168 -0
  118. package/src/actor/database.ts +23 -0
  119. package/src/actor/definition.ts +82 -0
  120. package/src/actor/driver.ts +84 -0
  121. package/src/actor/errors.ts +422 -0
  122. package/src/actor/generic-conn-driver.ts +246 -0
  123. package/src/actor/instance.ts +1844 -0
  124. package/src/actor/keys.test.ts +266 -0
  125. package/src/actor/keys.ts +89 -0
  126. package/src/actor/log.ts +6 -0
  127. package/src/actor/mod.ts +108 -0
  128. package/src/actor/persisted.ts +42 -0
  129. package/src/actor/protocol/old.ts +297 -0
  130. package/src/actor/protocol/serde.ts +131 -0
  131. package/src/actor/router-endpoints.ts +688 -0
  132. package/src/actor/router.ts +265 -0
  133. package/src/actor/schedule.ts +17 -0
  134. package/src/actor/unstable-react.ts +110 -0
  135. package/src/actor/utils.ts +102 -0
  136. package/src/client/actor-common.ts +30 -0
  137. package/src/client/actor-conn.ts +865 -0
  138. package/src/client/actor-handle.ts +268 -0
  139. package/src/client/actor-query.ts +65 -0
  140. package/src/client/client.ts +554 -0
  141. package/src/client/config.ts +44 -0
  142. package/src/client/errors.ts +42 -0
  143. package/src/client/log.ts +5 -0
  144. package/src/client/mod.ts +60 -0
  145. package/src/client/raw-utils.ts +149 -0
  146. package/src/client/test.ts +44 -0
  147. package/src/client/utils.ts +152 -0
  148. package/src/common/eventsource-interface.ts +47 -0
  149. package/src/common/eventsource.ts +80 -0
  150. package/src/common/fake-event-source.ts +267 -0
  151. package/src/common/inline-websocket-adapter2.ts +454 -0
  152. package/src/common/log-levels.ts +27 -0
  153. package/src/common/log.ts +214 -0
  154. package/src/common/logfmt.ts +219 -0
  155. package/src/common/network.ts +2 -0
  156. package/src/common/router.ts +80 -0
  157. package/src/common/utils.ts +336 -0
  158. package/src/common/versioned-data.ts +95 -0
  159. package/src/common/websocket-interface.ts +49 -0
  160. package/src/common/websocket.ts +42 -0
  161. package/src/driver-helpers/mod.ts +22 -0
  162. package/src/driver-helpers/utils.ts +17 -0
  163. package/src/driver-test-suite/log.ts +5 -0
  164. package/src/driver-test-suite/mod.ts +239 -0
  165. package/src/driver-test-suite/tests/action-features.ts +136 -0
  166. package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
  167. package/src/driver-test-suite/tests/actor-conn.ts +349 -0
  168. package/src/driver-test-suite/tests/actor-driver.ts +25 -0
  169. package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
  170. package/src/driver-test-suite/tests/actor-handle.ts +292 -0
  171. package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
  172. package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
  173. package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
  174. package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
  175. package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
  176. package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
  177. package/src/driver-test-suite/tests/actor-state.ts +54 -0
  178. package/src/driver-test-suite/tests/actor-vars.ts +93 -0
  179. package/src/driver-test-suite/tests/manager-driver.ts +367 -0
  180. package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -0
  181. package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
  182. package/src/driver-test-suite/tests/raw-http.ts +347 -0
  183. package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -0
  184. package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
  185. package/src/driver-test-suite/tests/request-access.ts +230 -0
  186. package/src/driver-test-suite/utils.ts +71 -0
  187. package/src/drivers/default.ts +34 -0
  188. package/src/drivers/engine/actor-driver.ts +369 -0
  189. package/src/drivers/engine/config.ts +31 -0
  190. package/src/drivers/engine/kv.ts +3 -0
  191. package/src/drivers/engine/log.ts +5 -0
  192. package/src/drivers/engine/mod.ts +35 -0
  193. package/src/drivers/file-system/actor.ts +91 -0
  194. package/src/drivers/file-system/global-state.ts +686 -0
  195. package/src/drivers/file-system/log.ts +5 -0
  196. package/src/drivers/file-system/manager.ts +329 -0
  197. package/src/drivers/file-system/mod.ts +48 -0
  198. package/src/drivers/file-system/utils.ts +109 -0
  199. package/src/globals.d.ts +6 -0
  200. package/src/inspector/actor.ts +298 -0
  201. package/src/inspector/config.ts +88 -0
  202. package/src/inspector/log.ts +5 -0
  203. package/src/inspector/manager.ts +86 -0
  204. package/src/inspector/mod.ts +2 -0
  205. package/src/inspector/protocol/actor.ts +10 -0
  206. package/src/inspector/protocol/common.ts +196 -0
  207. package/src/inspector/protocol/manager.ts +10 -0
  208. package/src/inspector/protocol/mod.ts +2 -0
  209. package/src/inspector/utils.ts +76 -0
  210. package/src/manager/driver.ts +88 -0
  211. package/src/manager/hono-websocket-adapter.ts +342 -0
  212. package/src/manager/log.ts +5 -0
  213. package/src/manager/mod.ts +2 -0
  214. package/src/manager/protocol/mod.ts +24 -0
  215. package/src/manager/protocol/query.ts +89 -0
  216. package/src/manager/router.ts +412 -0
  217. package/src/manager-api/routes/actors-create.ts +16 -0
  218. package/src/manager-api/routes/actors-delete.ts +4 -0
  219. package/src/manager-api/routes/actors-get-by-id.ts +7 -0
  220. package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
  221. package/src/manager-api/routes/actors-get.ts +7 -0
  222. package/src/manager-api/routes/common.ts +18 -0
  223. package/src/mod.ts +18 -0
  224. package/src/registry/config.ts +32 -0
  225. package/src/registry/log.ts +5 -0
  226. package/src/registry/mod.ts +157 -0
  227. package/src/registry/run-config.ts +52 -0
  228. package/src/registry/serve.ts +52 -0
  229. package/src/remote-manager-driver/actor-http-client.ts +72 -0
  230. package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
  231. package/src/remote-manager-driver/api-endpoints.ts +79 -0
  232. package/src/remote-manager-driver/api-utils.ts +43 -0
  233. package/src/remote-manager-driver/log.ts +5 -0
  234. package/src/remote-manager-driver/mod.ts +274 -0
  235. package/src/remote-manager-driver/ws-proxy.ts +180 -0
  236. package/src/schemas/actor-persist/mod.ts +1 -0
  237. package/src/schemas/actor-persist/versioned.ts +25 -0
  238. package/src/schemas/client-protocol/mod.ts +1 -0
  239. package/src/schemas/client-protocol/versioned.ts +63 -0
  240. package/src/schemas/file-system-driver/mod.ts +1 -0
  241. package/src/schemas/file-system-driver/versioned.ts +28 -0
  242. package/src/serde.ts +90 -0
  243. package/src/test/config.ts +16 -0
  244. package/src/test/log.ts +5 -0
  245. package/src/test/mod.ts +154 -0
  246. package/src/utils.ts +172 -0
@@ -0,0 +1,27 @@
1
+ export type LogLevel =
2
+ | "TRACE"
3
+ | "DEBUG"
4
+ | "INFO"
5
+ | "WARN"
6
+ | "ERROR"
7
+ | "CRITICAL";
8
+
9
+ export const LogLevels: Record<LogLevel, LevelIndex> = {
10
+ TRACE: 0,
11
+ DEBUG: 1,
12
+ INFO: 2,
13
+ WARN: 3,
14
+ ERROR: 4,
15
+ CRITICAL: 5,
16
+ } as const;
17
+
18
+ export const LevelNameMap: Record<number, LogLevel> = {
19
+ 0: "TRACE",
20
+ 1: "DEBUG",
21
+ 2: "INFO",
22
+ 3: "WARN",
23
+ 4: "ERROR",
24
+ 5: "CRITICAL",
25
+ };
26
+
27
+ export type LevelIndex = number;
@@ -0,0 +1,214 @@
1
+ import {
2
+ type LevelWithSilent,
3
+ type Logger,
4
+ pino,
5
+ stdTimeFunctions,
6
+ } from "pino";
7
+ import { z } from "zod";
8
+ import { getEnvUniversal } from "@/utils";
9
+ import {
10
+ castToLogValue,
11
+ formatTimestamp,
12
+ LOGGER_CONFIG,
13
+ stringify,
14
+ } from "./logfmt";
15
+
16
+ export type { Logger } from "pino";
17
+
18
+ let baseLogger: Logger | undefined;
19
+ let configuredLogLevel: LogLevel | undefined;
20
+
21
+ /** Cache of child loggers by logger name. */
22
+ const loggerCache = new Map<string, Logger>();
23
+
24
+ export const LogLevelSchema = z.enum([
25
+ "trace",
26
+ "debug",
27
+ "info",
28
+ "warn",
29
+ "error",
30
+ "fatal",
31
+ "silent",
32
+ ]);
33
+
34
+ export type LogLevel = z.infer<typeof LogLevelSchema>;
35
+
36
+ export function getPinoLevel(logLevel?: LogLevel): LevelWithSilent {
37
+ // Priority: provided > configured > env > default
38
+ if (logLevel) {
39
+ return logLevel;
40
+ }
41
+
42
+ if (configuredLogLevel) {
43
+ return configuredLogLevel;
44
+ }
45
+
46
+ const raw = (getEnvUniversal("LOG_LEVEL") || "warn").toString().toLowerCase();
47
+
48
+ const parsed = LogLevelSchema.safeParse(raw);
49
+ if (parsed.success) {
50
+ return parsed.data;
51
+ }
52
+
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);
77
+ }
78
+
79
+ // Add level
80
+ entries.level = level.toUpperCase();
81
+
82
+ // Add target if present
83
+ if (o.target) {
84
+ entries.target = o.target;
85
+ }
86
+
87
+ // Add message
88
+ if (o.msg) {
89
+ entries.msg = o.msg;
90
+ }
91
+
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
+ }
104
+ }
105
+
106
+ const output = stringify(entries);
107
+ console.log(output);
108
+ }
109
+
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
+ }
120
+
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
+ }
183
+
184
+ /**
185
+ * Get or initialize the base logger.
186
+ */
187
+ export function getBaseLogger(): Logger {
188
+ if (!baseLogger) {
189
+ configureDefaultLogger();
190
+ }
191
+ return baseLogger!;
192
+ }
193
+
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;
202
+ }
203
+
204
+ // Create
205
+ const base = getBaseLogger();
206
+
207
+ // Add target to log if enabled
208
+ const child = getIncludeTarget() ? base.child({ target: name }) : base;
209
+
210
+ // Cache the logger
211
+ loggerCache.set(name, child);
212
+
213
+ return child;
214
+ }
@@ -0,0 +1,219 @@
1
+ import { type LogLevel, LogLevels } from "./log-levels";
2
+
3
+ const LOG_LEVEL_COLORS: Record<number, string> = {
4
+ [LogLevels.CRITICAL]: "\x1b[31m", // Red
5
+ [LogLevels.ERROR]: "\x1b[31m", // Red
6
+ [LogLevels.WARN]: "\x1b[33m", // Yellow
7
+ [LogLevels.INFO]: "\x1b[32m", // Green
8
+ [LogLevels.DEBUG]: "\x1b[36m", // Cyan
9
+ [LogLevels.TRACE]: "\x1b[36m", // Cyan
10
+ };
11
+
12
+ const RESET_COLOR = "\x1b[0m";
13
+
14
+ /**
15
+ * Serializes logfmt line from an object.
16
+ *
17
+ * ## Styling Methodology
18
+ *
19
+ * The three things you need to know for every log line is the level, the
20
+ * message, and who called it. These properties are highlighted in different colros
21
+ * and sorted in th eorder that you usually read them.
22
+ *
23
+ * Once you've found a log line you care about, then you want to find the
24
+ * property you need to see. The property names are bolded and the default color
25
+ * while the rest of the data is dim. This lets you scan to find the property
26
+ * name quickly then look closer to read the data associated with the
27
+ * property.
28
+ */
29
+ export function stringify(data: any) {
30
+ let line = "";
31
+ const entries = Object.entries(data);
32
+
33
+ for (let i = 0; i < entries.length; i++) {
34
+ const [key, valueRaw] = entries[i];
35
+
36
+ let isNull = false;
37
+ let valueString: string;
38
+ if (valueRaw == null) {
39
+ isNull = true;
40
+ valueString = "";
41
+ } else {
42
+ valueString = valueRaw.toString();
43
+ }
44
+
45
+ // Clip value unless specifically the error message
46
+ if (valueString.length > 512 && key !== "msg" && key !== "error")
47
+ valueString = `${valueString.slice(0, 512)}...`;
48
+
49
+ const needsQuoting =
50
+ valueString.indexOf(" ") > -1 || valueString.indexOf("=") > -1;
51
+ const needsEscaping =
52
+ valueString.indexOf('"') > -1 || valueString.indexOf("\\") > -1;
53
+
54
+ valueString = valueString.replace(/\n/g, "\\n");
55
+ if (needsEscaping) valueString = valueString.replace(/["\\]/g, "\\$&");
56
+ if (needsQuoting || needsEscaping) valueString = `"${valueString}"`;
57
+ if (valueString === "" && !isNull) valueString = '""';
58
+
59
+ if (LOGGER_CONFIG.enableColor) {
60
+ // With color
61
+
62
+ // Special message colors
63
+ let color = "\x1b[2m";
64
+ if (key === "level") {
65
+ const level = LogLevels[valueString as LogLevel];
66
+ const levelColor = LOG_LEVEL_COLORS[level];
67
+ if (levelColor) {
68
+ color = levelColor;
69
+ }
70
+ } else if (key === "msg") {
71
+ color = "\x1b[32m";
72
+ } else if (key === "trace") {
73
+ color = "\x1b[34m";
74
+ }
75
+
76
+ // Format line
77
+ line += `\x1b[0m\x1b[1m${key}\x1b[0m\x1b[2m=\x1b[0m${color}${valueString}${RESET_COLOR}`;
78
+ } else {
79
+ // No color
80
+ line += `${key}=${valueString}`;
81
+ }
82
+
83
+ if (i !== entries.length - 1) {
84
+ line += " ";
85
+ }
86
+ }
87
+
88
+ return line;
89
+ }
90
+
91
+ export function formatTimestamp(date: Date): string {
92
+ const year = date.getUTCFullYear();
93
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
94
+ const day = String(date.getUTCDate()).padStart(2, "0");
95
+ const hours = String(date.getUTCHours()).padStart(2, "0");
96
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
97
+ const seconds = String(date.getUTCSeconds()).padStart(2, "0");
98
+ const milliseconds = String(date.getUTCMilliseconds()).padStart(3, "0");
99
+
100
+ return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`;
101
+ }
102
+
103
+ export function castToLogValue(v: unknown): any {
104
+ if (
105
+ typeof v === "string" ||
106
+ typeof v === "number" ||
107
+ typeof v === "bigint" ||
108
+ typeof v === "boolean" ||
109
+ v === null ||
110
+ v === undefined
111
+ ) {
112
+ return v;
113
+ }
114
+ if (v instanceof Error) {
115
+ //args.push(...errorToLogEntries(k, v));
116
+ return String(v);
117
+ }
118
+ try {
119
+ return JSON.stringify(v);
120
+ } catch {
121
+ return "[cannot stringify]";
122
+ }
123
+ }
124
+
125
+ // MARK: Config
126
+ interface GlobalLoggerConfig {
127
+ enableColor: boolean;
128
+ enableSpreadObject: boolean;
129
+ enableErrorStack: boolean;
130
+ }
131
+
132
+ export const LOGGER_CONFIG: GlobalLoggerConfig = {
133
+ enableColor: false,
134
+ enableSpreadObject: false,
135
+ enableErrorStack: false,
136
+ };
137
+
138
+ // MARK: Utils
139
+ /**
140
+ * Converts an object in to an easier to read KV of entries.
141
+ */
142
+ export function spreadObjectToLogEntries(base: string, data: unknown): any {
143
+ if (
144
+ LOGGER_CONFIG.enableSpreadObject &&
145
+ typeof data === "object" &&
146
+ !Array.isArray(data) &&
147
+ data !== null &&
148
+ Object.keys(data).length !== 0 &&
149
+ Object.keys(data).length < 16
150
+ ) {
151
+ const logData: any = {};
152
+ for (const key in data) {
153
+ Object.assign(
154
+ logData,
155
+ spreadObjectToLogEntries(
156
+ `${base}.${key}`,
157
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME
158
+ (data as any)[key],
159
+ ),
160
+ );
161
+ }
162
+ return logData;
163
+ }
164
+
165
+ return { [base]: JSON.stringify(data) };
166
+ }
167
+
168
+ export function errorToLogEntries(base: string, error: unknown): any {
169
+ if (error instanceof Error) {
170
+ return {
171
+ [`${base}.message`]: error.message,
172
+ ...(LOGGER_CONFIG.enableErrorStack && error.stack
173
+ ? { [`${base}.stack`]: formatStackTrace(error.stack) }
174
+ : {}),
175
+ ...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : {}),
176
+ };
177
+ }
178
+ return { [base]: `${error}` };
179
+ }
180
+
181
+ // export function errorToLogEntries(base: string, error: unknown): LogEntry[] {
182
+ // if (error instanceof RuntimeError) {
183
+ // return [
184
+ // [`${base}.code`, error.code],
185
+ // [`${base}.description`, error.errorConfig?.description],
186
+ // [`${base}.module`, error.moduleName],
187
+ // ...(error.trace ? [[`${base}.trace`, stringifyTrace(error.trace)] as LogEntry] : []),
188
+ // ...(LOGGER_CONFIG.enableErrorStack && error.stack
189
+ // ? [[`${base}.stack`, formatStackTrace(error.stack)] as LogEntry]
190
+ // : []),
191
+ // ...(error.meta ? [[`${base}.meta`, JSON.stringify(error.meta)] as LogEntry] : []),
192
+ // ...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : []),
193
+ // ];
194
+ // } else if (error instanceof Error) {
195
+ // return [
196
+ // [`${base}.name`, error.name],
197
+ // [`${base}.message`, error.message],
198
+ // ...(LOGGER_CONFIG.enableErrorStack && error.stack
199
+ // ? [[`${base}.stack`, formatStackTrace(error.stack)] as LogEntry]
200
+ // : []),
201
+ // ...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : []),
202
+ // ];
203
+ // } else {
204
+ // return [
205
+ // [base, `${error}`],
206
+ // ];
207
+ // }
208
+ // }
209
+
210
+ /**
211
+ * Formats a JS stack trace in to a legible one-liner.
212
+ */
213
+ function formatStackTrace(stackTrace: string): string {
214
+ const regex = /at (.+?)$/gm;
215
+ const matches = [...stackTrace.matchAll(regex)];
216
+ // Reverse array since the stack goes from top level -> bottom level
217
+ matches.reverse();
218
+ return matches.map((match) => match[1].trim()).join(" > ");
219
+ }
@@ -0,0 +1,2 @@
1
+ /** Only enforced client-side in order to prevent building malformed URLs. */
2
+ export const MAX_CONN_PARAMS_SIZE = 4096;
@@ -0,0 +1,80 @@
1
+ import * as cbor from "cbor-x";
2
+ import type { Context as HonoContext, Next } from "hono";
3
+ import type { Encoding } from "@/actor/protocol/serde";
4
+ import {
5
+ getRequestEncoding,
6
+ getRequestExposeInternalError,
7
+ } from "@/actor/router-endpoints";
8
+ import { HttpResponseError } from "@/schemas/client-protocol/mod";
9
+ import { HTTP_RESPONSE_ERROR_VERSIONED } from "@/schemas/client-protocol/versioned";
10
+ import { encodingIsBinary, serializeWithEncoding } from "@/serde";
11
+ import { bufferToArrayBuffer } from "@/utils";
12
+ import { getLogger, type Logger } from "./log";
13
+ import { deconstructError, stringifyError } from "./utils";
14
+
15
+ export function logger() {
16
+ return getLogger("router");
17
+ }
18
+
19
+ export function loggerMiddleware(logger: Logger) {
20
+ return async (c: HonoContext, next: Next) => {
21
+ const method = c.req.method;
22
+ const path = c.req.path;
23
+ const startTime = Date.now();
24
+
25
+ await next();
26
+
27
+ const duration = Date.now() - startTime;
28
+ logger.debug({
29
+ msg: "http request",
30
+ method,
31
+ path,
32
+ status: c.res.status,
33
+ dt: `${duration}ms`,
34
+ reqSize: c.req.header("content-length"),
35
+ resSize: c.res.headers.get("content-length"),
36
+ userAgent: c.req.header("user-agent"),
37
+ });
38
+ };
39
+ }
40
+
41
+ export function handleRouteNotFound(c: HonoContext) {
42
+ return c.text("Not Found (RivetKit)", 404);
43
+ }
44
+
45
+ export function handleRouteError(error: unknown, c: HonoContext) {
46
+ const exposeInternalError = getRequestExposeInternalError(c.req.raw);
47
+
48
+ const { statusCode, group, code, message, metadata } = deconstructError(
49
+ error,
50
+ logger(),
51
+ {
52
+ method: c.req.method,
53
+ path: c.req.path,
54
+ },
55
+ exposeInternalError,
56
+ );
57
+
58
+ let encoding: Encoding;
59
+ try {
60
+ encoding = getRequestEncoding(c.req);
61
+ } catch (_) {
62
+ encoding = "json";
63
+ }
64
+
65
+ const output = serializeWithEncoding(
66
+ encoding,
67
+ {
68
+ group,
69
+ code,
70
+ message,
71
+ // TODO: Cannot serialize non-binary meta since it requires ArrayBuffer atm
72
+ metadata: encodingIsBinary(encoding)
73
+ ? bufferToArrayBuffer(cbor.encode(metadata))
74
+ : null,
75
+ },
76
+ HTTP_RESPONSE_ERROR_VERSIONED,
77
+ );
78
+
79
+ return c.body(output, { status: statusCode });
80
+ }