@plexspaces/sdk 0.1.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.
@@ -0,0 +1,723 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // Copyright (C) 2025 PlexSpaces Contributors
3
+ //
4
+ // Protobuf wire encoding/decoding for shard group host functions.
5
+ // Matches the Rust prost-encoded protos in crates/wasm-runtime/src/simple_component_host.rs.
6
+ //
7
+ // Proto field numbers from actor_runtime.proto and common.proto.
8
+ import { appendLengthDelimited, appendVarint, readLengthDelimited, readVarint, skipField, } from './proto-wire-common.js';
9
+ const enc = new TextDecoder('utf-8', { fatal: false });
10
+ const encW = new TextEncoder();
11
+ // ---------------------------------------------------------------------------
12
+ // Varint helpers
13
+ // ---------------------------------------------------------------------------
14
+ function appendString(buf, fieldNum, s) {
15
+ if (!s)
16
+ return buf;
17
+ return appendLengthDelimited(buf, fieldNum, new Uint8Array(encW.encode(s)));
18
+ }
19
+ function appendUint32(buf, fieldNum, v) {
20
+ if (v === 0)
21
+ return buf;
22
+ const tag = (fieldNum << 3) | 0; // varint wire type
23
+ let b = appendVarint(buf, tag);
24
+ b = appendVarint(b, v >>> 0);
25
+ return b;
26
+ }
27
+ function appendBytes(buf, fieldNum, data) {
28
+ if (data.length === 0)
29
+ return buf;
30
+ return appendLengthDelimited(buf, fieldNum, data);
31
+ }
32
+ function readString(data, pos) {
33
+ const { slice, nextPos } = readLengthDelimited(data, pos);
34
+ return { value: enc.decode(slice), nextPos };
35
+ }
36
+ function readUint32(data, pos) {
37
+ const { value, n } = readVarint(data, pos);
38
+ return { value: Number(value) & 0xffffffff, nextPos: pos + n };
39
+ }
40
+ // ---------------------------------------------------------------------------
41
+ // Enum helpers — map JS string names to proto int values
42
+ // ---------------------------------------------------------------------------
43
+ function partitionStrategyEnum(s) {
44
+ switch ((s ?? '').toLowerCase()) {
45
+ case 'hash': return 1;
46
+ case 'range': return 2;
47
+ case 'consistent_hash': return 3;
48
+ case 'custom': return 99;
49
+ default: return 0;
50
+ }
51
+ }
52
+ function rebalancePolicyEnum(s) {
53
+ switch ((s ?? '').toLowerCase()) {
54
+ case 'none': return 1;
55
+ case 'on_scale': return 2;
56
+ case 'load_based': return 3;
57
+ default: return 0;
58
+ }
59
+ }
60
+ function nodePlacementStrategyEnum(s) {
61
+ switch ((s ?? '').toLowerCase()) {
62
+ case 'same_node': return 1;
63
+ case 'from_registry': return 2;
64
+ case 'node_ids': return 3;
65
+ default: return 0;
66
+ }
67
+ }
68
+ function aggregationStrategyEnum(s) {
69
+ switch ((s ?? '').toLowerCase()) {
70
+ case 'concat': return 1;
71
+ case 'merge': return 2;
72
+ case 'first': return 3;
73
+ case 'majority': return 4;
74
+ default: return 0;
75
+ }
76
+ }
77
+ // ---------------------------------------------------------------------------
78
+ // NodePlacement encoder (DataParallelConfig.placement, field 6)
79
+ //
80
+ // message NodePlacement {
81
+ // NodePlacementStrategy strategy = 1; (varint)
82
+ // string cluster = 2;
83
+ // repeated string node_ids = 3;
84
+ // }
85
+ // ---------------------------------------------------------------------------
86
+ function encodeNodePlacement(placement) {
87
+ let buf = new Uint8Array(0);
88
+ const strategy = nodePlacementStrategyEnum(placement.strategy);
89
+ if (strategy !== 0) {
90
+ buf = appendUint32(buf, 1, strategy);
91
+ }
92
+ const cluster = placement.cluster ?? '';
93
+ buf = appendString(buf, 2, cluster);
94
+ const nodeIds = placement.node_ids;
95
+ if (Array.isArray(nodeIds)) {
96
+ for (const n of nodeIds) {
97
+ buf = appendString(buf, 3, n);
98
+ }
99
+ }
100
+ return buf;
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // DataParallelConfig encoder (CreateShardGroupRequest.config, field 1)
104
+ //
105
+ // message DataParallelConfig {
106
+ // string group_id = 1;
107
+ // uint32 shard_count = 2;
108
+ // reserved 3;
109
+ // PartitionStrategy partition_strategy = 4; (varint)
110
+ // RebalancePolicy rebalance_policy = 5; (varint)
111
+ // NodePlacement placement = 6; (embedded)
112
+ // }
113
+ // ---------------------------------------------------------------------------
114
+ function encodeDataParallelConfig(cfg) {
115
+ let buf = new Uint8Array(0);
116
+ buf = appendString(buf, 1, cfg.group_id ?? '');
117
+ const shardCount = Number(cfg.shard_count ?? 0) >>> 0;
118
+ if (shardCount > 0)
119
+ buf = appendUint32(buf, 2, shardCount);
120
+ const ps = partitionStrategyEnum(cfg.partition_strategy);
121
+ if (ps !== 0)
122
+ buf = appendUint32(buf, 4, ps);
123
+ const rp = rebalancePolicyEnum(cfg.rebalance_policy);
124
+ if (rp !== 0)
125
+ buf = appendUint32(buf, 5, rp);
126
+ const placement = cfg.placement;
127
+ if (placement && typeof placement === 'object') {
128
+ const placementBytes = encodeNodePlacement(placement);
129
+ if (placementBytes.length > 0) {
130
+ buf = appendLengthDelimited(buf, 6, placementBytes);
131
+ }
132
+ }
133
+ return buf;
134
+ }
135
+ // ---------------------------------------------------------------------------
136
+ // Message encoder (ScatterGatherRequest.query, field 2)
137
+ //
138
+ // message Message {
139
+ // string id = 1;
140
+ // string sender_id = 2;
141
+ // string receiver_id = 3;
142
+ // string channel = 4;
143
+ // string message_type = 5;
144
+ // bytes payload = 6; ← JSON-encoded query dict
145
+ // }
146
+ // ---------------------------------------------------------------------------
147
+ function ulid() {
148
+ const t = Date.now();
149
+ const chars = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
150
+ let id = '';
151
+ let ts = t;
152
+ for (let i = 9; i >= 0; i--) {
153
+ id = chars[ts % 32] + id;
154
+ ts = Math.floor(ts / 32);
155
+ }
156
+ for (let i = 0; i < 16; i++)
157
+ id += chars[Math.floor(Math.random() * 32)];
158
+ return id;
159
+ }
160
+ function encodeMessage(query) {
161
+ let buf = new Uint8Array(0);
162
+ buf = appendString(buf, 1, ulid());
163
+ buf = appendString(buf, 5, 'call');
164
+ const payloadBytes = new Uint8Array(encW.encode(JSON.stringify(query)));
165
+ buf = appendBytes(buf, 6, payloadBytes);
166
+ return buf;
167
+ }
168
+ // ---------------------------------------------------------------------------
169
+ // CreateShardGroupRequest encoder
170
+ //
171
+ // message CreateShardGroupRequest {
172
+ // DataParallelConfig config = 1; (embedded)
173
+ // string actor_type = 2;
174
+ // ActorConfig shard_config = 3; (not used here)
175
+ // bytes initial_state = 4;
176
+ // }
177
+ // ---------------------------------------------------------------------------
178
+ export function encodeCreateShardGroupRequest(req) {
179
+ let buf = new Uint8Array(0);
180
+ // config = DataParallelConfig (fields: group_id, shard_count, partition_strategy, rebalance_policy, placement)
181
+ const cfgFields = {
182
+ group_id: req.group_id,
183
+ shard_count: req.shard_count,
184
+ partition_strategy: req.partition_strategy,
185
+ rebalance_policy: req.rebalance_policy,
186
+ placement: req.placement,
187
+ };
188
+ const cfgBytes = encodeDataParallelConfig(cfgFields);
189
+ buf = appendLengthDelimited(buf, 1, cfgBytes);
190
+ buf = appendString(buf, 2, req.actor_type ?? '');
191
+ const initialState = req.initial_state;
192
+ if (initialState !== undefined && initialState !== null) {
193
+ const stateBytes = new Uint8Array(encW.encode(JSON.stringify(initialState)));
194
+ if (stateBytes.length > 0) {
195
+ buf = appendBytes(buf, 4, stateBytes);
196
+ }
197
+ }
198
+ return buf;
199
+ }
200
+ // ---------------------------------------------------------------------------
201
+ // ScatterGatherRequest encoder
202
+ //
203
+ // message ScatterGatherRequest {
204
+ // string group_id = 1;
205
+ // Message query = 2; (embedded)
206
+ // google.protobuf.Duration timeout = 3; (embedded)
207
+ // ShardGroupAggregationStrategy aggregation = 4; (varint)
208
+ // uint32 min_responses = 5;
209
+ // }
210
+ //
211
+ // google.protobuf.Duration { int64 seconds=1, int32 nanos=2 }
212
+ // ---------------------------------------------------------------------------
213
+ function encodeDurationMs(ms) {
214
+ const seconds = Math.floor(ms / 1000);
215
+ const nanos = (ms % 1000) * 1000000;
216
+ let buf = new Uint8Array(0);
217
+ if (seconds > 0) {
218
+ // int64 seconds = field 1, wire type 0
219
+ buf = appendVarint(buf, (1 << 3) | 0);
220
+ buf = appendVarint(buf, seconds);
221
+ }
222
+ if (nanos > 0) {
223
+ // int32 nanos = field 2, wire type 0
224
+ buf = appendVarint(buf, (2 << 3) | 0);
225
+ buf = appendVarint(buf, nanos);
226
+ }
227
+ return buf;
228
+ }
229
+ export function encodeScatterGatherRequest(req) {
230
+ let buf = new Uint8Array(0);
231
+ buf = appendString(buf, 1, req.group_id ?? '');
232
+ const query = req.query;
233
+ if (query && typeof query === 'object') {
234
+ const msgBytes = encodeMessage(query);
235
+ buf = appendLengthDelimited(buf, 2, msgBytes);
236
+ }
237
+ const timeoutMs = Number(req.timeout_ms ?? 30000);
238
+ if (timeoutMs > 0) {
239
+ const durBytes = encodeDurationMs(timeoutMs);
240
+ if (durBytes.length > 0)
241
+ buf = appendLengthDelimited(buf, 3, durBytes);
242
+ }
243
+ const agg = aggregationStrategyEnum(req.aggregation);
244
+ if (agg !== 0)
245
+ buf = appendUint32(buf, 4, agg);
246
+ const minResponses = Number(req.min_responses ?? 0) >>> 0;
247
+ if (minResponses > 0)
248
+ buf = appendUint32(buf, 5, minResponses);
249
+ return buf;
250
+ }
251
+ // ---------------------------------------------------------------------------
252
+ // CreateShardGroupResponse decoder
253
+ //
254
+ // message CreateShardGroupResponse {
255
+ // ShardGroup group = 1;
256
+ // }
257
+ // message ShardGroup {
258
+ // DataParallelConfig config = 1;
259
+ // string actor_type = 2;
260
+ // repeated string shard_actor_ids = 3;
261
+ // ShardGroupState state = 4;
262
+ // }
263
+ // ---------------------------------------------------------------------------
264
+ function decodeShardGroup(data) {
265
+ const result = {
266
+ config: {},
267
+ actor_type: '',
268
+ shard_actor_ids: [],
269
+ state: 0,
270
+ };
271
+ let pos = 0;
272
+ while (pos < data.length) {
273
+ const { value: tag, n: tn } = readVarint(data, pos);
274
+ pos += tn;
275
+ const fn = Number(tag >> 3n);
276
+ const wt = Number(tag & 7n);
277
+ if (fn === 1 && wt === 2) {
278
+ const { slice, nextPos } = readLengthDelimited(data, pos);
279
+ pos = nextPos;
280
+ result.config = decodeDataParallelConfig(slice);
281
+ }
282
+ else if (fn === 2 && wt === 2) {
283
+ const { value, nextPos } = readString(data, pos);
284
+ pos = nextPos;
285
+ result.actor_type = value;
286
+ }
287
+ else if (fn === 3 && wt === 2) {
288
+ const { slice, nextPos } = readLengthDelimited(data, pos);
289
+ pos = nextPos;
290
+ result.shard_actor_ids.push(enc.decode(slice));
291
+ }
292
+ else if (fn === 4 && wt === 0) {
293
+ const { value, nextPos } = readUint32(data, pos);
294
+ pos = nextPos;
295
+ result.state = value;
296
+ }
297
+ else {
298
+ pos = skipField(data, pos, wt);
299
+ }
300
+ }
301
+ return result;
302
+ }
303
+ function decodeDataParallelConfig(data) {
304
+ const result = {
305
+ group_id: '',
306
+ shard_count: 0,
307
+ partition_strategy: 0,
308
+ rebalance_policy: 0,
309
+ };
310
+ let pos = 0;
311
+ while (pos < data.length) {
312
+ const { value: tag, n: tn } = readVarint(data, pos);
313
+ pos += tn;
314
+ const fn = Number(tag >> 3n);
315
+ const wt = Number(tag & 7n);
316
+ if (fn === 1 && wt === 2) {
317
+ const { value, nextPos } = readString(data, pos);
318
+ pos = nextPos;
319
+ result.group_id = value;
320
+ }
321
+ else if (fn === 2 && wt === 0) {
322
+ const { value, nextPos } = readUint32(data, pos);
323
+ pos = nextPos;
324
+ result.shard_count = value;
325
+ }
326
+ else if (fn === 4 && wt === 0) {
327
+ const { value, nextPos } = readUint32(data, pos);
328
+ pos = nextPos;
329
+ result.partition_strategy = value;
330
+ }
331
+ else if (fn === 5 && wt === 0) {
332
+ const { value, nextPos } = readUint32(data, pos);
333
+ pos = nextPos;
334
+ result.rebalance_policy = value;
335
+ }
336
+ else {
337
+ pos = skipField(data, pos, wt);
338
+ }
339
+ }
340
+ return result;
341
+ }
342
+ export function decodeCreateShardGroupResponse(data) {
343
+ let pos = 0;
344
+ let group = { shard_actor_ids: [] };
345
+ while (pos < data.length) {
346
+ const { value: tag, n: tn } = readVarint(data, pos);
347
+ pos += tn;
348
+ const fn = Number(tag >> 3n);
349
+ const wt = Number(tag & 7n);
350
+ if (fn === 1 && wt === 2) {
351
+ const { slice, nextPos } = readLengthDelimited(data, pos);
352
+ pos = nextPos;
353
+ group = decodeShardGroup(slice);
354
+ }
355
+ else {
356
+ pos = skipField(data, pos, wt);
357
+ }
358
+ }
359
+ return { group };
360
+ }
361
+ // ---------------------------------------------------------------------------
362
+ // ScatterGatherResponse decoder
363
+ //
364
+ // message ScatterGatherResponse {
365
+ // Message result = 1;
366
+ // repeated ShardQueryResponse shard_responses = 2;
367
+ // ScatterGatherStats stats = 3;
368
+ // }
369
+ // message ShardQueryResponse {
370
+ // uint32 shard_id = 1;
371
+ // string shard_actor_id = 2;
372
+ // Message response = 3;
373
+ // Duration latency = 4;
374
+ // bool success = 5;
375
+ // string error = 6;
376
+ // }
377
+ // message Message { ... bytes payload = 6; ... }
378
+ // ---------------------------------------------------------------------------
379
+ function decodeMessagePayload(data) {
380
+ let pos = 0;
381
+ let payloadBytes = null;
382
+ while (pos < data.length) {
383
+ const { value: tag, n: tn } = readVarint(data, pos);
384
+ pos += tn;
385
+ const fn = Number(tag >> 3n);
386
+ const wt = Number(tag & 7n);
387
+ if (fn === 6 && wt === 2) {
388
+ const { slice, nextPos } = readLengthDelimited(data, pos);
389
+ pos = nextPos;
390
+ payloadBytes = slice;
391
+ }
392
+ else {
393
+ pos = skipField(data, pos, wt);
394
+ }
395
+ }
396
+ if (!payloadBytes || payloadBytes.length === 0)
397
+ return {};
398
+ const text = enc.decode(payloadBytes);
399
+ try {
400
+ return JSON.parse(text);
401
+ }
402
+ catch {
403
+ return text;
404
+ }
405
+ }
406
+ function decodeShardQueryResponse(data) {
407
+ const result = {
408
+ shard_id: 0,
409
+ shard_actor_id: '',
410
+ payload: {},
411
+ success: false,
412
+ error: '',
413
+ };
414
+ let pos = 0;
415
+ while (pos < data.length) {
416
+ const { value: tag, n: tn } = readVarint(data, pos);
417
+ pos += tn;
418
+ const fn = Number(tag >> 3n);
419
+ const wt = Number(tag & 7n);
420
+ if (fn === 1 && wt === 0) {
421
+ const { value, nextPos } = readUint32(data, pos);
422
+ pos = nextPos;
423
+ result.shard_id = value;
424
+ }
425
+ else if (fn === 2 && wt === 2) {
426
+ const { value, nextPos } = readString(data, pos);
427
+ pos = nextPos;
428
+ result.shard_actor_id = value;
429
+ }
430
+ else if (fn === 3 && wt === 2) {
431
+ const { slice, nextPos } = readLengthDelimited(data, pos);
432
+ pos = nextPos;
433
+ // Expose the message payload directly so normalizeWorkerPayload can find it
434
+ result.payload = decodeMessagePayload(slice);
435
+ }
436
+ else if (fn === 5 && wt === 0) {
437
+ const { value, nextPos } = readUint32(data, pos);
438
+ pos = nextPos;
439
+ result.success = value !== 0;
440
+ }
441
+ else if (fn === 6 && wt === 2) {
442
+ const { value, nextPos } = readString(data, pos);
443
+ pos = nextPos;
444
+ result.error = value;
445
+ }
446
+ else {
447
+ pos = skipField(data, pos, wt);
448
+ }
449
+ }
450
+ return result;
451
+ }
452
+ export function decodeScatterGatherResponse(data) {
453
+ const shardResponses = [];
454
+ let pos = 0;
455
+ while (pos < data.length) {
456
+ const { value: tag, n: tn } = readVarint(data, pos);
457
+ pos += tn;
458
+ const fn = Number(tag >> 3n);
459
+ const wt = Number(tag & 7n);
460
+ if (fn === 2 && wt === 2) {
461
+ const { slice, nextPos } = readLengthDelimited(data, pos);
462
+ pos = nextPos;
463
+ shardResponses.push(decodeShardQueryResponse(slice));
464
+ }
465
+ else {
466
+ pos = skipField(data, pos, wt);
467
+ }
468
+ }
469
+ return { shard_responses: shardResponses };
470
+ }
471
+ // ---------------------------------------------------------------------------
472
+ // GetApplicationStatusResponse decoder
473
+ //
474
+ // message GetApplicationStatusResponse {
475
+ // optional ApplicationInfo application = 1;
476
+ // optional ApplicationRuntimeState state = 2;
477
+ // optional string error = 3;
478
+ // string node_id = 4;
479
+ // string node_address = 5;
480
+ // }
481
+ // message ApplicationInfo {
482
+ // string application_id = 1;
483
+ // string name = 2;
484
+ // ...
485
+ // optional ApplicationMetrics metrics = 8;
486
+ // }
487
+ // message ApplicationMetrics {
488
+ // map<string, uint64> actor_counts = 1;
489
+ // ...
490
+ // map<string, uint64> counter_metrics = 6;
491
+ // map<string, uint64> latency_totals_ms = 7;
492
+ // map<string, uint64> latency_max_ms = 8;
493
+ // map<string, uint64> latency_samples = 9;
494
+ // }
495
+ // ---------------------------------------------------------------------------
496
+ function decodeUint64MapEntry(data) {
497
+ let pos = 0;
498
+ let key = '';
499
+ let value = 0;
500
+ while (pos < data.length) {
501
+ const { value: tag, n: tn } = readVarint(data, pos);
502
+ pos += tn;
503
+ const fn = Number(tag >> 3n);
504
+ const wt = Number(tag & 7n);
505
+ if (fn === 1 && wt === 2) {
506
+ const { slice, nextPos } = readLengthDelimited(data, pos);
507
+ pos = nextPos;
508
+ key = enc.decode(slice);
509
+ }
510
+ else if (fn === 2 && wt === 0) {
511
+ const { value: v, n: m } = readVarint(data, pos);
512
+ pos += m;
513
+ value = Number(v);
514
+ }
515
+ else {
516
+ pos = skipField(data, pos, wt);
517
+ }
518
+ }
519
+ return { key, value };
520
+ }
521
+ function decodeUint64Map(entries) {
522
+ const result = {};
523
+ for (const entry of entries) {
524
+ const { key, value } = decodeUint64MapEntry(entry);
525
+ if (key)
526
+ result[key] = value;
527
+ }
528
+ return result;
529
+ }
530
+ export function decodeApplicationMetrics(data) {
531
+ const actorCountEntries = [];
532
+ const counterMetricEntries = [];
533
+ const latencyTotalsEntries = [];
534
+ const latencyMaxEntries = [];
535
+ const latencySamplesEntries = [];
536
+ let pos = 0;
537
+ let messageCount = 0;
538
+ let errorCount = 0;
539
+ let uptimeSeconds = 0;
540
+ while (pos < data.length) {
541
+ const { value: tag, n: tn } = readVarint(data, pos);
542
+ pos += tn;
543
+ const fn = Number(tag >> 3n);
544
+ const wt = Number(tag & 7n);
545
+ if (fn === 1 && wt === 2) {
546
+ const { slice, nextPos } = readLengthDelimited(data, pos);
547
+ pos = nextPos;
548
+ actorCountEntries.push(slice);
549
+ }
550
+ else if (fn === 3 && wt === 0) {
551
+ const { value, nextPos } = readUint32(data, pos);
552
+ pos = nextPos;
553
+ uptimeSeconds = value;
554
+ }
555
+ else if (fn === 4 && wt === 0) {
556
+ const { value: v, n: m } = readVarint(data, pos);
557
+ pos += m;
558
+ messageCount = Number(v);
559
+ }
560
+ else if (fn === 5 && wt === 0) {
561
+ const { value: v, n: m } = readVarint(data, pos);
562
+ pos += m;
563
+ errorCount = Number(v);
564
+ }
565
+ else if (fn === 6 && wt === 2) {
566
+ const { slice, nextPos } = readLengthDelimited(data, pos);
567
+ pos = nextPos;
568
+ counterMetricEntries.push(slice);
569
+ }
570
+ else if (fn === 7 && wt === 2) {
571
+ const { slice, nextPos } = readLengthDelimited(data, pos);
572
+ pos = nextPos;
573
+ latencyTotalsEntries.push(slice);
574
+ }
575
+ else if (fn === 8 && wt === 2) {
576
+ const { slice, nextPos } = readLengthDelimited(data, pos);
577
+ pos = nextPos;
578
+ latencyMaxEntries.push(slice);
579
+ }
580
+ else if (fn === 9 && wt === 2) {
581
+ const { slice, nextPos } = readLengthDelimited(data, pos);
582
+ pos = nextPos;
583
+ latencySamplesEntries.push(slice);
584
+ }
585
+ else {
586
+ pos = skipField(data, pos, wt);
587
+ }
588
+ }
589
+ return {
590
+ actor_counts: decodeUint64Map(actorCountEntries),
591
+ uptime_seconds: uptimeSeconds,
592
+ message_count: messageCount,
593
+ error_count: errorCount,
594
+ counter_metrics: decodeUint64Map(counterMetricEntries),
595
+ latency_totals_ms: decodeUint64Map(latencyTotalsEntries),
596
+ latency_max_ms: decodeUint64Map(latencyMaxEntries),
597
+ latency_samples: decodeUint64Map(latencySamplesEntries),
598
+ };
599
+ }
600
+ function decodeApplicationInfo(data) {
601
+ const result = {
602
+ application_id: '',
603
+ name: '',
604
+ metrics: null,
605
+ };
606
+ let pos = 0;
607
+ while (pos < data.length) {
608
+ const { value: tag, n: tn } = readVarint(data, pos);
609
+ pos += tn;
610
+ const fn = Number(tag >> 3n);
611
+ const wt = Number(tag & 7n);
612
+ if (fn === 1 && wt === 2) {
613
+ const { value, nextPos } = readString(data, pos);
614
+ pos = nextPos;
615
+ result.application_id = value;
616
+ }
617
+ else if (fn === 2 && wt === 2) {
618
+ const { value, nextPos } = readString(data, pos);
619
+ pos = nextPos;
620
+ result.name = value;
621
+ }
622
+ else if (fn === 8 && wt === 2) {
623
+ const { slice, nextPos } = readLengthDelimited(data, pos);
624
+ pos = nextPos;
625
+ result.metrics = decodeApplicationMetrics(slice);
626
+ }
627
+ else {
628
+ pos = skipField(data, pos, wt);
629
+ }
630
+ }
631
+ return result;
632
+ }
633
+ export function decodeGetApplicationStatusResponse(data) {
634
+ const result = {
635
+ application: null,
636
+ node_id: '',
637
+ node_address: '',
638
+ error: null,
639
+ };
640
+ let pos = 0;
641
+ while (pos < data.length) {
642
+ const { value: tag, n: tn } = readVarint(data, pos);
643
+ pos += tn;
644
+ const fn = Number(tag >> 3n);
645
+ const wt = Number(tag & 7n);
646
+ if (fn === 1 && wt === 2) {
647
+ const { slice, nextPos } = readLengthDelimited(data, pos);
648
+ pos = nextPos;
649
+ result.application = decodeApplicationInfo(slice);
650
+ }
651
+ else if (fn === 3 && wt === 2) {
652
+ const { value, nextPos } = readString(data, pos);
653
+ pos = nextPos;
654
+ result.error = value;
655
+ }
656
+ else if (fn === 4 && wt === 2) {
657
+ const { value, nextPos } = readString(data, pos);
658
+ pos = nextPos;
659
+ result.node_id = value;
660
+ }
661
+ else if (fn === 5 && wt === 2) {
662
+ const { value, nextPos } = readString(data, pos);
663
+ pos = nextPos;
664
+ result.node_address = value;
665
+ }
666
+ else {
667
+ pos = skipField(data, pos, wt);
668
+ }
669
+ }
670
+ return result;
671
+ }
672
+ // ---------------------------------------------------------------------------
673
+ // ApplicationMetricsAdd encoder
674
+ //
675
+ // The host function hostApplicationMetricsAdd takes (applicationId: string, metrics: payload)
676
+ // where metrics is a protobuf-encoded ApplicationMetrics.
677
+ // ---------------------------------------------------------------------------
678
+ function appendUint64(buf, fieldNum, v) {
679
+ if (v === 0)
680
+ return buf;
681
+ const tag = (fieldNum << 3) | 0;
682
+ let b = appendVarint(buf, tag);
683
+ b = appendVarint(b, v);
684
+ return b;
685
+ }
686
+ function encodeUint64MapEntry(key, value) {
687
+ let entry = new Uint8Array(0);
688
+ entry = appendString(entry, 1, key);
689
+ entry = appendUint64(entry, 2, value);
690
+ return entry;
691
+ }
692
+ export function encodeApplicationMetrics(metrics) {
693
+ let buf = new Uint8Array(0);
694
+ const counterMetrics = metrics.counter_metrics;
695
+ if (counterMetrics && typeof counterMetrics === 'object') {
696
+ for (const [key, value] of Object.entries(counterMetrics)) {
697
+ const entry = encodeUint64MapEntry(key, Number(value));
698
+ buf = appendLengthDelimited(buf, 6, entry);
699
+ }
700
+ }
701
+ const latencyTotals = metrics.latency_totals_ms;
702
+ if (latencyTotals && typeof latencyTotals === 'object') {
703
+ for (const [key, value] of Object.entries(latencyTotals)) {
704
+ const entry = encodeUint64MapEntry(key, Number(value));
705
+ buf = appendLengthDelimited(buf, 7, entry);
706
+ }
707
+ }
708
+ const latencyMax = metrics.latency_max_ms;
709
+ if (latencyMax && typeof latencyMax === 'object') {
710
+ for (const [key, value] of Object.entries(latencyMax)) {
711
+ const entry = encodeUint64MapEntry(key, Number(value));
712
+ buf = appendLengthDelimited(buf, 8, entry);
713
+ }
714
+ }
715
+ const latencySamples = metrics.latency_samples;
716
+ if (latencySamples && typeof latencySamples === 'object') {
717
+ for (const [key, value] of Object.entries(latencySamples)) {
718
+ const entry = encodeUint64MapEntry(key, Number(value));
719
+ buf = appendLengthDelimited(buf, 9, entry);
720
+ }
721
+ }
722
+ return buf;
723
+ }