UNPKG

life

Version:

Life.js is the first fullstack framework to build agentic web applications. It is minimal, extensible, and typesafe. Well, everything you love.

412 lines (383 loc) 13.9 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _chunk6PEHRAEPjs = require('./chunk-6PEHRAEP.js'); // shared/error.ts var _zod = require('zod'); var _zod2 = _interopRequireDefault(_zod); // shared/prefixed-id.ts var _cuid2 = require('@paralleldrive/cuid2'); function newId(prefix, length = 12) { const cuid2 = _cuid2.init.call(void 0, { length }); return `${prefix}_${cuid2()}`; } _chunk6PEHRAEPjs.__name.call(void 0, newId, "newId"); // shared/error.ts var lifeErrorCodes = { /** * Used when the user sends or the server returns invalid data. */ Validation: { retriable: false, defaultMessage: "Invalid data provided.", httpEquivalent: 400 }, /** * Used when the user is not authorized to access a resource */ Forbidden: { retriable: false, defaultMessage: "Not allowed to access this resource.", httpEquivalent: 403 }, /** * Used when an operation took too long and timed out. */ Timeout: { retriable: true, defaultMessage: "Operation timed out.", httpEquivalent: 504 }, /** * Used when the user has exceeded the rate limit for a resource. */ RateLimit: { retriable: true, defaultMessage: "Rate limit exceeded.", httpEquivalent: 429 }, /** * Used when a resource was not found or missing. */ NotFound: { retriable: false, defaultMessage: "Resource not found.", httpEquivalent: 404 }, /** * Used when an operation is about to conflict with another. * E.g., a version mismatch, a unique constraint violation, etc. */ Conflict: { retriable: false, defaultMessage: "Operation conflicted.", httpEquivalent: 409 }, /** * Used when an upstream service or resource fails. * E.g., a database connection error, an OpenAI API downtime, etc. */ Upstream: { retriable: true, defaultMessage: "Upstream error.", httpEquivalent: 502 }, /** * Used when an unexpected error is thrown. */ Unknown: { retriable: false, defaultMessage: "Unknown error.", httpEquivalent: 500 }, /** * Used to obfuscate internal errors publicly. * Prevents leaking sensitive informations to public consumers. */ Internal: { retriable: true, defaultMessage: "Internal error.", httpEquivalent: 500 } }; var LifeErrorClass = (_class = class _LifeErrorClass extends Error { static { _chunk6PEHRAEPjs.__name.call(void 0, this, "LifeErrorClass"); } __init() {this.name = "LifeError"} /** * The unique identifier of the error. */ __init2() {this.id = newId("error")} /** * The error code. * Can be one of: * - Validation * - Forbidden * - Timeout * - RateLimit * - NotFound * - Conflict * - Upstream * - Unknown * - Internal */ /** * Additional pieces of evidence attached to the error. */ /** * Used to indicate whether the operation that caused the error can be retried. */ /** * The suggested time (in ms) to wait before retrying the operation that caused the error. * Check `.retriable` first to ensure the operation can be retried. */ /** * The HTTP status code equivalent to the error code. */ /** * Used to indicate whether this error is public and can be safely sent to external clients. */ constructor({ code, message, attributes, retryAfterMs, cause, isPublic = false }) { const definition = lifeErrorCodes[code]; super(_nullishCoalesce(message, () => ( definition.defaultMessage)));_class.prototype.__init.call(this);_class.prototype.__init2.call(this);; this.code = code; this.retriable = definition.retriable; this.attributes = _nullishCoalesce(attributes, () => ( {})); this.retryAfterMs = retryAfterMs; this.httpEquivalent = definition.httpEquivalent; this.isPublic = isPublic; this.cause = cause; if (Error.captureStackTrace) Error.captureStackTrace(this, _LifeErrorClass); } toJSON() { return { id: this.id, code: this.code, message: this.message, retriable: this.retriable, attributes: this.attributes, retryAfterMs: this.retryAfterMs, httpEquivalent: this.httpEquivalent, stack: this.stack, cause: this.cause }; } }, _class); function lifeError(params) { if (params.code === "Unknown" && isLifeError(params.cause)) { return params.cause; } return new LifeErrorClass(params); } _chunk6PEHRAEPjs.__name.call(void 0, lifeError, "lifeError"); function isLifeError(error) { return error instanceof LifeErrorClass; } _chunk6PEHRAEPjs.__name.call(void 0, isLifeError, "isLifeError"); var serializedLifeErrorSchema = _zod2.default.object({ _isLifeError: _zod2.default.literal(true), id: _zod2.default.string(), code: _zod2.default.string(), stack: _zod2.default.string().optional(), message: _zod2.default.string(), attributes: _zod2.default.object().optional(), retryAfterMs: _zod2.default.number().optional(), isPublic: _zod2.default.boolean().optional(), cause: _zod2.default.any().optional() }); function lifeErrorToObject(error) { if (!(error instanceof LifeErrorClass)) throw lifeError({ code: "Validation", message: "The provided object is not a LifeError instance." }); return { _isLifeError: true, id: error.id, code: error.code, stack: error.stack, message: error.message, attributes: error.attributes, retryAfterMs: error.retryAfterMs, cause: error.cause }; } _chunk6PEHRAEPjs.__name.call(void 0, lifeErrorToObject, "lifeErrorToObject"); function lifeErrorFromObject(obj) { const { success: success2, data } = serializedLifeErrorSchema.safeParse(obj); if (!success2) throw lifeError({ code: "Validation", message: "The provided object is not a serialized LifeError." }); const err = lifeError({ code: data.code, message: data.message, retryAfterMs: data.retryAfterMs, attributes: data.attributes, cause: data.cause, isPublic: data.isPublic }); err.id = data.id; err.stack = data.stack; return err; } _chunk6PEHRAEPjs.__name.call(void 0, lifeErrorFromObject, "lifeErrorFromObject"); function obfuscateLifeError(error) { if (process.env.NODE_ENV === "development") return error; let publicError; if (error.isPublic) { publicError = lifeError({ code: error.code, message: error.message, attributes: error.attributes, retryAfterMs: error.retryAfterMs, cause: error.cause }); } else publicError = lifeError({ code: "Internal" }); publicError.isPublic = true; publicError.id = error.id; publicError.stack = void 0; return publicError; } _chunk6PEHRAEPjs.__name.call(void 0, obfuscateLifeError, "obfuscateLifeError"); // shared/operation.ts var OPERATION_RESULT = Symbol("OperationResult"); var isResult = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (value) => Array.isArray(value) && OPERATION_RESULT in value, "isResult"); var success = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (data) => { const result = Object.assign([void 0, isResult(data) ? data[1] : data], { [OPERATION_RESULT]: true }); return result; }, "success"); var failure = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (errorOrDef) => { const error = isLifeError(errorOrDef) ? errorOrDef : lifeError(errorOrDef); const result = Object.assign([error, void 0], { [OPERATION_RESULT]: true }); return result; }, "failure"); function attempt(task) { const handleError = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (error) => { if (isLifeError(error)) return failure(error); return failure({ code: "Unknown", cause: error }); }, "handleError"); const handleResult = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (result) => { if (isResult(result)) return result; return success(result); }, "handleResult"); if (task instanceof Promise) return task.then(handleResult).catch(handleError); try { const result = task(); if (result instanceof Promise) return result.then(handleResult).catch(handleError); return handleResult(result); } catch (error) { return handleError(error); } } _chunk6PEHRAEPjs.__name.call(void 0, attempt, "attempt"); var dataOrThrow = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (result) => { if (!isResult(result)) return result; const [error, data] = result; if (error) throw error; return data; }, "dataOrThrow"); var functionToPublic = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (func) => { const unsafeFunc = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (...args) => { try { const result = func(...args); if (result instanceof Promise) { return result.then((awaitedResult) => { if (isResult(awaitedResult)) { const [errAsync, dataAsync] = awaitedResult; if (errAsync) throw errAsync; return dataAsync; } return awaitedResult; }).catch((error) => { throw error; }); } if (isResult(result)) { const [errorSync, dataSync] = result; if (errorSync) throw errorSync; return dataSync; } return result; } catch (error) { if (error instanceof Error) throw error; throw error; } }, "unsafeFunc"); return unsafeFunc; }, "functionToPublic"); var instanceToPublic = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (instance) => { const wrappedCache = /* @__PURE__ */ new WeakMap(); const createProxy = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (target) => { if (wrappedCache.has(target)) return wrappedCache.get(target); const proxy = new Proxy(target, { get(innerTarget, prop) { if (prop === "safe") return innerTarget; const value = innerTarget[prop]; if (typeof value === "function") { return functionToPublic(value.bind(innerTarget)); } if (value !== null && typeof value === "object") { const shouldSkip = value instanceof Date || value instanceof RegExp || value instanceof Promise || Array.isArray(value) || value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet || ArrayBuffer.isView(value); if (shouldSkip) return value; return createProxy(value); } return value; } }); wrappedCache.set(target, proxy); return proxy; }, "createProxy"); return createProxy(instance); }, "instanceToPublic"); var classToPublic = /* @__PURE__ */ _chunk6PEHRAEPjs.__name.call(void 0, (InternalClass) => new Proxy(InternalClass, { construct(target, args) { const instance = new target(...args); return instanceToPublic(instance); } }), "classToPublic"); function toPublic(input) { if (typeof input === "function" && input.prototype && input.prototype.constructor === input) { return classToPublic(input); } if (typeof input === "function") { return functionToPublic(input); } if (typeof input === "object" && input !== null) { return instanceToPublic(input); } return input; } _chunk6PEHRAEPjs.__name.call(void 0, toPublic, "toPublic"); var resultSchema = _zod2.default.tuple([_zod2.default.null().or(_zod2.default.undefined()), _zod2.default.unknown()]).or(_zod2.default.tuple([_zod2.default.instanceof(LifeErrorClass), _zod2.default.null().or(_zod2.default.undefined())])).transform((val) => { const [error, data] = val; if (error) return failure(error); return success(data); }); function serializeResult(result) { if (!isResult(result)) { throw new Error("The provided value is not an OperationResult"); } return { _isOperationResult: true, // Extract the tuple without the symbol to avoid recursive serialization result: [_optionalChain([result, 'optionalAccess', _ => _[0]]), _optionalChain([result, 'optionalAccess', _2 => _2[1]])] }; } _chunk6PEHRAEPjs.__name.call(void 0, serializeResult, "serializeResult"); function deserializeResult(obj) { if (!obj._isOperationResult) { throw new Error("The provided object is not a serialized OperationResult"); } if (!Array.isArray(obj.result) || obj.result.length !== 2) { throw new Error("The provided object is not a serialized OperationResult"); } const [error, data] = obj.result; if (error) return failure(error); return success(data); } _chunk6PEHRAEPjs.__name.call(void 0, deserializeResult, "deserializeResult"); exports.newId = newId; exports.lifeError = lifeError; exports.isLifeError = isLifeError; exports.lifeErrorToObject = lifeErrorToObject; exports.lifeErrorFromObject = lifeErrorFromObject; exports.obfuscateLifeError = obfuscateLifeError; exports.isResult = isResult; exports.success = success; exports.failure = failure; exports.attempt = attempt; exports.dataOrThrow = dataOrThrow; exports.toPublic = toPublic; exports.resultSchema = resultSchema; exports.serializeResult = serializeResult; exports.deserializeResult = deserializeResult; //# sourceMappingURL=chunk-22H3U7VV.js.map