@wooksjs/event-core
Version:
@wooksjs/event-core
262 lines (253 loc) • 7.08 kB
JavaScript
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const crypto = __toESM(require("crypto"));
const node_async_hooks = __toESM(require("node:async_hooks"));
const __prostojs_logger = __toESM(require("@prostojs/logger"));
//#region packages/event-core/src/context-injector.ts
/**
* ContextInjector
*
* Provides a way to inject context
* Usefull when working with opentelemetry spans
*/
var ContextInjector = class {
with(name, attributes, cb) {
const fn = typeof attributes === "function" ? attributes : cb;
return fn();
}
hook(method, name, route) {}
};
let ci = new ContextInjector();
function getContextInjector() {
return ci;
}
function replaceContextInjector(newCi) {
ci = newCi;
}
//#endregion
//#region packages/event-core/src/hook.ts
function attachHook(target, opts, name) {
Object.defineProperty(target, name || "value", {
get: opts.get,
set: opts.set
});
return target;
}
//#endregion
//#region packages/event-core/src/context.ts
/**
* AsyncLocalStorage instance
*
* Use on your own risk only if you know what you're doing
*/
const asyncStorage = new node_async_hooks.AsyncLocalStorage();
/**
* Create Wooks Context
*/
function createAsyncEventContext(data) {
const newContext = { ...data };
const cc = asyncStorage.getStore();
if (cc && typeof cc === "object" && cc.event?.type) newContext.parentCtx = cc;
const ci$1 = getContextInjector();
return (cb) => asyncStorage.run(newContext, () => ci$1.with("Event:start", { eventType: newContext.event.type }, cb));
}
/**
* Use Wooks Context
*/
function useAsyncEventContext(expectedTypes) {
let cc = asyncStorage.getStore();
if (!cc) throw new Error("Event context does not exist at this point.");
if (expectedTypes || typeof expectedTypes === "string") {
const type = cc.event.type;
const types = typeof expectedTypes === "string" ? [expectedTypes] : expectedTypes;
if (!types.includes(type)) if (cc.parentCtx?.event.type && types.includes(cc.parentCtx.event.type)) cc = cc.parentCtx;
else throw new Error(`Event context type mismatch: expected ${types.map((t) => `"${t}"`).join(", ")}, received "${type}"`);
}
return _getCtxHelpers(cc);
}
/**
*
* @param cc
* @returns
*/
function _getCtxHelpers(cc) {
/**
* Hook to an event store property
*
* @param key store property key
* @returns a hook { value: <prop value>, hook: (key2: keyof <prop value>) => { value: <nested prop value> }, ... }
*/
function store(key) {
const obj = {
value: null,
hook,
init,
set: setNested,
get: getNested,
has: hasNested,
del: delNested,
entries,
clear
};
attachHook(obj, {
set: (v) => {
set(key, v);
},
get: () => get(key)
});
function init(key2, getter) {
if (hasNested(key2)) return getNested(key2);
return setNested(key2, getter());
}
function hook(key2) {
const obj$1 = {
value: null,
isDefined: null
};
attachHook(obj$1, {
set: (v) => setNested(key2, v),
get: () => getNested(key2)
});
attachHook(obj$1, { get: () => hasNested(key2) }, "isDefined");
return obj$1;
}
function setNested(key2, v) {
if (obj.value === void 0) obj.value = {};
obj.value[key2] = v;
return v;
}
function delNested(key2) {
setNested(key2, void 0);
}
function getNested(key2) {
return (obj.value || {})[key2];
}
function hasNested(key2) {
return (obj.value || {})[key2] !== void 0;
}
function entries() {
return Object.entries(obj.value || {});
}
function clear() {
obj.value = {};
}
return obj;
}
/**
* Get event context object
*
* @returns whole context object
*/
function getCtx() {
return cc;
}
/**
* Get value of event store property
*
* @param key property name
* @returns value of property by name
*/
function get(key) {
return getCtx()[key];
}
/**
* Set value of event store property
*
* @param key property name
* @param v property value
*/
function set(key, v) {
getCtx()[key] = v;
}
const hasParentCtx = () => !!cc.parentCtx;
return {
getCtx,
store,
getStore: get,
setStore: set,
setParentCtx: (parentCtx) => {
cc.parentCtx = parentCtx;
},
hasParentCtx,
getParentCtx: () => {
if (!hasParentCtx()) throw new Error("Parent context is not available");
return _getCtxHelpers(cc.parentCtx);
}
};
}
//#endregion
//#region packages/event-core/src/composables/event-id.ts
function useEventId() {
const { store } = useAsyncEventContext();
const { init } = store("event");
const getId = () => init("id", () => (0, crypto.randomUUID)());
return { getId };
}
//#endregion
//#region packages/event-core/src/event-logger.ts
var EventLogger = class extends __prostojs_logger.ProstoLogger {
constructor(eventId, opts) {
const _opts = opts || { level: 4 };
if (!_opts.mapper) _opts.mapper = (msg) => ({
...msg,
eventId
});
if (!_opts.transports) _opts.transports = [(0, __prostojs_logger.createConsoleTransort)({ format: __prostojs_logger.coloredConsole })];
super(_opts, opts?.topic || "event");
}
};
//#endregion
//#region packages/event-core/src/composables/event-logger.ts
function useEventLogger(topic) {
const { getId } = useEventId();
const { store, getCtx } = useAsyncEventContext();
const { init } = store("event");
const ctx = getCtx();
const get = () => init("logger", () => new EventLogger(getId(), ctx.options.eventLogger));
return topic ? get().createTopic(topic) : get();
}
//#endregion
//#region packages/event-core/src/composables/route-params.ts
function useRouteParams() {
const { store } = useAsyncEventContext();
const params = store("routeParams").value || {};
function get(name) {
return params[name];
}
return {
params,
get
};
}
//#endregion
exports.ContextInjector = ContextInjector;
exports.EventLogger = EventLogger;
exports.asyncStorage = asyncStorage;
exports.attachHook = attachHook;
exports.createAsyncEventContext = createAsyncEventContext;
exports.getContextInjector = getContextInjector;
exports.replaceContextInjector = replaceContextInjector;
exports.useAsyncEventContext = useAsyncEventContext;
exports.useEventId = useEventId;
exports.useEventLogger = useEventLogger;
exports.useRouteParams = useRouteParams;