-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathservice.ts
108 lines (100 loc) · 4.03 KB
/
service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import COM from '../communication.feature';
import type { AsyncApi, EnvironmentInstanceToken, EnvironmentTypes, ServiceComConfig } from '../com/types';
import type { RuntimeEngine } from '../runtime-engine';
import { CREATE_RUNTIME, REGISTER_VALUE } from '../symbols';
import type { EnvVisibility } from '../types';
import { AllEnvironments, Environment, normEnvVisibility, Universal } from './env';
import { FeatureOutput } from './output';
export type ServiceRuntime<T, ProvidedFrom> = ProvidedFrom extends Environment<string, EnvironmentTypes, 'single'>
? AsyncApi<T>
: ProvidedFrom extends Environment<string, EnvironmentTypes, 'multi', any>
? {
get(token: EnvironmentInstanceToken): AsyncApi<T>;
}
: AsyncApi<T>;
export class Service<
T,
PT,
ProvidedFrom extends EnvVisibility,
VisibleAt extends EnvVisibility,
RemoteAccess extends boolean
> extends FeatureOutput<T, PT, ProvidedFrom, VisibleAt, RemoteAccess> {
public static withType<T>() {
return {
defineEntity<E_ENV extends EnvVisibility>(providedFrom: E_ENV) {
return new Service<T, T, E_ENV, E_ENV, false>(providedFrom, providedFrom, false);
},
};
}
private constructor(
public providedFrom: ProvidedFrom,
public visibleAt: VisibleAt,
public remoteAccess: RemoteAccess,
private options: ServiceComConfig<T> = {}
) {
super(providedFrom, visibleAt, remoteAccess);
}
public allowRemoteAccess(options?: ServiceComConfig<T>) {
return new Service<T, ServiceRuntime<T, ProvidedFrom>, ProvidedFrom, Environment, true>(
this.providedFrom,
AllEnvironments,
true,
options
);
}
public [REGISTER_VALUE](
runtimeEngine: RuntimeEngine,
providedValue: T | undefined,
inputValue: PT,
featureID: string,
entityKey: string
) {
if (this.remoteAccess) {
const { communication } = runtimeEngine.get(COM).api;
const serviceKey = runtimeEngine.entityID(featureID, entityKey);
const providedFrom = normEnvVisibility(this.providedFrom);
const localEnv = communication.getEnvironmentName();
if (providedFrom.has(localEnv) || providedFrom.has(Universal.env)) {
if (!providedValue) {
throw new Error('service is not provide in runtime');
}
communication.registerAPI({ id: serviceKey }, providedValue);
return providedValue;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return inputValue || this.getApiProxy(runtimeEngine, serviceKey);
}
return providedValue;
}
public [CREATE_RUNTIME](context: RuntimeEngine, featureID: string, entityKey: string) {
if (this.remoteAccess) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return this.getApiProxy(context, context.entityID(featureID, entityKey));
}
}
public getApiProxy(context: RuntimeEngine, serviceKey: string): any {
const { communication } = context.get(COM).api;
const instanceId = getSingleInstanceId(this.providedFrom);
if (instanceId) {
return communication.apiProxy<T>({ id: instanceId }, { id: serviceKey }, this.options);
} else {
return {
get: (token: EnvironmentInstanceToken) => {
return communication.apiProxy<T>(token, { id: serviceKey }, this.options);
},
};
}
}
}
function getSingleInstanceId(providedFrom: unknown): string | void {
if (isSingleInstance(providedFrom)) {
return providedFrom.env;
}
}
function isSingleInstance(providedFrom: unknown): providedFrom is Environment<string, EnvironmentTypes, 'single'> {
return (
!!providedFrom &&
(providedFrom as Environment).endpointType &&
(providedFrom as Environment).endpointType === 'single'
);
}