@rivetkit/rivetkit-native 0.0.0-pr.4614.822b57f → 0.0.0-pr.4646.1725d01

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/index.d.ts CHANGED
@@ -27,7 +27,6 @@ export interface JsEnvoyConfig {
27
27
  poolName: string
28
28
  version: number
29
29
  metadata?: any
30
- notGlobal: boolean
31
30
  /**
32
31
  * Log level for the Rust tracing subscriber (e.g. "trace", "debug", "info", "warn", "error").
33
32
  * Falls back to RIVET_LOG_LEVEL, then LOG_LEVEL, then RUST_LOG env vars. Defaults to "warn".
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rivetkit/rivetkit-native",
3
- "version": "0.0.0-pr.4614.822b57f",
3
+ "version": "0.0.0-pr.4646.1725d01",
4
4
  "description": "Native N-API addon for RivetKit providing envoy client and SQLite access",
5
5
  "license": "Apache-2.0",
6
6
  "main": "index.js",
@@ -49,15 +49,15 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@napi-rs/cli": "^2.18.4",
52
- "@rivetkit/engine-envoy-protocol": "0.0.0-pr.4614.822b57f"
52
+ "@rivetkit/engine-envoy-protocol": "0.0.0-pr.4646.1725d01"
53
53
  },
54
54
  "optionalDependencies": {
55
- "@rivetkit/rivetkit-native-darwin-arm64": "0.0.0-pr.4614.822b57f",
56
- "@rivetkit/rivetkit-native-darwin-x64": "0.0.0-pr.4614.822b57f",
57
- "@rivetkit/rivetkit-native-linux-arm64-gnu": "0.0.0-pr.4614.822b57f",
58
- "@rivetkit/rivetkit-native-linux-arm64-musl": "0.0.0-pr.4614.822b57f",
59
- "@rivetkit/rivetkit-native-linux-x64-gnu": "0.0.0-pr.4614.822b57f",
60
- "@rivetkit/rivetkit-native-linux-x64-musl": "0.0.0-pr.4614.822b57f",
61
- "@rivetkit/rivetkit-native-win32-x64-msvc": "0.0.0-pr.4614.822b57f"
55
+ "@rivetkit/rivetkit-native-darwin-arm64": "0.0.0-pr.4646.1725d01",
56
+ "@rivetkit/rivetkit-native-darwin-x64": "0.0.0-pr.4646.1725d01",
57
+ "@rivetkit/rivetkit-native-linux-arm64-gnu": "0.0.0-pr.4646.1725d01",
58
+ "@rivetkit/rivetkit-native-linux-arm64-musl": "0.0.0-pr.4646.1725d01",
59
+ "@rivetkit/rivetkit-native-linux-x64-gnu": "0.0.0-pr.4646.1725d01",
60
+ "@rivetkit/rivetkit-native-linux-x64-musl": "0.0.0-pr.4646.1725d01",
61
+ "@rivetkit/rivetkit-native-win32-x64-msvc": "0.0.0-pr.4646.1725d01"
62
62
  }
63
63
  }
package/wrapper.d.ts CHANGED
@@ -136,4 +136,9 @@ export interface NativeRawDatabase {
136
136
  close: () => Promise<void>;
137
137
  }
138
138
 
139
+ export declare function openRawDatabaseFromEnvoy(
140
+ handle: EnvoyHandle,
141
+ actorId: string,
142
+ ): Promise<NativeRawDatabase>;
143
+
139
144
  export declare const utils: {};
package/wrapper.js CHANGED
@@ -8,6 +8,18 @@
8
8
 
9
9
  const native = require("./index");
10
10
 
11
+ // CloseEvent was added to Node.js in v22. Polyfill for older versions.
12
+ if (typeof CloseEvent === "undefined") {
13
+ global.CloseEvent = class CloseEvent extends Event {
14
+ constructor(type, init = {}) {
15
+ super(type);
16
+ this.code = init.code ?? 0;
17
+ this.reason = init.reason ?? "";
18
+ this.wasClean = init.wasClean ?? false;
19
+ }
20
+ };
21
+ }
22
+
11
23
  // Re-export protocol for consumers that need protocol types at runtime
12
24
  let _protocol;
13
25
  try {
@@ -99,9 +111,8 @@ function wrapHandle(jsHandle) {
99
111
  Buffer.from(requestId),
100
112
  clientMessageIndex,
101
113
  ),
102
- startServerlessActor: (payload) => {
103
- jsHandle.startServerless(Buffer.from(payload));
104
- },
114
+ startServerlessActor: async (payload) =>
115
+ await jsHandle.startServerless(Buffer.from(payload)),
105
116
  // Internal: expose raw handle for openDatabaseFromEnvoy
106
117
  _raw: jsHandle,
107
118
  };
@@ -123,7 +134,7 @@ function startEnvoySync(config) {
123
134
  poolName: config.poolName,
124
135
  version: config.version,
125
136
  metadata: config.metadata || null,
126
- notGlobal: config.notGlobal ?? false,
137
+ notGlobal: config.notGlobal,
127
138
  },
128
139
  (event) => {
129
140
  handleEvent(event, config, wrappedHandle);
@@ -152,6 +163,152 @@ async function openDatabaseFromEnvoy(handle, actorId) {
152
163
  return native.openDatabaseFromEnvoy(rawHandle, actorId);
153
164
  }
154
165
 
166
+ function isPlainObject(value) {
167
+ return (
168
+ !!value &&
169
+ typeof value === "object" &&
170
+ !Array.isArray(value) &&
171
+ Object.getPrototypeOf(value) === Object.prototype
172
+ );
173
+ }
174
+
175
+ function toNativeBinding(value) {
176
+ if (value === null || value === undefined) {
177
+ return { kind: "null" };
178
+ }
179
+ if (typeof value === "bigint") {
180
+ return { kind: "int", intValue: Number(value) };
181
+ }
182
+ if (typeof value === "number") {
183
+ return Number.isInteger(value)
184
+ ? { kind: "int", intValue: value }
185
+ : { kind: "float", floatValue: value };
186
+ }
187
+ if (typeof value === "string") {
188
+ return { kind: "text", textValue: value };
189
+ }
190
+ if (value instanceof ArrayBuffer) {
191
+ return { kind: "blob", blobValue: Buffer.from(value) };
192
+ }
193
+ if (ArrayBuffer.isView(value)) {
194
+ return {
195
+ kind: "blob",
196
+ blobValue: Buffer.from(value.buffer, value.byteOffset, value.byteLength),
197
+ };
198
+ }
199
+
200
+ throw new Error(`unsupported sqlite binding type: ${typeof value}`);
201
+ }
202
+
203
+ function extractNamedSqliteParameters(sql) {
204
+ return [...sql.matchAll(/([:@$][A-Za-z_][A-Za-z0-9_]*)/g)].map(
205
+ (match) => match[1],
206
+ );
207
+ }
208
+
209
+ function getNamedSqliteBinding(bindings, name) {
210
+ if (name in bindings) {
211
+ return bindings[name];
212
+ }
213
+
214
+ const bareName = name.slice(1);
215
+ if (bareName in bindings) {
216
+ return bindings[bareName];
217
+ }
218
+
219
+ for (const prefix of [":", "@", "$"]) {
220
+ const candidate = `${prefix}${bareName}`;
221
+ if (candidate in bindings) {
222
+ return bindings[candidate];
223
+ }
224
+ }
225
+
226
+ return undefined;
227
+ }
228
+
229
+ function normalizeBindings(sql, args) {
230
+ if (!args || args.length === 0) {
231
+ return [];
232
+ }
233
+
234
+ if (
235
+ args.length === 1 &&
236
+ isPlainObject(args[0]) &&
237
+ !(args[0] instanceof Uint8Array)
238
+ ) {
239
+ const names = extractNamedSqliteParameters(sql);
240
+ if (names.length === 0) {
241
+ throw new Error(
242
+ "native sqlite object bindings require named placeholders in the SQL statement",
243
+ );
244
+ }
245
+ return names.map((name) => {
246
+ const value = getNamedSqliteBinding(args[0], name);
247
+ if (value === undefined) {
248
+ throw new Error(`missing bind parameter: ${name}`);
249
+ }
250
+ return toNativeBinding(value);
251
+ });
252
+ }
253
+
254
+ return args.map(toNativeBinding);
255
+ }
256
+
257
+ function mapRows(rows, columns) {
258
+ return rows.map((row) => {
259
+ const rowObject = {};
260
+ for (let i = 0; i < columns.length; i++) {
261
+ rowObject[columns[i]] = row[i];
262
+ }
263
+ return rowObject;
264
+ });
265
+ }
266
+
267
+ async function openRawDatabaseFromEnvoy(handle, actorId) {
268
+ const nativeDb = await openDatabaseFromEnvoy(handle, actorId);
269
+ let closed = false;
270
+
271
+ const ensureOpen = () => {
272
+ if (closed) {
273
+ throw new Error("database is closed");
274
+ }
275
+ };
276
+
277
+ return {
278
+ execute: async (query, ...args) => {
279
+ ensureOpen();
280
+
281
+ if (args.length > 0) {
282
+ const bindings = normalizeBindings(query, args);
283
+ const token = query.trimStart().slice(0, 16).toUpperCase();
284
+ const returnsRows =
285
+ token.startsWith("SELECT") ||
286
+ token.startsWith("PRAGMA") ||
287
+ token.startsWith("WITH") ||
288
+ /\bRETURNING\b/i.test(query);
289
+
290
+ if (returnsRows) {
291
+ const result = await nativeDb.query(query, bindings);
292
+ return mapRows(result.rows, result.columns);
293
+ }
294
+
295
+ await nativeDb.run(query, bindings);
296
+ return [];
297
+ }
298
+
299
+ const result = await nativeDb.exec(query);
300
+ return mapRows(result.rows, result.columns);
301
+ },
302
+ close: async () => {
303
+ if (closed) {
304
+ return;
305
+ }
306
+ closed = true;
307
+ await nativeDb.close();
308
+ },
309
+ };
310
+ }
311
+
155
312
  /**
156
313
  * Route callback envelopes from the native addon to EnvoyConfig callbacks.
157
314
  */
@@ -176,15 +333,15 @@ function handleEvent(event, config, wrappedHandle) {
176
333
  null, // preloadedKv
177
334
  ),
178
335
  ).then(
179
- () => {
336
+ async () => {
180
337
  if (handle._raw) {
181
- handle._raw.respondCallback(event.responseId, {});
338
+ await handle._raw.respondCallback(event.responseId, {});
182
339
  }
183
340
  },
184
- (err) => {
341
+ async (err) => {
185
342
  console.error("onActorStart error:", err);
186
343
  if (handle._raw) {
187
- handle._raw.respondCallback(event.responseId, {
344
+ await handle._raw.respondCallback(event.responseId, {
188
345
  error: String(err),
189
346
  });
190
347
  }
@@ -201,15 +358,15 @@ function handleEvent(event, config, wrappedHandle) {
201
358
  event.reason || "stopped",
202
359
  ),
203
360
  ).then(
204
- () => {
361
+ async () => {
205
362
  if (handle._raw) {
206
- handle._raw.respondCallback(event.responseId, {});
363
+ await handle._raw.respondCallback(event.responseId, {});
207
364
  }
208
365
  },
209
- (err) => {
366
+ async (err) => {
210
367
  console.error("onActorStop error:", err);
211
368
  if (handle._raw) {
212
- handle._raw.respondCallback(event.responseId, {
369
+ await handle._raw.respondCallback(event.responseId, {
213
370
  error: String(err),
214
371
  });
215
372
  }
@@ -246,17 +403,17 @@ function handleEvent(event, config, wrappedHandle) {
246
403
  const respBody = response.body
247
404
  ? Buffer.from(await response.arrayBuffer()).toString("base64")
248
405
  : undefined;
249
- handle._raw.respondCallback(event.responseId, {
406
+ await handle._raw.respondCallback(event.responseId, {
250
407
  status: response.status || 200,
251
408
  headers: respHeaders,
252
409
  body: respBody,
253
410
  });
254
411
  }
255
412
  },
256
- (err) => {
413
+ async (err) => {
257
414
  console.error("fetch callback error:", err);
258
415
  if (handle._raw) {
259
- handle._raw.respondCallback(event.responseId, {
416
+ await handle._raw.respondCallback(event.responseId, {
260
417
  status: 500,
261
418
  headers: { "content-type": "text/plain" },
262
419
  body: Buffer.from(String(err)).toString("base64"),
@@ -335,7 +492,6 @@ function handleEvent(event, config, wrappedHandle) {
335
492
  )
336
493
  : false;
337
494
 
338
- console.log("[wrapper] websocket_open actorId:", event.actorId?.slice(0, 12), "path:", event.path);
339
495
  Promise.resolve(
340
496
  config.websocket(
341
497
  handle,
@@ -350,9 +506,7 @@ function handleEvent(event, config, wrappedHandle) {
350
506
  false,
351
507
  ),
352
508
  ).then(() => {
353
- console.log("[wrapper] websocket callback resolved, dispatching open event");
354
509
  ws.dispatchEvent(new Event("open"));
355
- console.log("[wrapper] open event dispatched");
356
510
  }).catch((err) => {
357
511
  console.error("[wrapper] websocket callback error:", err);
358
512
  });
@@ -420,3 +574,4 @@ function handleEvent(event, config, wrappedHandle) {
420
574
  module.exports.startEnvoy = startEnvoy;
421
575
  module.exports.startEnvoySync = startEnvoySync;
422
576
  module.exports.openDatabaseFromEnvoy = openDatabaseFromEnvoy;
577
+ module.exports.openRawDatabaseFromEnvoy = openRawDatabaseFromEnvoy;