@rivetkit/redis
Version:
_Lightweight Libraries for Backends_
721 lines (688 loc) • 19.9 kB
JavaScript
;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