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
JavaScript
;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