Skip to content

Commit

Permalink
feat: class based manifest
Browse files Browse the repository at this point in the history
- Related #500
- Related #501

[ci skip]
  • Loading branch information
tegefaulkes committed Feb 9, 2023
1 parent 266f2af commit d24df4c
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 274 deletions.
20 changes: 10 additions & 10 deletions src/RPC/RPCClient.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {
HandlerType,
JsonRpcRequestMessage,
ServerManifest,
MapWithHandlers,
StreamPairCreateCallback,
ClientManifest,
MapWithCallers,
} from './types';
import type { JSONValue } from 'types';
import type {
Expand All @@ -15,18 +15,18 @@ import type {
JsonRpcRequest,
JsonRpcResponse,
MiddlewareFactory,
MapHandlers,
MapCallers,
} from './types';
import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy';
import Logger from '@matrixai/logger';
import * as rpcErrors from './errors';
import * as rpcUtils from './utils';

// eslint-disable-next-line
interface RPCClient<M extends ServerManifest> extends CreateDestroy {}
interface RPCClient<M extends ClientManifest> extends CreateDestroy {}
@CreateDestroy()
class RPCClient<M extends ServerManifest> {
static async createRPCClient<M extends ServerManifest>({
class RPCClient<M extends ClientManifest> {
static async createRPCClient<M extends ClientManifest>({
manifest,
streamPairCreateCallback,
logger = new Logger(this.name),
Expand Down Expand Up @@ -113,13 +113,13 @@ class RPCClient<M extends ServerManifest> {
}

@ready(new rpcErrors.ErrorRpcDestroyed())
public get methods(): MapHandlers<M> {
return this.methodsProxy as MapHandlers<M>;
public get methods(): MapCallers<M> {
return this.methodsProxy as MapCallers<M>;
}

@ready(new rpcErrors.ErrorRpcDestroyed())
public get withMethods(): MapWithHandlers<M> {
return this.withMethodsProxy as MapWithHandlers<M>;
public get withMethods(): MapWithCallers<M> {
return this.withMethodsProxy as MapWithCallers<M>;
}

@ready(new rpcErrors.ErrorRpcDestroyed())
Expand Down
2 changes: 1 addition & 1 deletion src/RPC/RPCServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type {
UnaryHandlerImplementation,
} from './types';
import type { ReadableWritablePair } from 'stream/web';
import type { JSONValue, POJO } from '../types';
import type { JSONValue } from '../types';
import type { ConnectionInfo } from '../network/types';
import type { RPCErrorEvent } from './utils';
import type { MiddlewareFactory } from './types';
Expand Down
53 changes: 53 additions & 0 deletions src/RPC/callers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { JSONValue } from 'types';
import type { HandlerType } from './types';

abstract class Caller<
Input extends JSONValue = JSONValue,
Output extends JSONValue = JSONValue,
> {
protected _inputType: Input;
protected _outputType: Output;
// Need this to distinguish the classes when inferring types
abstract type: HandlerType;
}

class RawCaller extends Caller {
public type: 'RAW' = 'RAW' as const;
}

class DuplexCaller<
Input extends JSONValue = JSONValue,
Output extends JSONValue = JSONValue,
> extends Caller<Input, Output> {
public type: 'DUPLEX' = 'DUPLEX' as const;
}

class ServerCaller<
Input extends JSONValue = JSONValue,
Output extends JSONValue = JSONValue,
> extends Caller<Input, Output> {
public type: 'SERVER' = 'SERVER' as const;
}

class ClientCaller<
Input extends JSONValue = JSONValue,
Output extends JSONValue = JSONValue,
> extends Caller<Input, Output> {
public type: 'CLIENT' = 'CLIENT' as const;
}

class UnaryCaller<
Input extends JSONValue = JSONValue,
Output extends JSONValue = JSONValue,
> extends Caller<Input, Output> {
public type: 'UNARY' = 'UNARY' as const;
}

export {
Caller,
RawCaller,
DuplexCaller,
ServerCaller,
ClientCaller,
UnaryCaller,
};
4 changes: 2 additions & 2 deletions src/RPC/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ abstract class Handler<
Input extends JSONValue = JSONValue,
Output extends JSONValue = JSONValue,
> {
protected inputType: Input;
protected outputType: Output;
protected _inputType: Input;
protected _outputType: Output;

constructor(protected container: Container) {}
}
Expand Down
121 changes: 61 additions & 60 deletions src/RPC/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ import type {
WritableStream,
} from 'stream/web';
import type { Handler } from './handlers';
import type {
Caller,
RawCaller,
DuplexCaller,
ServerCaller,
ClientCaller,
UnaryCaller,
} from './callers';

/**
* This is the JSON RPC request object. this is the generic message type used for the RPC.
Expand Down Expand Up @@ -142,136 +150,127 @@ type MiddlewareFactory<FR, FW, RR, RW> = (header?: JsonRpcRequest) => {
reverse: ReadableWritablePair<RR, RW>;
};

type DuplexStreamCaller<
type RawCallerImplementation = (
params: JSONValue,
) => Promise<ReadableWritablePair<Uint8Array, Uint8Array>>;

type DuplexCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = () => Promise<ReadableWritablePair<O, I>>;

type ServerStreamCaller<
type ServerCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = (parameters: I) => Promise<ReadableStream<O>>;

type ClientStreamCaller<
type ClientCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = () => Promise<{
output: Promise<O>;
writable: WritableStream<I>;
}>;

type UnaryCaller<
type UnaryCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = (parameters: I) => Promise<O>;

type RawStreamCaller = (
params: JSONValue,
) => Promise<ReadableWritablePair<Uint8Array, Uint8Array>>;

type ConvertDuplexStreamHandler<T> = T extends DuplexHandlerImplementation<
infer I,
infer O
>
? DuplexStreamCaller<I, O>
type ConvertDuplexCaller<T> = T extends DuplexCaller<infer I, infer O>
? DuplexCallerImplementation<I, O>
: never;

type ConvertServerStreamHandler<T> = T extends ServerHandlerImplementation<
infer I,
infer O
>
? ServerStreamCaller<I, O>
type ConvertServerCaller<T> = T extends ServerCaller<infer I, infer O>
? ServerCallerImplementation<I, O>
: never;

type ConvertClientStreamHandler<T> = T extends ClientHandlerImplementation<
infer I,
infer O
>
? ClientStreamCaller<I, O>
type ConvertClientCaller<T> = T extends ClientCaller<infer I, infer O>
? ClientCallerImplementation<I, O>
: never;

type ConvertUnaryCaller<T> = T extends UnaryHandlerImplementation<
infer I,
infer O
>
? UnaryCaller<I, O>
type ConvertUnaryCaller<T> = T extends UnaryCaller<infer I, infer O>
? UnaryCallerImplementation<I, O>
: never;

type ConvertHandler<T> = T extends DuplexHandlerImplementation
? ConvertDuplexStreamHandler<T>
: T extends ServerHandlerImplementation
? ConvertServerStreamHandler<T>
: T extends ClientHandlerImplementation
? ConvertClientStreamHandler<T>
: T extends UnaryHandlerImplementation
type ConvertCaller<T extends Caller> = T extends DuplexCaller
? ConvertDuplexCaller<T>
: T extends ServerCaller
? ConvertServerCaller<T>
: T extends ClientCaller
? ConvertClientCaller<T>
: T extends UnaryCaller
? ConvertUnaryCaller<T>
: T extends RawHandlerImplementation
? RawStreamCaller
: T extends RawCaller
? RawCallerImplementation
: never;

type WithDuplexStreamCaller<
type WithDuplexCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = (f: (output: AsyncGenerator<O>) => AsyncGenerator<I>) => Promise<void>;

type WithServerStreamCaller<
type WithServerCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = (
parameters: I,
f: (output: AsyncGenerator<O>) => Promise<void>,
) => Promise<void>;

type WithClientStreamCaller<
type WithClientCallerImplementation<
I extends JSONValue = JSONValue,
O extends JSONValue = JSONValue,
> = (f: () => AsyncGenerator<I>) => Promise<O>;

type WithRawStreamCaller = (
type WithRawCallerImplementation = (
params: JSONValue,
f: (output: AsyncGenerator<Uint8Array>) => AsyncGenerator<Uint8Array>,
) => Promise<void>;

type ConvertWithDuplexStreamHandler<T> = T extends DuplexHandlerImplementation<
type ConvertWithDuplexStreamHandler<T> = T extends DuplexCaller<
infer I,
infer O
>
? WithDuplexStreamCaller<I, O>
? WithDuplexCallerImplementation<I, O>
: never;

type ConvertWithServerStreamHandler<T> = T extends ServerHandlerImplementation<
type ConvertWithServerStreamHandler<T> = T extends ServerCaller<
infer I,
infer O
>
? WithServerStreamCaller<I, O>
? WithServerCallerImplementation<I, O>
: never;

type ConvertWithClientStreamHandler<T> = T extends ClientHandlerImplementation<
type ConvertWithClientStreamHandler<T> = T extends ClientCaller<
infer I,
infer O
>
? WithClientStreamCaller<I, O>
? WithClientCallerImplementation<I, O>
: never;

type ConvertWithHandler<T> = T extends DuplexHandlerImplementation
type ConvertWithHandler<T> = T extends DuplexCaller
? ConvertWithDuplexStreamHandler<T>
: T extends ServerHandlerImplementation
: T extends ServerCaller
? ConvertWithServerStreamHandler<T>
: T extends ClientHandlerImplementation
: T extends ClientCaller
? ConvertWithClientStreamHandler<T>
: T extends RawHandlerImplementation
? WithRawStreamCaller
: T extends RawCaller
? WithRawCallerImplementation
: never;

type ServerManifest = Record<string, Handler>;
type ClientManifest = Record<string, Caller>;

// Type MapHandlers<T extends ServerManifest> = {
// [K in keyof T]: ConvertHandler<T[K]['handler']>;
// };
type HandlerType = 'DUPLEX' | 'SERVER' | 'CLIENT' | 'UNARY' | 'RAW';

// type MapWithHandlers<T extends ServerManifest> = {
// [K in keyof T]: ConvertWithHandler<T[K]['handler']>;
// };
type MapCallers<T extends ClientManifest> = {
[K in keyof T]: ConvertCaller<T[K]>;
};

type MapWithCallers<T extends ClientManifest> = {
[K in keyof T]: ConvertWithHandler<T[K]>;
};

export type {
JsonRpcRequestMessage,
Expand All @@ -292,6 +291,8 @@ export type {
StreamPairCreateCallback,
MiddlewareFactory,
ServerManifest,
// MapHandlers,
// MapWithHandlers,
ClientManifest,
HandlerType,
MapCallers,
MapWithCallers,
};
20 changes: 12 additions & 8 deletions src/RPC/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import type {
JsonRpcRequest,
JsonRpcResponse,
MiddlewareFactory,
HandlerType,
ClientManifest,
} from 'RPC/types';
import type { JSONValue } from '../types';
import { TransformStream } from 'stream/web';
Expand Down Expand Up @@ -562,13 +564,15 @@ function extractFirstMessageTransform<T extends JsonRpcMessage>(
return { headTransformStream, firstMessageProm: messageProm.p };
}

// Function getHandlerTypes(manifest: ServerManifest): Record<string, HandlerType> {
// const out: Record<string, HandlerType> = {};
// for (const [k, v] of Object.entries(manifest)) {
// out[k] = v.type;
// }
// return out;
// }
function getHandlerTypes(
manifest: ClientManifest,
): Record<string, HandlerType> {
const out: Record<string, HandlerType> = {};
for (const [k, v] of Object.entries(manifest)) {
out[k] = v.type;
}
return out;
}

const defaultMiddleware: MiddlewareFactory<
JsonRpcRequest,
Expand Down Expand Up @@ -642,7 +646,7 @@ export {
controllerTransformationFactory,
queueMergingTransformStream,
extractFirstMessageTransform,
// GetHandlerTypes,
getHandlerTypes,
defaultMiddleware,
defaultMiddlewareWrapper,
};
Loading

0 comments on commit d24df4c

Please sign in to comment.