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.
- package/README.md +3 -5
- package/dist/schemas/actor-persist/v1.ts +225 -0
- package/dist/schemas/client-protocol/v1.ts +435 -0
- package/dist/schemas/file-system-driver/v1.ts +102 -0
- package/dist/tsup/actor/errors.cjs +77 -0
- package/dist/tsup/actor/errors.cjs.map +1 -0
- package/dist/tsup/actor/errors.d.cts +156 -0
- package/dist/tsup/actor/errors.d.ts +156 -0
- package/dist/tsup/actor/errors.js +77 -0
- package/dist/tsup/actor/errors.js.map +1 -0
- package/dist/tsup/chunk-3F2YSRJL.js +117 -0
- package/dist/tsup/chunk-3F2YSRJL.js.map +1 -0
- package/dist/tsup/chunk-4CXBCT26.cjs +250 -0
- package/dist/tsup/chunk-4CXBCT26.cjs.map +1 -0
- package/dist/tsup/chunk-4R73YDN3.cjs +20 -0
- package/dist/tsup/chunk-4R73YDN3.cjs.map +1 -0
- package/dist/tsup/chunk-6LJT3QRL.cjs +539 -0
- package/dist/tsup/chunk-6LJT3QRL.cjs.map +1 -0
- package/dist/tsup/chunk-GICQ3YCU.cjs +1792 -0
- package/dist/tsup/chunk-GICQ3YCU.cjs.map +1 -0
- package/dist/tsup/chunk-H26RP6GD.js +251 -0
- package/dist/tsup/chunk-H26RP6GD.js.map +1 -0
- package/dist/tsup/chunk-HI3HWJRC.js +20 -0
- package/dist/tsup/chunk-HI3HWJRC.js.map +1 -0
- package/dist/tsup/chunk-HLLF4B4Q.js +1792 -0
- package/dist/tsup/chunk-HLLF4B4Q.js.map +1 -0
- package/dist/tsup/chunk-IH6CKNDW.cjs +117 -0
- package/dist/tsup/chunk-IH6CKNDW.cjs.map +1 -0
- package/dist/tsup/chunk-LV2S3OU3.js +250 -0
- package/dist/tsup/chunk-LV2S3OU3.js.map +1 -0
- package/dist/tsup/chunk-LWNKVZG5.cjs +251 -0
- package/dist/tsup/chunk-LWNKVZG5.cjs.map +1 -0
- package/dist/tsup/chunk-NFU2BBT5.js +374 -0
- package/dist/tsup/chunk-NFU2BBT5.js.map +1 -0
- package/dist/tsup/chunk-PQY7KKTL.js +539 -0
- package/dist/tsup/chunk-PQY7KKTL.js.map +1 -0
- package/dist/tsup/chunk-QK72M5JB.js +45 -0
- package/dist/tsup/chunk-QK72M5JB.js.map +1 -0
- package/dist/tsup/chunk-QNNXFOQV.cjs +45 -0
- package/dist/tsup/chunk-QNNXFOQV.cjs.map +1 -0
- package/dist/tsup/chunk-SBHHJ6QS.cjs +374 -0
- package/dist/tsup/chunk-SBHHJ6QS.cjs.map +1 -0
- package/dist/tsup/chunk-TQ62L3X7.js +325 -0
- package/dist/tsup/chunk-TQ62L3X7.js.map +1 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs +6293 -0
- package/dist/tsup/chunk-VO7ZRVVD.cjs.map +1 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs +325 -0
- package/dist/tsup/chunk-WHBPJNGW.cjs.map +1 -0
- package/dist/tsup/chunk-XJQHKJ4P.js +6293 -0
- package/dist/tsup/chunk-XJQHKJ4P.js.map +1 -0
- package/dist/tsup/client/mod.cjs +32 -0
- package/dist/tsup/client/mod.cjs.map +1 -0
- package/dist/tsup/client/mod.d.cts +20 -0
- package/dist/tsup/client/mod.d.ts +20 -0
- package/dist/tsup/client/mod.js +32 -0
- package/dist/tsup/client/mod.js.map +1 -0
- package/dist/tsup/common/log.cjs +21 -0
- package/dist/tsup/common/log.cjs.map +1 -0
- package/dist/tsup/common/log.d.cts +26 -0
- package/dist/tsup/common/log.d.ts +26 -0
- package/dist/tsup/common/log.js +21 -0
- package/dist/tsup/common/log.js.map +1 -0
- package/dist/tsup/common/websocket.cjs +10 -0
- package/dist/tsup/common/websocket.cjs.map +1 -0
- package/dist/tsup/common/websocket.d.cts +3 -0
- package/dist/tsup/common/websocket.d.ts +3 -0
- package/dist/tsup/common/websocket.js +10 -0
- package/dist/tsup/common/websocket.js.map +1 -0
- package/dist/tsup/common-CXCe7s6i.d.cts +218 -0
- package/dist/tsup/common-CXCe7s6i.d.ts +218 -0
- package/dist/tsup/connection-BI-6UIBJ.d.ts +2087 -0
- package/dist/tsup/connection-Dyd4NLGW.d.cts +2087 -0
- package/dist/tsup/driver-helpers/mod.cjs +30 -0
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -0
- package/dist/tsup/driver-helpers/mod.d.cts +17 -0
- package/dist/tsup/driver-helpers/mod.d.ts +17 -0
- package/dist/tsup/driver-helpers/mod.js +30 -0
- package/dist/tsup/driver-helpers/mod.js.map +1 -0
- package/dist/tsup/driver-test-suite/mod.cjs +3411 -0
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -0
- package/dist/tsup/driver-test-suite/mod.d.cts +63 -0
- package/dist/tsup/driver-test-suite/mod.d.ts +63 -0
- package/dist/tsup/driver-test-suite/mod.js +3411 -0
- package/dist/tsup/driver-test-suite/mod.js.map +1 -0
- package/dist/tsup/inspector/mod.cjs +51 -0
- package/dist/tsup/inspector/mod.cjs.map +1 -0
- package/dist/tsup/inspector/mod.d.cts +408 -0
- package/dist/tsup/inspector/mod.d.ts +408 -0
- package/dist/tsup/inspector/mod.js +51 -0
- package/dist/tsup/inspector/mod.js.map +1 -0
- package/dist/tsup/mod.cjs +67 -0
- package/dist/tsup/mod.cjs.map +1 -0
- package/dist/tsup/mod.d.cts +105 -0
- package/dist/tsup/mod.d.ts +105 -0
- package/dist/tsup/mod.js +67 -0
- package/dist/tsup/mod.js.map +1 -0
- package/dist/tsup/router-endpoints-BTe_Rsdn.d.cts +65 -0
- package/dist/tsup/router-endpoints-CBSrKHmo.d.ts +65 -0
- package/dist/tsup/test/mod.cjs +17 -0
- package/dist/tsup/test/mod.cjs.map +1 -0
- package/dist/tsup/test/mod.d.cts +26 -0
- package/dist/tsup/test/mod.d.ts +26 -0
- package/dist/tsup/test/mod.js +17 -0
- package/dist/tsup/test/mod.js.map +1 -0
- package/dist/tsup/utils-fwx3o3K9.d.cts +18 -0
- package/dist/tsup/utils-fwx3o3K9.d.ts +18 -0
- package/dist/tsup/utils.cjs +26 -0
- package/dist/tsup/utils.cjs.map +1 -0
- package/dist/tsup/utils.d.cts +36 -0
- package/dist/tsup/utils.d.ts +36 -0
- package/dist/tsup/utils.js +26 -0
- package/dist/tsup/utils.js.map +1 -0
- package/package.json +208 -5
- package/src/actor/action.ts +178 -0
- package/src/actor/config.ts +497 -0
- package/src/actor/connection.ts +257 -0
- package/src/actor/context.ts +168 -0
- package/src/actor/database.ts +23 -0
- package/src/actor/definition.ts +82 -0
- package/src/actor/driver.ts +84 -0
- package/src/actor/errors.ts +422 -0
- package/src/actor/generic-conn-driver.ts +246 -0
- package/src/actor/instance.ts +1844 -0
- package/src/actor/keys.test.ts +266 -0
- package/src/actor/keys.ts +89 -0
- package/src/actor/log.ts +6 -0
- package/src/actor/mod.ts +108 -0
- package/src/actor/persisted.ts +42 -0
- package/src/actor/protocol/old.ts +297 -0
- package/src/actor/protocol/serde.ts +131 -0
- package/src/actor/router-endpoints.ts +688 -0
- package/src/actor/router.ts +265 -0
- package/src/actor/schedule.ts +17 -0
- package/src/actor/unstable-react.ts +110 -0
- package/src/actor/utils.ts +102 -0
- package/src/client/actor-common.ts +30 -0
- package/src/client/actor-conn.ts +865 -0
- package/src/client/actor-handle.ts +268 -0
- package/src/client/actor-query.ts +65 -0
- package/src/client/client.ts +554 -0
- package/src/client/config.ts +44 -0
- package/src/client/errors.ts +42 -0
- package/src/client/log.ts +5 -0
- package/src/client/mod.ts +60 -0
- package/src/client/raw-utils.ts +149 -0
- package/src/client/test.ts +44 -0
- package/src/client/utils.ts +152 -0
- package/src/common/eventsource-interface.ts +47 -0
- package/src/common/eventsource.ts +80 -0
- package/src/common/fake-event-source.ts +267 -0
- package/src/common/inline-websocket-adapter2.ts +454 -0
- package/src/common/log-levels.ts +27 -0
- package/src/common/log.ts +214 -0
- package/src/common/logfmt.ts +219 -0
- package/src/common/network.ts +2 -0
- package/src/common/router.ts +80 -0
- package/src/common/utils.ts +336 -0
- package/src/common/versioned-data.ts +95 -0
- package/src/common/websocket-interface.ts +49 -0
- package/src/common/websocket.ts +42 -0
- package/src/driver-helpers/mod.ts +22 -0
- package/src/driver-helpers/utils.ts +17 -0
- package/src/driver-test-suite/log.ts +5 -0
- package/src/driver-test-suite/mod.ts +239 -0
- package/src/driver-test-suite/tests/action-features.ts +136 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +249 -0
- package/src/driver-test-suite/tests/actor-conn.ts +349 -0
- package/src/driver-test-suite/tests/actor-driver.ts +25 -0
- package/src/driver-test-suite/tests/actor-error-handling.ts +158 -0
- package/src/driver-test-suite/tests/actor-handle.ts +292 -0
- package/src/driver-test-suite/tests/actor-inline-client.ts +152 -0
- package/src/driver-test-suite/tests/actor-inspector.ts +570 -0
- package/src/driver-test-suite/tests/actor-metadata.ts +116 -0
- package/src/driver-test-suite/tests/actor-onstatechange.ts +95 -0
- package/src/driver-test-suite/tests/actor-schedule.ts +108 -0
- package/src/driver-test-suite/tests/actor-sleep.ts +413 -0
- package/src/driver-test-suite/tests/actor-state.ts +54 -0
- package/src/driver-test-suite/tests/actor-vars.ts +93 -0
- package/src/driver-test-suite/tests/manager-driver.ts +367 -0
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +227 -0
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +414 -0
- package/src/driver-test-suite/tests/raw-http.ts +347 -0
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +393 -0
- package/src/driver-test-suite/tests/raw-websocket.ts +484 -0
- package/src/driver-test-suite/tests/request-access.ts +230 -0
- package/src/driver-test-suite/utils.ts +71 -0
- package/src/drivers/default.ts +34 -0
- package/src/drivers/engine/actor-driver.ts +369 -0
- package/src/drivers/engine/config.ts +31 -0
- package/src/drivers/engine/kv.ts +3 -0
- package/src/drivers/engine/log.ts +5 -0
- package/src/drivers/engine/mod.ts +35 -0
- package/src/drivers/file-system/actor.ts +91 -0
- package/src/drivers/file-system/global-state.ts +686 -0
- package/src/drivers/file-system/log.ts +5 -0
- package/src/drivers/file-system/manager.ts +329 -0
- package/src/drivers/file-system/mod.ts +48 -0
- package/src/drivers/file-system/utils.ts +109 -0
- package/src/globals.d.ts +6 -0
- package/src/inspector/actor.ts +298 -0
- package/src/inspector/config.ts +88 -0
- package/src/inspector/log.ts +5 -0
- package/src/inspector/manager.ts +86 -0
- package/src/inspector/mod.ts +2 -0
- package/src/inspector/protocol/actor.ts +10 -0
- package/src/inspector/protocol/common.ts +196 -0
- package/src/inspector/protocol/manager.ts +10 -0
- package/src/inspector/protocol/mod.ts +2 -0
- package/src/inspector/utils.ts +76 -0
- package/src/manager/driver.ts +88 -0
- package/src/manager/hono-websocket-adapter.ts +342 -0
- package/src/manager/log.ts +5 -0
- package/src/manager/mod.ts +2 -0
- package/src/manager/protocol/mod.ts +24 -0
- package/src/manager/protocol/query.ts +89 -0
- package/src/manager/router.ts +412 -0
- package/src/manager-api/routes/actors-create.ts +16 -0
- package/src/manager-api/routes/actors-delete.ts +4 -0
- package/src/manager-api/routes/actors-get-by-id.ts +7 -0
- package/src/manager-api/routes/actors-get-or-create-by-id.ts +29 -0
- package/src/manager-api/routes/actors-get.ts +7 -0
- package/src/manager-api/routes/common.ts +18 -0
- package/src/mod.ts +18 -0
- package/src/registry/config.ts +32 -0
- package/src/registry/log.ts +5 -0
- package/src/registry/mod.ts +157 -0
- package/src/registry/run-config.ts +52 -0
- package/src/registry/serve.ts +52 -0
- package/src/remote-manager-driver/actor-http-client.ts +72 -0
- package/src/remote-manager-driver/actor-websocket-client.ts +63 -0
- package/src/remote-manager-driver/api-endpoints.ts +79 -0
- package/src/remote-manager-driver/api-utils.ts +43 -0
- package/src/remote-manager-driver/log.ts +5 -0
- package/src/remote-manager-driver/mod.ts +274 -0
- package/src/remote-manager-driver/ws-proxy.ts +180 -0
- package/src/schemas/actor-persist/mod.ts +1 -0
- package/src/schemas/actor-persist/versioned.ts +25 -0
- package/src/schemas/client-protocol/mod.ts +1 -0
- package/src/schemas/client-protocol/versioned.ts +63 -0
- package/src/schemas/file-system-driver/mod.ts +1 -0
- package/src/schemas/file-system-driver/versioned.ts +28 -0
- package/src/serde.ts +90 -0
- package/src/test/config.ts +16 -0
- package/src/test/log.ts +5 -0
- package/src/test/mod.ts +154 -0
- 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,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
|
+
}
|