Skip to content

Commit

Permalink
feat: enhanced singleton interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
tada5hi committed Feb 4, 2024
1 parent 91161e6 commit 806203e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 23 deletions.
6 changes: 4 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ npm install singa --save
## Usage

```typescript
import { defineSingleton } from 'singa';

class Foo {

}

const singleton = createSingleton({
create() {
const singleton = defineSingleton({
factory() {
return new Foo();
},
});
Expand Down
18 changes: 13 additions & 5 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import type { Singleton, SingletonCreateContext } from './types';
import type { Factory, Singleton, SingletonCreateContext } from './types';

export function createSingleton<T = any>(context: SingletonCreateContext<T> = {}) : Singleton<T> {
export function defineSingleton<T = any>(context: SingletonCreateContext<T> = {}) : Singleton<T> {
let instance : T | undefined;

let factory : Factory<T> | undefined;
if (context.factory) {
factory = context.factory;
}

return {
use: () => {
if (typeof instance !== 'undefined') {
return instance;
}

if (typeof context.create !== 'undefined') {
instance = context.create();
if (typeof factory !== 'undefined') {
instance = factory();
return instance;
}

Expand All @@ -19,7 +24,10 @@ export function createSingleton<T = any>(context: SingletonCreateContext<T> = {}
set: (input: T) => {
instance = input;
},
isSet: () => typeof instance !== 'undefined',
setFactory: (input: Factory<T>) => {
factory = input;
},
has: () => typeof instance !== 'undefined',
reset: () => {
instance = undefined;
},
Expand Down
7 changes: 5 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
export type Factory<T = any> = () => T;

export type SingletonCreateContext<T> = {
create?: () => T,
factory?: Factory<T>,
name?: string
};

export type Singleton<T> = {
use: () => T,
set: (instance: T) => void,
setFactory: (factory: Factory<T>) => void,
reset: () => void,
isSet: () => boolean
has: () => boolean
};
37 changes: 23 additions & 14 deletions test/unit/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,55 @@
import { createSingleton } from '../../src';
import { defineSingleton } from '../../src';

class Foo {

}

describe('src/index.ts', () => {
it('should create singleton', () => {
const singleton = createSingleton({
create() {
const singleton = defineSingleton({
factory() {
return new Foo();
},
});

expect(singleton.isSet()).toBeFalsy();
expect(singleton.has()).toBeFalsy();
expect(singleton.use()).toBeInstanceOf(Foo);
expect(singleton.isSet()).toBeTruthy();
expect(singleton.has()).toBeTruthy();
});

it('should set singleton', () => {
const singleton = createSingleton();
expect(singleton.isSet()).toBeFalsy();
const singleton = defineSingleton();
expect(singleton.has()).toBeFalsy();
singleton.set(new Foo());
expect(singleton.use()).toBeInstanceOf(Foo);
expect(singleton.isSet()).toBeTruthy();
expect(singleton.has()).toBeTruthy();
});

it('should reset singleton', () => {
const singleton = createSingleton({
create() {
const singleton = defineSingleton({
factory() {
return new Foo();
},
});
expect(singleton.isSet()).toBeFalsy();
expect(singleton.has()).toBeFalsy();
expect(singleton.use()).toBeInstanceOf(Foo);
expect(singleton.isSet()).toBeTruthy();
expect(singleton.has()).toBeTruthy();

singleton.reset();
expect(singleton.isSet()).toBeFalsy();
expect(singleton.has()).toBeFalsy();
});

it('should set factory', () => {
const singleton = defineSingleton();

expect(singleton.has()).toBeFalsy();
singleton.setFactory(() => new Foo());
expect(singleton.use()).toBeInstanceOf(Foo);
expect(singleton.has()).toBeTruthy();
});

it('should throw error', () => {
const singleton = createSingleton();
const singleton = defineSingleton();

try {
singleton.use();
Expand Down

0 comments on commit 806203e

Please sign in to comment.