@rasputin-ai/elysia 0.4.1 → 0.5.0-alpha.1
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 +180 -168
- package/dist/index.js +1 -1
- package/dist/sdk-meta.d.ts +1 -1
- package/dist/sdk-meta.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,168 +1,180 @@
|
|
|
1
|
-
# Official Rasputin AI SDK for Elysia
|
|
2
|
-
|
|
3
|
-
Report application errors to Rasputin.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
Initialize once and register the plugin early in your app:
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
import { Elysia } from 'elysia';
|
|
11
|
-
import { RasputinInit } from '@rasputin-ai/elysia';
|
|
12
|
-
|
|
13
|
-
const { client, plugin } = RasputinInit({
|
|
14
|
-
projectApiKey: process.env.RASPUTIN_PROJECT_API_KEY!,
|
|
15
|
-
release: process.env.RASPUTIN_RELEASE!,
|
|
16
|
-
environment: process.env.NODE_ENV ?? 'development',
|
|
17
|
-
enabled: ['staging', 'production'].includes(process.env.NODE_ENV ?? 'development'),
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const app = new Elysia()
|
|
21
|
-
.use(plugin) // Register Rasputin before other plugins when possible.
|
|
22
|
-
.use(otherPlugins)
|
|
23
|
-
.listen(3000);
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Route errors, uncaught exceptions, and unhandled rejections are reported automatically.
|
|
27
|
-
|
|
28
|
-
## Capture handled errors
|
|
29
|
-
|
|
30
|
-
```ts
|
|
31
|
-
try {
|
|
32
|
-
await processPayment();
|
|
33
|
-
} catch (error) {
|
|
34
|
-
client.captureException(error);
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Configuration
|
|
39
|
-
|
|
40
|
-
| Field | Required | Description |
|
|
41
|
-
| --- | --- | --- |
|
|
42
|
-
| `projectApiKey` | yes | Project API key from the Rasputin dashboard |
|
|
43
|
-
| `environment` | yes | Environment such as `production`, `staging`, or `preview` |
|
|
44
|
-
| `release` | yes | Git commit SHA for the deployed version |
|
|
45
|
-
| `enabled` | no | Enables or disables the SDK; defaults to `true` |
|
|
46
|
-
| `logSuccess` | no | Prints a configuration summary when setup succeeds; defaults to `true`. Failures always log. |
|
|
47
|
-
| `moduleUrl` | no | `import.meta.url` from the initialization file; helps normalize local stack paths |
|
|
48
|
-
| `sourceRoot` | no | Git repository folder for a single-package service, such as `apps/api` |
|
|
49
|
-
| `sourceRoots` | no | Package-name to Git-folder mappings for ambiguous monorepos |
|
|
50
|
-
| `repoRoot` | no | Local filesystem display root; it does not control instrumentation or Git identity |
|
|
51
|
-
|
|
52
|
-
Rasputin normally identifies source from the nearest `package.json` and verifies it against the exact release on the server. Filesystem paths such as `/container` are never used as source identity.
|
|
53
|
-
|
|
54
|
-
For deployment checks, call:
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
const verification = await client.verifyConfiguration();
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
`verified` means every instrumented source file maps uniquely to the configured Git release. If a monorepo is ambiguous, set `sourceRoot` or `sourceRoots` using repository-relative folders, never Docker paths.
|
|
61
|
-
|
|
62
|
-
Rasputin also prints a configuration summary after the instrumentation manifest is uploaded. Set `logSuccess: false` if you do not want that banner in production logs. Mapping failures still warn.
|
|
63
|
-
|
|
64
|
-
## Shutdown
|
|
65
|
-
|
|
66
|
-
Events are sent in the background. Flush before a short-lived process exits:
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
await client.flush();
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Call `await client.close()` during graceful shutdown when the process stays alive afterward.
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
# Runtime recorder
|
|
77
|
-
|
|
78
|
-
Optionally attach the runtime state that led to an error — arguments, return values, and call history from the failing execution.
|
|
79
|
-
|
|
80
|
-
The Elysia plugin scopes each HTTP request as an execution automatically. For background jobs and other non-HTTP work, wrap them manually (see below).
|
|
81
|
-
|
|
82
|
-
## Automatic instrumentation
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
```json
|
|
87
|
-
{
|
|
88
|
-
"scripts": {
|
|
89
|
-
"
|
|
90
|
-
"start:
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
| `
|
|
139
|
-
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
1
|
+
# Official Rasputin AI SDK for Elysia
|
|
2
|
+
|
|
3
|
+
Report application errors to Rasputin.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
Initialize once and register the plugin early in your app:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Elysia } from 'elysia';
|
|
11
|
+
import { RasputinInit } from '@rasputin-ai/elysia';
|
|
12
|
+
|
|
13
|
+
const { client, plugin } = RasputinInit({
|
|
14
|
+
projectApiKey: process.env.RASPUTIN_PROJECT_API_KEY!,
|
|
15
|
+
release: process.env.RASPUTIN_RELEASE!,
|
|
16
|
+
environment: process.env.NODE_ENV ?? 'development',
|
|
17
|
+
enabled: ['staging', 'production'].includes(process.env.NODE_ENV ?? 'development'),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const app = new Elysia()
|
|
21
|
+
.use(plugin) // Register Rasputin before other plugins when possible.
|
|
22
|
+
.use(otherPlugins)
|
|
23
|
+
.listen(3000);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Route errors, uncaught exceptions, and unhandled rejections are reported automatically.
|
|
27
|
+
|
|
28
|
+
## Capture handled errors
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
try {
|
|
32
|
+
await processPayment();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
client.captureException(error);
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Configuration
|
|
39
|
+
|
|
40
|
+
| Field | Required | Description |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `projectApiKey` | yes | Project API key from the Rasputin dashboard |
|
|
43
|
+
| `environment` | yes | Environment such as `production`, `staging`, or `preview` |
|
|
44
|
+
| `release` | yes | Git commit SHA for the deployed version |
|
|
45
|
+
| `enabled` | no | Enables or disables the SDK; defaults to `true` |
|
|
46
|
+
| `logSuccess` | no | Prints a configuration summary when setup succeeds; defaults to `true`. Failures always log. |
|
|
47
|
+
| `moduleUrl` | no | `import.meta.url` from the initialization file; helps normalize local stack paths |
|
|
48
|
+
| `sourceRoot` | no | Git repository folder for a single-package service, such as `apps/api` |
|
|
49
|
+
| `sourceRoots` | no | Package-name to Git-folder mappings for ambiguous monorepos |
|
|
50
|
+
| `repoRoot` | no | Local filesystem display root; it does not control instrumentation or Git identity |
|
|
51
|
+
|
|
52
|
+
Rasputin normally identifies source from the nearest `package.json` and verifies it against the exact release on the server. Filesystem paths such as `/container` are never used as source identity.
|
|
53
|
+
|
|
54
|
+
For deployment checks, call:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const verification = await client.verifyConfiguration();
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`verified` means every instrumented source file maps uniquely to the configured Git release. If a monorepo is ambiguous, set `sourceRoot` or `sourceRoots` using repository-relative folders, never Docker paths.
|
|
61
|
+
|
|
62
|
+
Rasputin also prints a configuration summary after the instrumentation manifest is uploaded. Set `logSuccess: false` if you do not want that banner in production logs. Mapping failures still warn.
|
|
63
|
+
|
|
64
|
+
## Shutdown
|
|
65
|
+
|
|
66
|
+
Events are sent in the background. Flush before a short-lived process exits:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
await client.flush();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Call `await client.close()` during graceful shutdown when the process stays alive afterward.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
# Runtime recorder
|
|
77
|
+
|
|
78
|
+
Optionally attach the runtime state that led to an error — arguments, return values, and call history from the failing execution.
|
|
79
|
+
|
|
80
|
+
The Elysia plugin scopes each HTTP request as an execution automatically. For background jobs and other non-HTTP work, wrap them manually (see below).
|
|
81
|
+
|
|
82
|
+
## Automatic instrumentation
|
|
83
|
+
|
|
84
|
+
Build-time instrumentation is the preferred high-performance mode. Transform compiled unbundled JavaScript after `tsc` so the production process never loads TypeScript:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"scripts": {
|
|
89
|
+
"build": "tsc && rasputin-instrument dist",
|
|
90
|
+
"start:node": "node dist/app.js",
|
|
91
|
+
"start:bun": "bun dist/app.js"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Load-time transformation remains available as a compatibility fallback:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"scripts": {
|
|
101
|
+
"start:node": "node --import @rasputin-ai/elysia/instrument/node dist/app.js",
|
|
102
|
+
"start:bun": "bun --preload @rasputin-ai/elysia/instrument/bun src/app.ts"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Runtime state is retained only inside an active execution and attached when that execution throws.
|
|
108
|
+
|
|
109
|
+
## Manual capture
|
|
110
|
+
|
|
111
|
+
For background jobs, scheduled tasks, or worker iterations, define an execution:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
await client.execution.run({ kind: 'job', name: 'sync-invoices' }, async () => {
|
|
115
|
+
await syncInvoices();
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
When automatic instrumentation is unavailable, mark individual functions explicitly:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
const syncInvoices = client.execution.trace(
|
|
123
|
+
'src/jobs/sync-invoices.ts:syncInvoices',
|
|
124
|
+
async () => {
|
|
125
|
+
// ...
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Runtime support
|
|
131
|
+
|
|
132
|
+
| Environment | Support |
|
|
133
|
+
| --- | --- |
|
|
134
|
+
| TypeScript compiled to multiple JavaScript files | Preferred: `rasputin-instrument dist` after `tsc`, with adjacent source maps |
|
|
135
|
+
| Elysia 1.4 or newer within 1.x on Bun 1.3.x | Supported for directly loaded JavaScript and TypeScript using `instrument/bun` as a compatibility fallback |
|
|
136
|
+
| Elysia 1.4 or newer within 1.x on Node.js 22.15 or newer | Supported for unbundled ESM/CJS JavaScript using `instrument/node` as a compatibility fallback; Node 22 and 24 are the supported LTS lines |
|
|
137
|
+
| Single-file bundles (esbuild, tsup, webpack, Vite SSR, Next.js) | Automatic instrumentation not supported |
|
|
138
|
+
| `tsx`, custom Node loader stacks, and Node's native TypeScript execution | Automatic instrumentation not supported |
|
|
139
|
+
| Deno and edge runtimes | Not supported |
|
|
140
|
+
|
|
141
|
+
Tested on Bun 1.3.13, Node.js 24.19.0, and Elysia 1.4.28. Node.js 22.15.0 is the minimum for automatic instrumentation (synchronous module hooks). Use `execution.run()` and `execution.trace()` when automatic instrumentation is not available.
|
|
142
|
+
|
|
143
|
+
## Recorder configuration
|
|
144
|
+
|
|
145
|
+
Defaults work for most apps. Customize to exclude noisy sources, redact fields, or retain less state:
|
|
146
|
+
|
|
147
|
+
| Field | Default | Description |
|
|
148
|
+
| --- | ---: | --- |
|
|
149
|
+
| `enabled` | `true` | Enables runtime-state capture |
|
|
150
|
+
| `maxEventsPerExecution` | `500` | Maximum events retained for one execution |
|
|
151
|
+
| `maxCapturedCallsPerFunction` | `3` | Detailed successful calls retained before similar calls are summarized |
|
|
152
|
+
| `maxActiveMemoryBytes` | `64 MiB` | Maximum recorder memory shared across active executions |
|
|
153
|
+
| `maxDepth` | `3` | Maximum captured value depth |
|
|
154
|
+
| `maxObjectKeys` | `30` | Maximum properties retained from one object |
|
|
155
|
+
| `maxArrayElements` | `20` | Maximum items retained from one array, map, or set |
|
|
156
|
+
| `maxStringLength` | `500` | Maximum characters retained from one string |
|
|
157
|
+
| `maxSerializedValueBytes` | `8 KiB` | Maximum retained size of one captured value |
|
|
158
|
+
| `redactKeys` | `[]` | Additional case-insensitive property names to redact |
|
|
159
|
+
| `excludeSources` | `[]` | Source globs or function-name patterns to exclude |
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
const { client, plugin } = RasputinInit({
|
|
163
|
+
// ...required options
|
|
164
|
+
executionRecorder: {
|
|
165
|
+
excludeSources: ['src/logger/**', 'packages/shared-logger/**'],
|
|
166
|
+
redactKeys: ['customerEmail'],
|
|
167
|
+
maxEventsPerExecution: 200,
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Runtime state can include application data. Use `redactKeys` for sensitive fields.
|
|
173
|
+
|
|
174
|
+
## Diagnostics
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
const { recorder, transport } = client.getStats();
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Counters are local to the current process and reset on restart.
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { Elysia } from "elysia";
|
|
|
13
13
|
|
|
14
14
|
// src/sdk-meta.ts
|
|
15
15
|
var SDK_NAME = "@rasputin-ai/elysia";
|
|
16
|
-
var SDK_VERSION = "0.
|
|
16
|
+
var SDK_VERSION = "0.5.0-alpha.1";
|
|
17
17
|
|
|
18
18
|
// src/rasputin-init.ts
|
|
19
19
|
var withExecution = (client, execution, installRuntime, manifest) => {
|
package/dist/sdk-meta.d.ts
CHANGED
package/dist/sdk-meta.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-meta.d.ts","sourceRoot":"","sources":["../src/sdk-meta.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,eAAO,MAAM,QAAQ,wBAAwB,CAAC;AAC9C,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"sdk-meta.d.ts","sourceRoot":"","sources":["../src/sdk-meta.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,eAAO,MAAM,QAAQ,wBAAwB,CAAC;AAC9C,eAAO,MAAM,WAAW,kBAAkB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rasputin-ai/elysia",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-alpha.1",
|
|
4
4
|
"description": "Official Rasputin AI SDK for Elysia.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@rasputin-ai/core": "0.
|
|
39
|
-
"@rasputin-ai/node": "0.
|
|
38
|
+
"@rasputin-ai/core": "0.5.0-alpha.1",
|
|
39
|
+
"@rasputin-ai/node": "0.5.0-alpha.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"elysia": ">=1.4.0 <2"
|