UNPKG

lakutata

Version:

An IoC-based universal application framework.

476 lines (424 loc) 14.1 kB
import { _ as t, a as e } from "./Package.1.mjs"; import { AsyncConstructor as s } from "../src/lib/base/async-constructor/AsyncConstructor.mjs"; import { Transient as i } from "../src/decorators/di/Lifetime.mjs"; import { MethodNotFoundException as r } from "../src/exceptions/MethodNotFoundException.mjs"; import { createContainer as o } from "../src/lib/ioc/DependencyInjectionContainer.mjs"; import { randomUUID as n } from "node:crypto"; import { GetConfigurableRecords as a, SetIdToInstance as c, SetConfigurableRecordsToInstance as l, SetConfigurableRecords as h, GetConfigurableRecordsFromInstance as d, GetIdFromInstance as m } from "../src/lib/base/internal/ConfigurableRecordsInjection.mjs"; import { GetObjectConfigurableProperties as p } from "../src/lib/base/internal/ObjectConfiguration.mjs"; import { GetObjectIsAutoload as u, GetObjectInjectItemsByPrototype as f } from "../src/lib/base/internal/ObjectInjection.mjs"; import { SetObjectContainerGetter as b } from "../src/lib/base/internal/ObjectContainer.mjs"; import { D as y, I as g } from "./Package.2.mjs"; import { ObjectConstructor as j } from "../src/lib/helpers/ObjectConstructor.mjs"; import { As as w } from "../src/lib/helpers/As.mjs"; import { DevNull as O } from "../src/lib/helpers/DevNull.mjs"; import { ObjectParentConstructors as P } from "../src/lib/helpers/ObjectParentConstructors.mjs"; import { DependencyInjectionException as C } from "../src/exceptions/di/DependencyInjectionException.mjs"; import { ConstructorSymbol as R } from "../src/lib/base/internal/ConstructorSymbol.mjs"; import { Expect as S } from "../src/decorators/dto/Expect.mjs"; import { IndexSignature as N } from "../src/decorators/dto/IndexSignature.mjs"; import { asValue as v, asClass as I } from "../src/lib/ioc/Resolvers.mjs"; import { GetObjectLifetime as E } from "../src/lib/base/internal/ObjectLifetime.mjs"; import { Accept as M } from "../src/decorators/dto/Accept.mjs"; import { listModules as A } from "../src/lib/ioc/ListModules.mjs"; import { pathToFileURL as T } from "url"; import { isClass as L } from "../src/lib/ioc/Utils.mjs"; import { IsEmptyObject as k } from "../src/lib/helpers/IsEmptyObject.mjs"; import { AppendObjectWeakRefs as D, GetObjectWeakRefs as U, ClearObjectWeakRefs as x } from "../src/lib/base/internal/ObjectWeakRefs.mjs"; var B; const _ = Symbol("OBJECT_ID"); let F = class LoadObjectOptions extends y { static { B = _; } }; t([ S(y.Alternatives(y.String(), y.Symbol()).optional()), e("design:type", Object) ], F.prototype, B, void 0); t([ S(y.Class((() => tt)).required()), e("design:type", Object) ], F.prototype, "class", void 0); F = t([ N(y.Any()) ], F); const G = Symbol("LAKUTATA.DI.CONTAINER.SYMBOL"); const Y = Symbol("LAKUTATA.DI.OWNER.SYMBOL"); class Container { #t; #e; #s; constructor(t, e) { this.#e = new Set; this.#s = false; this.injectionNames = new Set; this.parent = t; this.#t = t ? t.#t.createScope() : o({ injectionMode: "PROXY", strict: false }); if (this.parent) this.parent.#e.add(this); this.#t.register(G, v(this)); if (e) this.#t.register(Y, v(new WeakRef(e))); } async disposer(t) { try { await t.getMethod(H, false)(); } catch (t) { O(t); } } buildResolverOptions(t) { const e = E(t); return { lifetime: e, dispose: t => this.disposer(t) }; } async processResolved(t, e, s = {}) { const i = a(w(t.constructor), e); const r = y.isValid(t.constructor, y.Class(tt)); if (r) { c(w(t), e); l(w(t), { ...i, ...s }); } return Promise.resolve(t); } buildNameAndRegistrationPairFromOptions(t) { const e = {}; const s = t[_] ? t[_] : R(t.class); const i = { ...t, class: void 0 }; delete i.id; delete i.class; h(t.class, s, i); e[s] = I(t.class, this.buildResolverOptions(t.class)); return e; } async buildNameAndRegistrationPairFromGlob(t) { const e = []; A(t).forEach((t => { e.push(new Promise((e => { import(T(t.path).toString()).then((t => { Object.keys(t).forEach((s => { const i = t[s]; if (L(i) && y.isValid(i, y.Class(tt))) { const t = i; const s = {}; s[R(t)] = I(t, this.buildResolverOptions(t)); return e(s); } else { return e({}); } })); })).catch((() => e({}))); }))); })); const s = await Promise.all(e); let i = {}; s.forEach((t => { i = { ...i, ...t }; })); return i; } owner() { const t = this.#t.resolve(Y, { allowUnregistered: true }); return t ? t.deref() : undefined; } async load(t) { let e = {}; const s = []; t.forEach((t => { if (typeof t === "string") { s.push(new Promise(((e, s) => this.buildNameAndRegistrationPairFromGlob(t).then(e).catch(s)))); } else if (L(w(t))) { const s = { class: w(t) }; e = { ...e, ...this.buildNameAndRegistrationPairFromOptions(s) }; } else { const s = w(t); e = { ...e, ...this.buildNameAndRegistrationPairFromOptions(s) }; } })); if (s.length) { const t = await Promise.all(s); t.forEach((t => { e = { ...t, ...e }; })); } if (!k(e)) { Object.getOwnPropertyNames(e).forEach((t => this.injectionNames.add(t))); Object.getOwnPropertySymbols(e).forEach((t => this.injectionNames.add(t))); this.#t.register(e); } } async get(t, e = {}) { const s = typeof t === "function" ? R(t) : t; if (!this.#t.hasRegistration(s) && typeof t === "function" && u(w(t))) { await this.load([ { id: s, class: w(t) } ]); } return (this.#t.getRegistration(s)?.lifetime === "SINGLETON" || this.#t.getRegistration(s)?.lifetime === "MODULE_SINGLETON") && !this.injectionNames.has(s) && this.parent ? await this.parent.get(s, e) : await this.processResolved(this.#t.resolve(s), s, e); } has(t) { if (typeof t === "function") return this.#t.hasRegistration(R(t)); return this.#t.hasRegistration(t); } async set(t, e = {}) { await this.load([ { ...e, class: t } ]); return await this.get(t); } async setNamed(t, e, s = {}) { await this.load([ { ...s, class: e, [_]: t } ]); return await this.get(t); } async register(t, e = {}) { await this.load([ { ...e, class: t } ]); } async registerNamed(t, e, s = {}) { await this.load([ { ...s, class: e, [_]: t } ]); } async build(t, e = {}) { const s = await this.processResolved(this.#t.build(t, this.buildResolverOptions(t)), R(t), e); D(this.#t, s); return s; } createScope() { return new Container(this, this.owner()); } registerContainerToItsParent() { if (this.parent) this.parent.#e.add(this); } async clear() { const t = []; this.#e.forEach((e => t.push(new Promise(((t, s) => e.destroy().then(t).catch(s)))))); await Promise.all(t); await this.#t.dispose(); const e = []; U(this.#t).forEach((t => { let s = t.deref(); if (!s) return; if (s[H]) { e.push(new Promise((t => s ? Promise.resolve(s[H]()).then((() => { s = undefined; return t(); })).catch(O) : t()))); } })); await Promise.all(e); x(this.#t); } async destroy() { if (this.#s) return; this.#s = true; if (this.parent) this.parent.#e.delete(this); await this.clear(); } } t([ M(y.Array(y.Alternatives(F.Schema(), y.Class((() => tt)), y.Glob()))), e("design:type", Function), e("design:paramtypes", [ Array ]), e("design:returntype", Promise) ], Container.prototype, "load", null); const $ = Symbol("OBJECT.TYPE"); var q; (function(t) { t["Unknown"] = "Unknown"; t["Object"] = "Object"; t["Provider"] = "Provider"; t["Controller"] = "Controller"; t["Component"] = "Component"; t["Module"] = "Module"; })(q || (q = {})); function z(t) { return e => J(e, t); } function J(t, e) { Reflect.defineMetadata($, y.isValid(t, y.Class(tt)) ? e : q.Unknown, t); return t; } function V(t) { if (Reflect.hasOwnMetadata($, t)) return Reflect.getOwnMetadata($, t); let e = q.Unknown; for (const s of P(t)) { if (Reflect.hasOwnMetadata($, s)) { e = Reflect.getOwnMetadata($, s); break; } } J(t, e); return V(t); } var W; var K; const X = Symbol("__init"); const H = Symbol("__destroy"); const Q = Symbol("anonymous"); const Z = Symbol("OBJECT.SYMBOL.PROPERTY"); let tt = K = class BaseObject extends s { #i; #r; #o=n(); #n=false; async #a() { const t = d(this); const e = []; p(this).forEach(((s, i) => { if (g(i)) return; e.push(new Promise(((e, r) => { y.validateAsync(t[w(i)], s.schema, { targetName: i }).then((t => Promise.resolve(s.fn.bind(this)(t)).then((t => { this[i] = t; return e(); })).catch(r))).catch(r); }))); })); await Promise.all(e); } async #c() { const t = f(this); const e = []; t.forEach(((t, s) => { const i = t.name; e.push(new Promise(((e, r) => { this.#i.get(i).then((i => { Promise.resolve(t.transform(i)).then((t => { Reflect.set(this, s, t); return e(); })).catch(r); })).catch((t => r(new C("Unable to inject value for property {0} of {1} because: {2}", [ s, this.className, t.message ])))); }))); })); await Promise.all(e); } #l() { const t = m(this); this.#r = t ? t : Q; } constructor(t) { super((async () => { this.#l(); const t = Object.getOwnPropertyDescriptor(this, "then"); if (t) Object.defineProperty(this, "then", { enumerable: false }); await this[X](); })); this.#i = new Container(t[G], this); b(this, this.#i); } static get className() { return this.name; } get className() { return j(this).name; } async [X](...t) { this.#i.registerContainerToItsParent(); if (!this.#n) { await this.#c(); await this.#a(); this.#n = true; } for (const e of t) await e(); await this.init(); } async [H](...t) { await this.#i.destroy(); for (const e of t) await e(); await this.destroy(); } async init() {} async destroy() {} async getObject(t, e = {}) { return await this.#i.get(t, e); } async buildObject(t, e = {}) { return this.#i.build(t, e); } getParent() { return this.#i.parent?.owner(); } getModule() { let t = this.getParent(); while (t && V(w(j(t))) !== q.Module) { t = this.getParent(); } return w(t); } get $uuid() { return this.#o; } get $id() { return this.#r; } get $symbol() { if (Reflect.hasOwnMetadata(Z, this)) return Reflect.getOwnMetadata(Z, this); Reflect.defineMetadata(Z, Symbol(this.$uuid), this); return this.$symbol; } setProperty(t, e) { this[t] = e; } getProperty(t, e) { if (this.hasProperty(t)) return w(this[t]); return w(e); } hasProperty(t) { return typeof t === "string" ? this.propertyNames().includes(t) : this.propertySymbols().includes(t); } propertySymbols() { return Object.getOwnPropertySymbols(this); } propertyNames() { return Object.getOwnPropertyNames(this); } hasMethod(t) { const e = this.hasProperty(t); if (e) return false; return typeof this[t] === "function"; } getMethod(t, e = false) { if (this.hasMethod(t)) { return (...e) => this[t](...e); } else if (e) { throw new r('Method "{methodName}" not found in "{className}"', { methodName: t, className: this.constructor.name }); } else { return (...t) => O(...t); } } async dispose() { await this.destroy(); } }; tt = K = t([ i(), z(q.Object), e("design:paramtypes", [ Object ]) ], tt); export { tt as B, Container as C, z as D, V as G, F as L, q as O, J as S, X as _, H as a, _ as b, G as c, Q as d, Y as o };