UNPKG

@rivetkit/redis

Version:

_Lightweight Libraries for Backends_

721 lines (688 loc) 19.9 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class;// ../../core/dist/chunk-INRCNZ4I.js var INTERNAL_ERROR_CODE = "internal_error"; var INTERNAL_ERROR_DESCRIPTION = "Internal error. Read the server logs for more details."; var USER_ERROR_CODE = "user_error"; var ActorError = (_class = class extends Error { constructor(code, message, opts) { super(message, { cause: opts == null ? void 0 : opts.cause });_class.prototype.__init.call(this);_class.prototype.__init2.call(this);; this.code = code; this.public = _nullishCoalesce((opts == null ? void 0 : opts.public), () => ( false)); this.metadata = opts == null ? void 0 : opts.metadata; if (opts == null ? void 0 : opts.public) { this.statusCode = 400; } } __init() {this.__type = "ActorError"} __init2() {this.statusCode = 500} static isActorError(error) { return typeof error === "object" && error.__type === "ActorError"; } toString() { return this.message; } /** * Serialize error for HTTP response */ serializeForHttp() { return { type: this.code, message: this.message, metadata: this.metadata }; } }, _class); var InternalError = class extends ActorError { constructor(message) { super(INTERNAL_ERROR_CODE, message); } }; var Unreachable = class extends InternalError { constructor(x) { super(`Unreachable case: ${x}`); } }; var InvalidEncoding = class extends ActorError { constructor(format) { super( "invalid_encoding", `Invalid encoding \`${format}\`. (https://www.rivet.gg/docs/actors/clients/#actor-client)`, { public: true } ); } }; var ConnNotFound = class extends ActorError { constructor(id) { super("conn_not_found", `Connection not found for ID: ${id}`, { public: true }); } }; var IncorrectConnToken = class extends ActorError { constructor() { super("incorrect_conn_token", "Incorrect connection token.", { public: true }); } }; var MessageTooLong = class extends ActorError { constructor() { super( "message_too_long", "Message too long. This can be configured with: `registry.runServer({ maxIncomingMessageSize: ... })`", { public: true } ); } }; var MalformedMessage = class extends ActorError { constructor(cause) { super("malformed_message", `Malformed message: ${cause}`, { public: true, cause }); } }; var UserError = class extends ActorError { /** * Constructs a new UserError instance. * * @param message - The error message to be displayed. * @param opts - Optional parameters for the error, including a machine-readable code and additional metadata. */ constructor(message, opts) { super(_nullishCoalesce((opts == null ? void 0 : opts.code), () => ( USER_ERROR_CODE)), message, { public: true, metadata: opts == null ? void 0 : opts.metadata }); } }; var InvalidRequest = class extends ActorError { constructor(error) { super("invalid_request", `Invalid request: ${error}`, { public: true, cause: error }); } }; var ActorNotFound = class extends ActorError { constructor(identifier) { super( "actor_not_found", identifier ? `Actor not found: ${identifier} (https://www.rivet.gg/docs/actors/clients/#actor-client)` : "Actor not found (https://www.rivet.gg/docs/actors/clients/#actor-client)", { public: true } ); } }; var ActorAlreadyExists = class extends ActorError { constructor(name, key) { super( "actor_already_exists", `Actor already exists with name '${name}' and key '${JSON.stringify(key)}' (https://www.rivet.gg/docs/actors/clients/#actor-client)`, { public: true } ); } }; var InvalidActionRequest = class extends ActorError { constructor(message) { super("invalid_action_request", message, { public: true }); } }; var InvalidParams = class extends ActorError { constructor(message) { super("invalid_params", message, { public: true }); } }; // src/keys.ts var KEYS = { ACTOR: { // KEY LEASE: { // KEY (expire) = node ID node: (prefix, actorId) => `${prefix}:actor:${actorId}:lease:node` }, // KEY metadata: (prefix, actorId) => `${prefix}:actor:${actorId}:metadata`, // KEY persistedData: (prefix, actorId) => `${prefix}:actor:${actorId}:persisted_data` }, // KEY actorByKey: (prefix, name, key) => { let redisKey = `${prefix}:actor_by_key:${escapeRedisKey(name)}`; if (key.length > 0) { redisKey += `:${key.map((k) => escapeRedisKey(k)).join(":")}`; } return redisKey; } }; var PUBSUB = { node(prefix, nodeId) { return `${prefix}:node:${nodeId}:messages`; } }; function escapeRedisKey(part) { return part.replace(/\\/g, "\\\\").replace(/:/g, "\\:"); } // ../../core/dist/chunk-WDSX6QCH.js function assertUnreachable(x) { throw new Error(`Unreachable case: ${x}`); } function deconstructError(error, logger2, extraLog, exposeInternalError = false) { let statusCode; let public_; let code; let message; let metadata; if (ActorError.isActorError(error) && error.public) { statusCode = "statusCode" in error && error.statusCode ? error.statusCode : 400; public_ = true; code = error.code; message = getErrorMessage(error); metadata = error.metadata; logger2.info("public error", { code, message, issues: "https://github.com/rivet-gg/rivetkit/issues", support: "https://rivet.gg/discord", ...extraLog }); } else if (exposeInternalError) { if (ActorError.isActorError(error)) { statusCode = 500; public_ = false; code = error.code; message = getErrorMessage(error); metadata = error.metadata; logger2.info("internal error", { code, message, issues: "https://github.com/rivet-gg/rivetkit/issues", support: "https://rivet.gg/discord", ...extraLog }); } else { statusCode = 500; public_ = false; code = INTERNAL_ERROR_CODE; message = getErrorMessage(error); logger2.info("internal error", { code, message, issues: "https://github.com/rivet-gg/rivetkit/issues", support: "https://rivet.gg/discord", ...extraLog }); } } else { statusCode = 500; public_ = false; code = INTERNAL_ERROR_CODE; message = INTERNAL_ERROR_DESCRIPTION; metadata = { //url: `https://hub.rivet.gg/projects/${actorMetadata.project.slug}/environments/${actorMetadata.environment.slug}/actors?actorId=${actorMetadata.actor.id}`, }; logger2.warn("internal error", { error: getErrorMessage(error), stack: error == null ? void 0 : error.stack, issues: "https://github.com/rivet-gg/rivetkit/issues", support: "https://rivet.gg/discord", ...extraLog }); } return { __type: "ActorError", statusCode, public: public_, code, message, metadata }; } function stringifyError(error) { if (error instanceof Error) { if (typeof process !== "undefined" && getEnvUniversal("_RIVETKIT_ERROR_STACK") === "1") { return `${error.name}: ${error.message}${error.stack ? ` ${error.stack}` : ""}`; } else { return `${error.name}: ${error.message}`; } } else if (typeof error === "string") { return error; } else if (typeof error === "object" && error !== null) { try { return `${JSON.stringify(error)}`; } catch (e) { return "[cannot stringify error]"; } } else { return `Unknown error: ${getErrorMessage(error)}`; } } function getErrorMessage(err) { if (err && typeof err === "object" && "message" in err && typeof err.message === "string") { return err.message; } else { return String(err); } } function noopNext() { return async () => { }; } var package_default = { name: "@rivetkit/core", version: "0.9.9", license: "Apache-2.0", keywords: [ "rivetkit", "stateful", "serverless", "actors", "agents", "realtime", "websocket", "actors", "framework" ], files: [ "dist", "src", "deno.json", "bun.json", "package.json" ], type: "module", exports: { ".": { import: { types: "./dist/mod.d.ts", default: "./dist/mod.js" }, require: { types: "./dist/mod.d.cts", default: "./dist/mod.cjs" } }, "./client": { import: { types: "./dist/client/mod.d.ts", default: "./dist/client/mod.js" }, require: { types: "./dist/client/mod.d.cts", default: "./dist/client/mod.cjs" } }, "./log": { import: { types: "./dist/common/log.d.ts", default: "./dist/common/log.js" }, require: { types: "./dist/common/log.d.cts", default: "./dist/common/log.cjs" } }, "./errors": { import: { types: "./dist/actor/errors.d.ts", default: "./dist/actor/errors.js" }, require: { types: "./dist/actor/errors.d.cts", default: "./dist/actor/errors.cjs" } }, "./utils": { import: { types: "./dist/utils.d.ts", default: "./dist/utils.js" }, require: { types: "./dist/utils.d.cts", default: "./dist/utils.cjs" } }, "./driver-helpers": { import: { types: "./dist/driver-helpers/mod.d.ts", default: "./dist/driver-helpers/mod.js" }, require: { types: "./dist/driver-helpers/mod.d.cts", default: "./dist/driver-helpers/mod.cjs" } }, "./driver-helpers/websocket": { import: { types: "./dist/common/websocket.d.ts", default: "./dist/common/websocket.js" }, require: { types: "./dist/common/websocket.d.cts", default: "./dist/common/websocket.cjs" } }, "./driver-test-suite": { import: { types: "./dist/driver-test-suite/mod.d.ts", default: "./dist/driver-test-suite/mod.js" }, require: { types: "./dist/driver-test-suite/mod.d.cts", default: "./dist/driver-test-suite/mod.cjs" } }, "./topologies/coordinate": { import: { types: "./dist/topologies/coordinate/mod.d.ts", default: "./dist/topologies/coordinate/mod.js" }, require: { types: "./dist/topologies/coordinate/mod.d.cts", default: "./dist/topologies/coordinate/mod.cjs" } }, "./topologies/partition": { import: { types: "./dist/topologies/partition/mod.d.ts", default: "./dist/topologies/partition/mod.js" }, require: { types: "./dist/topologies/partition/mod.d.cts", default: "./dist/topologies/partition/mod.cjs" } }, "./test": { import: { types: "./dist/test/mod.d.ts", default: "./dist/test/mod.js" }, require: { types: "./dist/test/mod.d.cts", default: "./dist/test/mod.cjs" } }, "./inspector": { import: { types: "./dist/inspector/mod.d.ts", default: "./dist/inspector/mod.js" }, require: { types: "./dist/inspector/mod.d.cts", default: "./dist/inspector/mod.cjs" } } }, engines: { node: ">=22.0.0" }, sideEffects: false, scripts: { dev: "pnpm build --watch", build: "tsup src/mod.ts src/client/mod.ts src/common/log.ts src/common/websocket.ts src/actor/errors.ts src/topologies/coordinate/mod.ts src/topologies/partition/mod.ts src/utils.ts src/driver-helpers/mod.ts src/driver-test-suite/mod.ts src/test/mod.ts src/inspector/mod.ts", "check-types": "tsc --noEmit", boop: "tsc --outDir dist/test -d", test: "vitest run", "test:watch": "vitest", "dump-openapi": "tsx scripts/dump-openapi.ts" }, dependencies: { "@hono/standard-validator": "^0.1.3", "cbor-x": "^1.6.0", "@rivetkit/fast-json-patch": "^3.1.2", invariant: "^2.2.4", nanoevents: "^9.1.0", "on-change": "^5.0.1", "p-retry": "^6.2.1", zod: "^3.25.76", "@hono/zod-openapi": "^0.19.10", hono: "^4.7.0" }, devDependencies: { "@hono/node-server": "^1.14.0", "@hono/node-ws": "^1.1.1", "@rivet-gg/actor-core": "^25.1.0", "@types/invariant": "^2", "@types/node": "^22.13.1", "@types/ws": "^8", "@vitest/ui": "3.1.1", "bundle-require": "^5.1.0", eventsource: "^3.0.5", tsup: "^8.4.0", tsx: "^4.19.4", typescript: "^5.7.3", vitest: "^3.1.1", ws: "^8.18.1" }, peerDependencies: { "@hono/node-server": "^1.14.0", "@hono/node-ws": "^1.1.1", eventsource: "^3.0.5", ws: "^8.0.0" }, peerDependenciesMeta: { "@hono/node-server": { optional: true }, "@hono/node-ws": { optional: true }, eventsource: { optional: true }, ws: { optional: true } }, stableVersion: "0.8.0" }; var VERSION = package_default.version; var _userAgent; function httpUserAgent() { if (_userAgent !== void 0) { return _userAgent; } let userAgent = `RivetKit/${VERSION}`; const navigatorObj = typeof navigator !== "undefined" ? navigator : void 0; if (navigatorObj == null ? void 0 : navigatorObj.userAgent) userAgent += ` ${navigatorObj.userAgent}`; _userAgent = userAgent; return userAgent; } function getEnvUniversal(key) { if (typeof Deno !== "undefined") { return Deno.env.get(key); } else if (typeof process !== "undefined") { return process.env[key]; } } // ../../core/dist/chunk-CLOGFICZ.js var LogLevels = { TRACE: 0, DEBUG: 1, INFO: 2, WARN: 3, ERROR: 4, CRITICAL: 5 }; var LevelNameMap = { 0: "TRACE", 1: "DEBUG", 2: "INFO", 3: "WARN", 4: "ERROR", 5: "CRITICAL" }; var LOG_LEVEL_COLORS = { [LogLevels.CRITICAL]: "\x1B[31m", // Red [LogLevels.ERROR]: "\x1B[31m", // Red [LogLevels.WARN]: "\x1B[33m", // Yellow [LogLevels.INFO]: "\x1B[32m", // Green [LogLevels.DEBUG]: "\x1B[36m", // Cyan [LogLevels.TRACE]: "\x1B[36m" // Cyan }; var RESET_COLOR = "\x1B[0m"; function stringify(...data) { let line = ""; for (let i = 0; i < data.length; i++) { const [key, valueRaw] = data[i]; let isNull = false; let valueString; if (valueRaw == null) { isNull = true; valueString = ""; } else { valueString = valueRaw.toString(); } if (valueString.length > 512 && key !== "msg" && key !== "error") valueString = `${valueString.slice(0, 512)}...`; const needsQuoting = valueString.indexOf(" ") > -1 || valueString.indexOf("=") > -1; const needsEscaping = valueString.indexOf('"') > -1 || valueString.indexOf("\\") > -1; valueString = valueString.replace(/\n/g, "\\n"); if (needsEscaping) valueString = valueString.replace(/["\\]/g, "\\$&"); if (needsQuoting || needsEscaping) valueString = `"${valueString}"`; if (valueString === "" && !isNull) valueString = '""'; if (LOGGER_CONFIG.enableColor) { let color = "\x1B[2m"; if (key === "level") { const level = LogLevels[valueString]; const levelColor = LOG_LEVEL_COLORS[level]; if (levelColor) { color = levelColor; } } else if (key === "msg") { color = "\x1B[32m"; } else if (key === "trace") { color = "\x1B[34m"; } line += `\x1B[0m\x1B[1m${key}\x1B[0m\x1B[2m=\x1B[0m${color}${valueString}${RESET_COLOR}`; } else { line += `${key}=${valueString}`; } if (i !== data.length - 1) { line += " "; } } return line; } function formatTimestamp(date) { const year = date.getUTCFullYear(); const month = String(date.getUTCMonth() + 1).padStart(2, "0"); const day = String(date.getUTCDate()).padStart(2, "0"); const hours = String(date.getUTCHours()).padStart(2, "0"); const minutes = String(date.getUTCMinutes()).padStart(2, "0"); const seconds = String(date.getUTCSeconds()).padStart(2, "0"); const milliseconds = String(date.getUTCMilliseconds()).padStart(3, "0"); return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`; } function castToLogValue(v) { if (typeof v === "string" || typeof v === "number" || typeof v === "boolean" || v === null || v === void 0) { return v; } if (v instanceof Error) { return String(v); } try { return JSON.stringify(v); } catch (e2) { return "[cannot stringify]"; } } var LOGGER_CONFIG = { enableColor: false, enableSpreadObject: false, enableErrorStack: false }; var Logger = class { constructor(name, level) { this.name = name; this.level = level; } log(level, message, ...args) { const record = { msg: message, args, level, loggerName: this.name, datetime: /* @__PURE__ */ new Date(), levelName: LevelNameMap[level] }; if (this.#shouldLog(level)) { this.#logRecord(record); } } #shouldLog(level) { return level >= LogLevels[this.level]; } #logRecord(record) { console.log(formatter(record)); } trace(message, ...args) { this.log(LogLevels.TRACE, message, ...args); } debug(message, ...args) { this.log(LogLevels.DEBUG, message, ...args); } info(message, ...args) { this.log(LogLevels.INFO, message, ...args); } warn(message, ...args) { this.log(LogLevels.WARN, message, ...args); } error(message, ...args) { this.log(LogLevels.ERROR, message, ...args); } critical(message, ...args) { this.log(LogLevels.CRITICAL, message, ...args); } }; var loggers = {}; function getLogger(name = "default") { const defaultLogLevelEnv = getEnvUniversal( "_LOG_LEVEL" ); const defaultLogLevel = _nullishCoalesce(defaultLogLevelEnv, () => ( "INFO")); if (!loggers[name]) { loggers[name] = new Logger(name, defaultLogLevel); } return loggers[name]; } function formatter(log) { const args = []; for (let i = 0; i < log.args.length; i++) { const logArg = log.args[i]; if (logArg && typeof logArg === "object") { for (const k in logArg) { const v = logArg[k]; pushArg(k, v, args); } } else { pushArg(`arg${i}`, logArg, args); } } const logTs = getEnvUniversal("_LOG_TIMESTAMP") === "1"; const logTarget = getEnvUniversal("_LOG_TARGET") === "1"; return stringify( ...logTs ? [["ts", formatTimestamp(/* @__PURE__ */ new Date())]] : [], ["level", LevelNameMap[log.level]], ...logTarget ? [["target", log.loggerName]] : [], ["msg", log.msg], ...args ); } function pushArg(k, v, args) { args.push([k, castToLogValue(v)]); } // src/log.ts var LOGGER_NAME = "driver-redis"; function logger() { return getLogger(LOGGER_NAME); } exports.InternalError = InternalError; exports.Unreachable = Unreachable; exports.InvalidEncoding = InvalidEncoding; exports.ConnNotFound = ConnNotFound; exports.IncorrectConnToken = IncorrectConnToken; exports.MessageTooLong = MessageTooLong; exports.MalformedMessage = MalformedMessage; exports.UserError = UserError; exports.InvalidRequest = InvalidRequest; exports.ActorNotFound = ActorNotFound; exports.ActorAlreadyExists = ActorAlreadyExists; exports.InvalidActionRequest = InvalidActionRequest; exports.InvalidParams = InvalidParams; exports.assertUnreachable = assertUnreachable; exports.deconstructError = deconstructError; exports.stringifyError = stringifyError; exports.noopNext = noopNext; exports.httpUserAgent = httpUserAgent; exports.getEnvUniversal = getEnvUniversal; exports.getLogger = getLogger; exports.KEYS = KEYS; exports.PUBSUB = PUBSUB; exports.logger = logger; //# sourceMappingURL=chunk-RIAC4EUG.cjs.map