ayanami
Version:
A better way to react with state
76 lines (75 loc) • 3 kB
JavaScript
import { __spreadArray } from "tslib";
import { InjectableFactory, Inject } from '@asuka/di';
import { SameScopeMetadataKey } from './same-scope-decorator';
import { CleanupSymbol } from '../../ssr/constants';
import { isSSREnabled } from '../../ssr/flag';
import { reqMap } from '../../ssr/express';
var map = new Map();
export var ayanamiInstances = new Map();
export function createOrGetInstanceInScope(constructor, scope) {
var instanceAtScope = getInstanceFrom(constructor, scope);
return instanceAtScope ? instanceAtScope : createInstanceInScope(constructor, scope);
}
function createInstanceInScope(constructor, scope) {
var paramTypes = Reflect.getMetadata('design:paramtypes', constructor) || [];
// parameters decorated by @Inject
var paramAnnotations = Reflect.getMetadata('parameters', constructor) || [];
var sameScopeParams = Reflect.getMetadata(SameScopeMetadataKey, constructor) || [];
var deps = paramTypes.map(function (type, index) {
if (sameScopeParams[index]) {
return createOrGetInstanceInScope(type, scope);
}
if (paramAnnotations[index] !== null) {
var metadata = paramAnnotations[index];
metadata = Array.isArray(metadata) ? metadata : [metadata];
var inject = metadata.find(function (factory) { return factory instanceof Inject; });
if (inject && inject.token) {
return InjectableFactory.getInstanceByToken(inject.token);
}
}
return InjectableFactory.getInstance(type);
});
var newInstance = new (constructor.bind.apply(constructor, __spreadArray([void 0], deps)))();
setInstanceInScope(constructor, scope, newInstance);
return newInstance;
}
function setInstanceInScope(constructor, scope, newInstance) {
var scopeMap = map.get(constructor) || new Map();
scopeMap.set(scope, newInstance);
map.set(constructor, scopeMap);
newInstance[CleanupSymbol] = function () {
newInstance.destroy();
scopeMap.delete(scope);
};
if (isSSREnabled()) {
ayanamiInstances.set(scope, (ayanamiInstances.get(scope) || []).concat(newInstance));
}
}
function getInstanceFrom(constructor, scope) {
var scopeMap = map.get(constructor);
return scopeMap && scopeMap.get(scope);
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function createScopeWithRequest(req, scope) {
if (!scope) {
return req;
}
if (reqMap.has(req)) {
var scopes = reqMap.get(req);
if (scopes.has(scope)) {
return scopes.get(scope);
}
else {
var reqScope = { req: req, scope: scope };
scopes.set(scope, reqScope);
return reqScope;
}
}
else {
var reqScopeMap = new Map();
var reqScope = { req: req, scope: scope };
reqScopeMap.set(scope, reqScope);
reqMap.set(req, reqScopeMap);
return reqScope;
}
}