@litert/televoke 1.1.0 → 1.3.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.
Files changed (236) hide show
  1. package/CHANGES.md +25 -0
  2. package/docs/README.md +6 -0
  3. package/docs/Televoke_v2.1.md +499 -0
  4. package/docs/Televoke_v2.md +1 -1
  5. package/lib/client/Client.Constants.d.ts +5 -0
  6. package/lib/client/Client.Constants.d.ts.map +1 -0
  7. package/lib/client/Client.Constants.js +9 -0
  8. package/lib/client/Client.Constants.js.map +1 -0
  9. package/lib/client/Client.decl.d.ts +32 -2
  10. package/lib/client/Client.decl.d.ts.map +1 -1
  11. package/lib/client/Client.decl.js +1 -1
  12. package/lib/client/JsonApiClient.impl.d.ts +1 -1
  13. package/lib/client/JsonApiClient.impl.d.ts.map +1 -1
  14. package/lib/client/JsonApiClient.impl.js +30 -5
  15. package/lib/client/JsonApiClient.impl.js.map +1 -1
  16. package/lib/client/index.d.ts +1 -1
  17. package/lib/client/index.js +1 -1
  18. package/lib/index.d.ts +1 -1
  19. package/lib/index.js +1 -1
  20. package/lib/server/LegacyServerChannel.impl.d.ts +2 -2
  21. package/lib/server/LegacyServerChannel.impl.d.ts.map +1 -1
  22. package/lib/server/LegacyServerChannel.impl.js +1 -1
  23. package/lib/server/Server.decl.d.ts +18 -3
  24. package/lib/server/Server.decl.d.ts.map +1 -1
  25. package/lib/server/Server.decl.js +1 -1
  26. package/lib/server/Server.impl.d.ts +1 -1
  27. package/lib/server/Server.impl.d.ts.map +1 -1
  28. package/lib/server/Server.impl.js +5 -4
  29. package/lib/server/Server.impl.js.map +1 -1
  30. package/lib/server/ServerChannel.d.ts +1 -1
  31. package/lib/server/ServerChannel.js +1 -1
  32. package/lib/server/SimpleJsonApiRouter.d.ts +2 -2
  33. package/lib/server/SimpleJsonApiRouter.d.ts.map +1 -1
  34. package/lib/server/SimpleJsonApiRouter.js +9 -4
  35. package/lib/server/SimpleJsonApiRouter.js.map +1 -1
  36. package/lib/server/index.d.ts +1 -1
  37. package/lib/server/index.js +1 -1
  38. package/lib/shared/BinaryStream.d.ts +1 -1
  39. package/lib/shared/BinaryStream.js +1 -1
  40. package/lib/shared/BinaryStreamManager.d.ts +1 -1
  41. package/lib/shared/BinaryStreamManager.js +1 -1
  42. package/lib/shared/Channel.impl.d.ts +2 -2
  43. package/lib/shared/Channel.impl.d.ts.map +1 -1
  44. package/lib/shared/Channel.impl.js +23 -11
  45. package/lib/shared/Channel.impl.js.map +1 -1
  46. package/lib/shared/Constants.d.ts +1 -1
  47. package/lib/shared/Constants.js +1 -1
  48. package/lib/shared/Encodings/index.d.ts +1 -1
  49. package/lib/shared/Encodings/index.js +1 -1
  50. package/lib/shared/Encodings/v1/EncoderV1.d.ts +1 -1
  51. package/lib/shared/Encodings/v1/EncoderV1.js +1 -1
  52. package/lib/shared/Encodings/v1/Protocol.v1.decls.d.ts +1 -1
  53. package/lib/shared/Encodings/v1/Protocol.v1.decls.js +1 -1
  54. package/lib/shared/Encodings/v1/index.d.ts +1 -1
  55. package/lib/shared/Encodings/v1/index.js +1 -1
  56. package/lib/shared/Encodings/v2/Constants.v2.d.ts +14 -1
  57. package/lib/shared/Encodings/v2/Constants.v2.d.ts.map +1 -1
  58. package/lib/shared/Encodings/v2/Constants.v2.js +17 -2
  59. package/lib/shared/Encodings/v2/Constants.v2.js.map +1 -1
  60. package/lib/shared/Encodings/v2/DecoderV2.d.ts +1 -1
  61. package/lib/shared/Encodings/v2/DecoderV2.d.ts.map +1 -1
  62. package/lib/shared/Encodings/v2/DecoderV2.js +81 -7
  63. package/lib/shared/Encodings/v2/DecoderV2.js.map +1 -1
  64. package/lib/shared/Encodings/v2/EncoderV2.d.ts +3 -2
  65. package/lib/shared/Encodings/v2/EncoderV2.d.ts.map +1 -1
  66. package/lib/shared/Encodings/v2/EncoderV2.js +104 -25
  67. package/lib/shared/Encodings/v2/EncoderV2.js.map +1 -1
  68. package/lib/shared/Encodings/v2/Encoding.v2.decl.d.ts +70 -40
  69. package/lib/shared/Encodings/v2/Encoding.v2.decl.d.ts.map +1 -1
  70. package/lib/shared/Encodings/v2/Encoding.v2.decl.js +1 -1
  71. package/lib/shared/Encodings/v2/index.d.ts +1 -1
  72. package/lib/shared/Encodings/v2/index.js +1 -1
  73. package/lib/shared/Errors.d.ts +2 -1
  74. package/lib/shared/Errors.d.ts.map +1 -1
  75. package/lib/shared/Errors.js +2 -1
  76. package/lib/shared/Errors.js.map +1 -1
  77. package/lib/shared/Shared.decl.d.ts +17 -17
  78. package/lib/shared/Shared.decl.d.ts.map +1 -1
  79. package/lib/shared/Shared.decl.js +1 -1
  80. package/lib/shared/Utils.d.ts +2 -2
  81. package/lib/shared/Utils.d.ts.map +1 -1
  82. package/lib/shared/Utils.js +1 -1
  83. package/lib/shared/Utils.js.map +1 -1
  84. package/lib/shared/index.d.ts +1 -1
  85. package/lib/shared/index.js +1 -1
  86. package/lib/transporters/Transporter.decl.d.ts +1 -1
  87. package/lib/transporters/Transporter.decl.js +1 -1
  88. package/lib/transporters/http-listener/AbstractHttpListener.d.ts +2 -2
  89. package/lib/transporters/http-listener/AbstractHttpListener.d.ts.map +1 -1
  90. package/lib/transporters/http-listener/AbstractHttpListener.js +10 -6
  91. package/lib/transporters/http-listener/AbstractHttpListener.js.map +1 -1
  92. package/lib/transporters/http-listener/Http.Decl.d.ts +1 -5
  93. package/lib/transporters/http-listener/Http.Decl.d.ts.map +1 -1
  94. package/lib/transporters/http-listener/Http.Decl.js +2 -22
  95. package/lib/transporters/http-listener/Http.Decl.js.map +1 -1
  96. package/lib/transporters/http-listener/HttpListener.d.ts +1 -1
  97. package/lib/transporters/http-listener/HttpListener.d.ts.map +1 -1
  98. package/lib/transporters/http-listener/HttpListener.js +4 -2
  99. package/lib/transporters/http-listener/HttpListener.js.map +1 -1
  100. package/lib/transporters/http-listener/HttpUnixSocketListener.d.ts +1 -1
  101. package/lib/transporters/http-listener/HttpUnixSocketListener.d.ts.map +1 -1
  102. package/lib/transporters/http-listener/HttpUnixSocketListener.js +4 -2
  103. package/lib/transporters/http-listener/HttpUnixSocketListener.js.map +1 -1
  104. package/lib/transporters/http-listener/HttpsListener.d.ts +1 -1
  105. package/lib/transporters/http-listener/HttpsListener.d.ts.map +1 -1
  106. package/lib/transporters/http-listener/HttpsListener.js +6 -4
  107. package/lib/transporters/http-listener/HttpsListener.js.map +1 -1
  108. package/lib/transporters/http-listener/index.d.ts +1 -1
  109. package/lib/transporters/http-listener/index.js +1 -1
  110. package/lib/transporters/index.d.ts +1 -1
  111. package/lib/transporters/index.js +1 -1
  112. package/lib/transporters/legacy-http/LegacyHttp.Client.Native.d.ts +12 -2
  113. package/lib/transporters/legacy-http/LegacyHttp.Client.Native.d.ts.map +1 -1
  114. package/lib/transporters/legacy-http/LegacyHttp.Client.Native.js +33 -7
  115. package/lib/transporters/legacy-http/LegacyHttp.Client.Native.js.map +1 -1
  116. package/lib/transporters/legacy-http/LegacyHttp.Server.d.ts +29 -1
  117. package/lib/transporters/legacy-http/LegacyHttp.Server.d.ts.map +1 -1
  118. package/lib/transporters/legacy-http/LegacyHttp.Server.js +35 -10
  119. package/lib/transporters/legacy-http/LegacyHttp.Server.js.map +1 -1
  120. package/lib/transporters/legacy-http/LegacyHttp.Transporter.d.ts +1 -1
  121. package/lib/transporters/legacy-http/LegacyHttp.Transporter.js +1 -1
  122. package/lib/transporters/legacy-http/index.d.ts +1 -1
  123. package/lib/transporters/legacy-http/index.js +1 -1
  124. package/lib/transporters/lwdfx/LwDFX.Tcp.Client.d.ts +1 -1
  125. package/lib/transporters/lwdfx/LwDFX.Tcp.Client.js +1 -1
  126. package/lib/transporters/lwdfx/LwDFX.Tcp.Server.d.ts +1 -1
  127. package/lib/transporters/lwdfx/LwDFX.Tcp.Server.js +1 -1
  128. package/lib/transporters/lwdfx/LwDFX.Tls.Client.d.ts +1 -1
  129. package/lib/transporters/lwdfx/LwDFX.Tls.Client.js +1 -1
  130. package/lib/transporters/lwdfx/LwDFX.Tls.Server.d.ts +1 -1
  131. package/lib/transporters/lwdfx/LwDFX.Tls.Server.js +1 -1
  132. package/lib/transporters/lwdfx/LwDFX.Transporter.d.ts +1 -1
  133. package/lib/transporters/lwdfx/LwDFX.Transporter.js +1 -1
  134. package/lib/transporters/lwdfx/LwDFX.UnixSocket.Client.d.ts +1 -1
  135. package/lib/transporters/lwdfx/LwDFX.UnixSocket.Client.js +1 -1
  136. package/lib/transporters/lwdfx/LwDFX.UnixSocket.Server.d.ts +1 -1
  137. package/lib/transporters/lwdfx/LwDFX.UnixSocket.Server.js +1 -1
  138. package/lib/transporters/lwdfx/LwDFX.decl.d.ts +1 -1
  139. package/lib/transporters/lwdfx/LwDFX.decl.js +1 -1
  140. package/lib/transporters/lwdfx/index.d.ts +1 -1
  141. package/lib/transporters/lwdfx/index.js +1 -1
  142. package/lib/transporters/memory/Memory.Impl.d.ts +1 -1
  143. package/lib/transporters/memory/Memory.Impl.js +1 -1
  144. package/lib/transporters/memory/Memory.Impl.js.map +1 -1
  145. package/lib/transporters/memory/index.d.ts +1 -1
  146. package/lib/transporters/memory/index.js +1 -1
  147. package/lib/transporters/websocket/WebSocket.Client.d.ts +18 -3
  148. package/lib/transporters/websocket/WebSocket.Client.d.ts.map +1 -1
  149. package/lib/transporters/websocket/WebSocket.Client.js +21 -1
  150. package/lib/transporters/websocket/WebSocket.Client.js.map +1 -1
  151. package/lib/transporters/websocket/WebSocket.Server.d.ts +24 -2
  152. package/lib/transporters/websocket/WebSocket.Server.d.ts.map +1 -1
  153. package/lib/transporters/websocket/WebSocket.Server.js +29 -10
  154. package/lib/transporters/websocket/WebSocket.Server.js.map +1 -1
  155. package/lib/transporters/websocket/WebSocket.Transporter.d.ts +1 -1
  156. package/lib/transporters/websocket/WebSocket.Transporter.js +1 -1
  157. package/lib/transporters/websocket/WebSocket.decl.d.ts +1 -1
  158. package/lib/transporters/websocket/WebSocket.decl.js +1 -1
  159. package/lib/transporters/websocket/index.d.ts +1 -1
  160. package/lib/transporters/websocket/index.js +1 -1
  161. package/lib/transporters/worker-thread/WorkerThread.Client.d.ts +1 -1
  162. package/lib/transporters/worker-thread/WorkerThread.Client.js +1 -1
  163. package/lib/transporters/worker-thread/WorkerThread.Constants.d.ts +1 -1
  164. package/lib/transporters/worker-thread/WorkerThread.Constants.js +1 -1
  165. package/lib/transporters/worker-thread/WorkerThread.Errors.d.ts +1 -1
  166. package/lib/transporters/worker-thread/WorkerThread.Errors.d.ts.map +1 -1
  167. package/lib/transporters/worker-thread/WorkerThread.Errors.js +1 -1
  168. package/lib/transporters/worker-thread/WorkerThread.Server.d.ts +1 -1
  169. package/lib/transporters/worker-thread/WorkerThread.Server.js +1 -1
  170. package/lib/transporters/worker-thread/WorkerThread.Transporter.d.ts +1 -1
  171. package/lib/transporters/worker-thread/WorkerThread.Transporter.js +1 -1
  172. package/lib/transporters/worker-thread/index.d.ts +1 -1
  173. package/lib/transporters/worker-thread/index.js +1 -1
  174. package/package.json +5 -5
  175. package/src/lib/client/Client.Constants.ts +4 -0
  176. package/src/lib/client/Client.decl.ts +42 -2
  177. package/src/lib/client/JsonApiClient.impl.ts +59 -8
  178. package/src/lib/client/index.ts +1 -1
  179. package/src/lib/index.ts +1 -1
  180. package/src/lib/server/LegacyServerChannel.impl.ts +2 -2
  181. package/src/lib/server/Server.decl.ts +23 -2
  182. package/src/lib/server/Server.impl.ts +5 -4
  183. package/src/lib/server/ServerChannel.ts +1 -1
  184. package/src/lib/server/SimpleJsonApiRouter.ts +17 -4
  185. package/src/lib/server/index.ts +1 -1
  186. package/src/lib/shared/BinaryStream.ts +1 -1
  187. package/src/lib/shared/BinaryStreamManager.ts +1 -1
  188. package/src/lib/shared/Channel.impl.ts +43 -23
  189. package/src/lib/shared/Constants.ts +1 -1
  190. package/src/lib/shared/Encodings/index.ts +1 -1
  191. package/src/lib/shared/Encodings/v1/EncoderV1.ts +1 -1
  192. package/src/lib/shared/Encodings/v1/Protocol.v1.decls.ts +1 -1
  193. package/src/lib/shared/Encodings/v1/index.ts +1 -1
  194. package/src/lib/shared/Encodings/v2/Constants.v2.ts +20 -1
  195. package/src/lib/shared/Encodings/v2/DecoderV2.ts +137 -15
  196. package/src/lib/shared/Encodings/v2/EncoderV2.ts +160 -36
  197. package/src/lib/shared/Encodings/v2/Encoding.v2.decl.ts +96 -44
  198. package/src/lib/shared/Encodings/v2/index.ts +1 -1
  199. package/src/lib/shared/Errors.ts +2 -1
  200. package/src/lib/shared/Shared.decl.ts +23 -18
  201. package/src/lib/shared/Utils.ts +3 -3
  202. package/src/lib/shared/index.ts +1 -1
  203. package/src/lib/transporters/Transporter.decl.ts +1 -1
  204. package/src/lib/transporters/http-listener/AbstractHttpListener.ts +14 -6
  205. package/src/lib/transporters/http-listener/Http.Decl.ts +1 -27
  206. package/src/lib/transporters/http-listener/HttpListener.ts +10 -2
  207. package/src/lib/transporters/http-listener/HttpUnixSocketListener.ts +10 -2
  208. package/src/lib/transporters/http-listener/HttpsListener.ts +12 -4
  209. package/src/lib/transporters/http-listener/index.ts +1 -1
  210. package/src/lib/transporters/index.ts +1 -1
  211. package/src/lib/transporters/legacy-http/LegacyHttp.Client.Native.ts +60 -10
  212. package/src/lib/transporters/legacy-http/LegacyHttp.Server.ts +58 -10
  213. package/src/lib/transporters/legacy-http/LegacyHttp.Transporter.ts +1 -1
  214. package/src/lib/transporters/legacy-http/index.ts +1 -1
  215. package/src/lib/transporters/lwdfx/LwDFX.Tcp.Client.ts +1 -1
  216. package/src/lib/transporters/lwdfx/LwDFX.Tcp.Server.ts +1 -1
  217. package/src/lib/transporters/lwdfx/LwDFX.Tls.Client.ts +1 -1
  218. package/src/lib/transporters/lwdfx/LwDFX.Tls.Server.ts +1 -1
  219. package/src/lib/transporters/lwdfx/LwDFX.Transporter.ts +1 -1
  220. package/src/lib/transporters/lwdfx/LwDFX.UnixSocket.Client.ts +1 -1
  221. package/src/lib/transporters/lwdfx/LwDFX.UnixSocket.Server.ts +1 -1
  222. package/src/lib/transporters/lwdfx/LwDFX.decl.ts +1 -1
  223. package/src/lib/transporters/lwdfx/index.ts +1 -1
  224. package/src/lib/transporters/memory/Memory.Impl.ts +4 -4
  225. package/src/lib/transporters/memory/index.ts +1 -1
  226. package/src/lib/transporters/websocket/WebSocket.Client.ts +52 -7
  227. package/src/lib/transporters/websocket/WebSocket.Server.ts +59 -12
  228. package/src/lib/transporters/websocket/WebSocket.Transporter.ts +1 -1
  229. package/src/lib/transporters/websocket/WebSocket.decl.ts +1 -1
  230. package/src/lib/transporters/websocket/index.ts +1 -1
  231. package/src/lib/transporters/worker-thread/WorkerThread.Client.ts +1 -1
  232. package/src/lib/transporters/worker-thread/WorkerThread.Constants.ts +1 -1
  233. package/src/lib/transporters/worker-thread/WorkerThread.Errors.ts +1 -1
  234. package/src/lib/transporters/worker-thread/WorkerThread.Server.ts +1 -1
  235. package/src/lib/transporters/worker-thread/WorkerThread.Transporter.ts +1 -1
  236. package/src/lib/transporters/worker-thread/index.ts +1 -1
@@ -0,0 +1,4 @@
1
+ export enum EArgsEncodings {
2
+ JSON = 0,
3
+ RESERVED = 0x10000, // All customized encodings should be greater than this value.
4
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -23,6 +23,31 @@ export interface IChannelEvents extends Shared.IDefaultEvents {
23
23
  ['push_message'](msg: Buffer[]): void;
24
24
  }
25
25
 
26
+ export interface IApiCallResult<T> {
27
+
28
+ /**
29
+ * The extension binary chunks replied from server.
30
+ *
31
+ * @optional only the server who supports `televoke/2.1` would send this field, if necessary.
32
+ */
33
+ binChunks?: Buffer[][];
34
+
35
+ /**
36
+ * The API call result.
37
+ */
38
+ result: T;
39
+ }
40
+
41
+ export interface IApiCallOptions {
42
+
43
+ /**
44
+ * The extension binary chunks to be sent to server.
45
+ *
46
+ * @optional only the server who supports `televoke/2.1` could recognize this field, and the old implementation will ignore this field.
47
+ */
48
+ binChunks?: Array<Buffer | string | Array<Buffer | string>>;
49
+ }
50
+
26
51
  export interface IClient<TApis extends Shared.IObject>
27
52
  extends Shared.IEventListener<IChannelEvents>, Pick<
28
53
  Shared.IChannelBase<IChannelEvents>,
@@ -51,11 +76,26 @@ export interface IClient<TApis extends Shared.IObject>
51
76
  /**
52
77
  * Invoke an API.
53
78
  *
79
+ * > This method does not support extension added in `televoke/2.1`.
80
+ * > To use the extension feature, please use `callApi` instead.
81
+ *
54
82
  * @param name The API name.
55
83
  * @param args The arguments.
56
84
  */
57
85
  invoke<TName extends keyof TApis>(
58
86
  name: Shared.IfIsFn<TApis[TName], TName>,
59
- ...args: TApis[TName] extends Shared.IFn<infer TArgs, any> ? TArgs : never
87
+ ...args: TApis[TName] extends Shared.IFn<infer TArgs, unknown> ? TArgs : never
60
88
  ): Promise<TApis[TName] extends Shared.IFn<any[], infer TRet> ? TRet : never>;
89
+
90
+ /**
91
+ * Invoke an API.
92
+ *
93
+ * @param name The API name.
94
+ * @param args The arguments.
95
+ */
96
+ callApi<TName extends keyof TApis>(
97
+ name: Shared.IfIsFn<TApis[TName], TName>,
98
+ args: TApis[TName] extends Shared.IFn<infer TArgs, unknown> ? TArgs : never,
99
+ opts?: IApiCallOptions,
100
+ ): Promise<TApis[TName] extends Shared.IFn<any[], infer TRet> ? IApiCallResult<TRet> : never>;
61
101
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
16
16
 
17
17
  import * as Shared from '../shared';
18
18
  import type * as dC from './Client.decl';
19
+ import * as cC from './Client.Constants';
19
20
  import type * as dT from '../transporters';
20
21
  import { EventEmitter } from 'node:events';
21
22
  import { AbstractTvChannelV2, encoder } from '../shared/Channel.impl';
@@ -144,9 +145,55 @@ class TvJsonApiClient<TApis extends Shared.IObject> extends EventEmitter impleme
144
145
 
145
146
  try {
146
147
 
147
- const resp = await (await this._getChannel()).apiCall(name as string, JSON.stringify(args));
148
+ const resp = await (await this._getChannel()).apiCall(
149
+ name as string,
150
+ JSON.stringify(args),
151
+ cC.EArgsEncodings.JSON,
152
+ );
148
153
 
149
- return buffer2json(resp);
154
+ return buffer2json(resp.body);
155
+ }
156
+ catch (e) {
157
+
158
+ if (e instanceof Shared.errors.app_error) {
159
+
160
+ let info: unknown;
161
+
162
+ try {
163
+
164
+ info = JSON.parse(e.message);
165
+ }
166
+ catch {
167
+
168
+ throw e;
169
+ }
170
+
171
+ throw new Shared.TvErrorResponse(info);
172
+ }
173
+
174
+ throw e;
175
+ }
176
+ }
177
+
178
+ public async callApi(
179
+ name: unknown,
180
+ args: any[],
181
+ opts?: dC.IApiCallOptions
182
+ ): Promise<any> {
183
+
184
+ try {
185
+
186
+ const resp = await (await this._getChannel()).apiCall(
187
+ name as string,
188
+ JSON.stringify(args),
189
+ cC.EArgsEncodings.JSON,
190
+ opts?.binChunks,
191
+ );
192
+
193
+ return {
194
+ result: buffer2json(resp.body),
195
+ binChunks: resp.binChunks,
196
+ } satisfies dC.IApiCallResult<any>;
150
197
  }
151
198
  catch (e) {
152
199
 
@@ -205,8 +252,10 @@ class TvClientChannel extends AbstractTvChannelV2 {
205
252
 
206
253
  public apiCall(
207
254
  name: string,
208
- argsBody: Buffer | string | Buffer[],
209
- ): Promise<Buffer[]> {
255
+ argsBody: v2.IEncBinItem,
256
+ argsEncoding: number,
257
+ extBinaryChunks?: Array<Buffer | string | Array<Buffer | string>>,
258
+ ): Promise<{ body: Buffer[]; binChunks?: Buffer[][]; }> {
210
259
 
211
260
  if (!this.writable) {
212
261
 
@@ -221,9 +270,11 @@ class TvClientChannel extends AbstractTvChannelV2 {
221
270
  'seq': seq,
222
271
  'ct': {
223
272
  'name': name,
224
- 'body': typeof argsBody === 'string' ? Buffer.from(argsBody) : argsBody
273
+ 'body': argsBody,
274
+ 'bodyEnc': argsEncoding,
275
+ 'binChunks': extBinaryChunks,
225
276
  }
226
- } satisfies v2.IApiRequestPacket));
277
+ } satisfies v2.IApiRequestPacketEncoding));
227
278
 
228
279
  return new Promise((resolve, reject) => {
229
280
 
@@ -235,7 +286,7 @@ class TvClientChannel extends AbstractTvChannelV2 {
235
286
  return;
236
287
  }
237
288
 
238
- resolve(resp.ct as Buffer[]);
289
+ resolve(resp.ct as v2.IApiReplyPacketDecoded['ct']);
239
290
  });
240
291
  });
241
292
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
package/src/lib/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ import * as Shared from '../shared';
18
18
  import { EventEmitter } from 'node:events';
19
19
  import * as v2 from '../shared/Encodings/v2';
20
20
 
21
- export type ILegacyApiResponseCallback = (body: v2.IDataChunkField | Shared.TelevokeError) => void;
21
+ export type ILegacyApiResponseCallback = (body: v2.IEncBinItem | Shared.TelevokeError) => void;
22
22
 
23
23
  const streamManager = Shared.createDisabledStreamManagerFactory()(null as any);
24
24
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -35,9 +35,28 @@ export interface IRequestContext {
35
35
  * The channel which the request comes from.
36
36
  */
37
37
  readonly channel: IChannel;
38
+
39
+ /**
40
+ * The extension binary chunks carried by the request.
41
+ *
42
+ * @optional only the client implemented `televoke/2.1` will send this field, if necessary.
43
+ */
44
+ readonly requestBinaryChunks?: Buffer[][];
45
+
46
+ /**
47
+ * The extension binary chunks should be replied to the client.
48
+ *
49
+ * If the field is set, the client could receive the binary chunks in the reply.
50
+ *
51
+ * @optional only the client implemented `televoke/2.1` could recognize this field, and the old implementation will ignore this field.
52
+ */
53
+ replyBinaryChunks?: Array<Buffer[] | Buffer>;
38
54
  }
39
55
 
40
- export type IRouteApiCallback = (response: string | Buffer | Array<string | Buffer> | Shared.TelevokeError) => void;
56
+ export type IRouteApiCallback = (
57
+ response: string | Buffer | Array<string | Buffer> | Shared.TelevokeError,
58
+ replyBinaryChunks?: Array<Buffer[] | Buffer>
59
+ ) => void;
41
60
 
42
61
  export type IRouteLegacyApiCallback = (response: unknown | Shared.TvErrorResponse | Shared.TelevokeError) => void;
43
62
 
@@ -53,12 +72,14 @@ export interface IRouter extends Shared.IEventListener<Shared.IDefaultEvents> {
53
72
  *
54
73
  * @param cb The callback function of processing result.
55
74
  * @param name The API name.
75
+ * @param argsEnc The encoding of the API arguments.
56
76
  * @param args The API arguments.
57
77
  * @param context The request context.
58
78
  */
59
79
  processApi(
60
80
  cb: IRouteApiCallback,
61
81
  name: string,
82
+ argsEnc: number,
62
83
  args: Buffer[],
63
84
  context: IRequestContext
64
85
  ): void;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -62,9 +62,10 @@ export class TvServer extends EventEmitter implements dS.IServer, dT.IServer {
62
62
  );
63
63
 
64
64
  (this._channels[id] as Shared.IChannelBase<IChannelEvents>)
65
- .on('api_call', (cb, name, body) => {
66
- this.router.processApi(cb, name, body, {
67
- channel: this._channels[id],
65
+ .on('api_call', (cb, name, argsBody, _seq, argsEnc, binChunks) => {
66
+ this.router.processApi(cb, name, argsEnc, argsBody, {
67
+ 'channel': this._channels[id],
68
+ 'requestBinaryChunks': binChunks
68
69
  });
69
70
  })
70
71
  .on('error', (err) => this.emit('error', err))
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ import type * as dS from './Server.decl';
18
18
  import * as Shared from '../shared';
19
19
  import { buffer2json } from '../shared/Utils';
20
20
  import { EventEmitter } from 'node:events';
21
+ import { v2 } from '../shared/Encodings';
21
22
 
22
23
  export type ISimpleJsonApiHandler = (ctx: dS.IRequestContext, ...args: any[]) => unknown;
23
24
 
@@ -39,7 +40,19 @@ export class SimpleJsonApiRouter extends EventEmitter implements dS.IRouter {
39
40
  return this;
40
41
  }
41
42
 
42
- public processApi(cb: dS.IRouteApiCallback, name: string, body: Buffer[], ctx: dS.IRequestContext): void {
43
+ public processApi(
44
+ cb: dS.IRouteApiCallback,
45
+ name: string,
46
+ argsEnc: number,
47
+ body: Buffer[],
48
+ ctx: dS.IRequestContext
49
+ ): void {
50
+
51
+ if (argsEnc !== v2.JSON_API_ARGS_ENCODING) {
52
+
53
+ cb(new Shared.errors.unk_api_enc());
54
+ return;
55
+ }
43
56
 
44
57
  if (!this._apiHandlers[name]) {
45
58
  cb(new Shared.errors.api_not_found({ name }));
@@ -70,7 +83,7 @@ export class SimpleJsonApiRouter extends EventEmitter implements dS.IRouter {
70
83
 
71
84
  try {
72
85
 
73
- cb(JSON.stringify(data ?? null));
86
+ cb(JSON.stringify(data ?? null), ctx.replyBinaryChunks);
74
87
  }
75
88
  catch (e) {
76
89
 
@@ -82,7 +95,7 @@ export class SimpleJsonApiRouter extends EventEmitter implements dS.IRouter {
82
95
  }
83
96
  else {
84
97
 
85
- cb(JSON.stringify(result ?? null));
98
+ cb(JSON.stringify(result ?? null), ctx.replyBinaryChunks);
86
99
  }
87
100
  }
88
101
  catch (e) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,6 @@
1
+ /* eslint-disable max-lines */
1
2
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
3
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
4
  *
4
5
  * Licensed under the Apache License, Version 2.0 (the "License");
5
6
  * you may not use this file except in compliance with the License.
@@ -26,10 +27,15 @@ export interface IChannelEvents extends Shared.IDefaultEvents {
26
27
  close(): void;
27
28
 
28
29
  ['api_call'](
29
- callback: (response: v2.IDataChunkField | E.TelevokeError | E.TvErrorResponse) => void,
30
+ callback: (
31
+ result: string | Buffer | Array<string | Buffer> | E.TelevokeError | E.TvErrorResponse,
32
+ binChunks?: Array<Buffer | Buffer[]>,
33
+ ) => void,
30
34
  name: string,
31
35
  args: Buffer[],
32
36
  sequence: number,
37
+ argsEncoding: number,
38
+ extBinChunks?: Buffer[][],
33
39
  ): void;
34
40
 
35
41
  ['push_message'](
@@ -290,7 +296,7 @@ export abstract class AbstractTvChannelV2
290
296
  request.callback(packet);
291
297
  }
292
298
 
293
- private _reply(packet: v2.ICommandPacket): void {
299
+ private _reply<T extends v2.ICommandPacket = v2.ICommandPacket>(packet: T): void {
294
300
 
295
301
  try {
296
302
 
@@ -403,30 +409,44 @@ export abstract class AbstractTvChannelV2
403
409
 
404
410
  this.emit(
405
411
  'api_call',
406
- once((response: v2.IDataChunkField | E.TelevokeError) => {
412
+ once((response: v2.IEncBinItem | E.TelevokeError, binChunks?: v2.IEncBinItem[]) => {
407
413
 
408
414
  this._recvRequests--;
409
415
 
410
- this._reply({
411
- 'cmd': v2.ECommand.API_CALL,
412
- 'typ': response instanceof E.TelevokeError ?
413
- v2.EPacketType.ERROR_RESPONSE :
414
- v2.EPacketType.SUCCESS_RESPONSE,
415
- 'seq': packet.seq,
416
- 'ct': response,
417
- });
416
+ if (response instanceof E.TelevokeError) {
417
+
418
+ this._reply<v2.IErrorReplyPacket>({
419
+ 'cmd': v2.ECommand.API_CALL,
420
+ 'typ': v2.EPacketType.ERROR_RESPONSE,
421
+ 'seq': packet.seq,
422
+ 'ct': response,
423
+ });
424
+ }
425
+ else {
426
+ this._reply<v2.IApiReplyPacketEncoding>({
427
+ 'cmd': v2.ECommand.API_CALL,
428
+ 'typ': v2.EPacketType.SUCCESS_RESPONSE,
429
+ 'seq': packet.seq,
430
+ 'ct': {
431
+ 'body': response,
432
+ binChunks,
433
+ },
434
+ });
435
+ }
418
436
  this._tryClean();
419
437
  }),
420
- (packet as v2.IApiRequestPacket).ct.name,
421
- (packet as v2.IApiRequestPacket).ct.body,
422
- packet.seq
438
+ (packet as v2.IApiRequestPacketDecoded).ct.name,
439
+ (packet as v2.IApiRequestPacketDecoded).ct.body,
440
+ packet.seq,
441
+ (packet as v2.IApiRequestPacketDecoded).ct.bodyEnc,
442
+ (packet as v2.IApiRequestPacketDecoded).ct.binChunks,
423
443
  );
424
444
 
425
445
  break;
426
446
 
427
447
  case v2.ECommand.BINARY_CHUNK: {
428
448
 
429
- const stream = this.streams.get((packet as v2.IBinaryChunkRequestPacket).ct.streamId)!;
449
+ const stream = this.streams.get((packet as v2.IBinaryChunkRequestPacketEncoding).ct.streamId)!;
430
450
 
431
451
  if (!stream) {
432
452
 
@@ -435,16 +455,16 @@ export abstract class AbstractTvChannelV2
435
455
  'typ': v2.EPacketType.ERROR_RESPONSE,
436
456
  'seq': packet.seq,
437
457
  'ct': new E.errors.stream_not_found({
438
- 'sid': (packet as v2.IBinaryChunkRequestPacket).ct.streamId,
458
+ 'sid': (packet as v2.IBinaryChunkRequestPacketEncoding).ct.streamId,
439
459
  'chId': this.id,
440
460
  }),
441
461
  });
442
462
  break;
443
463
  }
444
464
 
445
- const chunkSegments = (packet as v2.IBinaryChunkRequestPacket).ct.body as Buffer[];
465
+ const chunkSegments = (packet as v2.IBinaryChunkRequestPacketEncoding).ct.body as Buffer[];
446
466
 
447
- const chunkIndex = (packet as v2.IBinaryChunkRequestPacket).ct.index;
467
+ const chunkIndex = (packet as v2.IBinaryChunkRequestPacketEncoding).ct.index;
448
468
 
449
469
  if (chunkIndex === 0xFFFFFFFF) {
450
470
 
@@ -457,7 +477,7 @@ export abstract class AbstractTvChannelV2
457
477
  'typ': v2.EPacketType.ERROR_RESPONSE,
458
478
  'seq': packet.seq,
459
479
  'ct': new E.errors.stream_index_mismatch({
460
- 'sid': (packet as v2.IBinaryChunkRequestPacket).ct.streamId,
480
+ 'sid': (packet as v2.IBinaryChunkRequestPacketEncoding).ct.streamId,
461
481
  'chId': this.id,
462
482
  }),
463
483
  });
@@ -541,7 +561,7 @@ export abstract class AbstractTvChannelV2
541
561
  'typ': v2.EPacketType.REQUEST,
542
562
  'seq': seq,
543
563
  'ct': message,
544
- } satisfies v2.IPingRequestPacket));
564
+ } satisfies v2.IPingRequestPacketEncoding));
545
565
 
546
566
  return new Promise((resolve, reject) => {
547
567
 
@@ -584,7 +604,7 @@ export abstract class AbstractTvChannelV2
584
604
  'index': index === false ? 0xFFFFFFFF : index,
585
605
  'body': chunk ?? [],
586
606
  }
587
- } satisfies v2.IBinaryChunkRequestPacket));
607
+ } satisfies v2.IBinaryChunkRequestPacketEncoding));
588
608
 
589
609
  return new Promise((resolve, reject) => {
590
610
 
@@ -616,7 +636,7 @@ export abstract class AbstractTvChannelV2
616
636
  'typ': v2.EPacketType.REQUEST,
617
637
  'seq': seq,
618
638
  'ct': message,
619
- } satisfies v2.IPushMessageRequestPacket));
639
+ } satisfies v2.IPushMessageRequestPacketEncoding));
620
640
 
621
641
  return new Promise((resolve, reject) => {
622
642
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2024 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2025 Angus.Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -28,4 +28,23 @@ export enum EPacketType {
28
28
  ERROR_RESPONSE = 0x02,
29
29
  }
30
30
 
31
+ export const JSON_API_ARGS_ENCODING = 0x00; // JSON encoding
32
+ export const DEFAULT_API_ARGS_ENCODING = JSON_API_ARGS_ENCODING;
33
+
31
34
  export const HEADER_SIZE = 8;
35
+
36
+ export const API_CALL_REQ_EXT_HEADER_SIZE = 12;
37
+ export const API_CALL_RESP_EXT_HEADER_SIZE = 8;
38
+
39
+ export enum EApiCallReqExtHeaderFieldOffset {
40
+
41
+ LENGTH = 0,
42
+ BODY_ENC = 4,
43
+ BIN_CHUNK_QTY = 8
44
+ }
45
+
46
+ export enum EApiCallRespExtHeaderFieldOffset {
47
+
48
+ LENGTH = 0,
49
+ BIN_CHUNK_QTY = 4
50
+ }