MCPcopy Create free account
hub / github.com/hydro-dev/Hydro / serviceInstance

Function serviceInstance

packages/hydrooj/src/utils.ts:34–72  ·  view source on GitHub ↗
(ImplClass: T)

Source from the content-addressed store, hash-verified

32// EXPERIMENTAL: This function is subject to change
33// Don't try to understand this wrapper
34export function serviceInstance<T extends new (...args: any[]) => any>(ImplClass: T) {
35 let instance: any = null;
36 let state: 'pending' | 'initializing' | 'initialized' = 'pending';
37 const onClass: (symbol | string)[] = ['name', 'Config', 'inject', 'prototype'];
38 const name = ImplClass.name;
39
40 const proxyObj = new Proxy(ImplClass, {
41 get(_, key) {
42 if (key === 'Service') return proxyObj;
43 if (Reflect.has(ImplClass, key) || onClass.includes(key)) return Reflect.get(ImplClass, key);
44 if (state === 'pending') throw new Error(`${name} is not initialized yet (getting ${String(key)})`);
45 if (state === 'initializing') throw new Error(`${name} is still initializing (getting ${String(key)})`);
46 return Reflect.get(instance, key);
47 },
48 has(_, key) {
49 if (key === Symbol.for('hydro.initialize')) return state !== 'pending';
50 return Reflect.has(_, key);
51 },
52 construct(_, args, target) {
53 if (state !== 'pending') throw new Error(`${name} is already constructed`);
54 state = 'initializing';
55 const originalInit = ImplClass.prototype[Service.init];
56 if (originalInit) {
57 ImplClass.prototype[Service.init] = new Proxy(originalInit, {
58 apply(...applyArgs) {
59 const result = Reflect.apply(...applyArgs);
60 if (result instanceof Promise) result.then(() => { state = 'initialized'; });
61 else state = 'initialized';
62 return result;
63 },
64 });
65 }
66 instance = Reflect.construct(ImplClass, args, target);
67 if (!Reflect.has(ImplClass, Service.init)) state = 'initialized';
68 return instance;
69 },
70 }) as (T extends (new (...args: any[]) => infer R) ? (R & { Service: (new (...args: any[]) => R) }) : never);
71 return proxyObj;
72}
73
74export * from '@hydrooj/utils/lib/utils';

Callers 1

system.tsFile · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected