need to impl swap

This commit is contained in:
Jacob Nguyen
2024-06-11 00:58:54 -05:00
parent 6227be632a
commit 4df491b2af
3 changed files with 49 additions and 20 deletions

View File

@@ -5,6 +5,7 @@
"main": "dist/index.js",
"scripts": {
"test": "vitest --run",
"tdd": "vitest",
"build": "tsc"
},
"devDependencies": {

View File

@@ -1,6 +1,9 @@
/**
* 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
*/
function hasCallableMethod(obj: object, name: PropertyKey) {
// object will always be defined
//@ts-ignore
return typeof obj[name] == 'function';
}
/**
@@ -21,17 +24,18 @@ export class Container {
this.hooks.get(name)!.push(callback);
}
private registerHooks(hookname: string, insert: object) {
if(hasCallableMethod(insert, hookname)) {
console.log(hookname)
//@ts-ignore
this.addHook(hookname, async () => await insert[hookname]())
this.addHook(hookname, () => insert[hookname]())
}
}
addSingleton(key: string, insert: object) {
if(typeof insert !== 'object') {
throw Error("Inserted object must be an object");
}
if(!this.__singletons.has(key)){
if(!this.__singletons.has(key)) {
this.registerHooks('init', insert)
this.registerHooks('dispose', insert)
this.__singletons.set(key, insert);
@@ -40,8 +44,8 @@ export class Container {
return false;
}
addWiredSingleton(key: string, fn: (c: Container) => object) {
const insert = fn(this);
addWiredSingleton(key: string, fn: (c: Record<string,unknown>) => object) {
const insert = fn(this.deps());
return this.addSingleton(key, insert);
}
@@ -70,5 +74,16 @@ export class Container {
await hookFunction();
}
}
}
swap(key: string, swp: object) {
if (typeof swp !== 'object') {
throw Error("Inserted object must be an object");
}
const existing = this.__singletons.get(key);
if (!existing) {
throw Error("No existing key to swap for " + key);
}
this.__singletons.set(key, swp);
}
}

View File

@@ -1,12 +1,17 @@
import { Container } from '../src/container';
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
describe('CoreContainer Tests', () => {
let coreContainer: Container;
let singletonWInit: { init: Mock<any, any>; value: string }
beforeEach(() => {
coreContainer = new Container({ autowire: false });
singletonWInit = {
value: 'singletonWithInit',
init: vi.fn()
}
});
it('Adding and getting singletons', () => {
@@ -99,22 +104,30 @@ describe('CoreContainer Tests', () => {
expect(coreContainer.isReady()).toBe(true);
});
it('Registering and executing hooks - init should be called once after ready', async () => {
let initCount = 0;
const singletonWithInit = {
value: 'singletonValueWithInit',
init: async () => {
initCount++;
}
};
coreContainer.addSingleton('singletonKeyWithInit', singletonWithInit);
coreContainer.addSingleton('singletonKeyWithInit', singletonWInit);
// Call ready twice to ensure hooks are executed only once
await coreContainer.ready();
await coreContainer.ready();
expect(initCount).toBe(1);
expect(singletonWInit.init).toHaveBeenCalledOnce();
});
it('should throw because not swapping anything', () => {
expect(() => coreContainer.swap('singletonKeyWithInit', singletonWInit)).toThrow()
})
it('should swap object with another', () => {
coreContainer.addSingleton('singleton', singletonWInit)
const singletonWithInit2 = {
value: 'singletonValueWithInit2',
init: vi.fn()
};
coreContainer.swap('singleton', singletonWithInit2)
expect(coreContainer.get('singleton')).toBe(singletonWithInit2)
})
it('should swap object, calling dispose hook', () => {
coreContainer.addSingleton('singleton', singletonWInit)
})
})