Skip to content

Commit

Permalink
feat: defer
Browse files Browse the repository at this point in the history
  • Loading branch information
jackmellis committed Oct 7, 2024
1 parent fce0d91 commit 1d12a96
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 3 deletions.
75 changes: 75 additions & 0 deletions src/__tests__/defer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import _jpex, { Jpex } from '..';

let jpex: Jpex;
type Foo = (v: string) => string;
type FooAsync = (v: string) => Promise<string>;
type Bar = string;

beforeEach(() => {
jpex = _jpex.extend();

jpex.factory<Foo>((bar: Bar) => (v: string) => `${v}foo${bar}`);
jpex.factory<Bar>(() => 'bar');
jpex.factory<FooAsync>((foo: Foo) => async (v: string) => `${foo(v)}async`);
});

it('returns a function', () => {
const foo = jpex.defer<Foo>();

expect(foo).toBeInstanceOf(Function);
});

it('does not resolve any dependencies at creation time', () => {
jpex.defer<Foo>();

expect(jpex.$$factories[jpex.infer<Foo>()]?.resolved).toBeFalsy();
expect(jpex.$$resolved[jpex.infer<Foo>()]).toBeFalsy();
expect(jpex.$$factories[jpex.infer<Bar>()]?.resolved).toBeFalsy();
expect(jpex.$$resolved[jpex.infer<Bar>()]).toBeFalsy();
});

it('resolves and calls the factory at call time', () => {
const foo = jpex.defer<Foo>();

const result = foo('provided');

expect(result).toBe('providedfoobar');
});

it('works with async factories', async () => {
const foo = jpex.defer<FooAsync>();

const result = await foo('provided');

expect(result).toBe('providedfoobarasync');
});

it('caches the inner function', () => {
const spyFactory = jest.fn(() => () => 'spy');

jpex.factory<Foo>(spyFactory);

const foo = jpex.defer<Foo>();

expect(spyFactory).not.toHaveBeenCalled();

foo('provided');

expect(spyFactory).toHaveBeenCalledTimes(1);

foo('provided');

expect(spyFactory).toHaveBeenCalledTimes(1);

jpex.clearCache();

foo('provided');
expect(spyFactory).toHaveBeenCalledTimes(2);
});

it('keeps a list of deferred dependencies', () => {
jpex.defer<Foo>();

expect(jpex.$$deps).toContain(jpex.infer<Foo>());
expect(jpex.$$deps).toContain(jpex.infer<Bar>());
});
5 changes: 5 additions & 0 deletions src/defer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Dependency, JpexInstance } from './types';

export default function defer(this: JpexInstance, name: Dependency) {
return this.encase([name], (fn) => fn);
}
2 changes: 2 additions & 0 deletions src/makeJpex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { constant, factory, service, alias, factoryAsync } from './registers';
import { resolve, getFactory, resolveAsync } from './resolver';
import encase from './encase';
import clearCache from './clearCache';
import defer from './defer';

const defaultConfig = {
lifecycle: 'container' as const,
Expand Down Expand Up @@ -35,6 +36,7 @@ export default function makeJpex(
resolve,
resolveAsync,
encase,
defer,
clearCache,
extend(config?: SetupConfig): IJpex {
return makeJpex(config, this);
Expand Down
3 changes: 3 additions & 0 deletions src/types/JpexInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ export interface JpexInstance {
fn: F,
): ReturnType<F> & { encased: F };

defer<T extends AnyFunction>(): T;
defer<T extends AnyFunction>(name: Dependency): T;

raw(name: Dependency): AnyFunction;
raw<T>(): AnyFunction<T>;
raw<T>(name: Dependency): AnyFunction<T>;
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1275,9 +1275,9 @@
chalk "^4.0.0"

"@jpex-js/babel-plugin@^1.3.0":
version "1.8.0"
resolved "https://registry.yarnpkg.com/@jpex-js/babel-plugin/-/babel-plugin-1.8.0.tgz#c0318f45762fdccc440e851be04c7e7216e6564b"
integrity sha512-B5SGp2PcdCXWgob3eV2YmA205xqG8qxJuYg3ZFiKvFGJCMvjqnrHx8HAG9NH43IFGry3rt3lCZCiito/dEy9jw==
version "1.9.0"
resolved "https://registry.yarnpkg.com/@jpex-js/babel-plugin/-/babel-plugin-1.9.0.tgz#758fe356db62179465c88f05fc0b5e2df9dbbaac"
integrity sha512-q4LIMl/CW5BoReuYfKvNGSxXAmR/bmqM2ekmJlUmG/aFCgEZIYh5FhLYGU4cQ1dcBcIZBB94m2d9+Esu36RBng==

"@marionebl/sander@^0.6.0":
version "0.6.1"
Expand Down

0 comments on commit 1d12a96

Please sign in to comment.