novy-syndicate/experiments/i0.ts

144 lines
5.6 KiB
TypeScript

type ValidSelector = string | number | symbol;
export type EventMessage<Selector extends ValidSelector, Args extends any[]> = {
selector: Selector,
args: Args,
};
export type RequestMessage<Selector extends ValidSelector, Args extends any[], Result> = {
selector: Selector,
args: Args,
callback: (result: Result) => void,
};
export type Message<Selector extends ValidSelector, Args extends any[], Result> =
void extends Result ? EventMessage<Selector, Args> : RequestMessage<Selector, Args, Result>;
// export type EventMessage<Selector extends ValidSelector, Args extends any[]> = {
// selector: Selector,
// args: Args,
// };
//
// export type RequestMessage<Selector extends ValidSelector, Args extends any[], Result> = {
// selector: Selector,
// args: Args,
// callback: (result: Result) => void,
// };
//
// export type Message<Selector extends ValidSelector, Args extends any[], Result> =
// | EventMessage<Selector, Args>
// | RequestMessage<Selector, Args, Result>;
//
// type Messages1<I, ContextArgs extends any[]> = {
// [K in keyof I]: (I[K] extends (...args: [...ContextArgs, ...infer P]) => infer Q
// ? (void extends Q ? EventMessage<K, P> : RequestMessage<K, P, Q>)
// : never);
// };
type Messages1<I, ContextArgs extends any[]> = {
[K in keyof I]: (I[K] extends (...args: [...ContextArgs, ...infer P]) => infer Q
? Message<K, P, Q>
: never);
};
// type Proj1<I, K extends keyof I> = I[K];
// type Proj<I> = Proj1<I, keyof I>;
// export type Messages<I, ContextArgs extends any[] = []> = Proj<Messages1<I, ContextArgs>>;
export type Messages<I, ContextArgs extends any[] = []> = Messages1<I, ContextArgs>[keyof I];
export type Methods<M extends { selector: ValidSelector }, ContextArgs extends any[] = []> = {
[S in M['selector']]: (
M extends RequestMessage<S, infer P, infer R> ? (...args: [...ContextArgs, ...P]) => R :
M extends EventMessage<S, infer P> ? (... args: [...ContextArgs, ...P]) => void :
never);
};
// interface I {
// m1(a: string, b: number): boolean;
// m2(): void;
// m3(n: number): void;
// m4(x: [string, string]): { k: string, j: string };
// m5(a: string, b: string[]): number;
// v: string;
// w: number;
// };
//
// const a = { a(): string { console.log('in a'); return 'hi'; }, b(): void { console.log('in b'); } };
// type A = typeof a;
// type A1 = Messages<A>;
// type A2 = Methods<A1>;
// const b: A2 = a;
// export function performRequest<S extends ValidSelector, A extends any[], R, ContextArgs extends any[] = []>(
// i: { [s in S]: (...args: [...ContextArgs, ...A]) => R },
// m: { selector: S, args: A, callback: (result: R) => void },
// ...ctxt: ContextArgs)
// : R
// {
// const r = i[m.selector](...ctxt, ... m.args);
// m.callback(r);
// return r;
// }
// export function performEvent<S extends ValidSelector, A extends any[], ContextArgs extends any[] = []>(
// i: { [s in S]: (...args: [...ContextArgs, ...A]) => void },
// m: { selector: S, args: A },
// ...ctxt: ContextArgs)
// : void
// {
// i[m.selector](...ctxt, ...m.args);
// }
// function send<S extends ValidSelector, A extends any[], R>(
// i: { [s in S]: (...args: A) => R },
// m: { selector: S, args: A, callback?: (result: R) => void })
// : R;
// function send<S extends ValidSelector, A extends any[], R>(
// i: { [s in S]: (...args: A) => void },
// m: { selector: S, args: A })
// : void;
// function send<S extends ValidSelector, A extends any[], R>(
// i: { [s in S]: (...args: A) => R },
// m: { selector: S, args: A, callback?: (result: R) => void })
// : R
// // function send<I extends {}, M extends Messages<I>>(i: I, m: M): [M, I] extends [RequestMessage<any, any, infer R>, Methods<M>] ? R : void
// {
// const r = i[m.selector](... m.args);
// m.callback?.(r);
// return r;
// }
export function perform<I extends Methods<M, ContextArgs>, S extends ValidSelector, M extends RequestMessage<S, any, any>, ContextArgs extends any[] = []>(i: I, m: M, ...ctxt: ContextArgs)
: [M, I] extends [RequestMessage<S, any, infer R>, Methods<M>] ? R : void;
export function perform<I extends Methods<M, ContextArgs>, S extends ValidSelector, M extends EventMessage<S, any>, ContextArgs extends any[] = []>(i: I, m: M, ...ctxt: ContextArgs): void;
export function perform<I extends Methods<M, ContextArgs>, S extends ValidSelector, M extends RequestMessage<S, any, any>, R, ContextArgs extends any[] = []>(i: I, m: M, ...ctxt: ContextArgs): R
{
const r = i[m.selector](...ctxt, ... m.args);
m.callback?.(r);
return r;
}
// function perform<I extends Methods<M>, S extends ValidSelector, M extends RequestMessage<S, any, any>>(i: I, m: M)
// : [M, I] extends [RequestMessage<S, any, infer R>, Methods<M>] ? R : void;
// function perform<I extends Methods<M>, S extends ValidSelector, M extends EventMessage<S, any>>(i: I, m: M): void;
// function perform<I extends Methods<M>, S extends ValidSelector, M extends RequestMessage<S, any, any>>(i: I, m: M): R
// {
// const r = i[m.selector](... m.args);
// m.callback?.(r);
// return r;
// }
// const aa = perform(a, { selector: 'a', args: [], callback: (_r: string) => {} });
// const bb = perform(a, { selector: 'b', args: [], callback: (_r: void) => { console.log('bb'); } });
// const bb2 = perform(a, { selector: 'b', args: [] });
// // perform({ a(): string { return 'hi' } }, { selector: 'a', args: [123], callback: (_r: string) => {} });
// type Q = Messages<I>;
// type M = Methods<Q>;
// type N = M;
// type R = Messages<Methods<Q>>;
// type S = R;
// const x: Q = { selector: 'm2', args: [] };