UNPKG

@decaf-ts/db-decorators

Version:

Agnostic database decorators and repository

174 lines 5.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Context = exports.DefaultContextFactory = void 0; const constants_1 = require("./constants.cjs"); const typed_object_accumulator_1 = require("typed-object-accumulator"); const logging_1 = require("@decaf-ts/logging"); /** * @description Default factory for creating context instances. * @summary A factory function that creates new Context instances with the provided repository flags. * It automatically adds a timestamp to the context and returns a properly typed context instance. * @const DefaultContextFactory * @memberOf module:db-decorators */ const DefaultContextFactory = (arg) => { return new Context().accumulate(Object.assign({}, arg, { timestamp: new Date(), logger: arg.logger || logging_1.Logging.get(), })); }; exports.DefaultContextFactory = DefaultContextFactory; /** * @description A context management class for handling repository operations. * @summary The Context class provides a mechanism for managing repository operations with flags, * parent-child relationships, and state accumulation. It allows for hierarchical context chains * and maintains operation-specific configurations while supporting type safety through generics. * * @template F - Type extending RepositoryFlags that defines the context configuration * * @param {ObjectAccumulator<F>} cache - The internal cache storing accumulated values * * @class * * @example * ```typescript * // Creating a new context with repository flags * const context = new Context<RepositoryFlags>(); * * // Accumulating values * const enrichedContext = context.accumulate({ * writeOperation: true, * affectedTables: ['users'], * operation: OperationKeys.CREATE * }); * * // Accessing values * const isWrite = enrichedContext.get('writeOperation'); // true * const tables = enrichedContext.get('affectedTables'); // ['users'] * ``` * * @mermaid * sequenceDiagram * participant C as Client * participant Ctx as Context * participant Cache as ObjectAccumulator * * C->>Ctx: new Context() * Ctx->>Cache: create cache * * C->>Ctx: accumulate(value) * Ctx->>Cache: accumulate(value) * Cache-->>Ctx: updated cache * Ctx-->>C: updated context * * C->>Ctx: get(key) * Ctx->>Cache: get(key) * alt Key exists in cache * Cache-->>Ctx: value * else Key not found * Ctx->>Ctx: check parent context * alt Parent exists * Ctx->>Parent: get(key) * Parent-->>Ctx: value * else No parent * Ctx-->>C: throw error * end * end * Ctx-->>C: requested value */ class Context { constructor(ctx) { this.cache = new typed_object_accumulator_1.ObjectAccumulator(); Object.defineProperty(this, "cache", { value: ctx ? ctx["cache"] : new typed_object_accumulator_1.ObjectAccumulator(), writable: false, enumerable: false, configurable: true, }); } static { this.factory = exports.DefaultContextFactory; } /** * @description Accumulates new values into the context. * @summary Merges the provided value object with the existing context state, * creating a new immutable cache state. */ accumulate(value) { Object.defineProperty(this, "cache", { value: this.cache.accumulate(value), writable: false, enumerable: false, configurable: true, }); return this; } get logger() { return this.cache.logger; } get timestamp() { return this.cache.timestamp; } /** * @description Retrieves a value from the context by key. * @param {string} key * @return {any} */ get(key) { try { return this.cache.get(key); } catch (e) { const parent = this.cache.parentContext; if (parent) return parent.get(key); throw e; } } /** * @description Creates a child context from another context */ static childFrom(context, overrides) { return Context.factory(Object.assign({}, context.cache, overrides || {})); } /** * @description Creates a new context from operation parameters */ static async from(operation, overrides, model, // eslint-disable-next-line @typescript-eslint/no-unused-vars ...args) { return Context.factory(Object.assign({}, constants_1.DefaultRepositoryFlags, overrides, { operation: operation, model: model, logger: overrides.logger || logging_1.Logging.get(), })); } /** * @description Prepares arguments for context operations */ static async args(operation, model, args, contextual, overrides) { const last = args.pop(); async function getContext() { if (contextual) return contextual.context(operation, overrides || {}, model, ...args); return Context.from(operation, overrides || {}, model, ...args); } let c; if (last) { if (last instanceof Context) { c = last; args.push(last); } else { args.push(last); c = (await getContext()); args.push(c); } } else { c = (await getContext()); args.push(c); } return { context: c, args: args }; } } exports.Context = Context; //# sourceMappingURL=Context.js.map