@camera.ui/rpc 1.0.2 → 1.0.4

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 (38) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +2 -0
  3. package/dist/{wrapper.js → browser.js} +1 -1
  4. package/dist/browser.js.map +1 -0
  5. package/externals/nats.js/core/src/authenticator.ts +159 -0
  6. package/externals/nats.js/core/src/bench.ts +426 -0
  7. package/externals/nats.js/core/src/codec.ts +28 -0
  8. package/externals/nats.js/core/src/core.ts +1219 -0
  9. package/externals/nats.js/core/src/databuffer.ts +129 -0
  10. package/externals/nats.js/core/src/denobuffer.ts +248 -0
  11. package/externals/nats.js/core/src/encoders.ts +53 -0
  12. package/externals/nats.js/core/src/errors.ts +300 -0
  13. package/externals/nats.js/core/src/headers.ts +315 -0
  14. package/externals/nats.js/core/src/heartbeats.ts +114 -0
  15. package/externals/nats.js/core/src/idleheartbeat_monitor.ts +140 -0
  16. package/externals/nats.js/core/src/internal_mod.ts +167 -0
  17. package/externals/nats.js/core/src/ipparser.ts +215 -0
  18. package/externals/nats.js/core/src/mod.ts +113 -0
  19. package/externals/nats.js/core/src/msg.ts +120 -0
  20. package/externals/nats.js/core/src/muxsubscription.ts +111 -0
  21. package/externals/nats.js/core/src/nats.ts +650 -0
  22. package/externals/nats.js/core/src/nkeys.ts +1 -0
  23. package/externals/nats.js/core/src/nuid.ts +16 -0
  24. package/externals/nats.js/core/src/options.ts +202 -0
  25. package/externals/nats.js/core/src/parser.ts +756 -0
  26. package/externals/nats.js/core/src/protocol.ts +1304 -0
  27. package/externals/nats.js/core/src/queued_iterator.ts +171 -0
  28. package/externals/nats.js/core/src/request.ts +177 -0
  29. package/externals/nats.js/core/src/semver.ts +165 -0
  30. package/externals/nats.js/core/src/servers.ts +424 -0
  31. package/externals/nats.js/core/src/transport.ts +117 -0
  32. package/externals/nats.js/core/src/types.ts +17 -0
  33. package/externals/nats.js/core/src/util.ts +367 -0
  34. package/externals/nats.js/core/src/version.ts +2 -0
  35. package/externals/nats.js/core/src/ws_transport.ts +391 -0
  36. package/package.json +17 -5
  37. package/dist/wrapper.js.map +0 -1
  38. /package/dist/{wrapper.d.ts → browser.d.ts} +0 -0
package/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020-2026 seydx <hi@seydx.dev>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
1
  # @camera.ui/rpc
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/@camera.ui/rpc?label=npm&logo=npm)](https://www.npmjs.com/package/@camera.ui/rpc)
4
+
3
5
  This is the Node implementation of the camera-ui-rpc library.
@@ -1,2 +1,2 @@
1
1
  export { wsconnect as connect, createInbox, errors, headers } from '@nats-io/nats-core';
2
- //# sourceMappingURL=wrapper.js.map
2
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,159 @@
1
+ /*
2
+ * Copyright 2020-2023 The NATS Authors
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+ import { nkeys } from "./nkeys.ts";
16
+ import { TD, TE } from "./encoders.ts";
17
+ import type {
18
+ Auth,
19
+ Authenticator,
20
+ JwtAuth,
21
+ NKeyAuth,
22
+ NoAuth,
23
+ TokenAuth,
24
+ UserPass,
25
+ } from "./core.ts";
26
+
27
+ export function multiAuthenticator(authenticators: Authenticator[]) {
28
+ return (nonce?: string): Auth => {
29
+ let auth: Partial<NoAuth & TokenAuth & UserPass & NKeyAuth & JwtAuth> = {};
30
+ authenticators.forEach((a) => {
31
+ const args = a(nonce) || {};
32
+ auth = Object.assign(auth, args);
33
+ });
34
+ return auth as Auth;
35
+ };
36
+ }
37
+
38
+ export function noAuthFn(): Authenticator {
39
+ return (): NoAuth => {
40
+ return;
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Returns a user/pass authenticator for the specified user and optional password
46
+ * @param { string | () => string } user
47
+ * @param {string | () => string } pass
48
+ * @return {UserPass}
49
+ */
50
+ export function usernamePasswordAuthenticator(
51
+ user: string | (() => string),
52
+ pass?: string | (() => string),
53
+ ): Authenticator {
54
+ return (): UserPass => {
55
+ const u = typeof user === "function" ? user() : user;
56
+ const p = typeof pass === "function" ? pass() : pass;
57
+ return { user: u, pass: p };
58
+ };
59
+ }
60
+
61
+ /**
62
+ * Returns a token authenticator for the specified token
63
+ * @param { string | () => string } token
64
+ * @return {TokenAuth}
65
+ */
66
+ export function tokenAuthenticator(
67
+ token: string | (() => string),
68
+ ): Authenticator {
69
+ return (): TokenAuth => {
70
+ const auth_token = typeof token === "function" ? token() : token;
71
+ return { auth_token };
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Returns an Authenticator that returns a NKeyAuth based that uses the
77
+ * specified seed or function returning a seed.
78
+ * @param {Uint8Array | (() => Uint8Array)} seed - the nkey seed
79
+ * @return {NKeyAuth}
80
+ */
81
+ export function nkeyAuthenticator(
82
+ seed?: Uint8Array | (() => Uint8Array),
83
+ ): Authenticator {
84
+ return (nonce?: string): NKeyAuth => {
85
+ const s = typeof seed === "function" ? seed() : seed;
86
+ const kp = s ? nkeys.fromSeed(s) : undefined;
87
+ const nkey = kp ? kp.getPublicKey() : "";
88
+ const challenge = TE.encode(nonce || "");
89
+ const sigBytes = kp !== undefined && nonce ? kp.sign(challenge) : undefined;
90
+ const sig = sigBytes ? nkeys.encode(sigBytes) : "";
91
+ return { nkey, sig };
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Returns an Authenticator function that returns a JwtAuth.
97
+ * If a seed is provided, the public key, and signature are
98
+ * calculated.
99
+ *
100
+ * @param {string | ()=>string} ajwt - the jwt
101
+ * @param {Uint8Array | ()=> Uint8Array } seed - the optional nkey seed
102
+ * @return {Authenticator}
103
+ */
104
+ export function jwtAuthenticator(
105
+ ajwt: string | (() => string),
106
+ seed?: Uint8Array | (() => Uint8Array),
107
+ ): Authenticator {
108
+ return (
109
+ nonce?: string,
110
+ ): JwtAuth => {
111
+ const jwt = typeof ajwt === "function" ? ajwt() : ajwt;
112
+ const fn = nkeyAuthenticator(seed);
113
+ const { nkey, sig } = fn(nonce) as NKeyAuth;
114
+ return { jwt, nkey, sig };
115
+ };
116
+ }
117
+
118
+ /**
119
+ * Returns an Authenticator function that returns a JwtAuth.
120
+ * This is a convenience Authenticator that parses the
121
+ * specified creds and delegates to the jwtAuthenticator.
122
+ * @param {Uint8Array | () => Uint8Array } creds - the contents of a creds file or a function that returns the creds
123
+ * @returns {JwtAuth}
124
+ */
125
+ export function credsAuthenticator(
126
+ creds: Uint8Array | (() => Uint8Array),
127
+ ): Authenticator {
128
+ const fn = typeof creds !== "function" ? () => creds : creds;
129
+ const parse = () => {
130
+ const CREDS =
131
+ /\s*(?:(?:[-]{3,}[^\n]*[-]{3,}\n)(.+)(?:\n\s*[-]{3,}[^\n]*[-]{3,}\n))/ig;
132
+ const s = TD.decode(fn());
133
+ // get the JWT
134
+ let m = CREDS.exec(s);
135
+ if (!m) {
136
+ throw new Error("unable to parse credentials");
137
+ }
138
+ const jwt = m[1].trim();
139
+ // get the nkey
140
+ m = CREDS.exec(s);
141
+ if (!m) {
142
+ throw new Error("unable to parse credentials");
143
+ }
144
+ const seed = TE.encode(m[1].trim());
145
+
146
+ return { jwt, seed };
147
+ };
148
+
149
+ const jwtFn = () => {
150
+ const { jwt } = parse();
151
+ return jwt;
152
+ };
153
+ const nkeyFn = () => {
154
+ const { seed } = parse();
155
+ return seed;
156
+ };
157
+
158
+ return jwtAuthenticator(jwtFn, nkeyFn);
159
+ }
@@ -0,0 +1,426 @@
1
+ /*
2
+ * Copyright 2020-2022 The NATS Authors
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+ import { Empty } from "./types.ts";
17
+ import { nuid } from "./nuid.ts";
18
+ import { deferred, Perf } from "./util.ts";
19
+ import type { NatsConnectionImpl } from "./nats.ts";
20
+ import type { NatsConnection } from "./core.ts";
21
+
22
+ export class Metric {
23
+ name: string;
24
+ duration: number;
25
+ date: number;
26
+ payload: number;
27
+ msgs: number;
28
+ lang!: string;
29
+ version!: string;
30
+ bytes: number;
31
+ asyncRequests?: boolean;
32
+ min?: number;
33
+ max?: number;
34
+
35
+ constructor(name: string, duration: number) {
36
+ this.name = name;
37
+ this.duration = duration;
38
+ this.date = Date.now();
39
+ this.payload = 0;
40
+ this.msgs = 0;
41
+ this.bytes = 0;
42
+ }
43
+
44
+ toString(): string {
45
+ const sec = (this.duration) / 1000;
46
+ const mps = Math.round(this.msgs / sec);
47
+ const label = this.asyncRequests ? "asyncRequests" : "";
48
+ let minmax = "";
49
+ if (this.max) {
50
+ minmax = `${this.min}/${this.max}`;
51
+ }
52
+
53
+ return `${this.name}${label ? " [asyncRequests]" : ""} ${
54
+ humanizeNumber(mps)
55
+ } msgs/sec - [${sec.toFixed(2)} secs] ~ ${
56
+ throughput(this.bytes, sec)
57
+ } ${minmax}`;
58
+ }
59
+
60
+ toCsv(): string {
61
+ return `"${this.name}",${
62
+ new Date(this.date).toISOString()
63
+ },${this.lang},${this.version},${this.msgs},${this.payload},${this.bytes},${this.duration},${
64
+ this.asyncRequests ? this.asyncRequests : false
65
+ }\n`;
66
+ }
67
+
68
+ static header(): string {
69
+ return `Test,Date,Lang,Version,Count,MsgPayload,Bytes,Millis,Async\n`;
70
+ }
71
+ }
72
+
73
+ export interface BenchOpts {
74
+ callbacks?: boolean;
75
+ msgs?: number;
76
+ size?: number;
77
+ subject?: string;
78
+ asyncRequests?: boolean;
79
+ pub?: boolean;
80
+ sub?: boolean;
81
+ rep?: boolean;
82
+ req?: boolean;
83
+ }
84
+
85
+ export class Bench {
86
+ nc: NatsConnection;
87
+ callbacks: boolean;
88
+ msgs: number;
89
+ size: number;
90
+ subject: string;
91
+ asyncRequests?: boolean;
92
+ pub?: boolean;
93
+ sub?: boolean;
94
+ req?: boolean;
95
+ rep?: boolean;
96
+ perf: Perf;
97
+ payload: Uint8Array;
98
+
99
+ constructor(
100
+ nc: NatsConnection,
101
+ opts: BenchOpts = {
102
+ msgs: 100000,
103
+ size: 128,
104
+ subject: "",
105
+ asyncRequests: false,
106
+ pub: false,
107
+ sub: false,
108
+ req: false,
109
+ rep: false,
110
+ },
111
+ ) {
112
+ this.nc = nc;
113
+ this.callbacks = opts.callbacks || false;
114
+ this.msgs = opts.msgs || 0;
115
+ this.size = opts.size || 0;
116
+ this.subject = opts.subject || nuid.next();
117
+ this.asyncRequests = opts.asyncRequests || false;
118
+ this.pub = opts.pub || false;
119
+ this.sub = opts.sub || false;
120
+ this.req = opts.req || false;
121
+ this.rep = opts.rep || false;
122
+ this.perf = new Perf();
123
+ this.payload = this.size ? new Uint8Array(this.size) : Empty;
124
+
125
+ if (!this.pub && !this.sub && !this.req && !this.rep) {
126
+ throw new Error("no options selected");
127
+ }
128
+ }
129
+
130
+ async run(): Promise<Metric[]> {
131
+ this.nc.closed()
132
+ .then((err) => {
133
+ if (err) {
134
+ throw err;
135
+ }
136
+ });
137
+
138
+ if (this.callbacks) {
139
+ await this.runCallbacks();
140
+ } else {
141
+ await this.runAsync();
142
+ }
143
+ return this.processMetrics();
144
+ }
145
+
146
+ processMetrics(): Metric[] {
147
+ const nc = this.nc as NatsConnectionImpl;
148
+ const { lang, version } = nc.protocol.transport;
149
+
150
+ if (this.pub && this.sub) {
151
+ this.perf.measure("pubsub", "pubStart", "subStop");
152
+ }
153
+ if (this.req && this.rep) {
154
+ this.perf.measure("reqrep", "reqStart", "reqStop");
155
+ }
156
+
157
+ const measures = this.perf.getEntries();
158
+ const pubsub = measures.find((m) => m.name === "pubsub");
159
+ const reqrep = measures.find((m) => m.name === "reqrep");
160
+ const req = measures.find((m) => m.name === "req");
161
+ const rep = measures.find((m) => m.name === "rep");
162
+ const pub = measures.find((m) => m.name === "pub");
163
+ const sub = measures.find((m) => m.name === "sub");
164
+
165
+ const stats = this.nc.stats();
166
+
167
+ const metrics: Metric[] = [];
168
+ if (pubsub) {
169
+ const { name, duration } = pubsub;
170
+ const m = new Metric(name, duration);
171
+ m.msgs = this.msgs * 2;
172
+ m.bytes = stats.inBytes + stats.outBytes;
173
+ m.lang = lang;
174
+ m.version = version;
175
+ m.payload = this.payload.length;
176
+ metrics.push(m);
177
+ }
178
+
179
+ if (reqrep) {
180
+ const { name, duration } = reqrep;
181
+ const m = new Metric(name, duration);
182
+ m.msgs = this.msgs * 2;
183
+ m.bytes = stats.inBytes + stats.outBytes;
184
+ m.lang = lang;
185
+ m.version = version;
186
+ m.payload = this.payload.length;
187
+ metrics.push(m);
188
+ }
189
+
190
+ if (pub) {
191
+ const { name, duration } = pub;
192
+ const m = new Metric(name, duration);
193
+ m.msgs = this.msgs;
194
+ m.bytes = stats.outBytes;
195
+ m.lang = lang;
196
+ m.version = version;
197
+ m.payload = this.payload.length;
198
+ metrics.push(m);
199
+ }
200
+
201
+ if (sub) {
202
+ const { name, duration } = sub;
203
+ const m = new Metric(name, duration);
204
+ m.msgs = this.msgs;
205
+ m.bytes = stats.inBytes;
206
+ m.lang = lang;
207
+ m.version = version;
208
+ m.payload = this.payload.length;
209
+ metrics.push(m);
210
+ }
211
+
212
+ if (rep) {
213
+ const { name, duration } = rep;
214
+ const m = new Metric(name, duration);
215
+ m.msgs = this.msgs;
216
+ m.bytes = stats.inBytes + stats.outBytes;
217
+ m.lang = lang;
218
+ m.version = version;
219
+ m.payload = this.payload.length;
220
+ metrics.push(m);
221
+ }
222
+
223
+ if (req) {
224
+ const { name, duration } = req;
225
+ const m = new Metric(name, duration);
226
+ m.msgs = this.msgs;
227
+ m.bytes = stats.inBytes + stats.outBytes;
228
+ m.lang = lang;
229
+ m.version = version;
230
+ m.payload = this.payload.length;
231
+ metrics.push(m);
232
+ }
233
+
234
+ return metrics;
235
+ }
236
+
237
+ async runCallbacks(): Promise<void> {
238
+ const jobs: Promise<void>[] = [];
239
+
240
+ if (this.sub) {
241
+ const d = deferred<void>();
242
+ jobs.push(d);
243
+ let i = 0;
244
+ this.nc.subscribe(this.subject, {
245
+ max: this.msgs,
246
+ callback: () => {
247
+ i++;
248
+ if (i === 1) {
249
+ this.perf.mark("subStart");
250
+ }
251
+ if (i === this.msgs) {
252
+ this.perf.mark("subStop");
253
+ this.perf.measure("sub", "subStart", "subStop");
254
+ d.resolve();
255
+ }
256
+ },
257
+ });
258
+ }
259
+
260
+ if (this.rep) {
261
+ const d = deferred<void>();
262
+ jobs.push(d);
263
+ let i = 0;
264
+ this.nc.subscribe(this.subject, {
265
+ max: this.msgs,
266
+ callback: (_, m) => {
267
+ m.respond(this.payload);
268
+ i++;
269
+ if (i === 1) {
270
+ this.perf.mark("repStart");
271
+ }
272
+ if (i === this.msgs) {
273
+ this.perf.mark("repStop");
274
+ this.perf.measure("rep", "repStart", "repStop");
275
+ d.resolve();
276
+ }
277
+ },
278
+ });
279
+ }
280
+
281
+ if (this.pub) {
282
+ const job = (async () => {
283
+ this.perf.mark("pubStart");
284
+ for (let i = 0; i < this.msgs; i++) {
285
+ this.nc.publish(this.subject, this.payload);
286
+ }
287
+ await this.nc.flush();
288
+ this.perf.mark("pubStop");
289
+ this.perf.measure("pub", "pubStart", "pubStop");
290
+ })();
291
+ jobs.push(job);
292
+ }
293
+
294
+ if (this.req) {
295
+ const job = (async () => {
296
+ if (this.asyncRequests) {
297
+ this.perf.mark("reqStart");
298
+ const a = [];
299
+ for (let i = 0; i < this.msgs; i++) {
300
+ a.push(
301
+ this.nc.request(this.subject, this.payload, { timeout: 20000 }),
302
+ );
303
+ }
304
+ await Promise.all(a);
305
+ this.perf.mark("reqStop");
306
+ this.perf.measure("req", "reqStart", "reqStop");
307
+ } else {
308
+ this.perf.mark("reqStart");
309
+ for (let i = 0; i < this.msgs; i++) {
310
+ await this.nc.request(this.subject);
311
+ }
312
+ this.perf.mark("reqStop");
313
+ this.perf.measure("req", "reqStart", "reqStop");
314
+ }
315
+ })();
316
+ jobs.push(job);
317
+ }
318
+
319
+ await Promise.all(jobs);
320
+ }
321
+
322
+ async runAsync(): Promise<void> {
323
+ const jobs: Promise<void>[] = [];
324
+
325
+ if (this.rep) {
326
+ let first = false;
327
+ const sub = this.nc.subscribe(this.subject, { max: this.msgs });
328
+ const job = (async () => {
329
+ for await (const m of sub) {
330
+ if (!first) {
331
+ this.perf.mark("repStart");
332
+ first = true;
333
+ }
334
+ m.respond(this.payload);
335
+ }
336
+ await this.nc.flush();
337
+ this.perf.mark("repStop");
338
+ this.perf.measure("rep", "repStart", "repStop");
339
+ })();
340
+ jobs.push(job);
341
+ }
342
+
343
+ if (this.sub) {
344
+ let first = false;
345
+ const sub = this.nc.subscribe(this.subject, { max: this.msgs });
346
+ const job = (async () => {
347
+ for await (const _m of sub) {
348
+ if (!first) {
349
+ this.perf.mark("subStart");
350
+ first = true;
351
+ }
352
+ }
353
+ this.perf.mark("subStop");
354
+ this.perf.measure("sub", "subStart", "subStop");
355
+ })();
356
+ jobs.push(job);
357
+ }
358
+
359
+ if (this.pub) {
360
+ const job = (async () => {
361
+ this.perf.mark("pubStart");
362
+ for (let i = 0; i < this.msgs; i++) {
363
+ this.nc.publish(this.subject, this.payload);
364
+ }
365
+ await this.nc.flush();
366
+ this.perf.mark("pubStop");
367
+ this.perf.measure("pub", "pubStart", "pubStop");
368
+ })();
369
+ jobs.push(job);
370
+ }
371
+
372
+ if (this.req) {
373
+ const job = (async () => {
374
+ if (this.asyncRequests) {
375
+ this.perf.mark("reqStart");
376
+ const a = [];
377
+ for (let i = 0; i < this.msgs; i++) {
378
+ a.push(
379
+ this.nc.request(this.subject, this.payload, { timeout: 20000 }),
380
+ );
381
+ }
382
+ await Promise.all(a);
383
+ this.perf.mark("reqStop");
384
+ this.perf.measure("req", "reqStart", "reqStop");
385
+ } else {
386
+ this.perf.mark("reqStart");
387
+ for (let i = 0; i < this.msgs; i++) {
388
+ await this.nc.request(this.subject);
389
+ }
390
+ this.perf.mark("reqStop");
391
+ this.perf.measure("req", "reqStart", "reqStop");
392
+ }
393
+ })();
394
+ jobs.push(job);
395
+ }
396
+
397
+ await Promise.all(jobs);
398
+ }
399
+ }
400
+
401
+ export function throughput(bytes: number, seconds: number): string {
402
+ return `${humanizeBytes(bytes / seconds)}/sec`;
403
+ }
404
+
405
+ export function msgThroughput(msgs: number, seconds: number): string {
406
+ return `${(Math.floor(msgs / seconds))} msgs/sec`;
407
+ }
408
+
409
+ export function humanizeBytes(bytes: number, si = false): string {
410
+ const base = si ? 1000 : 1024;
411
+ const pre = si
412
+ ? ["k", "M", "G", "T", "P", "E"]
413
+ : ["K", "M", "G", "T", "P", "E"];
414
+ const post = si ? "iB" : "B";
415
+
416
+ if (bytes < base) {
417
+ return `${bytes.toFixed(2)} ${post}`;
418
+ }
419
+ const exp = parseInt(Math.log(bytes) / Math.log(base) + "");
420
+ const index = parseInt((exp - 1) + "");
421
+ return `${(bytes / Math.pow(base, exp)).toFixed(2)} ${pre[index]}${post}`;
422
+ }
423
+
424
+ function humanizeNumber(n: number) {
425
+ return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
426
+ }
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright 2020-2022 The NATS Authors
3
+ * Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+
16
+ export interface Codec<T> {
17
+ /**
18
+ * Encode T to an Uint8Array suitable for including in a message payload.
19
+ * @param d
20
+ */
21
+ encode(d: T): Uint8Array;
22
+
23
+ /**
24
+ * Decode an Uint8Array from a message payload into a T
25
+ * @param a
26
+ */
27
+ decode(a: Uint8Array): T;
28
+ }