@nmtjs/client 0.5.3 → 0.6.0
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 +92 -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 +150 -0
- package/lib/static.ts +56 -0
- package/lib/types.ts +85 -17
- 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
package/lib/client.ts
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { type BaseClientFormat, ErrorCode } from '@nmtjs/common'
|
|
2
|
-
|
|
3
|
-
import type { TServiceContract } from '@nmtjs/contract'
|
|
4
|
-
import { ClientError } from './common.ts'
|
|
5
|
-
import type { ClientTransport } from './transport.ts'
|
|
6
|
-
import type { ClientCallOptions } from './types.ts'
|
|
7
|
-
import * as utils from './utils.ts'
|
|
8
|
-
|
|
9
|
-
export type ClientOptions = {
|
|
10
|
-
defaultTimeout: number
|
|
11
|
-
debug?: boolean
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type ClientServices = Record<string, TServiceContract>
|
|
15
|
-
|
|
16
|
-
export abstract class Client extends utils.EventEmitter {
|
|
17
|
-
protected transport!: ClientTransport
|
|
18
|
-
protected format!: BaseClientFormat
|
|
19
|
-
|
|
20
|
-
auth?: string
|
|
21
|
-
|
|
22
|
-
private ids = {
|
|
23
|
-
call: 0,
|
|
24
|
-
stream: 0,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
constructor(
|
|
28
|
-
protected readonly options: ClientOptions,
|
|
29
|
-
protected services: string[],
|
|
30
|
-
) {
|
|
31
|
-
super()
|
|
32
|
-
if (!options.defaultTimeout) options.defaultTimeout = 15000
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
useTransport<T extends new (...args: any[]) => ClientTransport>(
|
|
36
|
-
transportClass: T,
|
|
37
|
-
...options: ConstructorParameters<T>
|
|
38
|
-
) {
|
|
39
|
-
this.transport = new transportClass(...options)
|
|
40
|
-
this.transport.client = Object.freeze({
|
|
41
|
-
services: this.services,
|
|
42
|
-
format: this.format,
|
|
43
|
-
auth: this.auth,
|
|
44
|
-
})
|
|
45
|
-
this.checkTransport(this.transport)
|
|
46
|
-
return this as Omit<this, 'useTransport'>
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
useFormat(format: BaseClientFormat) {
|
|
50
|
-
this.format = format
|
|
51
|
-
return this as Omit<this, 'useFormat'>
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async connect() {
|
|
55
|
-
await this.transport.connect()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async disconnect() {
|
|
59
|
-
await this.transport.disconnect()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async reconnect() {
|
|
63
|
-
await this.disconnect()
|
|
64
|
-
await this.connect()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
protected checkTransport(transport: ClientTransport) {}
|
|
68
|
-
|
|
69
|
-
protected createCaller(
|
|
70
|
-
service: string,
|
|
71
|
-
procedure: string,
|
|
72
|
-
{
|
|
73
|
-
timeout = this.options.defaultTimeout,
|
|
74
|
-
transformInput,
|
|
75
|
-
transformOutput,
|
|
76
|
-
}: {
|
|
77
|
-
timeout?: number
|
|
78
|
-
transformInput?: (input: any) => any
|
|
79
|
-
transformOutput?: (output: any) => any
|
|
80
|
-
} = {},
|
|
81
|
-
) {
|
|
82
|
-
return async (payload: any, options: ClientCallOptions = {}) => {
|
|
83
|
-
const { signal } = options
|
|
84
|
-
|
|
85
|
-
const abortSignal = signal
|
|
86
|
-
? AbortSignal.any([signal, AbortSignal.timeout(timeout)])
|
|
87
|
-
: AbortSignal.timeout(timeout)
|
|
88
|
-
|
|
89
|
-
const callId = ++this.ids.call
|
|
90
|
-
|
|
91
|
-
if (this.options.debug) {
|
|
92
|
-
console.groupCollapsed(`RPC [${callId}] ${service}/${procedure}`)
|
|
93
|
-
console.log(payload)
|
|
94
|
-
console.groupEnd()
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const callExecution = this.transport
|
|
98
|
-
.rpc({
|
|
99
|
-
callId,
|
|
100
|
-
service,
|
|
101
|
-
procedure,
|
|
102
|
-
payload: transformInput ? transformInput(payload) : payload,
|
|
103
|
-
signal: abortSignal,
|
|
104
|
-
})
|
|
105
|
-
.then((result) => {
|
|
106
|
-
if (result.success) return result.value
|
|
107
|
-
throw new ClientError(
|
|
108
|
-
result.error.code,
|
|
109
|
-
result.error.message,
|
|
110
|
-
result.error.data,
|
|
111
|
-
)
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
const callTimeout = utils.forAborted(abortSignal).catch(() => {
|
|
115
|
-
const error = new ClientError(ErrorCode.RequestTimeout)
|
|
116
|
-
return Promise.reject(error)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
const response = await Promise.race([callTimeout, callExecution])
|
|
121
|
-
|
|
122
|
-
if (this.options.debug) {
|
|
123
|
-
console.groupCollapsed(`RPC [${callId}] Success`)
|
|
124
|
-
console.log(response)
|
|
125
|
-
console.groupEnd()
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return transformOutput ? transformOutput(response) : response
|
|
129
|
-
} catch (error) {
|
|
130
|
-
if (this.options.debug) {
|
|
131
|
-
console.groupCollapsed(`RPC [${callId}] Error`)
|
|
132
|
-
console.log(error)
|
|
133
|
-
console.groupEnd()
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
throw error
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
package/lib/stream.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { ApiBlob, ApiBlobMetadata } from '@nmtjs/common'
|
|
2
|
-
import type { AnyFn } from './utils.ts'
|
|
3
|
-
|
|
4
|
-
export class ClientUpStream {
|
|
5
|
-
readonly reader: ReadableStreamBYOBReader
|
|
6
|
-
|
|
7
|
-
constructor(
|
|
8
|
-
readonly id: number,
|
|
9
|
-
readonly blob: ApiBlob,
|
|
10
|
-
) {
|
|
11
|
-
if (this.blob.source instanceof ReadableStream === false)
|
|
12
|
-
throw new Error('Blob source is not a ReadableStream')
|
|
13
|
-
this.reader = this.blob.source.getReader({ mode: 'byob' })
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type ClientDownStreamBlob = {
|
|
18
|
-
readonly metadata: ApiBlobMetadata
|
|
19
|
-
readonly stream: ReadableStream<Uint8Array>
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type ClientDownStreamWrapper = {
|
|
23
|
-
writer: WritableStreamDefaultWriter
|
|
24
|
-
blob: ClientDownStreamBlob
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export const createClientDownStream = (
|
|
28
|
-
metadata: ApiBlobMetadata,
|
|
29
|
-
pull: AnyFn,
|
|
30
|
-
): ClientDownStreamWrapper => {
|
|
31
|
-
let bytes = 0
|
|
32
|
-
|
|
33
|
-
const { readable, writable } = new TransformStream<Uint8Array, Uint8Array>(
|
|
34
|
-
{
|
|
35
|
-
start: () => pull,
|
|
36
|
-
transform(chunk, controller) {
|
|
37
|
-
if (metadata.size !== -1) {
|
|
38
|
-
bytes += chunk.byteLength
|
|
39
|
-
if (bytes > metadata.size) {
|
|
40
|
-
const error = new Error('Stream size exceeded')
|
|
41
|
-
controller.error(error)
|
|
42
|
-
} else {
|
|
43
|
-
try {
|
|
44
|
-
controller.enqueue(chunk)
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error(error)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
controller.enqueue(chunk)
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
{ highWaterMark: 1 },
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
const writer = writable.getWriter()
|
|
58
|
-
|
|
59
|
-
const blob: ClientDownStreamBlob = {
|
|
60
|
-
get metadata() {
|
|
61
|
-
return metadata
|
|
62
|
-
},
|
|
63
|
-
get stream() {
|
|
64
|
-
return readable
|
|
65
|
-
},
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
blob,
|
|
70
|
-
writer,
|
|
71
|
-
}
|
|
72
|
-
}
|
package/lib/subscription.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { EventEmitter, type EventMap } from './utils.ts'
|
|
2
|
-
|
|
3
|
-
export class Subscription<
|
|
4
|
-
Events extends EventMap = EventMap,
|
|
5
|
-
> extends EventEmitter<Events> {
|
|
6
|
-
constructor(
|
|
7
|
-
readonly key: string,
|
|
8
|
-
readonly unsubscribe: () => void,
|
|
9
|
-
) {
|
|
10
|
-
super()
|
|
11
|
-
}
|
|
12
|
-
}
|
package/lib/transport.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { BaseClientFormat } from '@nmtjs/common'
|
|
2
|
-
import { EventEmitter, type EventMap } from './utils.ts'
|
|
3
|
-
|
|
4
|
-
export type ClientTransportRpcCall = {
|
|
5
|
-
service: string
|
|
6
|
-
procedure: string
|
|
7
|
-
callId: number
|
|
8
|
-
payload: any
|
|
9
|
-
signal: AbortSignal
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type ClientTransportRpcResult =
|
|
13
|
-
| {
|
|
14
|
-
success: false
|
|
15
|
-
error: { code: string; message?: string; data?: any }
|
|
16
|
-
}
|
|
17
|
-
| {
|
|
18
|
-
success: true
|
|
19
|
-
value: any
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export abstract class ClientTransport<
|
|
23
|
-
T extends EventMap = EventMap,
|
|
24
|
-
> extends EventEmitter<
|
|
25
|
-
T & { event: [service: string, event: string, payload: any] }
|
|
26
|
-
> {
|
|
27
|
-
abstract type: string
|
|
28
|
-
|
|
29
|
-
client!: {
|
|
30
|
-
readonly services: string[]
|
|
31
|
-
readonly format: BaseClientFormat
|
|
32
|
-
readonly auth?: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
abstract connect(): Promise<void>
|
|
36
|
-
abstract disconnect(): Promise<void>
|
|
37
|
-
abstract rpc(
|
|
38
|
-
params: ClientTransportRpcCall,
|
|
39
|
-
): Promise<ClientTransportRpcResult>
|
|
40
|
-
}
|
package/lib/utils.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
export type AnyFn = (...args: any[]) => any
|
|
2
|
-
|
|
3
|
-
export type EventMap = { [K: string]: any[] }
|
|
4
|
-
|
|
5
|
-
export function forAborted(signal: AbortSignal) {
|
|
6
|
-
return new Promise((_, reject) => {
|
|
7
|
-
const handler = () => reject(new Error('aborted'))
|
|
8
|
-
const options = { once: true }
|
|
9
|
-
signal.addEventListener('abort', handler, options)
|
|
10
|
-
})
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function onAbort(signal: AbortSignal, listener: () => void) {
|
|
14
|
-
signal.addEventListener('abort', listener, { once: true })
|
|
15
|
-
return () => signal.removeEventListener('abort', listener)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Very simple node-like event emitter wrapper around EventTarget
|
|
20
|
-
*
|
|
21
|
-
* @todo add errors and promise rejections handling
|
|
22
|
-
*/
|
|
23
|
-
export class EventEmitter<
|
|
24
|
-
Events extends EventMap = EventMap,
|
|
25
|
-
EventNames extends Extract<keyof Events, string> = Extract<
|
|
26
|
-
keyof Events,
|
|
27
|
-
string
|
|
28
|
-
>,
|
|
29
|
-
> {
|
|
30
|
-
#target = new EventTarget()
|
|
31
|
-
#listeners = new Map<AnyFn, AnyFn>()
|
|
32
|
-
|
|
33
|
-
on<E extends EventNames>(
|
|
34
|
-
event: E | (Object & string),
|
|
35
|
-
listener: (...args: Events[E]) => void,
|
|
36
|
-
options?: AddEventListenerOptions,
|
|
37
|
-
) {
|
|
38
|
-
const wrapper = (event) => listener(...event.detail)
|
|
39
|
-
this.#listeners.set(listener, wrapper)
|
|
40
|
-
this.#target.addEventListener(event, wrapper, options)
|
|
41
|
-
return () => this.#target.removeEventListener(event, wrapper)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
once<E extends EventNames>(
|
|
45
|
-
event: E | (Object & string),
|
|
46
|
-
listener: (...args: Events[E]) => void,
|
|
47
|
-
) {
|
|
48
|
-
return this.on(event, listener, { once: true })
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
off(event: EventNames | (Object & string), listener: AnyFn) {
|
|
52
|
-
const wrapper = this.#listeners.get(listener)
|
|
53
|
-
if (wrapper) this.#target.removeEventListener(event, wrapper)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
emit<E extends EventNames | (Object & string)>(
|
|
57
|
-
event: E,
|
|
58
|
-
...args: E extends EventEmitter ? Events[E] : any[]
|
|
59
|
-
) {
|
|
60
|
-
return this.#target.dispatchEvent(new CustomEvent(event, { detail: args }))
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export const once = (ee: EventEmitter, event: string) =>
|
|
65
|
-
new Promise((resolve) => ee.once(event, resolve))
|
|
File without changes
|