@snap/camera-kit
Version:
Camera Kit Web
72 lines • 2.98 kB
JavaScript
import { isMemoized, memoize } from "../common/memoize";
import { PartialContainer } from "./PartialContainer";
export const CONTAINER = "$container";
export class Container {
static provides(fnOrContainer) {
if (fnOrContainer instanceof PartialContainer)
return new Container({}).provides(fnOrContainer);
if (fnOrContainer instanceof Container)
return new Container({}).provides(fnOrContainer);
return new Container({}).provides(fnOrContainer);
}
constructor(factories) {
this.factories = {};
for (const k in factories) {
const fn = factories[k];
if (isMemoized(fn))
this.factories[k] = fn;
else
this.factories[k] = memoize(fn);
}
}
copy(scopedServices) {
const factories = Object.assign({}, this.factories);
(scopedServices || []).forEach((token) => {
factories[token] = this.factories[token].delegate;
});
return new Container(factories);
}
get(token) {
if (token === CONTAINER)
return this;
const factory = this.factories[token];
if (!factory) {
throw new Error(`[Container::get] Could not find Service for Token "${String(token)}". This should've caused a ` +
"compile-time error. If the Token is 'undefined', check all your calls to the Injectable " +
"function. Make sure you define dependencies using string literals or string constants that are " +
"definitely initialized before the call to Injectable.");
}
return factory(this);
}
run(fnOrContainer) {
if (fnOrContainer instanceof PartialContainer) {
const runnableContainer = this.provides(fnOrContainer);
for (const token of fnOrContainer.getTokens()) {
runnableContainer.get(token);
}
}
else {
this.provides(fnOrContainer).get(fnOrContainer.token);
}
return this;
}
provides(fnOrContainer) {
if (fnOrContainer instanceof PartialContainer || fnOrContainer instanceof Container) {
const factories = fnOrContainer instanceof PartialContainer ? fnOrContainer.getFactories(this) : fnOrContainer.factories;
return new Container(Object.assign(Object.assign({}, this.factories), factories));
}
return this.providesService(fnOrContainer);
}
providesService(fn) {
const token = fn.token;
const dependencies = fn.dependencies;
const factory = memoize((container) => {
return fn(...dependencies.map((t) => {
return t === token ? this.get(t) : container.get(t);
}));
});
const factories = Object.assign(Object.assign({}, this.factories), { [token]: factory });
return new Container(factories);
}
}
//# sourceMappingURL=Container.js.map