@nmtjs/client 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common.js +5 -0
- package/dist/common.js.map +1 -0
- package/dist/runtime.js +95 -0
- package/dist/runtime.js.map +1 -0
- package/dist/static.js +22 -0
- package/dist/static.js.map +1 -0
- package/dist/types.js.map +1 -0
- package/lib/common.ts +12 -9
- package/lib/runtime.ts +156 -0
- package/lib/static.ts +61 -0
- package/lib/types.ts +85 -18
- package/package.json +15 -14
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
- package/dist/lib/client-runtime.js +0 -87
- package/dist/lib/client-runtime.js.map +0 -1
- package/dist/lib/client-static.js +0 -21
- package/dist/lib/client-static.js.map +0 -1
- package/dist/lib/client.js +0 -94
- package/dist/lib/client.js.map +0 -1
- package/dist/lib/common.js +0 -9
- package/dist/lib/common.js.map +0 -1
- package/dist/lib/stream.js +0 -51
- package/dist/lib/stream.js.map +0 -1
- package/dist/lib/subscription.js +0 -10
- package/dist/lib/subscription.js.map +0 -1
- package/dist/lib/transport.js +0 -4
- package/dist/lib/transport.js.map +0 -1
- package/dist/lib/types.js.map +0 -1
- package/dist/lib/utils.js +0 -40
- package/dist/lib/utils.js.map +0 -1
- package/index.ts +0 -6
- package/lib/client-runtime.ts +0 -185
- package/lib/client-static.ts +0 -91
- package/lib/client.ts +0 -140
- package/lib/stream.ts +0 -72
- package/lib/subscription.ts +0 -12
- package/lib/transport.ts +0 -40
- package/lib/utils.ts +0 -65
- /package/dist/{lib/types.js → types.js} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/client-runtime.ts"],"sourcesContent":["import type {\n TEventContract,\n TServiceContract,\n TSubscriptionContract,\n} from '@nmtjs/contract'\nimport { type BaseType, NeverType, type t } from '@nmtjs/type'\nimport { type Compiled, compile } from '@nmtjs/type/compiler'\n\nimport { Client, type ClientOptions } from './client.ts'\nimport type { Subscription } from './subscription.ts'\nimport type { ClientTransport } from './transport.ts'\nimport type { ClientCallOptions, InputType, OutputType } from './types.ts'\n\ntype CompiledContract<T extends TServiceContract = TServiceContract> = {\n compiled: Map<BaseType, Compiled>\n contract: T\n}\n\ntype ClientServicesResolved<Services extends ClientServices> = {\n [K in keyof Services]: {\n [P in keyof Services[K]['contract']['procedures']]: {\n contract: Services[K]['contract']['procedures'][P]\n input: InputType<\n t.infer.decoded<Services[K]['contract']['procedures'][P]['input']>\n >\n output: OutputType<\n t.infer.decoded<Services[K]['contract']['procedures'][P]['output']>\n >\n events: Services[K]['contract']['procedures'][P] extends TSubscriptionContract\n ? {\n [KE in keyof Services[K]['contract']['procedures'][P]['events']]: {\n payload: OutputType<\n t.infer.decoded<\n Services[K]['contract']['procedures'][P]['events'][KE]['payload']\n >\n >\n }\n }\n : {}\n }\n }\n}\n\ntype ClientServices = Record<string, CompiledContract>\n\ntype ClientCallers<Services extends ClientServicesResolved<ClientServices>> = {\n [K in keyof Services]: {\n [P in keyof Services[K]]: (\n ...args: Services[K][P]['input'] extends NeverType\n ? [options?: ClientCallOptions]\n : t.infer.input.decoded<\n Services[K][P]['contract']['input']\n > extends undefined\n ? [data?: Services[K][P]['input'], options?: ClientCallOptions]\n : [data: Services[K][P]['input'], options?: ClientCallOptions]\n ) => Promise<\n Services[K][P] extends TSubscriptionContract\n ? {\n payload: Services[K][P]['output'] extends never\n ? undefined\n : t.infer.decoded<Services[K][P]['output']>\n subscription: Subscription<{\n [KE in keyof Services[K][P]['events']]: [\n t.infer.decoded<Services[K][P]['events'][KE]['payload']>,\n ]\n }>\n }\n : Services[K][P]['output'] extends never\n ? void\n : Services[K][P]['output']\n >\n }\n}\n\nexport class RuntimeClient<Services extends ClientServices> extends Client {\n $types!: ClientServicesResolved<Services>\n #callers: ClientCallers<this['$types']>\n\n constructor(\n protected readonly contracts: Services,\n options: ClientOptions,\n ) {\n super(\n options,\n Object.values(contracts).map((s) => s.contract.name),\n )\n\n const callers = {} as any\n for (const [serviceKey, service] of Object.entries(contracts)) {\n service.contract.procedures\n\n callers[serviceKey] = {} as any\n\n for (const procedureName in service.contract.procedures) {\n const { input, output } = service.contract.procedures[procedureName]\n\n function decodeOutput(data) {\n if (output instanceof NeverType) return undefined\n const compiled = service.compiled.get(output)!\n const result = compiled.decodeSafe(data)\n if (result.success) {\n return result.value\n } else {\n console.dir(result.error)\n throw new Error('Failed to decode output', {\n cause: result.error,\n })\n }\n }\n\n callers[serviceKey][procedureName] = this.createCaller(\n service.contract.name,\n procedureName,\n {\n timeout: service.contract.timeout,\n transformInput: (data: any) => {\n if (input instanceof NeverType) return undefined\n const compiled = service.compiled.get(input)!\n const result = compiled.encodeSafe(data)\n if (result.success) {\n return result.value\n } else {\n console.dir(result.error)\n throw new Error('Failed to encode input', {\n cause: result.error,\n })\n }\n },\n transformOutput: (data: any) => {\n if (\n service.contract.procedures[procedureName].type ===\n 'neemata:subscription'\n ) {\n data.payload = decodeOutput(data.payload)\n return data\n } else {\n return decodeOutput(data)\n }\n },\n },\n )\n }\n }\n this.#callers = callers\n }\n\n get call() {\n return this.#callers\n }\n\n protected checkTransport(transport: ClientTransport): void {\n for (const { contract } of Object.values(this.contracts)) {\n if (!contract.transports[transport.type])\n throw new Error(\n `Transport [${transport.type}] not supported for service [${contract.name}]`,\n )\n }\n }\n}\n\nexport const compileContract = <T extends TServiceContract>(\n contract: T,\n): CompiledContract<T> => {\n const compiled = new Map<BaseType, Compiled>()\n\n for (const procedure of Object.values(contract.procedures)) {\n const { input, output } = procedure\n if (procedure.type === 'neemata:subscription') {\n const { events } = procedure as TSubscriptionContract\n for (const event of Object.values(events) as TEventContract[]) {\n compiled.set(event.payload, compile(event.payload))\n }\n }\n compiled.set(input, compile(input))\n compiled.set(output, compile(output))\n }\n for (const event of Object.values(contract.events)) {\n compiled.set(event.payload, compile(event.payload))\n }\n\n return {\n compiled,\n contract,\n }\n}\n"],"names":["NeverType","compile","Client","RuntimeClient","$types","constructor","contracts","options","Object","values","map","s","contract","name","callers","serviceKey","service","entries","procedures","procedureName","input","output","decodeOutput","data","undefined","compiled","get","result","decodeSafe","success","value","console","dir","error","Error","cause","createCaller","timeout","transformInput","encodeSafe","transformOutput","type","payload","call","checkTransport","transport","transports","compileContract","Map","procedure","events","event","set"],"mappings":"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"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Client } from "./client.js";
|
|
2
|
-
export class StaticClient extends Client {
|
|
3
|
-
$types;
|
|
4
|
-
#callers;
|
|
5
|
-
constructor(services, options){
|
|
6
|
-
super(options, Object.values(services));
|
|
7
|
-
const callers = {};
|
|
8
|
-
for (const [serviceKey, serviceName] of Object.entries(services)){
|
|
9
|
-
callers[serviceKey] = new Proxy(Object(), {
|
|
10
|
-
get: (target, prop, receiver)=>{
|
|
11
|
-
if (prop === 'then') return target;
|
|
12
|
-
return this.createCaller(serviceName, prop);
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
this.#callers = callers;
|
|
17
|
-
}
|
|
18
|
-
get call() {
|
|
19
|
-
return this.#callers;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/client-static.ts"],"sourcesContent":["import type { TServiceContract, TSubscriptionContract } from '@nmtjs/contract'\nimport type { NeverType, t } from '@nmtjs/type'\nimport { Client, type ClientOptions } from './client.ts'\nimport type { Subscription } from './subscription.ts'\nimport type { ClientCallOptions, InputType, OutputType } from './types.ts'\n\ntype ClientServices = Record<string, TServiceContract>\n\ntype ClientServicesResolved<Services extends ClientServices> = {\n [K in keyof Services]: {\n [P in keyof Services[K]['procedures']]: {\n contract: Services[K]['procedures'][P]\n input: t.infer.input.encoded<Services[K]['procedures'][P]['input']>\n output: OutputType<\n t.infer.encoded<Services[K]['procedures'][P]['output']>\n >\n events: Services[K]['procedures'][P] extends TSubscriptionContract\n ? {\n [KE in keyof Services[K]['procedures'][P]['events']]: {\n payload: OutputType<\n t.infer.encoded<\n Services[K]['procedures'][P]['events'][KE]['payload']\n >\n >\n }\n }\n : {}\n }\n }\n}\n\ntype ClientCallers<\n Services extends ClientServicesResolved<Record<string, TServiceContract>>,\n> = {\n [K in keyof Services]: {\n [P in keyof Services[K]]: (\n ...args: Services[K][P]['input'] extends never\n ? [options?: ClientCallOptions]\n : Services[K][P]['input'] extends undefined\n ? [data?: Services[K][P]['input'], options?: ClientCallOptions]\n : [data: Services[K][P]['input'], options?: ClientCallOptions]\n ) => Promise<\n Services[K][P]['contract'] extends TSubscriptionContract\n ? {\n payload: Services[K][P]['output'] extends never\n ? undefined\n : Services[K][P]['output']\n subscription: Subscription<{\n [KE in keyof Services[K][P]['events']]: [\n Services[K][P]['events'][KE],\n ]\n }>\n }\n : Services[K][P]['output'] extends never\n ? void\n : Services[K][P]['output']\n >\n }\n}\n\nexport class StaticClient<Services extends ClientServices> extends Client {\n $types!: ClientServicesResolved<Services>\n #callers: ClientCallers<this['$types']>\n\n constructor(\n services: { [K in keyof Services]: Services[K]['name'] },\n options: ClientOptions,\n ) {\n super(options, Object.values(services))\n\n const callers = {} as any\n\n for (const [serviceKey, serviceName] of Object.entries(services)) {\n callers[serviceKey] = new Proxy(Object(), {\n get: (target, prop, receiver) => {\n // `await client.call.serviceName` or `await client.call.serviceName.procedureName`\n // without explicitly calling a function implicitly calls .then() on target\n // FIXME: this basically makes \"then\" a reserved word\n if (prop === 'then') return target\n return this.createCaller(serviceName, prop as string)\n },\n })\n }\n\n this.#callers = callers\n }\n\n get call() {\n return this.#callers\n }\n}\n"],"names":["Client","StaticClient","$types","constructor","services","options","Object","values","callers","serviceKey","serviceName","entries","Proxy","get","target","prop","receiver","createCaller","call"],"mappings":"AAEA,SAASA,MAAM,QAA4B,cAAa;AA0DxD,OAAO,MAAMC,qBAAsDD;IACjEE,OAAyC;IACzC,CAAA,OAAQ,CAA+B;IAEvCC,YACEC,QAAwD,EACxDC,OAAsB,CACtB;QACA,KAAK,CAACA,SAASC,OAAOC,MAAM,CAACH;QAE7B,MAAMI,UAAU,CAAC;QAEjB,KAAK,MAAM,CAACC,YAAYC,YAAY,IAAIJ,OAAOK,OAAO,CAACP,UAAW;YAChEI,OAAO,CAACC,WAAW,GAAG,IAAIG,MAAMN,UAAU;gBACxCO,KAAK,CAACC,QAAQC,MAAMC;oBAIlB,IAAID,SAAS,QAAQ,OAAOD;oBAC5B,OAAO,IAAI,CAACG,YAAY,CAACP,aAAaK;gBACxC;YACF;QACF;QAEA,IAAI,CAAC,CAAA,OAAQ,GAAGP;IAClB;IAEA,IAAIU,OAAO;QACT,OAAO,IAAI,CAAC,CAAA,OAAQ;IACtB;AACF"}
|
package/dist/lib/client.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { ErrorCode } from '@nmtjs/common';
|
|
2
|
-
import { ClientError } from "./common.js";
|
|
3
|
-
import * as utils from "./utils.js";
|
|
4
|
-
export class Client extends utils.EventEmitter {
|
|
5
|
-
options;
|
|
6
|
-
services;
|
|
7
|
-
transport;
|
|
8
|
-
format;
|
|
9
|
-
auth;
|
|
10
|
-
ids;
|
|
11
|
-
constructor(options, services){
|
|
12
|
-
super();
|
|
13
|
-
this.options = options;
|
|
14
|
-
this.services = services;
|
|
15
|
-
this.ids = {
|
|
16
|
-
call: 0,
|
|
17
|
-
stream: 0
|
|
18
|
-
};
|
|
19
|
-
if (!options.defaultTimeout) options.defaultTimeout = 15000;
|
|
20
|
-
}
|
|
21
|
-
useTransport(transportClass, ...options) {
|
|
22
|
-
this.transport = new transportClass(...options);
|
|
23
|
-
this.transport.client = Object.freeze({
|
|
24
|
-
services: this.services,
|
|
25
|
-
format: this.format,
|
|
26
|
-
auth: this.auth
|
|
27
|
-
});
|
|
28
|
-
this.checkTransport(this.transport);
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
useFormat(format) {
|
|
32
|
-
this.format = format;
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
async connect() {
|
|
36
|
-
await this.transport.connect();
|
|
37
|
-
}
|
|
38
|
-
async disconnect() {
|
|
39
|
-
await this.transport.disconnect();
|
|
40
|
-
}
|
|
41
|
-
async reconnect() {
|
|
42
|
-
await this.disconnect();
|
|
43
|
-
await this.connect();
|
|
44
|
-
}
|
|
45
|
-
checkTransport(transport) {}
|
|
46
|
-
createCaller(service, procedure, { timeout = this.options.defaultTimeout, transformInput, transformOutput } = {}) {
|
|
47
|
-
return async (payload, options = {})=>{
|
|
48
|
-
const { signal } = options;
|
|
49
|
-
const abortSignal = signal ? AbortSignal.any([
|
|
50
|
-
signal,
|
|
51
|
-
AbortSignal.timeout(timeout)
|
|
52
|
-
]) : AbortSignal.timeout(timeout);
|
|
53
|
-
const callId = ++this.ids.call;
|
|
54
|
-
if (this.options.debug) {
|
|
55
|
-
console.groupCollapsed(`RPC [${callId}] ${service}/${procedure}`);
|
|
56
|
-
console.log(payload);
|
|
57
|
-
console.groupEnd();
|
|
58
|
-
}
|
|
59
|
-
const callExecution = this.transport.rpc({
|
|
60
|
-
callId,
|
|
61
|
-
service,
|
|
62
|
-
procedure,
|
|
63
|
-
payload: transformInput ? transformInput(payload) : payload,
|
|
64
|
-
signal: abortSignal
|
|
65
|
-
}).then((result)=>{
|
|
66
|
-
if (result.success) return result.value;
|
|
67
|
-
throw new ClientError(result.error.code, result.error.message, result.error.data);
|
|
68
|
-
});
|
|
69
|
-
const callTimeout = utils.forAborted(abortSignal).catch(()=>{
|
|
70
|
-
const error = new ClientError(ErrorCode.RequestTimeout);
|
|
71
|
-
return Promise.reject(error);
|
|
72
|
-
});
|
|
73
|
-
try {
|
|
74
|
-
const response = await Promise.race([
|
|
75
|
-
callTimeout,
|
|
76
|
-
callExecution
|
|
77
|
-
]);
|
|
78
|
-
if (this.options.debug) {
|
|
79
|
-
console.groupCollapsed(`RPC [${callId}] Success`);
|
|
80
|
-
console.log(response);
|
|
81
|
-
console.groupEnd();
|
|
82
|
-
}
|
|
83
|
-
return transformOutput ? transformOutput(response) : response;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
if (this.options.debug) {
|
|
86
|
-
console.groupCollapsed(`RPC [${callId}] Error`);
|
|
87
|
-
console.log(error);
|
|
88
|
-
console.groupEnd();
|
|
89
|
-
}
|
|
90
|
-
throw error;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
}
|
package/dist/lib/client.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/client.ts"],"sourcesContent":["import { type BaseClientFormat, ErrorCode } from '@nmtjs/common'\n\nimport type { TServiceContract } from '@nmtjs/contract'\nimport { ClientError } from './common.ts'\nimport type { ClientTransport } from './transport.ts'\nimport type { ClientCallOptions } from './types.ts'\nimport * as utils from './utils.ts'\n\nexport type ClientOptions = {\n defaultTimeout: number\n debug?: boolean\n}\n\nexport type ClientServices = Record<string, TServiceContract>\n\nexport abstract class Client extends utils.EventEmitter {\n protected transport!: ClientTransport\n protected format!: BaseClientFormat\n\n auth?: string\n\n private ids = {\n call: 0,\n stream: 0,\n }\n\n constructor(\n protected readonly options: ClientOptions,\n protected services: string[],\n ) {\n super()\n if (!options.defaultTimeout) options.defaultTimeout = 15000\n }\n\n useTransport<T extends new (...args: any[]) => ClientTransport>(\n transportClass: T,\n ...options: ConstructorParameters<T>\n ) {\n this.transport = new transportClass(...options)\n this.transport.client = Object.freeze({\n services: this.services,\n format: this.format,\n auth: this.auth,\n })\n this.checkTransport(this.transport)\n return this as Omit<this, 'useTransport'>\n }\n\n useFormat(format: BaseClientFormat) {\n this.format = format\n return this as Omit<this, 'useFormat'>\n }\n\n async connect() {\n await this.transport.connect()\n }\n\n async disconnect() {\n await this.transport.disconnect()\n }\n\n async reconnect() {\n await this.disconnect()\n await this.connect()\n }\n\n protected checkTransport(transport: ClientTransport) {}\n\n protected createCaller(\n service: string,\n procedure: string,\n {\n timeout = this.options.defaultTimeout,\n transformInput,\n transformOutput,\n }: {\n timeout?: number\n transformInput?: (input: any) => any\n transformOutput?: (output: any) => any\n } = {},\n ) {\n return async (payload: any, options: ClientCallOptions = {}) => {\n const { signal } = options\n\n const abortSignal = signal\n ? AbortSignal.any([signal, AbortSignal.timeout(timeout)])\n : AbortSignal.timeout(timeout)\n\n const callId = ++this.ids.call\n\n if (this.options.debug) {\n console.groupCollapsed(`RPC [${callId}] ${service}/${procedure}`)\n console.log(payload)\n console.groupEnd()\n }\n\n const callExecution = this.transport\n .rpc({\n callId,\n service,\n procedure,\n payload: transformInput ? transformInput(payload) : payload,\n signal: abortSignal,\n })\n .then((result) => {\n if (result.success) return result.value\n throw new ClientError(\n result.error.code,\n result.error.message,\n result.error.data,\n )\n })\n\n const callTimeout = utils.forAborted(abortSignal).catch(() => {\n const error = new ClientError(ErrorCode.RequestTimeout)\n return Promise.reject(error)\n })\n\n try {\n const response = await Promise.race([callTimeout, callExecution])\n\n if (this.options.debug) {\n console.groupCollapsed(`RPC [${callId}] Success`)\n console.log(response)\n console.groupEnd()\n }\n\n return transformOutput ? transformOutput(response) : response\n } catch (error) {\n if (this.options.debug) {\n console.groupCollapsed(`RPC [${callId}] Error`)\n console.log(error)\n console.groupEnd()\n }\n\n throw error\n }\n }\n }\n}\n"],"names":["ErrorCode","ClientError","utils","Client","EventEmitter","transport","format","auth","ids","constructor","options","services","call","stream","defaultTimeout","useTransport","transportClass","client","Object","freeze","checkTransport","useFormat","connect","disconnect","reconnect","createCaller","service","procedure","timeout","transformInput","transformOutput","payload","signal","abortSignal","AbortSignal","any","callId","debug","console","groupCollapsed","log","groupEnd","callExecution","rpc","then","result","success","value","error","code","message","data","callTimeout","forAborted","catch","RequestTimeout","Promise","reject","response","race"],"mappings":"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"}
|
package/dist/lib/common.js
DELETED
package/dist/lib/common.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/common.ts"],"sourcesContent":["export class ClientError extends Error {\n constructor(\n public code: string,\n message?: string,\n public data?: any,\n ) {\n super(message)\n }\n}\n"],"names":["ClientError","Error","constructor","code","message","data"],"mappings":"AAAA,OAAO,MAAMA,oBAAoBC;;;IAC/BC,YACE,AAAOC,IAAY,EACnBC,OAAgB,EAChB,AAAOC,IAAU,CACjB;QACA,KAAK,CAACD;aAJCD,OAAAA;aAEAE,OAAAA;IAGT;AACF"}
|
package/dist/lib/stream.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export class ClientUpStream {
|
|
2
|
-
id;
|
|
3
|
-
blob;
|
|
4
|
-
reader;
|
|
5
|
-
constructor(id, blob){
|
|
6
|
-
this.id = id;
|
|
7
|
-
this.blob = blob;
|
|
8
|
-
if (this.blob.source instanceof ReadableStream === false) throw new Error('Blob source is not a ReadableStream');
|
|
9
|
-
this.reader = this.blob.source.getReader({
|
|
10
|
-
mode: 'byob'
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export const createClientDownStream = (metadata, pull)=>{
|
|
15
|
-
let bytes = 0;
|
|
16
|
-
const { readable, writable } = new TransformStream({
|
|
17
|
-
start: ()=>pull,
|
|
18
|
-
transform (chunk, controller) {
|
|
19
|
-
if (metadata.size !== -1) {
|
|
20
|
-
bytes += chunk.byteLength;
|
|
21
|
-
if (bytes > metadata.size) {
|
|
22
|
-
const error = new Error('Stream size exceeded');
|
|
23
|
-
controller.error(error);
|
|
24
|
-
} else {
|
|
25
|
-
try {
|
|
26
|
-
controller.enqueue(chunk);
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.error(error);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
} else {
|
|
32
|
-
controller.enqueue(chunk);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}, {
|
|
36
|
-
highWaterMark: 1
|
|
37
|
-
});
|
|
38
|
-
const writer = writable.getWriter();
|
|
39
|
-
const blob = {
|
|
40
|
-
get metadata () {
|
|
41
|
-
return metadata;
|
|
42
|
-
},
|
|
43
|
-
get stream () {
|
|
44
|
-
return readable;
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
return {
|
|
48
|
-
blob,
|
|
49
|
-
writer
|
|
50
|
-
};
|
|
51
|
-
};
|
package/dist/lib/stream.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/stream.ts"],"sourcesContent":["import type { ApiBlob, ApiBlobMetadata } from '@nmtjs/common'\nimport type { AnyFn } from './utils.ts'\n\nexport class ClientUpStream {\n readonly reader: ReadableStreamBYOBReader\n\n constructor(\n readonly id: number,\n readonly blob: ApiBlob,\n ) {\n if (this.blob.source instanceof ReadableStream === false)\n throw new Error('Blob source is not a ReadableStream')\n this.reader = this.blob.source.getReader({ mode: 'byob' })\n }\n}\n\nexport type ClientDownStreamBlob = {\n readonly metadata: ApiBlobMetadata\n readonly stream: ReadableStream<Uint8Array>\n}\n\nexport type ClientDownStreamWrapper = {\n writer: WritableStreamDefaultWriter\n blob: ClientDownStreamBlob\n}\n\nexport const createClientDownStream = (\n metadata: ApiBlobMetadata,\n pull: AnyFn,\n): ClientDownStreamWrapper => {\n let bytes = 0\n\n const { readable, writable } = new TransformStream<Uint8Array, Uint8Array>(\n {\n start: () => pull,\n transform(chunk, controller) {\n if (metadata.size !== -1) {\n bytes += chunk.byteLength\n if (bytes > metadata.size) {\n const error = new Error('Stream size exceeded')\n controller.error(error)\n } else {\n try {\n controller.enqueue(chunk)\n } catch (error) {\n console.error(error)\n }\n }\n } else {\n controller.enqueue(chunk)\n }\n },\n },\n { highWaterMark: 1 },\n )\n\n const writer = writable.getWriter()\n\n const blob: ClientDownStreamBlob = {\n get metadata() {\n return metadata\n },\n get stream() {\n return readable\n },\n }\n\n return {\n blob,\n writer,\n }\n}\n"],"names":["ClientUpStream","reader","constructor","id","blob","source","ReadableStream","Error","getReader","mode","createClientDownStream","metadata","pull","bytes","readable","writable","TransformStream","start","transform","chunk","controller","size","byteLength","error","enqueue","console","highWaterMark","writer","getWriter","stream"],"mappings":"AAGA,OAAO,MAAMA;;;IACFC,OAAgC;IAEzCC,YACE,AAASC,EAAU,EACnB,AAASC,IAAa,CACtB;aAFSD,KAAAA;aACAC,OAAAA;QAET,IAAI,IAAI,CAACA,IAAI,CAACC,MAAM,YAAYC,mBAAmB,OACjD,MAAM,IAAIC,MAAM;QAClB,IAAI,CAACN,MAAM,GAAG,IAAI,CAACG,IAAI,CAACC,MAAM,CAACG,SAAS,CAAC;YAAEC,MAAM;QAAO;IAC1D;AACF;AAYA,OAAO,MAAMC,yBAAyB,CACpCC,UACAC;IAEA,IAAIC,QAAQ;IAEZ,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAE,GAAG,IAAIC,gBACjC;QACEC,OAAO,IAAML;QACbM,WAAUC,KAAK,EAAEC,UAAU;YACzB,IAAIT,SAASU,IAAI,KAAK,CAAC,GAAG;gBACxBR,SAASM,MAAMG,UAAU;gBACzB,IAAIT,QAAQF,SAASU,IAAI,EAAE;oBACzB,MAAME,QAAQ,IAAIhB,MAAM;oBACxBa,WAAWG,KAAK,CAACA;gBACnB,OAAO;oBACL,IAAI;wBACFH,WAAWI,OAAO,CAACL;oBACrB,EAAE,OAAOI,OAAO;wBACdE,QAAQF,KAAK,CAACA;oBAChB;gBACF;YACF,OAAO;gBACLH,WAAWI,OAAO,CAACL;YACrB;QACF;IACF,GACA;QAAEO,eAAe;IAAE;IAGrB,MAAMC,SAASZ,SAASa,SAAS;IAEjC,MAAMxB,OAA6B;QACjC,IAAIO,YAAW;YACb,OAAOA;QACT;QACA,IAAIkB,UAAS;YACX,OAAOf;QACT;IACF;IAEA,OAAO;QACLV;QACAuB;IACF;AACF,EAAC"}
|
package/dist/lib/subscription.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/subscription.ts"],"sourcesContent":["import { EventEmitter, type EventMap } from './utils.ts'\n\nexport class Subscription<\n Events extends EventMap = EventMap,\n> extends EventEmitter<Events> {\n constructor(\n readonly key: string,\n readonly unsubscribe: () => void,\n ) {\n super()\n }\n}\n"],"names":["EventEmitter","Subscription","constructor","key","unsubscribe"],"mappings":"AAAA,SAASA,YAAY,QAAuB,aAAY;AAExD,OAAO,MAAMC,qBAEHD;;;IACRE,YACE,AAASC,GAAW,EACpB,AAASC,WAAuB,CAChC;QACA,KAAK;aAHID,MAAAA;aACAC,cAAAA;IAGX;AACF"}
|
package/dist/lib/transport.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/transport.ts"],"sourcesContent":["import type { BaseClientFormat } from '@nmtjs/common'\nimport { EventEmitter, type EventMap } from './utils.ts'\n\nexport type ClientTransportRpcCall = {\n service: string\n procedure: string\n callId: number\n payload: any\n signal: AbortSignal\n}\n\nexport type ClientTransportRpcResult =\n | {\n success: false\n error: { code: string; message?: string; data?: any }\n }\n | {\n success: true\n value: any\n }\n\nexport abstract class ClientTransport<\n T extends EventMap = EventMap,\n> extends EventEmitter<\n T & { event: [service: string, event: string, payload: any] }\n> {\n abstract type: string\n\n client!: {\n readonly services: string[]\n readonly format: BaseClientFormat\n readonly auth?: string\n }\n\n abstract connect(): Promise<void>\n abstract disconnect(): Promise<void>\n abstract rpc(\n params: ClientTransportRpcCall,\n ): Promise<ClientTransportRpcResult>\n}\n"],"names":["EventEmitter","ClientTransport","client"],"mappings":"AACA,SAASA,YAAY,QAAuB,aAAY;AAoBxD,OAAO,MAAeC,wBAEZD;IAKRE,OAIC;AAOH"}
|
package/dist/lib/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/types.ts"],"sourcesContent":["import type { ApiBlob, ApiBlobInterface } from '@nmtjs/common'\nimport type { ClientDownStreamBlob } from './stream.ts'\n\nexport type ClientCallOptions = {\n signal?: AbortSignal\n}\n\nexport type InputType<T> = T extends any[]\n ? InputType<T[number]>[]\n : T extends ApiBlobInterface\n ? ApiBlob\n : T extends object\n ? { [K in keyof T]: InputType<T[K]> }\n : T\n\nexport type OutputType<T> = T extends any[]\n ? OutputType<T[number]>[]\n : T extends ApiBlobInterface\n ? ClientDownStreamBlob\n : T extends object\n ? { [K in keyof T]: OutputType<T[K]> }\n : T\n"],"names":[],"mappings":"AAeA,WAMS"}
|
package/dist/lib/utils.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export function forAborted(signal) {
|
|
2
|
-
return new Promise((_, reject)=>{
|
|
3
|
-
const handler = ()=>reject(new Error('aborted'));
|
|
4
|
-
const options = {
|
|
5
|
-
once: true
|
|
6
|
-
};
|
|
7
|
-
signal.addEventListener('abort', handler, options);
|
|
8
|
-
});
|
|
9
|
-
}
|
|
10
|
-
export function onAbort(signal, listener) {
|
|
11
|
-
signal.addEventListener('abort', listener, {
|
|
12
|
-
once: true
|
|
13
|
-
});
|
|
14
|
-
return ()=>signal.removeEventListener('abort', listener);
|
|
15
|
-
}
|
|
16
|
-
export class EventEmitter {
|
|
17
|
-
#target = new EventTarget();
|
|
18
|
-
#listeners = new Map();
|
|
19
|
-
on(event, listener, options) {
|
|
20
|
-
const wrapper = (event)=>listener(...event.detail);
|
|
21
|
-
this.#listeners.set(listener, wrapper);
|
|
22
|
-
this.#target.addEventListener(event, wrapper, options);
|
|
23
|
-
return ()=>this.#target.removeEventListener(event, wrapper);
|
|
24
|
-
}
|
|
25
|
-
once(event, listener) {
|
|
26
|
-
return this.on(event, listener, {
|
|
27
|
-
once: true
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
off(event, listener) {
|
|
31
|
-
const wrapper = this.#listeners.get(listener);
|
|
32
|
-
if (wrapper) this.#target.removeEventListener(event, wrapper);
|
|
33
|
-
}
|
|
34
|
-
emit(event, ...args) {
|
|
35
|
-
return this.#target.dispatchEvent(new CustomEvent(event, {
|
|
36
|
-
detail: args
|
|
37
|
-
}));
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
export const once = (ee, event)=>new Promise((resolve)=>ee.once(event, resolve));
|
package/dist/lib/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../lib/utils.ts"],"sourcesContent":["export type AnyFn = (...args: any[]) => any\n\nexport type EventMap = { [K: string]: any[] }\n\nexport function forAborted(signal: AbortSignal) {\n return new Promise((_, reject) => {\n const handler = () => reject(new Error('aborted'))\n const options = { once: true }\n signal.addEventListener('abort', handler, options)\n })\n}\n\nexport function onAbort(signal: AbortSignal, listener: () => void) {\n signal.addEventListener('abort', listener, { once: true })\n return () => signal.removeEventListener('abort', listener)\n}\n\n/**\n * Very simple node-like event emitter wrapper around EventTarget\n *\n * @todo add errors and promise rejections handling\n */\nexport class EventEmitter<\n Events extends EventMap = EventMap,\n EventNames extends Extract<keyof Events, string> = Extract<\n keyof Events,\n string\n >,\n> {\n #target = new EventTarget()\n #listeners = new Map<AnyFn, AnyFn>()\n\n on<E extends EventNames>(\n event: E | (Object & string),\n listener: (...args: Events[E]) => void,\n options?: AddEventListenerOptions,\n ) {\n const wrapper = (event) => listener(...event.detail)\n this.#listeners.set(listener, wrapper)\n this.#target.addEventListener(event, wrapper, options)\n return () => this.#target.removeEventListener(event, wrapper)\n }\n\n once<E extends EventNames>(\n event: E | (Object & string),\n listener: (...args: Events[E]) => void,\n ) {\n return this.on(event, listener, { once: true })\n }\n\n off(event: EventNames | (Object & string), listener: AnyFn) {\n const wrapper = this.#listeners.get(listener)\n if (wrapper) this.#target.removeEventListener(event, wrapper)\n }\n\n emit<E extends EventNames | (Object & string)>(\n event: E,\n ...args: E extends EventEmitter ? Events[E] : any[]\n ) {\n return this.#target.dispatchEvent(new CustomEvent(event, { detail: args }))\n }\n}\n\nexport const once = (ee: EventEmitter, event: string) =>\n new Promise((resolve) => ee.once(event, resolve))\n"],"names":["forAborted","signal","Promise","_","reject","handler","Error","options","once","addEventListener","onAbort","listener","removeEventListener","EventEmitter","EventTarget","Map","on","event","wrapper","detail","set","off","get","emit","args","dispatchEvent","CustomEvent","ee","resolve"],"mappings":"AAIA,OAAO,SAASA,WAAWC,MAAmB;IAC5C,OAAO,IAAIC,QAAQ,CAACC,GAAGC;QACrB,MAAMC,UAAU,IAAMD,OAAO,IAAIE,MAAM;QACvC,MAAMC,UAAU;YAAEC,MAAM;QAAK;QAC7BP,OAAOQ,gBAAgB,CAAC,SAASJ,SAASE;IAC5C;AACF;AAEA,OAAO,SAASG,QAAQT,MAAmB,EAAEU,QAAoB;IAC/DV,OAAOQ,gBAAgB,CAAC,SAASE,UAAU;QAAEH,MAAM;IAAK;IACxD,OAAO,IAAMP,OAAOW,mBAAmB,CAAC,SAASD;AACnD;AAOA,OAAO,MAAME;IAOX,CAAA,MAAO,GAAG,IAAIC,cAAa;IAC3B,CAAA,SAAU,GAAG,IAAIC,MAAmB;IAEpCC,GACEC,KAA4B,EAC5BN,QAAsC,EACtCJ,OAAiC,EACjC;QACA,MAAMW,UAAU,CAACD,QAAUN,YAAYM,MAAME,MAAM;QACnD,IAAI,CAAC,CAAA,SAAU,CAACC,GAAG,CAACT,UAAUO;QAC9B,IAAI,CAAC,CAAA,MAAO,CAACT,gBAAgB,CAACQ,OAAOC,SAASX;QAC9C,OAAO,IAAM,IAAI,CAAC,CAAA,MAAO,CAACK,mBAAmB,CAACK,OAAOC;IACvD;IAEAV,KACES,KAA4B,EAC5BN,QAAsC,EACtC;QACA,OAAO,IAAI,CAACK,EAAE,CAACC,OAAON,UAAU;YAAEH,MAAM;QAAK;IAC/C;IAEAa,IAAIJ,KAAqC,EAAEN,QAAe,EAAE;QAC1D,MAAMO,UAAU,IAAI,CAAC,CAAA,SAAU,CAACI,GAAG,CAACX;QACpC,IAAIO,SAAS,IAAI,CAAC,CAAA,MAAO,CAACN,mBAAmB,CAACK,OAAOC;IACvD;IAEAK,KACEN,KAAQ,EACR,GAAGO,IAAgD,EACnD;QACA,OAAO,IAAI,CAAC,CAAA,MAAO,CAACC,aAAa,CAAC,IAAIC,YAAYT,OAAO;YAAEE,QAAQK;QAAK;IAC1E;AACF;AAEA,OAAO,MAAMhB,OAAO,CAACmB,IAAkBV,QACrC,IAAIf,QAAQ,CAAC0B,UAAYD,GAAGnB,IAAI,CAACS,OAAOW,UAAS"}
|
package/index.ts
DELETED
package/lib/client-runtime.ts
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
TEventContract,
|
|
3
|
-
TServiceContract,
|
|
4
|
-
TSubscriptionContract,
|
|
5
|
-
} from '@nmtjs/contract'
|
|
6
|
-
import { type BaseType, NeverType, type t } from '@nmtjs/type'
|
|
7
|
-
import { type Compiled, compile } from '@nmtjs/type/compiler'
|
|
8
|
-
|
|
9
|
-
import { Client, type ClientOptions } from './client.ts'
|
|
10
|
-
import type { Subscription } from './subscription.ts'
|
|
11
|
-
import type { ClientTransport } from './transport.ts'
|
|
12
|
-
import type { ClientCallOptions, InputType, OutputType } from './types.ts'
|
|
13
|
-
|
|
14
|
-
type CompiledContract<T extends TServiceContract = TServiceContract> = {
|
|
15
|
-
compiled: Map<BaseType, Compiled>
|
|
16
|
-
contract: T
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
type ClientServicesResolved<Services extends ClientServices> = {
|
|
20
|
-
[K in keyof Services]: {
|
|
21
|
-
[P in keyof Services[K]['contract']['procedures']]: {
|
|
22
|
-
contract: Services[K]['contract']['procedures'][P]
|
|
23
|
-
input: InputType<
|
|
24
|
-
t.infer.decoded<Services[K]['contract']['procedures'][P]['input']>
|
|
25
|
-
>
|
|
26
|
-
output: OutputType<
|
|
27
|
-
t.infer.decoded<Services[K]['contract']['procedures'][P]['output']>
|
|
28
|
-
>
|
|
29
|
-
events: Services[K]['contract']['procedures'][P] extends TSubscriptionContract
|
|
30
|
-
? {
|
|
31
|
-
[KE in keyof Services[K]['contract']['procedures'][P]['events']]: {
|
|
32
|
-
payload: OutputType<
|
|
33
|
-
t.infer.decoded<
|
|
34
|
-
Services[K]['contract']['procedures'][P]['events'][KE]['payload']
|
|
35
|
-
>
|
|
36
|
-
>
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
: {}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
type ClientServices = Record<string, CompiledContract>
|
|
45
|
-
|
|
46
|
-
type ClientCallers<Services extends ClientServicesResolved<ClientServices>> = {
|
|
47
|
-
[K in keyof Services]: {
|
|
48
|
-
[P in keyof Services[K]]: (
|
|
49
|
-
...args: Services[K][P]['input'] extends NeverType
|
|
50
|
-
? [options?: ClientCallOptions]
|
|
51
|
-
: t.infer.input.decoded<
|
|
52
|
-
Services[K][P]['contract']['input']
|
|
53
|
-
> extends undefined
|
|
54
|
-
? [data?: Services[K][P]['input'], options?: ClientCallOptions]
|
|
55
|
-
: [data: Services[K][P]['input'], options?: ClientCallOptions]
|
|
56
|
-
) => Promise<
|
|
57
|
-
Services[K][P] extends TSubscriptionContract
|
|
58
|
-
? {
|
|
59
|
-
payload: Services[K][P]['output'] extends never
|
|
60
|
-
? undefined
|
|
61
|
-
: t.infer.decoded<Services[K][P]['output']>
|
|
62
|
-
subscription: Subscription<{
|
|
63
|
-
[KE in keyof Services[K][P]['events']]: [
|
|
64
|
-
t.infer.decoded<Services[K][P]['events'][KE]['payload']>,
|
|
65
|
-
]
|
|
66
|
-
}>
|
|
67
|
-
}
|
|
68
|
-
: Services[K][P]['output'] extends never
|
|
69
|
-
? void
|
|
70
|
-
: Services[K][P]['output']
|
|
71
|
-
>
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export class RuntimeClient<Services extends ClientServices> extends Client {
|
|
76
|
-
$types!: ClientServicesResolved<Services>
|
|
77
|
-
#callers: ClientCallers<this['$types']>
|
|
78
|
-
|
|
79
|
-
constructor(
|
|
80
|
-
protected readonly contracts: Services,
|
|
81
|
-
options: ClientOptions,
|
|
82
|
-
) {
|
|
83
|
-
super(
|
|
84
|
-
options,
|
|
85
|
-
Object.values(contracts).map((s) => s.contract.name),
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
const callers = {} as any
|
|
89
|
-
for (const [serviceKey, service] of Object.entries(contracts)) {
|
|
90
|
-
service.contract.procedures
|
|
91
|
-
|
|
92
|
-
callers[serviceKey] = {} as any
|
|
93
|
-
|
|
94
|
-
for (const procedureName in service.contract.procedures) {
|
|
95
|
-
const { input, output } = service.contract.procedures[procedureName]
|
|
96
|
-
|
|
97
|
-
function decodeOutput(data) {
|
|
98
|
-
if (output instanceof NeverType) return undefined
|
|
99
|
-
const compiled = service.compiled.get(output)!
|
|
100
|
-
const result = compiled.decodeSafe(data)
|
|
101
|
-
if (result.success) {
|
|
102
|
-
return result.value
|
|
103
|
-
} else {
|
|
104
|
-
console.dir(result.error)
|
|
105
|
-
throw new Error('Failed to decode output', {
|
|
106
|
-
cause: result.error,
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
callers[serviceKey][procedureName] = this.createCaller(
|
|
112
|
-
service.contract.name,
|
|
113
|
-
procedureName,
|
|
114
|
-
{
|
|
115
|
-
timeout: service.contract.timeout,
|
|
116
|
-
transformInput: (data: any) => {
|
|
117
|
-
if (input instanceof NeverType) return undefined
|
|
118
|
-
const compiled = service.compiled.get(input)!
|
|
119
|
-
const result = compiled.encodeSafe(data)
|
|
120
|
-
if (result.success) {
|
|
121
|
-
return result.value
|
|
122
|
-
} else {
|
|
123
|
-
console.dir(result.error)
|
|
124
|
-
throw new Error('Failed to encode input', {
|
|
125
|
-
cause: result.error,
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
transformOutput: (data: any) => {
|
|
130
|
-
if (
|
|
131
|
-
service.contract.procedures[procedureName].type ===
|
|
132
|
-
'neemata:subscription'
|
|
133
|
-
) {
|
|
134
|
-
data.payload = decodeOutput(data.payload)
|
|
135
|
-
return data
|
|
136
|
-
} else {
|
|
137
|
-
return decodeOutput(data)
|
|
138
|
-
}
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
this.#callers = callers
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
get call() {
|
|
148
|
-
return this.#callers
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
protected checkTransport(transport: ClientTransport): void {
|
|
152
|
-
for (const { contract } of Object.values(this.contracts)) {
|
|
153
|
-
if (!contract.transports[transport.type])
|
|
154
|
-
throw new Error(
|
|
155
|
-
`Transport [${transport.type}] not supported for service [${contract.name}]`,
|
|
156
|
-
)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export const compileContract = <T extends TServiceContract>(
|
|
162
|
-
contract: T,
|
|
163
|
-
): CompiledContract<T> => {
|
|
164
|
-
const compiled = new Map<BaseType, Compiled>()
|
|
165
|
-
|
|
166
|
-
for (const procedure of Object.values(contract.procedures)) {
|
|
167
|
-
const { input, output } = procedure
|
|
168
|
-
if (procedure.type === 'neemata:subscription') {
|
|
169
|
-
const { events } = procedure as TSubscriptionContract
|
|
170
|
-
for (const event of Object.values(events) as TEventContract[]) {
|
|
171
|
-
compiled.set(event.payload, compile(event.payload))
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
compiled.set(input, compile(input))
|
|
175
|
-
compiled.set(output, compile(output))
|
|
176
|
-
}
|
|
177
|
-
for (const event of Object.values(contract.events)) {
|
|
178
|
-
compiled.set(event.payload, compile(event.payload))
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
compiled,
|
|
183
|
-
contract,
|
|
184
|
-
}
|
|
185
|
-
}
|
package/lib/client-static.ts
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import type { TServiceContract, TSubscriptionContract } from '@nmtjs/contract'
|
|
2
|
-
import type { NeverType, t } from '@nmtjs/type'
|
|
3
|
-
import { Client, type ClientOptions } from './client.ts'
|
|
4
|
-
import type { Subscription } from './subscription.ts'
|
|
5
|
-
import type { ClientCallOptions, InputType, OutputType } from './types.ts'
|
|
6
|
-
|
|
7
|
-
type ClientServices = Record<string, TServiceContract>
|
|
8
|
-
|
|
9
|
-
type ClientServicesResolved<Services extends ClientServices> = {
|
|
10
|
-
[K in keyof Services]: {
|
|
11
|
-
[P in keyof Services[K]['procedures']]: {
|
|
12
|
-
contract: Services[K]['procedures'][P]
|
|
13
|
-
input: t.infer.input.encoded<Services[K]['procedures'][P]['input']>
|
|
14
|
-
output: OutputType<
|
|
15
|
-
t.infer.encoded<Services[K]['procedures'][P]['output']>
|
|
16
|
-
>
|
|
17
|
-
events: Services[K]['procedures'][P] extends TSubscriptionContract
|
|
18
|
-
? {
|
|
19
|
-
[KE in keyof Services[K]['procedures'][P]['events']]: {
|
|
20
|
-
payload: OutputType<
|
|
21
|
-
t.infer.encoded<
|
|
22
|
-
Services[K]['procedures'][P]['events'][KE]['payload']
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
: {}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type ClientCallers<
|
|
33
|
-
Services extends ClientServicesResolved<Record<string, TServiceContract>>,
|
|
34
|
-
> = {
|
|
35
|
-
[K in keyof Services]: {
|
|
36
|
-
[P in keyof Services[K]]: (
|
|
37
|
-
...args: Services[K][P]['input'] extends never
|
|
38
|
-
? [options?: ClientCallOptions]
|
|
39
|
-
: Services[K][P]['input'] extends undefined
|
|
40
|
-
? [data?: Services[K][P]['input'], options?: ClientCallOptions]
|
|
41
|
-
: [data: Services[K][P]['input'], options?: ClientCallOptions]
|
|
42
|
-
) => Promise<
|
|
43
|
-
Services[K][P]['contract'] extends TSubscriptionContract
|
|
44
|
-
? {
|
|
45
|
-
payload: Services[K][P]['output'] extends never
|
|
46
|
-
? undefined
|
|
47
|
-
: Services[K][P]['output']
|
|
48
|
-
subscription: Subscription<{
|
|
49
|
-
[KE in keyof Services[K][P]['events']]: [
|
|
50
|
-
Services[K][P]['events'][KE],
|
|
51
|
-
]
|
|
52
|
-
}>
|
|
53
|
-
}
|
|
54
|
-
: Services[K][P]['output'] extends never
|
|
55
|
-
? void
|
|
56
|
-
: Services[K][P]['output']
|
|
57
|
-
>
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export class StaticClient<Services extends ClientServices> extends Client {
|
|
62
|
-
$types!: ClientServicesResolved<Services>
|
|
63
|
-
#callers: ClientCallers<this['$types']>
|
|
64
|
-
|
|
65
|
-
constructor(
|
|
66
|
-
services: { [K in keyof Services]: Services[K]['name'] },
|
|
67
|
-
options: ClientOptions,
|
|
68
|
-
) {
|
|
69
|
-
super(options, Object.values(services))
|
|
70
|
-
|
|
71
|
-
const callers = {} as any
|
|
72
|
-
|
|
73
|
-
for (const [serviceKey, serviceName] of Object.entries(services)) {
|
|
74
|
-
callers[serviceKey] = new Proxy(Object(), {
|
|
75
|
-
get: (target, prop, receiver) => {
|
|
76
|
-
// `await client.call.serviceName` or `await client.call.serviceName.procedureName`
|
|
77
|
-
// without explicitly calling a function implicitly calls .then() on target
|
|
78
|
-
// FIXME: this basically makes "then" a reserved word
|
|
79
|
-
if (prop === 'then') return target
|
|
80
|
-
return this.createCaller(serviceName, prop as string)
|
|
81
|
-
},
|
|
82
|
-
})
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
this.#callers = callers
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
get call() {
|
|
89
|
-
return this.#callers
|
|
90
|
-
}
|
|
91
|
-
}
|