From 6bc748d2faa85e5f908a51cb08817b42a1711603 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Wed, 16 Aug 2023 23:14:28 -0500 Subject: [PATCH 1/3] feat: dispose hooks --- src/core/contracts/disposable.ts | 9 +++++ src/core/contracts/index.ts | 1 + src/core/ioc/container.ts | 43 +++++---------------- src/core/ioc/dependency-injection.ts | 2 +- src/core/ioc/hooks.ts | 45 ++++++++++++++++++++++ test/core/ioc.test.ts | 56 +++++++++++++++++++++++----- test/core/services.test.ts | 4 +- 7 files changed, 114 insertions(+), 46 deletions(-) create mode 100644 src/core/contracts/disposable.ts create mode 100644 src/core/ioc/hooks.ts diff --git a/src/core/contracts/disposable.ts b/src/core/contracts/disposable.ts new file mode 100644 index 00000000..42b0142c --- /dev/null +++ b/src/core/contracts/disposable.ts @@ -0,0 +1,9 @@ +import type { Awaitable } from '../../types/utility'; + +/** + * Represents a Disposable contract. + * Let dependencies implement this to dispose and cleanup. + */ +export interface Disposable { + dispose(): Awaitable; +} diff --git a/src/core/contracts/index.ts b/src/core/contracts/index.ts index f19756e0..7d123b1e 100644 --- a/src/core/contracts/index.ts +++ b/src/core/contracts/index.ts @@ -4,3 +4,4 @@ export * from './module-manager'; export * from './module-store'; export * from './init'; export * from './emitter'; +export * from './disposable' diff --git a/src/core/ioc/container.ts b/src/core/ioc/container.ts index 98bbd617..c97bfaf1 100644 --- a/src/core/ioc/container.ts +++ b/src/core/ioc/container.ts @@ -1,22 +1,24 @@ import { Container } from 'iti'; import { SernEmitter } from '../'; -import { isAsyncFunction } from 'node:util/types'; - import * as assert from 'node:assert'; import { Subject } from 'rxjs'; import { DefaultServices, ModuleStore } from '../_internal'; +import * as Hooks from './hooks' + /** - * Provides all the defaults for sern to function properly. - * The only user provided dependency needs to be @sern/client + * A semi-generic container that provides error handling, emitter, and module store. + * For the handler to operate correctly, The only user provided dependency needs to be @sern/client */ export class CoreContainer> extends Container { - private ready$ = new Subject(); - private beenCalled = new Set(); + private ready$ = new Subject(); constructor() { super(); + assert.ok(!this.isReady(), 'Listening for dispose & init should occur prior to sern being ready.'); - this.listenForInsertions(); + const { unsubscribe } = Hooks.createInitListener(this); + this.ready$ + .subscribe({ complete: unsubscribe }); (this as Container<{}, {}>) .add({ @@ -32,36 +34,11 @@ export class CoreContainer> extends Container this.callInitHooks(e)); - - this.ready$.subscribe({ - complete: unsubscriber, - }); - } - - private async callInitHooks(e: { key: keyof T; newContainer: T[keyof T] | null }) { - const dep = e.newContainer; - - assert.ok(dep); - //Ignore any dependencies that are not objects or array - if (typeof dep !== 'object' || Array.isArray(dep)) { - return; - } - if ('init' in dep && typeof dep.init === 'function' && !this.beenCalled.has(e.key)) { - isAsyncFunction(dep.init) ? await dep.init() : dep.init(); - this.beenCalled.add(e.key); - } - } - isReady() { return this.ready$.closed; } ready() { + this.ready$.complete(); this.ready$.unsubscribe(); } } diff --git a/src/core/ioc/dependency-injection.ts b/src/core/ioc/dependency-injection.ts index 7a67de5c..c8046267 100644 --- a/src/core/ioc/dependency-injection.ts +++ b/src/core/ioc/dependency-injection.ts @@ -1,5 +1,5 @@ import type { CoreDependencies, DependencyConfiguration, IntoDependencies } from '../../types/ioc'; -import { SernError, DefaultServices } from '../_internal'; +import { DefaultServices } from '../_internal'; import { useContainerRaw } from './base'; import { CoreContainer } from './container'; diff --git a/src/core/ioc/hooks.ts b/src/core/ioc/hooks.ts new file mode 100644 index 00000000..5b3e265b --- /dev/null +++ b/src/core/ioc/hooks.ts @@ -0,0 +1,45 @@ +import type { Disposable } from "../contracts"; +import type { CoreContainer } from "./container" + +interface HookEvent { + key : PropertyKey + newContainer: any +} +type HookName = 'init' | 'dispose'; + +export const createInitListener = (coreContainer : CoreContainer) => { + const initCalled = new Set(); + const hasCallableMethod = createPredicate(initCalled); + const unsubscribe = coreContainer.on('containerUpserted', async (event) => { + + if(isNotHookable(event)) { + return; + } + + if(hasCallableMethod('dispose', event)) { + coreContainer.addDisposer({ [event.key]: (l: Disposable) => l.dispose() }) + } + + if(hasCallableMethod('init', event)) { + await event.newContainer?.init(); + initCalled.add(event.key); + } + + }); + return { unsubscribe }; +} + +const isNotHookable = (hk: HookEvent) => { + return typeof hk.newContainer !== 'object' + || Array.isArray(hk.newContainer) + || hk.newContainer === null; +} + +const createPredicate = (called: Set) => { + return (hookName: HookName, event: T) => { + const hasMethod = Reflect.has(event.newContainer!, hookName); + const beenCalledOnce = !called.has(event.key) + + return hasMethod && beenCalledOnce + } +} diff --git a/test/core/ioc.test.ts b/test/core/ioc.test.ts index 94134442..57847f7b 100644 --- a/test/core/ioc.test.ts +++ b/test/core/ioc.test.ts @@ -1,23 +1,37 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { CoreContainer } from '../../src/core/ioc/container'; -import { CoreDependencies } from '../../src/core/ioc'; import { EventEmitter } from 'events'; -import { DefaultLogging, Init, Logging } from '../../src/core'; +import { DefaultLogging, Disposable, Init, Logging } from '../../src/core'; +import { CoreDependencies } from '../../src/types/ioc'; +import { promisify } from 'util'; describe('ioc container', () => { - let container: CoreContainer<{}>; - let initDependency: Logging & Init; + let container: CoreContainer<{}> = new CoreContainer(); + let dependency: Logging & Init & Disposable; beforeEach(() => { - initDependency = { + dependency = { init: vi.fn(), error(): void {}, warning(): void {}, info(): void {}, debug(): void {}, + dispose: vi.fn() }; container = new CoreContainer(); }); - + const wait = (seconds: number) => new Promise((resolve) => setTimeout(resolve, seconds)); + class DB implements Init, Disposable { + public connected = false + constructor() {} + async init() { + this.connected = true + await wait(10) + } + async dispose() { + await wait(20) + this.connected = false + } + } it('should be ready after calling container.ready()', () => { container.ready(); expect(container.isReady()).toBe(true); @@ -39,14 +53,36 @@ describe('ioc container', () => { } }); it('should init modules', () => { - container.upsert({ '@sern/logger': initDependency }); + container.upsert({ '@sern/logger': dependency }); + container.ready(); + expect(dependency.init).to.toHaveBeenCalledOnce(); + }); + it('should dispose modules', async () => { + + container.upsert({ '@sern/logger': dependency }) + container.ready(); - expect(initDependency.init).to.toHaveBeenCalledOnce(); + + // We need to access the dependency at least once to be able to dispose of it. + container.get('@sern/logger' as never); + await container.disposeAll(); + expect(dependency.dispose).toHaveBeenCalledOnce(); }); + it('should init and dispose', async () => { + container.add({ db: new DB() }) + container.ready() + const db = container.get('db' as never) as DB + expect(db.connected).toBeTruthy() + + await container.disposeAll(); + + expect(db.connected).toBeFalsy() + }) + it('should not lazy module', () => { - container.upsert({ '@sern/logger': () => initDependency }); + container.upsert({ '@sern/logger': () => dependency }); container.ready(); - expect(initDependency.init).toHaveBeenCalledTimes(0); + expect(dependency.init).toHaveBeenCalledTimes(0); }); }); diff --git a/test/core/services.test.ts b/test/core/services.test.ts index c8205ab8..fea60460 100644 --- a/test/core/services.test.ts +++ b/test/core/services.test.ts @@ -39,14 +39,14 @@ describe('services', () => { .map((path, i) => `${path}/${modules[i]}.js`); const metadata: CommandMeta[] = modules.map((cm, i) => ({ - id: Id.create(cm.name, cm.type), + id: Id.create(cm.name!, cm.type), isClass: false, fullPath: `${paths[i]}/${cm.name}.js`, })); const moduleManager = container.get('@sern/modules'); let i = 0; for (const m of modules) { - moduleManager.set(Id.create(m.name, m.type), paths[i]); + moduleManager.set(Id.create(m.name!, m.type), paths[i]); moduleManager.setMetadata(m, metadata[i]); i++; } From 4271b35160d8174c72219e0769328aa5cce26bd3 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Thu, 17 Aug 2023 01:04:22 -0500 Subject: [PATCH 2/3] build: unminify, add source map, deprecate useContainerRaw --- .gitignore | 2 + dependency-graph.svg | 1484 ----------------------------------- src/core/_internal.ts | 1 + src/core/ioc/base.ts | 2 + src/core/ioc/container.ts | 18 +- src/core/ioc/hooks.ts | 7 +- src/core/ioc/index.ts | 2 +- src/handlers/event-utils.ts | 3 +- src/index.ts | 3 + test/core/ioc.test.ts | 2 - tsup.config.js | 4 +- 11 files changed, 32 insertions(+), 1496 deletions(-) delete mode 100644 dependency-graph.svg diff --git a/.gitignore b/.gitignore index b6a7e19a..87a9da11 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,5 @@ dist .yalc yalc.lock + +*.svg diff --git a/dependency-graph.svg b/dependency-graph.svg deleted file mode 100644 index 2ae619b0..00000000 --- a/dependency-graph.svg +++ /dev/null @@ -1,1484 +0,0 @@ - - - - - - -dependency-cruiser output - - -cluster_src - -src - - -cluster_src/core - -core - - -cluster_src/core/contracts - -contracts - - -cluster_src/core/ioc - -ioc - - -cluster_src/core/structures - -structures - - -cluster_src/core/structures/services - -services - - -cluster_src/handlers - -handlers - - -cluster_src/types - -types - - - -src/core/_internal.ts - - -_internal.ts - - - - - -src/types/core-plugin.ts - - -core-plugin.ts - - - - - -src/core/_internal.ts->src/types/core-plugin.ts - - - - - -no-circular - - - -src/core/functions.ts - - -functions.ts - - - - - -src/core/_internal.ts->src/core/functions.ts - - - - - -no-circular - - - -src/core/id.ts - - -id.ts - - - - - -src/core/_internal.ts->src/core/id.ts - - - - - -no-circular - - - -src/core/module-loading.ts - - -module-loading.ts - - - - - -src/core/_internal.ts->src/core/module-loading.ts - - - - - -no-circular - - - -src/core/operators.ts - - -operators.ts - - - - - -src/core/_internal.ts->src/core/operators.ts - - - - - -no-circular - - - -src/core/predicates.ts - - -predicates.ts - - - - - -src/core/_internal.ts->src/core/predicates.ts - - - - - -src/core/structures/enums.ts - - -enums.ts - - - - - -src/core/_internal.ts->src/core/structures/enums.ts - - - - - -src/core/structures/module-store.ts - - -module-store.ts - - - - - -src/core/_internal.ts->src/core/structures/module-store.ts - - - - - -no-circular - - - -src/core/structures/services/index.ts - - -index.ts - - - - - -src/core/_internal.ts->src/core/structures/services/index.ts - - - - - -no-circular - - - -src/types/utility.ts - - -utility.ts - - - - - -src/types/core-plugin.ts->src/types/utility.ts - - - - - -no-circular - - - -src/types/core-modules.ts - - -core-modules.ts - - - - - -src/types/core-plugin.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/core/index.ts - - -index.ts - - - - - -src/types/core-plugin.ts->src/core/index.ts - - - - - -no-circular - - - -src/core/functions.ts->src/types/core-plugin.ts - - - - - -no-circular - - - -src/core/functions.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/core/structures/index.ts - - -index.ts - - - - - -src/core/functions.ts->src/core/structures/index.ts - - - - - -no-circular - - - -src/core/id.ts->src/core/structures/index.ts - - - - - -no-circular - - - -src/core/module-loading.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/types/core.ts - - -core.ts - - - - - -src/core/module-loading.ts->src/types/core.ts - - - - - -src/core/operators.ts->src/types/core-plugin.ts - - - - - -no-circular - - - -src/core/contracts/index.ts - - -index.ts - - - - - -src/core/operators.ts->src/core/contracts/index.ts - - - - - -src/core/structures/module-store.ts->src/core/contracts/index.ts - - - - - -src/core/structures/module-store.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/core/structures/services/error-handling.ts - - -error-handling.ts - - - - - -src/core/structures/services/index.ts->src/core/structures/services/error-handling.ts - - - - - -no-circular - - - -src/core/structures/services/logger.ts - - -logger.ts - - - - - -src/core/structures/services/index.ts->src/core/structures/services/logger.ts - - - - - -no-circular - - - -src/core/structures/services/module-manager.ts - - -module-manager.ts - - - - - -src/core/structures/services/index.ts->src/core/structures/services/module-manager.ts - - - - - -no-circular - - - -src/core/contracts/emitter.ts - - -emitter.ts - - - - - -src/core/contracts/emitter.ts->src/types/utility.ts - - - - - -no-circular - - - -src/types/utility.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/types/utility.ts->src/core/index.ts - - - - - -no-circular - - - -src/core/contracts/error-handling.ts - - -error-handling.ts - - - - - -src/core/contracts/index.ts->src/core/contracts/emitter.ts - - - - - -no-circular - - - -src/core/contracts/index.ts->src/core/contracts/error-handling.ts - - - - - -src/core/contracts/init.ts - - -init.ts - - - - - -src/core/contracts/index.ts->src/core/contracts/init.ts - - - - - -no-circular - - - -src/core/contracts/logging.ts - - -logging.ts - - - - - -src/core/contracts/index.ts->src/core/contracts/logging.ts - - - - - -src/core/contracts/module-manager.ts - - -module-manager.ts - - - - - -src/core/contracts/index.ts->src/core/contracts/module-manager.ts - - - - - -no-circular - - - -src/core/contracts/module-store.ts - - -module-store.ts - - - - - -src/core/contracts/index.ts->src/core/contracts/module-store.ts - - - - - -no-circular - - - -src/core/contracts/init.ts->src/types/utility.ts - - - - - -no-circular - - - -src/core/contracts/module-manager.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/core/contracts/module-manager.ts->src/core/structures/index.ts - - - - - -no-circular - - - -src/core/contracts/module-store.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/types/core-modules.ts->src/types/core-plugin.ts - - - - - -no-circular - - - -src/types/core-modules.ts->src/types/utility.ts - - - - - -no-circular - - - -src/types/core-modules.ts->src/core/index.ts - - - - - -no-circular - - - -src/core/structures/index.ts->src/core/structures/enums.ts - - - - - -src/core/structures/index.ts->src/core/structures/module-store.ts - - - - - -no-circular - - - -src/core/structures/index.ts->src/core/structures/services/index.ts - - - - - -no-circular - - - -src/core/structures/context.ts - - -context.ts - - - - - -src/core/structures/index.ts->src/core/structures/context.ts - - - - - -no-circular - - - -src/core/structures/sern-emitter.ts - - -sern-emitter.ts - - - - - -src/core/structures/index.ts->src/core/structures/sern-emitter.ts - - - - - -no-circular - - - -src/core/create-plugins.ts - - -create-plugins.ts - - - - - -src/core/create-plugins.ts->src/types/core-plugin.ts - - - - - -no-circular - - - -src/core/create-plugins.ts->src/core/structures/index.ts - - - - - -no-circular - - - -src/core/index.ts->src/core/contracts/index.ts - - - - - -no-circular - - - -src/core/index.ts->src/core/structures/index.ts - - - - - -no-circular - - - -src/core/index.ts->src/core/create-plugins.ts - - - - - -no-circular - - - -src/core/ioc/index.ts - - -index.ts - - - - - -src/core/index.ts->src/core/ioc/index.ts - - - - - -no-circular - - - -src/core/ioc/base.ts - - -base.ts - - - - - -src/core/ioc/index.ts->src/core/ioc/base.ts - - - - - -no-circular - - - -src/core/ioc/dependency-injection.ts - - -dependency-injection.ts - - - - - -src/core/ioc/index.ts->src/core/ioc/dependency-injection.ts - - - - - -no-circular - - - -src/types/ioc.ts - - -ioc.ts - - - - - -src/core/ioc/base.ts->src/types/ioc.ts - - - - - -no-circular - - - -src/core/ioc/container.ts - - -container.ts - - - - - -src/core/ioc/base.ts->src/core/ioc/container.ts - - - - - -no-circular - - - -src/core/ioc/base.ts->src/core/ioc/dependency-injection.ts - - - - - -no-circular - - - -src/types/ioc.ts->src/core/contracts/index.ts - - - - - -no-circular - - - -src/core/ioc/container.ts->src/core/_internal.ts - - - - - -no-circular - - - -src/core/ioc/container.ts->src/core/index.ts - - - - - -no-circular - - - -src/core/ioc/dependency-injection.ts->src/core/_internal.ts - - - - - -no-circular - - - -src/core/ioc/dependency-injection.ts->src/core/ioc/base.ts - - - - - -no-circular - - - -src/core/ioc/dependency-injection.ts->src/types/ioc.ts - - - - - -no-circular - - - -src/core/ioc/dependency-injection.ts->src/core/ioc/container.ts - - - - - -no-circular - - - -src/core/modules.ts - - -modules.ts - - - - - -src/core/modules.ts->src/core/_internal.ts - - - - - -src/core/modules.ts->src/types/core-plugin.ts - - - - - -src/core/modules.ts->src/types/utility.ts - - - - - -src/core/modules.ts->src/types/core-modules.ts - - - - - -src/core/modules.ts->src/core/structures/index.ts - - - - - -src/core/structures/core-context.ts - - -core-context.ts - - - - - -src/core/structures/context.ts->src/core/structures/core-context.ts - - - - - -no-circular - - - -src/core/structures/core-context.ts->src/core/_internal.ts - - - - - -no-circular - - - -src/core/structures/sern-emitter.ts->src/types/utility.ts - - - - - -no-circular - - - -src/core/structures/sern-emitter.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/core/structures/sern-emitter.ts->src/core/structures/index.ts - - - - - -no-circular - - - -src/core/structures/services/error-handling.ts->src/core/contracts/index.ts - - - - - -src/core/structures/services/logger.ts->src/core/contracts/index.ts - - - - - -src/core/structures/services/module-manager.ts->src/core/_internal.ts - - - - - -no-circular - - - -src/core/structures/services/module-manager.ts->src/core/id.ts - - - - - -no-circular - - - -src/core/structures/services/module-manager.ts->src/core/structures/enums.ts - - - - - -src/core/structures/services/module-manager.ts->src/core/contracts/index.ts - - - - - -src/core/structures/services/module-manager.ts->src/types/core-modules.ts - - - - - -no-circular - - - -src/handlers/_internal.ts - - -_internal.ts - - - - - -src/handlers/dispatchers.ts - - -dispatchers.ts - - - - - -src/handlers/_internal.ts->src/handlers/dispatchers.ts - - - - - -src/handlers/event-utils.ts - - -event-utils.ts - - - - - -src/handlers/_internal.ts->src/handlers/event-utils.ts - - - - - -src/handlers/dispatchers.ts->src/core/_internal.ts - - - - - -src/handlers/dispatchers.ts->src/types/core-plugin.ts - - - - - -src/handlers/dispatchers.ts->src/types/utility.ts - - - - - -src/handlers/dispatchers.ts->src/types/core-modules.ts - - - - - -src/handlers/dispatchers.ts->src/core/index.ts - - - - - -src/handlers/dispatchers.ts->src/handlers/event-utils.ts - - - - - -no-circular - - - -src/handlers/event-utils.ts->src/core/_internal.ts - - - - - -src/handlers/event-utils.ts->src/types/core-plugin.ts - - - - - -src/handlers/event-utils.ts->src/types/utility.ts - - - - - -src/handlers/event-utils.ts->src/types/core-modules.ts - - - - - -src/handlers/event-utils.ts->src/core/index.ts - - - - - -src/handlers/event-utils.ts->src/types/core.ts - - - - - -src/handlers/event-utils.ts->src/handlers/dispatchers.ts - - - - - -no-circular - - - -src/handlers/interaction-event.ts - - -interaction-event.ts - - - - - -src/handlers/interaction-event.ts->src/core/_internal.ts - - - - - -src/handlers/interaction-event.ts->src/core/index.ts - - - - - -src/handlers/interaction-event.ts->src/handlers/_internal.ts - - - - - -src/handlers/message-event.ts - - -message-event.ts - - - - - -src/handlers/message-event.ts->src/core/_internal.ts - - - - - -src/handlers/message-event.ts->src/core/index.ts - - - - - -src/handlers/message-event.ts->src/handlers/_internal.ts - - - - - -src/handlers/ready-event.ts - - -ready-event.ts - - - - - -src/handlers/ready-event.ts->src/core/_internal.ts - - - - - -src/handlers/ready-event.ts->src/core/contracts/index.ts - - - - - -src/handlers/ready-event.ts->src/core/structures/index.ts - - - - - -src/handlers/ready-event.ts->src/handlers/_internal.ts - - - - - -src/handlers/user-defined-events.ts - - -user-defined-events.ts - - - - - -src/handlers/user-defined-events.ts->src/core/_internal.ts - - - - - -src/handlers/user-defined-events.ts->src/core/structures/index.ts - - - - - -src/handlers/user-defined-events.ts->src/core/ioc/index.ts - - - - - -src/handlers/user-defined-events.ts->src/handlers/_internal.ts - - - - - -src/index.ts - - -index.ts - - - - - -src/index.ts->src/types/core-plugin.ts - - - - - -src/index.ts->src/types/utility.ts - - - - - -src/index.ts->src/types/core-modules.ts - - - - - -src/index.ts->src/core/index.ts - - - - - -src/index.ts->src/types/ioc.ts - - - - - -src/index.ts->src/types/core.ts - - - - - -src/index.ts->src/core/modules.ts - - - - - -src/sern.ts - - -sern.ts - - - - - -src/index.ts->src/sern.ts - - - - - -src/sern.ts->src/core/_internal.ts - - - - - -src/sern.ts->src/core/ioc/index.ts - - - - - -src/sern.ts->src/types/core.ts - - - - - -src/sern.ts->src/handlers/_internal.ts - - - - - -src/sern.ts->src/handlers/interaction-event.ts - - - - - -src/sern.ts->src/handlers/message-event.ts - - - - - -src/sern.ts->src/handlers/ready-event.ts - - - - - -src/sern.ts->src/handlers/user-defined-events.ts - - - - - -src/types/dependencies.d.ts - - -dependencies.d.ts - - - - - -src/types/dependencies.d.ts->src/types/ioc.ts - - - - - diff --git a/src/core/_internal.ts b/src/core/_internal.ts index 2899afc7..026d036f 100644 --- a/src/core/_internal.ts +++ b/src/core/_internal.ts @@ -7,3 +7,4 @@ export type { VoidResult } from '../types/core-plugin'; export { SernError } from './structures/enums'; export { ModuleStore } from './structures/module-store'; export * as DefaultServices from './structures/services'; +export { useContainerRaw } from './ioc/base' diff --git a/src/core/ioc/base.ts b/src/core/ioc/base.ts index efb25644..ca82206d 100644 --- a/src/core/ioc/base.ts +++ b/src/core/ioc/base.ts @@ -7,8 +7,10 @@ import { CoreContainer } from './container'; let containerSubject: CoreContainer>; /** + * @deprecated * Returns the underlying data structure holding all dependencies. * Exposes methods from iti + * Use the Service API. The container should be readonly */ export function useContainerRaw() { assert.ok( diff --git a/src/core/ioc/container.ts b/src/core/ioc/container.ts index c97bfaf1..0302afc1 100644 --- a/src/core/ioc/container.ts +++ b/src/core/ioc/container.ts @@ -1,5 +1,5 @@ import { Container } from 'iti'; -import { SernEmitter } from '../'; +import { Disposable, SernEmitter } from '../'; import * as assert from 'node:assert'; import { Subject } from 'rxjs'; import { DefaultServices, ModuleStore } from '../_internal'; @@ -34,9 +34,25 @@ export class CoreContainer> extends Container + 'dispose' in value + ? [key] + : []); + + for(const key of otherDisposables) { + this.addDisposer({ [key]: (dep: Disposable) => dep.dispose() } as never); + } + await super.disposeAll() + } ready() { this.ready$.complete(); this.ready$.unsubscribe(); diff --git a/src/core/ioc/hooks.ts b/src/core/ioc/hooks.ts index 5b3e265b..a1db322e 100644 --- a/src/core/ioc/hooks.ts +++ b/src/core/ioc/hooks.ts @@ -1,11 +1,10 @@ -import type { Disposable } from "../contracts"; import type { CoreContainer } from "./container" interface HookEvent { key : PropertyKey newContainer: any } -type HookName = 'init' | 'dispose'; +type HookName = 'init'; export const createInitListener = (coreContainer : CoreContainer) => { const initCalled = new Set(); @@ -16,10 +15,6 @@ export const createInitListener = (coreContainer : CoreContainer) => { return; } - if(hasCallableMethod('dispose', event)) { - coreContainer.addDisposer({ [event.key]: (l: Disposable) => l.dispose() }) - } - if(hasCallableMethod('init', event)) { await event.newContainer?.init(); initCalled.add(event.key); diff --git a/src/core/ioc/index.ts b/src/core/ioc/index.ts index 436b54e7..e89f8b6f 100644 --- a/src/core/ioc/index.ts +++ b/src/core/ioc/index.ts @@ -1,2 +1,2 @@ -export { useContainerRaw, makeDependencies } from './base'; +export { makeDependencies } from './base'; export { Service, Services, single, transient } from './dependency-injection'; diff --git a/src/handlers/event-utils.ts b/src/handlers/event-utils.ts index 8e5c8cf3..e61cc2ed 100644 --- a/src/handlers/event-utils.ts +++ b/src/handlers/event-utils.ts @@ -21,8 +21,9 @@ import { handleError, SernError, VoidResult, + useContainerRaw, } from '../core/_internal'; -import { Emitter, ErrorHandling, Logging, ModuleManager, useContainerRaw } from '../core'; +import { Emitter, ErrorHandling, Logging, ModuleManager } from '../core'; import { contextArgs, createDispatcher, dispatchMessage } from './dispatchers'; import { ObservableInput, pipe } from 'rxjs'; import { SernEmitter } from '../core'; diff --git a/src/index.ts b/src/index.ts index c9ffad7c..62bcbad8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -50,4 +50,7 @@ export { CommandExecutable, } from './core/modules'; +export { + useContainerRaw +} from './core/_internal' export { controller } from './sern'; diff --git a/test/core/ioc.test.ts b/test/core/ioc.test.ts index 57847f7b..48f4d8ad 100644 --- a/test/core/ioc.test.ts +++ b/test/core/ioc.test.ts @@ -3,7 +3,6 @@ import { CoreContainer } from '../../src/core/ioc/container'; import { EventEmitter } from 'events'; import { DefaultLogging, Disposable, Init, Logging } from '../../src/core'; import { CoreDependencies } from '../../src/types/ioc'; -import { promisify } from 'util'; describe('ioc container', () => { let container: CoreContainer<{}> = new CoreContainer(); @@ -62,7 +61,6 @@ describe('ioc container', () => { container.upsert({ '@sern/logger': dependency }) container.ready(); - // We need to access the dependency at least once to be able to dispose of it. container.get('@sern/logger' as never); await container.disposeAll(); diff --git a/tsup.config.js b/tsup.config.js index c9c1a1af..462b7ec5 100644 --- a/tsup.config.js +++ b/tsup.config.js @@ -4,7 +4,7 @@ const shared = { external: ['discord.js', 'iti'], platform: 'node', clean: true, - sourcemap: false, + sourcemap: true, treeshake: { moduleSideEffects: false, correctVarValueBeforeDeclaration: true, //need this to treeshake esm discord.js empty import @@ -19,6 +19,8 @@ export default defineConfig([ outDir: './dist', splitting: true, dts: true, + minify: false, + bundle: false, ...shared, }, // { From 5c2e8387630137dc9065afae75362fd9b432fd05 Mon Sep 17 00:00:00 2001 From: Jacob Nguyen <76754747+jacoobes@users.noreply.github.com> Date: Thu, 17 Aug 2023 10:37:54 -0500 Subject: [PATCH 3/3] fix regression of context and fix tsup build --- package.json | 2 +- src/core/structures/context.ts | 5 ++++- tsup.config.js | 31 ++----------------------------- 3 files changed, 7 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 58598c58..dddc7022 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "lint": "eslint src/**/*.ts", "format": "eslint src/**/*.ts --fix", "build:dev": "tsup --metafile", - "build:prod": "tsup --minify", + "build:prod": "tsup ", "prepare": "npm run build:prod", "pretty": "prettier --write .", "tdd": "vitest", diff --git a/src/core/structures/context.ts b/src/core/structures/context.ts index a009f901..d933fdd1 100644 --- a/src/core/structures/context.ts +++ b/src/core/structures/context.ts @@ -120,5 +120,8 @@ export class Context extends CoreContext { } function safeUnwrap(res: Result) { - return res.unwrap() + if(res.isOk()) { + return res.expect("Tried unwrapping message field: " + res) + } + return res.expectErr("Tried unwrapping interaction field" + res) } diff --git a/tsup.config.js b/tsup.config.js index 462b7ec5..812c2a60 100644 --- a/tsup.config.js +++ b/tsup.config.js @@ -17,35 +17,8 @@ export default defineConfig([ target: 'node18', tsconfig: './tsconfig.json', outDir: './dist', - splitting: true, - dts: true, minify: false, - bundle: false, + dts: true, ...shared, }, - // { - // format: 'cjs', - // esbuildPlugins: [ifdefPlugin({ variables: { MODE: 'cjs' }, verbose: true })], - // splitting: false, - // target: 'node18', - // tsconfig: './tsconfig-cjs.json', - // outDir: './dist/cjs', - // outExtension() { - // return { - // js: '.cjs', - // }; - // }, - // async onSuccess() { - // console.log('writing json commonjs'); - // await writeFile('./dist/cjs/package.json', JSON.stringify({ type: 'commonjs' })); - // }, - // ...shared, - // }, - // { - // dts: { - // only: true, - // }, - // entry: ['src/index.ts'], - // outDir: 'dist', - // }, -]); + ]);