@nmtjs/protocol 0.14.5 → 0.15.0-beta.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/LICENSE.md +1 -1
- package/README.md +1 -1
- package/package.json +17 -22
- package/dist/client/events.d.ts +0 -15
- package/dist/client/events.js +0 -28
- package/dist/client/format.d.ts +0 -21
- package/dist/client/format.js +0 -2
- package/dist/client/index.d.ts +0 -4
- package/dist/client/index.js +0 -4
- package/dist/client/protocol.d.ts +0 -150
- package/dist/client/protocol.js +0 -354
- package/dist/client/stream.d.ts +0 -31
- package/dist/client/stream.js +0 -98
- package/dist/common/binary.d.ts +0 -19
- package/dist/common/binary.js +0 -27
- package/dist/common/blob.d.ts +0 -22
- package/dist/common/blob.js +0 -42
- package/dist/common/enums.d.ts +0 -41
- package/dist/common/enums.js +0 -45
- package/dist/common/index.d.ts +0 -4
- package/dist/common/index.js +0 -4
- package/dist/common/types.d.ts +0 -33
- package/dist/common/types.js +0 -1
- package/dist/server/api.d.ts +0 -33
- package/dist/server/api.js +0 -7
- package/dist/server/connection.d.ts +0 -25
- package/dist/server/connection.js +0 -22
- package/dist/server/constants.d.ts +0 -4
- package/dist/server/constants.js +0 -2
- package/dist/server/format.d.ts +0 -40
- package/dist/server/format.js +0 -60
- package/dist/server/index.d.ts +0 -11
- package/dist/server/index.js +0 -11
- package/dist/server/injectables.d.ts +0 -14
- package/dist/server/injectables.js +0 -22
- package/dist/server/protocol.d.ts +0 -128
- package/dist/server/protocol.js +0 -374
- package/dist/server/registry.d.ts +0 -3
- package/dist/server/registry.js +0 -3
- package/dist/server/stream.d.ts +0 -13
- package/dist/server/stream.js +0 -32
- package/dist/server/transport.d.ts +0 -23
- package/dist/server/transport.js +0 -3
- package/dist/server/types.d.ts +0 -13
- package/dist/server/types.js +0 -1
- package/dist/server/utils.d.ts +0 -15
- package/dist/server/utils.js +0 -15
package/LICENSE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (c)
|
|
1
|
+
Copyright (c) 2025 Denys Ilchyshyn
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -2,40 +2,35 @@
|
|
|
2
2
|
"name": "@nmtjs/protocol",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"exports": {
|
|
5
|
-
".":
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"module-sync": "./dist/common/index.js"
|
|
9
|
-
},
|
|
10
|
-
"./server": {
|
|
11
|
-
"types": "./dist/server/index.d.ts",
|
|
12
|
-
"import": "./dist/server/index.js",
|
|
13
|
-
"module-sync": "./dist/server/index.js"
|
|
14
|
-
},
|
|
15
|
-
"./client": {
|
|
16
|
-
"types": "./dist/client/index.d.ts",
|
|
17
|
-
"import": "./dist/client/index.js",
|
|
18
|
-
"module-sync": "./dist/client/index.js"
|
|
19
|
-
}
|
|
5
|
+
".": "./dist/common/index.js",
|
|
6
|
+
"./server": "./dist/server/index.js",
|
|
7
|
+
"./client": "./dist/client/index.js"
|
|
20
8
|
},
|
|
21
9
|
"dependencies": {
|
|
22
|
-
"
|
|
23
|
-
"@nmtjs/
|
|
24
|
-
"@nmtjs/
|
|
10
|
+
"hookable": "6.0.0-rc.1",
|
|
11
|
+
"@nmtjs/common": "0.15.0-beta.1",
|
|
12
|
+
"@nmtjs/contract": "0.15.0-beta.1",
|
|
13
|
+
"@nmtjs/type": "0.15.0-beta.1"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@nmtjs/core": "0.15.0-beta.1"
|
|
25
17
|
},
|
|
26
18
|
"peerDependencies": {
|
|
27
|
-
"@nmtjs/common": "0.
|
|
28
|
-
"@nmtjs/
|
|
29
|
-
"@nmtjs/
|
|
19
|
+
"@nmtjs/common": "0.15.0-beta.1",
|
|
20
|
+
"@nmtjs/core": "0.15.0-beta.1",
|
|
21
|
+
"@nmtjs/type": "0.15.0-beta.1",
|
|
22
|
+
"@nmtjs/contract": "0.15.0-beta.1"
|
|
30
23
|
},
|
|
31
24
|
"files": [
|
|
32
25
|
"dist",
|
|
33
26
|
"LICENSE.md",
|
|
34
27
|
"README.md"
|
|
35
28
|
],
|
|
36
|
-
"version": "0.
|
|
29
|
+
"version": "0.15.0-beta.1",
|
|
37
30
|
"scripts": {
|
|
31
|
+
"clean-build": "rm -rf ./dist",
|
|
38
32
|
"build": "tsc",
|
|
33
|
+
"dev": "tsc --watch",
|
|
39
34
|
"type-check": "tsc --noEmit"
|
|
40
35
|
}
|
|
41
36
|
}
|
package/dist/client/events.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Callback } from '@nmtjs/common';
|
|
2
|
-
export type EventMap = {
|
|
3
|
-
[K: string]: any[];
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* Very simple node-like event emitter wrapper around EventTarget
|
|
7
|
-
*/
|
|
8
|
-
export declare class EventEmitter<Events extends EventMap = EventMap, EventName extends Extract<keyof Events, string> = Extract<keyof Events, string>> {
|
|
9
|
-
#private;
|
|
10
|
-
static once<T extends EventEmitter, E extends T extends EventEmitter<any, infer Event> ? Event : never>(ee: T, event: E): Promise<unknown>;
|
|
11
|
-
on<E extends EventName>(event: E | (Object & string), listener: (...args: Events[E]) => void, options?: AddEventListenerOptions): () => void;
|
|
12
|
-
once<E extends EventName>(event: E | (Object & string), listener: (...args: Events[E]) => void, options?: AddEventListenerOptions): () => void;
|
|
13
|
-
off(event: EventName | (Object & string), listener: Callback): void;
|
|
14
|
-
emit<E extends EventName | (Object & string)>(event: E, ...args: E extends EventName ? Events[E] : any[]): boolean;
|
|
15
|
-
}
|
package/dist/client/events.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// TODO: add errors and promise rejections handling
|
|
2
|
-
/**
|
|
3
|
-
* Very simple node-like event emitter wrapper around EventTarget
|
|
4
|
-
*/
|
|
5
|
-
export class EventEmitter {
|
|
6
|
-
static once(ee, event) {
|
|
7
|
-
return new Promise((resolve) => ee.once(event, resolve));
|
|
8
|
-
}
|
|
9
|
-
#target = new EventTarget();
|
|
10
|
-
#listeners = new Map();
|
|
11
|
-
on(event, listener, options) {
|
|
12
|
-
const wrapper = (event) => listener(...event.detail);
|
|
13
|
-
this.#listeners.set(listener, wrapper);
|
|
14
|
-
this.#target.addEventListener(event, wrapper, { ...options, once: false });
|
|
15
|
-
return () => this.#target.removeEventListener(event, wrapper);
|
|
16
|
-
}
|
|
17
|
-
once(event, listener, options) {
|
|
18
|
-
return this.on(event, listener, { ...options, once: true });
|
|
19
|
-
}
|
|
20
|
-
off(event, listener) {
|
|
21
|
-
const wrapper = this.#listeners.get(listener);
|
|
22
|
-
if (wrapper)
|
|
23
|
-
this.#target.removeEventListener(event, wrapper);
|
|
24
|
-
}
|
|
25
|
-
emit(event, ...args) {
|
|
26
|
-
return this.#target.dispatchEvent(new CustomEvent(event, { detail: args }));
|
|
27
|
-
}
|
|
28
|
-
}
|
package/dist/client/format.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { DecodeRPCContext, EncodeRPCContext, ProtocolRPC, ProtocolRPCResponse } from '../common/types.ts';
|
|
2
|
-
import type { ProtocolClientBlobStream, ProtocolServerBlobStream } from './stream.ts';
|
|
3
|
-
export type ProtocolRPCEncode = {
|
|
4
|
-
buffer: ArrayBuffer;
|
|
5
|
-
streams: Record<number, ProtocolClientBlobStream>;
|
|
6
|
-
};
|
|
7
|
-
export interface BaseClientDecoder {
|
|
8
|
-
decode(buffer: ArrayBuffer): any;
|
|
9
|
-
decodeRPC(buffer: ArrayBuffer, context: DecodeRPCContext<ProtocolServerBlobStream>): ProtocolRPCResponse<ProtocolServerBlobStream>;
|
|
10
|
-
}
|
|
11
|
-
export interface BaseClientEncoder {
|
|
12
|
-
encode(data: any): ArrayBuffer;
|
|
13
|
-
encodeRPC(rpc: ProtocolRPC, context: EncodeRPCContext<ProtocolClientBlobStream>): ProtocolRPCEncode;
|
|
14
|
-
}
|
|
15
|
-
export declare abstract class BaseClientFormat implements BaseClientDecoder, BaseClientEncoder {
|
|
16
|
-
abstract contentType: string;
|
|
17
|
-
abstract encode(data: any): ArrayBuffer;
|
|
18
|
-
abstract encodeRPC(rpc: ProtocolRPC, context: EncodeRPCContext<ProtocolClientBlobStream>): ProtocolRPCEncode;
|
|
19
|
-
abstract decode(buffer: ArrayBuffer): any;
|
|
20
|
-
abstract decodeRPC(buffer: ArrayBuffer, context: DecodeRPCContext<ProtocolServerBlobStream>): ProtocolRPCResponse<ProtocolServerBlobStream>;
|
|
21
|
-
}
|
package/dist/client/format.js
DELETED
package/dist/client/index.d.ts
DELETED
package/dist/client/index.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { InteractivePromise, OneOf } from '@nmtjs/common';
|
|
2
|
-
import type { ProtocolBlobMetadata } from '../common/blob.ts';
|
|
3
|
-
import type { BaseProtocolError, ProtocolRPCResponse } from '../common/types.ts';
|
|
4
|
-
import type { BaseClientFormat } from './format.ts';
|
|
5
|
-
import { ClientMessageType, ServerMessageType } from '../common/enums.ts';
|
|
6
|
-
import { EventEmitter } from './events.ts';
|
|
7
|
-
import { ProtocolClientBlobStream, ProtocolServerBlobStream, ProtocolServerStream } from './stream.ts';
|
|
8
|
-
export declare class ProtocolError extends Error implements BaseProtocolError {
|
|
9
|
-
code: string;
|
|
10
|
-
data?: any;
|
|
11
|
-
constructor(code: string, message?: string, data?: any);
|
|
12
|
-
get message(): string;
|
|
13
|
-
toString(): string;
|
|
14
|
-
toJSON(): {
|
|
15
|
-
code: string;
|
|
16
|
-
message: string;
|
|
17
|
-
data: any;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
export declare class ProtocolClientStreams {
|
|
21
|
-
#private;
|
|
22
|
-
get(streamId: number): ProtocolClientBlobStream;
|
|
23
|
-
add(source: ReadableStream, streamId: number, metadata: ProtocolBlobMetadata): ProtocolClientBlobStream;
|
|
24
|
-
remove(streamId: number): void;
|
|
25
|
-
abort(streamId: number, error?: Error): void;
|
|
26
|
-
pull(streamId: number, size: number): Promise<ArrayBuffer | null>;
|
|
27
|
-
end(streamId: number): void;
|
|
28
|
-
clear(error?: Error): void;
|
|
29
|
-
}
|
|
30
|
-
export declare class ProtocolServerStreams<T extends ProtocolServerStream = ProtocolServerStream> {
|
|
31
|
-
#private;
|
|
32
|
-
has(streamId: number): boolean;
|
|
33
|
-
get(streamId: number): T;
|
|
34
|
-
add(streamId: number, stream: T): T;
|
|
35
|
-
remove(streamId: number): void;
|
|
36
|
-
abort(streamId: number): void;
|
|
37
|
-
push(streamId: number, chunk: ArrayBuffer): Promise<void>;
|
|
38
|
-
end(streamId: number): void;
|
|
39
|
-
clear(error?: Error): void;
|
|
40
|
-
}
|
|
41
|
-
export type ProtocolTransportEventMap = {
|
|
42
|
-
connected: [];
|
|
43
|
-
disconnected: [reason: 'server' | 'client' | 'error'];
|
|
44
|
-
};
|
|
45
|
-
export interface ProtocolSendMetadata {
|
|
46
|
-
callId?: number;
|
|
47
|
-
streamId?: number;
|
|
48
|
-
}
|
|
49
|
-
export declare enum ProtocolTransportStatus {
|
|
50
|
-
CONNECTED = "CONNECTED",
|
|
51
|
-
DISCONNECTED = "DISCONNECTED",
|
|
52
|
-
CONNECTING = "CONNECTING"
|
|
53
|
-
}
|
|
54
|
-
export declare abstract class ProtocolTransport<Options = unknown> extends EventEmitter<ProtocolTransportEventMap> {
|
|
55
|
-
protected options?: Options | undefined;
|
|
56
|
-
status: ProtocolTransportStatus;
|
|
57
|
-
constructor(options?: Options | undefined);
|
|
58
|
-
abstract connect(auth: any, transformer: ProtocolBaseTransformer): Promise<void>;
|
|
59
|
-
abstract disconnect(): Promise<void>;
|
|
60
|
-
abstract call(procedure: string, payload: any, options: ProtocolBaseClientCallOptions, transformer: ProtocolBaseTransformer): Promise<ProtocolClientCall>;
|
|
61
|
-
abstract send(messageType: ClientMessageType, buffer: ArrayBuffer, metadata: ProtocolSendMetadata): Promise<void>;
|
|
62
|
-
}
|
|
63
|
-
export declare class ProtocolBaseTransformer {
|
|
64
|
-
encodeRPC(_procedure: string, payload: any): any;
|
|
65
|
-
decodeRPC(_procedure: string, payload: any): any;
|
|
66
|
-
decodeRPCChunk(_procedure: string, payload: any): any;
|
|
67
|
-
decodeEvent(_event: string, payload: any): any;
|
|
68
|
-
}
|
|
69
|
-
export type ProtocolClientCall = InteractivePromise<any> & {
|
|
70
|
-
procedure: string;
|
|
71
|
-
signal: AbortSignal;
|
|
72
|
-
};
|
|
73
|
-
export type ProtocolBaseClientOptions = {
|
|
74
|
-
transport: ProtocolTransport;
|
|
75
|
-
format: BaseClientFormat;
|
|
76
|
-
transformer?: ProtocolBaseTransformer;
|
|
77
|
-
timeout?: number;
|
|
78
|
-
};
|
|
79
|
-
export type ProtocolBaseClientCallOptions = {
|
|
80
|
-
signal?: AbortSignal;
|
|
81
|
-
timeout: number;
|
|
82
|
-
};
|
|
83
|
-
export declare class BaseProtocol<T extends Record<string, Record<string, any>> = Record<string, Record<string, any>>> extends EventEmitter<{
|
|
84
|
-
[N in keyof T]: {
|
|
85
|
-
[E in keyof T[N] as `${Extract<N, string>}/${Extract<E, string>}`]: [
|
|
86
|
-
payload: T[N][E]
|
|
87
|
-
];
|
|
88
|
-
};
|
|
89
|
-
}[keyof T]> {
|
|
90
|
-
readonly format: BaseClientFormat;
|
|
91
|
-
protected readonly clientStreams: ProtocolClientStreams;
|
|
92
|
-
protected readonly serverStreams: ProtocolServerStreams<ProtocolServerBlobStream>;
|
|
93
|
-
protected readonly rpcStreams: ProtocolServerStreams;
|
|
94
|
-
protected readonly calls: Map<number, ProtocolClientCall>;
|
|
95
|
-
protected callId: number;
|
|
96
|
-
protected streamId: number;
|
|
97
|
-
constructor(format: BaseClientFormat);
|
|
98
|
-
get contentType(): string;
|
|
99
|
-
handleCallResponse(callId: number, call: ProtocolClientCall, response: OneOf<[
|
|
100
|
-
{
|
|
101
|
-
error: BaseProtocolError;
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
result: any;
|
|
105
|
-
stream?: any;
|
|
106
|
-
}
|
|
107
|
-
]>, transformer: ProtocolBaseTransformer): void;
|
|
108
|
-
handleRpcResponse({ callId, error, result, streams }: ProtocolRPCResponse, transformer: ProtocolBaseTransformer, stream?: ProtocolServerStream): ProtocolClientCall;
|
|
109
|
-
handleRpcStreamResponse(response: ProtocolRPCResponse, stream: ProtocolServerStream, transformer: ProtocolBaseTransformer): ProtocolClientCall;
|
|
110
|
-
createCall(procedure: string, options: ProtocolBaseClientCallOptions): InteractivePromise<unknown> & {
|
|
111
|
-
procedure: string;
|
|
112
|
-
signal: AbortSignal;
|
|
113
|
-
};
|
|
114
|
-
createRpc(procedure: string, payload: any, options: ProtocolBaseClientCallOptions, transformer: ProtocolBaseTransformer): {
|
|
115
|
-
callId: number;
|
|
116
|
-
call: InteractivePromise<unknown> & {
|
|
117
|
-
procedure: string;
|
|
118
|
-
signal: AbortSignal;
|
|
119
|
-
};
|
|
120
|
-
streams: Record<number, ProtocolClientBlobStream>;
|
|
121
|
-
buffer: ArrayBuffer;
|
|
122
|
-
};
|
|
123
|
-
pushRpcStream(callId: number, chunk: any): void;
|
|
124
|
-
endRpcStream(callId: number): void;
|
|
125
|
-
abortRpcStream(callId: number): void;
|
|
126
|
-
removeClientStream(streamId: number): void;
|
|
127
|
-
pullClientStream(streamId: number, size: number): Promise<ArrayBuffer | null>;
|
|
128
|
-
endClientStream(streamId: number): void;
|
|
129
|
-
abortClientStream(streamId: number, error?: Error): void;
|
|
130
|
-
addServerStream(stream: ProtocolServerBlobStream): void;
|
|
131
|
-
removeServerStream(streamId: number): void;
|
|
132
|
-
pushServerStream(streamId: number, chunk: ArrayBuffer): Promise<void>;
|
|
133
|
-
endServerStream(streamId: number): void;
|
|
134
|
-
abortServerStream(streamId: number, _error?: Error): void;
|
|
135
|
-
emitEvent(event: string, payload: string, transformer: ProtocolBaseTransformer): void;
|
|
136
|
-
}
|
|
137
|
-
export declare class Protocol<T extends Record<string, Record<string, any>> = Record<string, Record<string, any>>> extends BaseProtocol<T> {
|
|
138
|
-
handleServerMessage(buffer: ArrayBuffer, transport: ProtocolTransport, transformer: ProtocolBaseTransformer): void;
|
|
139
|
-
protected [ServerMessageType.Event](buffer: ArrayBuffer, _transport: ProtocolTransport, transformer: ProtocolBaseTransformer): void;
|
|
140
|
-
protected [ServerMessageType.RpcResponse](buffer: ArrayBuffer, transport: ProtocolTransport, transformer: ProtocolBaseTransformer): void;
|
|
141
|
-
protected [ServerMessageType.RpcStreamResponse](buffer: ArrayBuffer, transport: ProtocolTransport, transformer: ProtocolBaseTransformer): void;
|
|
142
|
-
protected [ServerMessageType.RpcStreamChunk](buffer: ArrayBuffer, _transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
143
|
-
protected [ServerMessageType.RpcStreamEnd](buffer: ArrayBuffer, _transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
144
|
-
protected [ServerMessageType.RpcStreamAbort](buffer: ArrayBuffer, _transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
145
|
-
protected [ServerMessageType.ServerStreamPush](buffer: ArrayBuffer, transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
146
|
-
protected [ServerMessageType.ServerStreamEnd](buffer: ArrayBuffer, _transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
147
|
-
protected [ServerMessageType.ServerStreamAbort](buffer: ArrayBuffer, _transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
148
|
-
protected [ServerMessageType.ClientStreamPull](buffer: ArrayBuffer, transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
149
|
-
protected [ServerMessageType.ClientStreamAbort](buffer: ArrayBuffer, _transport: ProtocolTransport, _transformer: ProtocolBaseTransformer): void;
|
|
150
|
-
}
|
package/dist/client/protocol.js
DELETED
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
import { createPromise } from '@nmtjs/common';
|
|
2
|
-
import { concat, decodeNumber, encodeNumber } from "../common/binary.js";
|
|
3
|
-
import { ClientMessageType, ErrorCode, ServerMessageType, } from "../common/enums.js";
|
|
4
|
-
import { EventEmitter } from "./events.js";
|
|
5
|
-
import { ProtocolClientBlobStream, ProtocolServerBlobStream, ProtocolServerStream, } from "./stream.js";
|
|
6
|
-
export class ProtocolError extends Error {
|
|
7
|
-
code;
|
|
8
|
-
data;
|
|
9
|
-
constructor(code, message, data) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.code = code;
|
|
12
|
-
this.data = data;
|
|
13
|
-
}
|
|
14
|
-
get message() {
|
|
15
|
-
return `${this.code} ${super.message}`;
|
|
16
|
-
}
|
|
17
|
-
toString() {
|
|
18
|
-
return `${this.code} ${this.message}`;
|
|
19
|
-
}
|
|
20
|
-
toJSON() {
|
|
21
|
-
return { code: this.code, message: this.message, data: this.data };
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
export class ProtocolClientStreams {
|
|
25
|
-
#collection = new Map();
|
|
26
|
-
get(streamId) {
|
|
27
|
-
const stream = this.#collection.get(streamId);
|
|
28
|
-
if (!stream)
|
|
29
|
-
throw new Error('Stream not found');
|
|
30
|
-
return stream;
|
|
31
|
-
}
|
|
32
|
-
add(source, streamId, metadata) {
|
|
33
|
-
const stream = new ProtocolClientBlobStream(source, streamId, metadata);
|
|
34
|
-
this.#collection.set(streamId, stream);
|
|
35
|
-
return stream;
|
|
36
|
-
}
|
|
37
|
-
remove(streamId) {
|
|
38
|
-
this.#collection.delete(streamId);
|
|
39
|
-
}
|
|
40
|
-
abort(streamId, error) {
|
|
41
|
-
const stream = this.get(streamId);
|
|
42
|
-
stream.abort(error);
|
|
43
|
-
this.remove(streamId);
|
|
44
|
-
}
|
|
45
|
-
pull(streamId, size) {
|
|
46
|
-
const stream = this.get(streamId);
|
|
47
|
-
return stream.read(size);
|
|
48
|
-
}
|
|
49
|
-
end(streamId) {
|
|
50
|
-
this.get(streamId).end();
|
|
51
|
-
this.remove(streamId);
|
|
52
|
-
}
|
|
53
|
-
clear(error) {
|
|
54
|
-
if (error) {
|
|
55
|
-
for (const stream of this.#collection.values()) {
|
|
56
|
-
stream.abort(error);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
this.#collection.clear();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
export class ProtocolServerStreams {
|
|
63
|
-
#collection = new Map();
|
|
64
|
-
has(streamId) {
|
|
65
|
-
return this.#collection.has(streamId);
|
|
66
|
-
}
|
|
67
|
-
get(streamId) {
|
|
68
|
-
const stream = this.#collection.get(streamId);
|
|
69
|
-
if (!stream)
|
|
70
|
-
throw new Error('Stream not found');
|
|
71
|
-
return stream;
|
|
72
|
-
}
|
|
73
|
-
add(streamId, stream) {
|
|
74
|
-
this.#collection.set(streamId, stream);
|
|
75
|
-
return stream;
|
|
76
|
-
}
|
|
77
|
-
remove(streamId) {
|
|
78
|
-
this.#collection.delete(streamId);
|
|
79
|
-
}
|
|
80
|
-
abort(streamId) {
|
|
81
|
-
if (this.has(streamId)) {
|
|
82
|
-
const stream = this.get(streamId);
|
|
83
|
-
stream.abort();
|
|
84
|
-
this.remove(streamId);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
async push(streamId, chunk) {
|
|
88
|
-
const stream = this.get(streamId);
|
|
89
|
-
return await stream.push(chunk);
|
|
90
|
-
}
|
|
91
|
-
end(streamId) {
|
|
92
|
-
const stream = this.get(streamId);
|
|
93
|
-
stream.end();
|
|
94
|
-
this.remove(streamId);
|
|
95
|
-
}
|
|
96
|
-
clear(error) {
|
|
97
|
-
if (error) {
|
|
98
|
-
for (const stream of this.#collection.values()) {
|
|
99
|
-
stream.abort(error);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
this.#collection.clear();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
export var ProtocolTransportStatus;
|
|
106
|
-
(function (ProtocolTransportStatus) {
|
|
107
|
-
ProtocolTransportStatus["CONNECTED"] = "CONNECTED";
|
|
108
|
-
ProtocolTransportStatus["DISCONNECTED"] = "DISCONNECTED";
|
|
109
|
-
ProtocolTransportStatus["CONNECTING"] = "CONNECTING";
|
|
110
|
-
})(ProtocolTransportStatus || (ProtocolTransportStatus = {}));
|
|
111
|
-
export class ProtocolTransport extends EventEmitter {
|
|
112
|
-
options;
|
|
113
|
-
status = ProtocolTransportStatus.DISCONNECTED;
|
|
114
|
-
constructor(options) {
|
|
115
|
-
super();
|
|
116
|
-
this.options = options;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
export class ProtocolBaseTransformer {
|
|
120
|
-
encodeRPC(_procedure, payload) {
|
|
121
|
-
return payload;
|
|
122
|
-
}
|
|
123
|
-
decodeRPC(_procedure, payload) {
|
|
124
|
-
return payload;
|
|
125
|
-
}
|
|
126
|
-
decodeRPCChunk(_procedure, payload) {
|
|
127
|
-
return payload;
|
|
128
|
-
}
|
|
129
|
-
decodeEvent(_event, payload) {
|
|
130
|
-
return payload;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
export class BaseProtocol extends EventEmitter {
|
|
134
|
-
format;
|
|
135
|
-
clientStreams = new ProtocolClientStreams();
|
|
136
|
-
serverStreams = new ProtocolServerStreams();
|
|
137
|
-
rpcStreams = new ProtocolServerStreams();
|
|
138
|
-
calls = new Map();
|
|
139
|
-
callId = 0;
|
|
140
|
-
streamId = 0;
|
|
141
|
-
constructor(format) {
|
|
142
|
-
super();
|
|
143
|
-
this.format = format;
|
|
144
|
-
}
|
|
145
|
-
get contentType() {
|
|
146
|
-
return this.format.contentType;
|
|
147
|
-
}
|
|
148
|
-
handleCallResponse(callId, call, response, transformer) {
|
|
149
|
-
if (response.error) {
|
|
150
|
-
call.reject(new ProtocolError(response.error.code, response.error.message, response.error.data));
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
try {
|
|
154
|
-
const transformed = transformer.decodeRPC(call.procedure, response.result);
|
|
155
|
-
if (response.stream)
|
|
156
|
-
call.resolve({ result: transformed, stream: response.stream });
|
|
157
|
-
else
|
|
158
|
-
call.resolve(transformed);
|
|
159
|
-
}
|
|
160
|
-
catch (error) {
|
|
161
|
-
call.reject(new ProtocolError(ErrorCode.ClientRequestError, 'Unable to decode response', error));
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
this.calls.delete(callId);
|
|
165
|
-
}
|
|
166
|
-
handleRpcResponse({ callId, error, result, streams }, transformer, stream) {
|
|
167
|
-
const call = this.calls.get(callId);
|
|
168
|
-
if (!call)
|
|
169
|
-
throw new Error('Call not found');
|
|
170
|
-
for (const key in streams) {
|
|
171
|
-
const stream = streams[key];
|
|
172
|
-
this.serverStreams.add(stream.id, stream);
|
|
173
|
-
}
|
|
174
|
-
this.handleCallResponse(callId, call, error ? { error } : { result, stream }, transformer);
|
|
175
|
-
return call;
|
|
176
|
-
}
|
|
177
|
-
handleRpcStreamResponse(response, stream, transformer) {
|
|
178
|
-
const call = this.handleRpcResponse(response, transformer, stream);
|
|
179
|
-
this.rpcStreams.add(response.callId, stream);
|
|
180
|
-
return call;
|
|
181
|
-
}
|
|
182
|
-
createCall(procedure, options) {
|
|
183
|
-
const timeoutSignal = AbortSignal.timeout(options.timeout);
|
|
184
|
-
const signal = options.signal
|
|
185
|
-
? AbortSignal.any([options.signal, timeoutSignal])
|
|
186
|
-
: timeoutSignal;
|
|
187
|
-
const call = Object.assign(createPromise(), { procedure, signal });
|
|
188
|
-
timeoutSignal.addEventListener('abort', () => {
|
|
189
|
-
const error = new ProtocolError(ErrorCode.RequestTimeout, 'Request timeout');
|
|
190
|
-
call.reject(error);
|
|
191
|
-
}, { once: true });
|
|
192
|
-
return call;
|
|
193
|
-
}
|
|
194
|
-
createRpc(procedure, payload, options, transformer) {
|
|
195
|
-
const callId = ++this.callId;
|
|
196
|
-
const call = this.createCall(procedure, options);
|
|
197
|
-
const { buffer, streams } = this.format.encodeRPC({ callId, procedure, payload: transformer.encodeRPC(procedure, payload) }, {
|
|
198
|
-
addStream: (blob) => {
|
|
199
|
-
const streamId = ++this.streamId;
|
|
200
|
-
return this.clientStreams.add(blob.source, streamId, blob.metadata);
|
|
201
|
-
},
|
|
202
|
-
getStream: (id) => {
|
|
203
|
-
const stream = this.clientStreams.get(id);
|
|
204
|
-
return stream;
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
this.calls.set(callId, call);
|
|
208
|
-
return { callId, call, streams, buffer };
|
|
209
|
-
}
|
|
210
|
-
pushRpcStream(callId, chunk) {
|
|
211
|
-
this.rpcStreams.push(callId, chunk);
|
|
212
|
-
}
|
|
213
|
-
endRpcStream(callId) {
|
|
214
|
-
this.rpcStreams.end(callId);
|
|
215
|
-
}
|
|
216
|
-
abortRpcStream(callId) {
|
|
217
|
-
this.rpcStreams.abort(callId);
|
|
218
|
-
}
|
|
219
|
-
removeClientStream(streamId) {
|
|
220
|
-
this.clientStreams.remove(streamId);
|
|
221
|
-
}
|
|
222
|
-
pullClientStream(streamId, size) {
|
|
223
|
-
return this.clientStreams.pull(streamId, size);
|
|
224
|
-
}
|
|
225
|
-
endClientStream(streamId) {
|
|
226
|
-
this.clientStreams.end(streamId);
|
|
227
|
-
}
|
|
228
|
-
abortClientStream(streamId, error) {
|
|
229
|
-
this.clientStreams.abort(streamId, error);
|
|
230
|
-
}
|
|
231
|
-
addServerStream(stream) {
|
|
232
|
-
this.serverStreams.add(stream.id, stream);
|
|
233
|
-
}
|
|
234
|
-
removeServerStream(streamId) {
|
|
235
|
-
this.serverStreams.remove(streamId);
|
|
236
|
-
}
|
|
237
|
-
pushServerStream(streamId, chunk) {
|
|
238
|
-
return this.serverStreams.push(streamId, chunk);
|
|
239
|
-
}
|
|
240
|
-
endServerStream(streamId) {
|
|
241
|
-
this.serverStreams.end(streamId);
|
|
242
|
-
}
|
|
243
|
-
abortServerStream(streamId, _error) {
|
|
244
|
-
this.serverStreams.abort(streamId);
|
|
245
|
-
}
|
|
246
|
-
emitEvent(event, payload, transformer) {
|
|
247
|
-
const transformed = transformer.decodeEvent(event, payload);
|
|
248
|
-
this.emit(event,
|
|
249
|
-
//@ts-expect-error
|
|
250
|
-
transformed);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
export class Protocol extends BaseProtocol {
|
|
254
|
-
handleServerMessage(buffer, transport, transformer) {
|
|
255
|
-
const type = decodeNumber(buffer, 'Uint8');
|
|
256
|
-
const messageBuffer = buffer.slice(Uint8Array.BYTES_PER_ELEMENT);
|
|
257
|
-
if (type in ServerMessageType) {
|
|
258
|
-
const messageType = type;
|
|
259
|
-
if (typeof ServerMessageType[messageType] !== 'undefined') {
|
|
260
|
-
this[messageType](messageBuffer, transport, transformer);
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
throw new Error(`Unknown message type: ${messageType}`);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
[ServerMessageType.Event](buffer, _transport, transformer) {
|
|
268
|
-
const [event, payload] = this.format.decode(buffer);
|
|
269
|
-
this.emitEvent(event, payload, transformer);
|
|
270
|
-
}
|
|
271
|
-
[ServerMessageType.RpcResponse](buffer, transport, transformer) {
|
|
272
|
-
const response = this.format.decodeRPC(buffer, {
|
|
273
|
-
addStream: (id, callId, metadata) => {
|
|
274
|
-
return new ProtocolServerBlobStream(id, metadata, {
|
|
275
|
-
start: () => {
|
|
276
|
-
transport.send(ClientMessageType.ServerStreamPull, encodeNumber(id, 'Uint32'), { callId, streamId: id });
|
|
277
|
-
},
|
|
278
|
-
});
|
|
279
|
-
},
|
|
280
|
-
getStream: (id) => {
|
|
281
|
-
return this.serverStreams.get(id);
|
|
282
|
-
},
|
|
283
|
-
});
|
|
284
|
-
this.handleRpcResponse(response, transformer);
|
|
285
|
-
}
|
|
286
|
-
[ServerMessageType.RpcStreamResponse](buffer, transport, transformer) {
|
|
287
|
-
const response = this.format.decodeRPC(buffer, {
|
|
288
|
-
addStream: (id, callId, metadata) => {
|
|
289
|
-
return new ProtocolServerBlobStream(id, metadata, {
|
|
290
|
-
start: () => {
|
|
291
|
-
transport.send(ClientMessageType.ServerStreamPull, encodeNumber(id, 'Uint32'), { callId, streamId: id });
|
|
292
|
-
},
|
|
293
|
-
});
|
|
294
|
-
},
|
|
295
|
-
getStream: (id) => {
|
|
296
|
-
return this.serverStreams.get(id);
|
|
297
|
-
},
|
|
298
|
-
});
|
|
299
|
-
const stream = new ProtocolServerStream({
|
|
300
|
-
transform: (chunk, controller) => {
|
|
301
|
-
const transformed = transformer.decodeRPCChunk(call.procedure, chunk);
|
|
302
|
-
controller.enqueue(transformed);
|
|
303
|
-
},
|
|
304
|
-
});
|
|
305
|
-
const call = this.handleRpcStreamResponse(response, stream, transformer);
|
|
306
|
-
}
|
|
307
|
-
[ServerMessageType.RpcStreamChunk](buffer, _transport, _transformer) {
|
|
308
|
-
const callId = decodeNumber(buffer, 'Uint32');
|
|
309
|
-
const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
|
|
310
|
-
const payload = this.format.decode(chunk);
|
|
311
|
-
this.pushRpcStream(callId, payload);
|
|
312
|
-
}
|
|
313
|
-
[ServerMessageType.RpcStreamEnd](buffer, _transport, _transformer) {
|
|
314
|
-
const callId = decodeNumber(buffer, 'Uint32');
|
|
315
|
-
this.endRpcStream(callId);
|
|
316
|
-
}
|
|
317
|
-
[ServerMessageType.RpcStreamAbort](buffer, _transport, _transformer) {
|
|
318
|
-
const callId = decodeNumber(buffer, 'Uint32');
|
|
319
|
-
this.abortRpcStream(callId);
|
|
320
|
-
}
|
|
321
|
-
[ServerMessageType.ServerStreamPush](buffer, transport, _transformer) {
|
|
322
|
-
const streamId = decodeNumber(buffer, 'Uint32');
|
|
323
|
-
const chunk = buffer.slice(Uint32Array.BYTES_PER_ELEMENT);
|
|
324
|
-
this.pushServerStream(streamId, chunk);
|
|
325
|
-
transport.send(ClientMessageType.ServerStreamPull, encodeNumber(streamId, 'Uint32'), { streamId });
|
|
326
|
-
}
|
|
327
|
-
[ServerMessageType.ServerStreamEnd](buffer, _transport, _transformer) {
|
|
328
|
-
const streamId = decodeNumber(buffer, 'Uint32');
|
|
329
|
-
this.endServerStream(streamId);
|
|
330
|
-
}
|
|
331
|
-
[ServerMessageType.ServerStreamAbort](buffer, _transport, _transformer) {
|
|
332
|
-
const streamId = decodeNumber(buffer, 'Uint32');
|
|
333
|
-
this.abortServerStream(streamId);
|
|
334
|
-
}
|
|
335
|
-
[ServerMessageType.ClientStreamPull](buffer, transport, _transformer) {
|
|
336
|
-
const streamId = decodeNumber(buffer, 'Uint32');
|
|
337
|
-
const size = decodeNumber(buffer, 'Uint32', Uint32Array.BYTES_PER_ELEMENT);
|
|
338
|
-
this.pullClientStream(streamId, size).then((chunk) => {
|
|
339
|
-
if (chunk) {
|
|
340
|
-
transport.send(ClientMessageType.ClientStreamPush, concat(encodeNumber(streamId, 'Uint32'), chunk), { streamId });
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
transport.send(ClientMessageType.ClientStreamEnd, encodeNumber(streamId, 'Uint32'), { streamId });
|
|
344
|
-
this.endClientStream(streamId);
|
|
345
|
-
}
|
|
346
|
-
}, () => {
|
|
347
|
-
transport.send(ClientMessageType.ClientStreamAbort, encodeNumber(streamId, 'Uint32'), { streamId });
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
[ServerMessageType.ClientStreamAbort](buffer, _transport, _transformer) {
|
|
351
|
-
const streamId = decodeNumber(buffer, 'Uint32');
|
|
352
|
-
this.abortClientStream(streamId);
|
|
353
|
-
}
|
|
354
|
-
}
|