@rikaidev/yomi 0.2.6

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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +81 -0
  3. package/PRIVACY.md +39 -0
  4. package/README.md +659 -0
  5. package/dist/auth/credential-store.js +395 -0
  6. package/dist/auth/keychain.js +256 -0
  7. package/dist/cli/login.js +142 -0
  8. package/dist/line/auth/protocol/e2ee-bootstrap.js +87 -0
  9. package/dist/line/auth/protocol/index.js +3 -0
  10. package/dist/line/auth/protocol/login-metadata.js +159 -0
  11. package/dist/line/auth/protocol/pwless-login-flow.js +83 -0
  12. package/dist/line/auth/pwless/index.js +163 -0
  13. package/dist/line/auth/pwless/steps.js +213 -0
  14. package/dist/line/client/auth-service/client.js +240 -0
  15. package/dist/line/client/e2ee-service/client.js +69 -0
  16. package/dist/line/client/e2ee-service/requests.js +92 -0
  17. package/dist/line/client/e2ee-service/shared-key-log.js +24 -0
  18. package/dist/line/client/e2ee-service/shared-key-payload.js +35 -0
  19. package/dist/line/client/index.js +213 -0
  20. package/dist/line/client/obs-media-client.js +140 -0
  21. package/dist/line/client/parsers.js +69 -0
  22. package/dist/line/client/shop-service/client.js +63 -0
  23. package/dist/line/client/sticker-meta.js +46 -0
  24. package/dist/line/client/sync-service/client.js +317 -0
  25. package/dist/line/client/talk-service/chat-query.js +122 -0
  26. package/dist/line/client/talk-service/command-client.js +242 -0
  27. package/dist/line/client/talk-service/contact-query.js +77 -0
  28. package/dist/line/client/talk-service/message-box-query.js +137 -0
  29. package/dist/line/client/talk-service/message-id-query.js +241 -0
  30. package/dist/line/client/talk-service/query-client.js +219 -0
  31. package/dist/line/client/talk-service/requests.js +383 -0
  32. package/dist/line/client/transport.js +138 -0
  33. package/dist/line/core/auth-session-logout.js +55 -0
  34. package/dist/line/core/auth-session-runtime.js +231 -0
  35. package/dist/line/core/auth-session-service.js +85 -0
  36. package/dist/line/core/chat-runtime-service.js +343 -0
  37. package/dist/line/core/client-runtime.js +17 -0
  38. package/dist/line/core/config.js +67 -0
  39. package/dist/line/core/constants.js +56 -0
  40. package/dist/line/core/contact-query-service.js +20 -0
  41. package/dist/line/core/directory-runtime-service.js +83 -0
  42. package/dist/line/core/e2ee/bootstrap/keychain.js +41 -0
  43. package/dist/line/core/e2ee/crypto/crypto-primitives.js +98 -0
  44. package/dist/line/core/e2ee/index.js +6 -0
  45. package/dist/line/core/e2ee/keys/decrypt.js +110 -0
  46. package/dist/line/core/e2ee/keys/encrypt.js +117 -0
  47. package/dist/line/core/e2ee/keys/group-key.js +260 -0
  48. package/dist/line/core/e2ee/keys/key-manager.js +231 -0
  49. package/dist/line/core/e2ee/keys/key-payload.js +130 -0
  50. package/dist/line/core/e2ee/keys/key-types.js +1 -0
  51. package/dist/line/core/e2ee/keys/message-crypto.js +146 -0
  52. package/dist/line/core/e2ee/keys/message-decrypt.js +390 -0
  53. package/dist/line/core/e2ee/keys/peer-key.js +191 -0
  54. package/dist/line/core/e2ee/recovery/bootstrap-keys.js +161 -0
  55. package/dist/line/core/e2ee/types.js +4 -0
  56. package/dist/line/core/group-query-service.js +20 -0
  57. package/dist/line/core/media-decrypt.js +78 -0
  58. package/dist/line/core/media-encrypt.js +97 -0
  59. package/dist/line/core/mention.js +89 -0
  60. package/dist/line/core/message-command-service.js +454 -0
  61. package/dist/line/core/message-query-service.js +161 -0
  62. package/dist/line/core/service.js +134 -0
  63. package/dist/line/core/session-state/index.js +243 -0
  64. package/dist/line/core/session-state/persist.js +192 -0
  65. package/dist/line/core/store.js +8 -0
  66. package/dist/line/core/thrift/binary/binary-reader.js +151 -0
  67. package/dist/line/core/thrift/binary/binary-writer.js +157 -0
  68. package/dist/line/core/thrift/binary/type-codec-dsl.js +42 -0
  69. package/dist/line/core/thrift/compact/compact-reader.js +180 -0
  70. package/dist/line/core/thrift/compact/compact-writer.js +161 -0
  71. package/dist/line/core/thrift/compact/type-codec-dsl.js +66 -0
  72. package/dist/line/core/thrift/fields/builders.js +124 -0
  73. package/dist/line/core/thrift/index.js +12 -0
  74. package/dist/line/core/thrift/message/decoder.js +55 -0
  75. package/dist/line/core/thrift/message/encoder.js +25 -0
  76. package/dist/line/core/thrift/primitives/varint.js +64 -0
  77. package/dist/line/core/thrift/struct/reader.js +172 -0
  78. package/dist/line/core/thrift/struct/writer.js +189 -0
  79. package/dist/line/core/thrift/types.js +23 -0
  80. package/dist/line/core/video-thumbnail.js +104 -0
  81. package/dist/mcp/handlers/contacts.js +166 -0
  82. package/dist/mcp/handlers/conversations.js +193 -0
  83. package/dist/mcp/handlers/groups.js +123 -0
  84. package/dist/mcp/handlers/index.js +15 -0
  85. package/dist/mcp/handlers/login.js +473 -0
  86. package/dist/mcp/handlers/media.js +69 -0
  87. package/dist/mcp/handlers/message-actions.js +62 -0
  88. package/dist/mcp/handlers/scope.js +120 -0
  89. package/dist/mcp/handlers/search.js +196 -0
  90. package/dist/mcp/handlers/send.js +523 -0
  91. package/dist/mcp/handlers/shared.js +84 -0
  92. package/dist/mcp/handlers/stickers.js +87 -0
  93. package/dist/mcp/media.js +228 -0
  94. package/dist/mcp/names.js +133 -0
  95. package/dist/mcp/phi-guard.js +105 -0
  96. package/dist/mcp/policy.js +34 -0
  97. package/dist/mcp/server.js +301 -0
  98. package/dist/mcp/tools.js +761 -0
  99. package/dist/mcp/ui/capability.js +26 -0
  100. package/dist/mcp/ui/login-app-protocol.js +118 -0
  101. package/dist/mcp/ui/login-app-styles.js +142 -0
  102. package/dist/mcp/ui/login-app-view.js +361 -0
  103. package/dist/mcp/ui/login-app.js +72 -0
  104. package/dist/mcp/ui/login-structured-content.js +1 -0
  105. package/dist/mcp/ui/resource.js +35 -0
  106. package/dist/mcp/ui/tools-with-ui.js +40 -0
  107. package/dist/search/bigram.js +86 -0
  108. package/dist/search/capture.js +140 -0
  109. package/dist/search/collector.js +176 -0
  110. package/dist/search/default-embedder.js +101 -0
  111. package/dist/search/embedder.js +13 -0
  112. package/dist/search/scope.js +142 -0
  113. package/dist/search/sqlite.js +141 -0
  114. package/dist/search/store.js +469 -0
  115. package/dist/util/data-dir.js +55 -0
  116. package/dist/util/log.js +86 -0
  117. package/dist/version.js +7 -0
  118. package/package.json +63 -0
  119. package/run.mjs +71 -0
@@ -0,0 +1,66 @@
1
+ import { THRIFT_TYPE } from '../types.js';
2
+ export const COMPACT_TYPE_CODEC_DEFINITIONS = [
3
+ {
4
+ type: THRIFT_TYPE.BOOL,
5
+ readHandler: 'readBoolValue',
6
+ writeHandler: 'writeBoolValue',
7
+ },
8
+ {
9
+ type: THRIFT_TYPE.BYTE,
10
+ readHandler: 'readByteValue',
11
+ writeHandler: 'writeByteValue',
12
+ },
13
+ {
14
+ type: THRIFT_TYPE.I16,
15
+ readHandler: 'readI16Value',
16
+ writeHandler: 'writeI16Value',
17
+ },
18
+ {
19
+ type: THRIFT_TYPE.I32,
20
+ readHandler: 'readI32Value',
21
+ writeHandler: 'writeI32Value',
22
+ },
23
+ {
24
+ type: THRIFT_TYPE.I64,
25
+ readHandler: 'readI64Value',
26
+ writeHandler: 'writeI64Value',
27
+ },
28
+ {
29
+ type: THRIFT_TYPE.STRING,
30
+ readHandler: 'readStringValue',
31
+ writeHandler: 'writeStringValue',
32
+ },
33
+ ];
34
+ export const COMPACT_STRUCT_TYPE_DEFINITIONS = [
35
+ { type: 0, handler: 'readNullValue' },
36
+ { type: 1, handler: 'readTrueValue' },
37
+ { type: 2, handler: 'readFalseValue' },
38
+ { type: 3, handler: 'readByteValue' },
39
+ { type: 4, handler: 'readI16Value' },
40
+ { type: 5, handler: 'readI32Value' },
41
+ { type: 6, handler: 'readI64Value' },
42
+ { type: 7, handler: 'readDoubleValue' },
43
+ { type: 8, handler: 'readStringValue' },
44
+ { type: 9, handler: 'readCollectionValue' },
45
+ { type: 10, handler: 'readCollectionValue' },
46
+ { type: 11, handler: 'readMapValue' },
47
+ { type: 12, handler: 'readStructValue' },
48
+ ];
49
+ /**
50
+ * Resolve one compact thrift type into its configured codec definition.
51
+ *
52
+ * @param type - Thrift wire type.
53
+ * @returns Codec definition, if defined.
54
+ */
55
+ export function getCompactTypeCodecDefinition(type) {
56
+ return (COMPACT_TYPE_CODEC_DEFINITIONS.find((candidate) => candidate.type === type) ?? null);
57
+ }
58
+ /**
59
+ * Resolve one compact struct field type into its configured reader handler.
60
+ *
61
+ * @param type - Compact field type.
62
+ * @returns Handler definition, if defined.
63
+ */
64
+ export function getCompactStructTypeDefinition(type) {
65
+ return (COMPACT_STRUCT_TYPE_DEFINITIONS.find((candidate) => candidate.type === type) ?? null);
66
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * TCompact field builders.
3
+ */
4
+ /**
5
+ * Build a generic thrift field tuple.
6
+ *
7
+ * @param type - Thrift wire type.
8
+ * @param fieldId - Thrift field ID.
9
+ * @param value - Field value.
10
+ * @returns Thrift field tuple.
11
+ */
12
+ export function field(type, fieldId, value) {
13
+ return [type, fieldId, value];
14
+ }
15
+ /**
16
+ * Build a BOOL field tuple.
17
+ *
18
+ * @param fieldId - Thrift field ID.
19
+ * @param value - Boolean value.
20
+ * @returns Thrift field tuple.
21
+ */
22
+ export function boolField(fieldId, value) {
23
+ return field(2, fieldId, value);
24
+ }
25
+ /**
26
+ * Build a BYTE field tuple.
27
+ *
28
+ * @param fieldId - Thrift field ID.
29
+ * @param value - Byte value.
30
+ * @returns Thrift field tuple.
31
+ */
32
+ export function byteField(fieldId, value) {
33
+ return field(3, fieldId, value);
34
+ }
35
+ /**
36
+ * Build an I16 field tuple.
37
+ *
38
+ * @param fieldId - Thrift field ID.
39
+ * @param value - I16 value.
40
+ * @returns Thrift field tuple.
41
+ */
42
+ export function i16Field(fieldId, value) {
43
+ return field(6, fieldId, value);
44
+ }
45
+ /**
46
+ * Build an I32 field tuple.
47
+ *
48
+ * @param fieldId - Thrift field ID.
49
+ * @param value - I32 value.
50
+ * @returns Thrift field tuple.
51
+ */
52
+ export function i32Field(fieldId, value) {
53
+ return field(8, fieldId, value);
54
+ }
55
+ /**
56
+ * Build an I64 field tuple.
57
+ *
58
+ * @param fieldId - Thrift field ID.
59
+ * @param value - I64 value.
60
+ * @returns Thrift field tuple.
61
+ */
62
+ export function i64Field(fieldId, value) {
63
+ return field(10, fieldId, value);
64
+ }
65
+ /**
66
+ * Build a STRING/BINARY field tuple.
67
+ *
68
+ * @param fieldId - Thrift field ID.
69
+ * @param value - String or buffer value.
70
+ * @returns Thrift field tuple.
71
+ */
72
+ export function stringField(fieldId, value) {
73
+ return field(11, fieldId, value);
74
+ }
75
+ /**
76
+ * Build a STRUCT field tuple.
77
+ *
78
+ * @param fieldId - Thrift field ID.
79
+ * @param fields - Nested struct fields.
80
+ * @returns Thrift field tuple.
81
+ */
82
+ export function structField(fieldId, fields) {
83
+ return field(12, fieldId, fields);
84
+ }
85
+ /**
86
+ * Build a MAP field tuple.
87
+ *
88
+ * @param fieldId - Thrift field ID.
89
+ * @param keyType - Key thrift type.
90
+ * @param valueType - Value thrift type.
91
+ * @param entries - Map entries.
92
+ * @returns Thrift field tuple.
93
+ */
94
+ export function mapField(fieldId, keyType, valueType, entries) {
95
+ return field(13, fieldId, [keyType, valueType, entries]);
96
+ }
97
+ /**
98
+ * Build a LIST field tuple.
99
+ *
100
+ * @param fieldId - Thrift field ID.
101
+ * @param elementType - Element thrift type.
102
+ * @param items - List items.
103
+ * @returns Thrift field tuple.
104
+ */
105
+ export function listField(fieldId, elementType, items) {
106
+ return field(15, fieldId, [elementType, items]);
107
+ }
108
+ /**
109
+ * Build a SET field tuple.
110
+ *
111
+ * A thrift SET (type 14) is wire-identical to a LIST in TCompact — same
112
+ * element-type/count header and element payload — only the field header's
113
+ * type nibble differs. LINE distinguishes them: e.g. inviteIntoChat /
114
+ * deleteOtherFromChat / createChat read `targetUserMids` as a SET and see an
115
+ * empty collection if it arrives as a LIST.
116
+ *
117
+ * @param fieldId - Thrift field ID.
118
+ * @param elementType - Element thrift type.
119
+ * @param items - Set items.
120
+ * @returns Thrift field tuple.
121
+ */
122
+ export function setField(fieldId, elementType, items) {
123
+ return field(14, fieldId, [elementType, items]);
124
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Thrift - exports all modules
3
+ */
4
+ export { TBinaryReader } from './binary/binary-reader.js';
5
+ export { TBinaryWriter } from './binary/binary-writer.js';
6
+ export { TCompactReader } from './compact/compact-reader.js';
7
+ export { TCompactWriter } from './compact/compact-writer.js';
8
+ export { boolField, byteField, field, i16Field, i32Field, i64Field, listField, mapField, setField, stringField, structField, } from './fields/builders.js';
9
+ export { decodeResponseMessage } from './message/decoder.js';
10
+ export { encodeCallMessage } from './message/encoder.js';
11
+ export { readStructFields } from './struct/reader.js';
12
+ export { MSG_TYPE, THRIFT_TYPE } from './types.js';
@@ -0,0 +1,55 @@
1
+ /**
2
+ * TCompact response message decoder.
3
+ */
4
+ import { readStructFields } from '../struct/reader.js';
5
+ /**
6
+ * Decode a full TCompact response message from raw bytes.
7
+ *
8
+ * Parses the 2-byte protocol header, varint seqId, varint+bytes method name,
9
+ * then delegates struct body parsing to readStructFields().
10
+ *
11
+ * @param data - Raw response bytes from the LINE server
12
+ * @returns Decoded message with fields map, or an error object
13
+ */
14
+ export function decodeResponseMessage(data) {
15
+ if (!data || data.length < 2 || data[0] !== 0x82) {
16
+ throw new Error('invalid');
17
+ }
18
+ let pos = 1;
19
+ const typeByte = data[pos++];
20
+ const msgType = (typeByte >> 5) & 0x07;
21
+ let seqId = 0;
22
+ let shift = 0;
23
+ while (pos < data.length) {
24
+ const b = data[pos++];
25
+ seqId |= (b & 0x7f) << shift;
26
+ if (!(b & 0x80)) {
27
+ break;
28
+ }
29
+ shift += 7;
30
+ }
31
+ let nameLen = 0;
32
+ shift = 0;
33
+ while (pos < data.length) {
34
+ const b = data[pos++];
35
+ nameLen |= (b & 0x7f) << shift;
36
+ if (!(b & 0x80)) {
37
+ break;
38
+ }
39
+ shift += 7;
40
+ }
41
+ const name = new TextDecoder().decode(data.subarray(pos, pos + nameLen));
42
+ pos += nameLen;
43
+ const fields = readStructFields(data.subarray(pos), true);
44
+ const typeNames = {
45
+ 1: 'CALL',
46
+ 2: 'REPLY',
47
+ 3: 'EXCEPTION',
48
+ };
49
+ return {
50
+ type: typeNames[msgType] || `?${msgType}`,
51
+ method: name,
52
+ seqId,
53
+ fields,
54
+ };
55
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * LINE Thrift TCompact message encoder.
3
+ */
4
+ import { Buffer } from 'node:buffer';
5
+ import { varint } from '../primitives/varint.js';
6
+ import { writeFieldsArray } from '../struct/writer.js';
7
+ /**
8
+ * Build a TCompact CALL message using array-style field definitions.
9
+ *
10
+ * @param method - Method name.
11
+ * @param seqId - Sequence ID.
12
+ * @param args - Array of [type, fieldId, value] tuples.
13
+ * @returns Serialized TCompact message as Buffer.
14
+ */
15
+ export function encodeCallMessage(method, seqId, args) {
16
+ const methodName = Buffer.from(method, 'utf-8');
17
+ return Buffer.concat([
18
+ Buffer.from([0x82, 0x21]),
19
+ varint(seqId),
20
+ varint(methodName.length),
21
+ methodName,
22
+ args?.length ? writeFieldsArray(args, { v: 0 }) : Buffer.alloc(0),
23
+ Buffer.from([0]),
24
+ ]);
25
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * TCompact primitive encoding helpers.
3
+ */
4
+ import { Buffer } from 'node:buffer';
5
+ /**
6
+ * Encode an unsigned integer as a base-128 varint.
7
+ *
8
+ * @param value - The number to encode.
9
+ * @returns Encoded varint buffer.
10
+ */
11
+ export function varint(value) {
12
+ const bytes = [];
13
+ let remaining = value >>> 0;
14
+ do {
15
+ let byte = remaining & 0x7f;
16
+ remaining >>>= 7;
17
+ if (remaining) {
18
+ byte |= 0x80;
19
+ }
20
+ bytes.push(byte);
21
+ } while (remaining);
22
+ return Buffer.from(bytes);
23
+ }
24
+ /**
25
+ * Encode a signed 32-bit integer using ZigZag encoding.
26
+ *
27
+ * @param value - Signed 32-bit integer.
28
+ * @returns Encoded varint buffer.
29
+ */
30
+ export function zigzag(value) {
31
+ return varint(((value << 1) ^ (value >> 31)) >>> 0);
32
+ }
33
+ /**
34
+ * Encode an unsigned bigint as a base-128 varint.
35
+ *
36
+ * @param value - Bigint to encode.
37
+ * @returns Encoded varint buffer.
38
+ */
39
+ export function varintBig(value) {
40
+ const bytes = [];
41
+ let remaining = value;
42
+ if (remaining < 0n) {
43
+ remaining += 1n << 64n;
44
+ }
45
+ do {
46
+ let byte = Number(remaining & 0x7fn);
47
+ remaining >>= 7n;
48
+ if (remaining) {
49
+ byte |= 0x80;
50
+ }
51
+ bytes.push(byte);
52
+ } while (remaining);
53
+ return Buffer.from(bytes);
54
+ }
55
+ /**
56
+ * Encode a signed 64-bit integer using ZigZag encoding.
57
+ *
58
+ * @param value - Signed 64-bit integer.
59
+ * @returns Encoded varint buffer.
60
+ */
61
+ export function zigzag64(value) {
62
+ const bigintValue = BigInt(value);
63
+ return varintBig((bigintValue << 1n) ^ (bigintValue >> 63n));
64
+ }
@@ -0,0 +1,172 @@
1
+ /**
2
+ * TCompact struct parser.
3
+ */
4
+ import { Buffer } from 'node:buffer';
5
+ import { getCompactStructTypeDefinition } from '../compact/type-codec-dsl.js';
6
+ /**
7
+ * Parse a TCompact struct from raw bytes (no message header).
8
+ *
9
+ * @param buf - Raw bytes starting at the first field header (or STOP byte)
10
+ * @param textStrings - If true, decode STRING fields as UTF-8 string (default: false → Buffer)
11
+ * @returns Object mapping field ID → parsed value
12
+ */
13
+ export function readStructFields(buf, textStrings = false) {
14
+ let pos = 0;
15
+ let lastFieldId = 0;
16
+ let lastType = -1;
17
+ const readByte = () => buf[pos++];
18
+ const readVarint = () => {
19
+ let result = 0;
20
+ let shift = 0;
21
+ while (pos < buf.length) {
22
+ const byte = buf[pos++];
23
+ result |= (byte & 0x7f) << shift;
24
+ if (!(byte & 0x80)) {
25
+ break;
26
+ }
27
+ shift += 7;
28
+ }
29
+ return result >>> 0;
30
+ };
31
+ const readZigzagInt = () => {
32
+ const value = readVarint();
33
+ return (value >>> 1) ^ -(value & 1);
34
+ };
35
+ const readZigzagBigInt = () => {
36
+ let result = 0n;
37
+ let shift = 0n;
38
+ while (pos < buf.length) {
39
+ const byte = BigInt(buf[pos++]);
40
+ result |= (byte & 0x7fn) << shift;
41
+ if (!(byte & 0x80n)) {
42
+ break;
43
+ }
44
+ shift += 7n;
45
+ }
46
+ return (result >> 1n) ^ -(result & 1n);
47
+ };
48
+ const readString = () => {
49
+ const length = readVarint();
50
+ if (length < 0 || pos + length > buf.length) {
51
+ throw new Error(`Invalid Length: len=${length} pos=${pos} buf=${buf.length} field=${lastFieldId} type=${lastType}`);
52
+ }
53
+ const slice = buf.subarray(pos, pos + length);
54
+ pos += length;
55
+ if (!textStrings) {
56
+ return Buffer.from(slice);
57
+ }
58
+ try {
59
+ return new TextDecoder('utf-8', { fatal: true }).decode(slice);
60
+ }
61
+ catch {
62
+ return Buffer.from(slice);
63
+ }
64
+ };
65
+ /**
66
+ * Read a TCompact LIST or SET payload.
67
+ *
68
+ * @param header - Collection header byte.
69
+ * @returns Parsed collection items.
70
+ */
71
+ function readCollection(header) {
72
+ const items = [];
73
+ let size = (header >> 4) & 0xf;
74
+ const elementType = header & 0xf;
75
+ if (size === 15) {
76
+ size = readVarint();
77
+ }
78
+ if (size < 0 || size > 100000) {
79
+ throw new Error(`Invalid Length: collection=${size} pos=${pos} field=${lastFieldId} type=${lastType}`);
80
+ }
81
+ for (let i = 0; i < size; i++) {
82
+ items.push(readValue(elementType));
83
+ }
84
+ return items;
85
+ }
86
+ /**
87
+ * Read a TCompact MAP payload.
88
+ *
89
+ * @returns Parsed key/value object.
90
+ */
91
+ function readMap() {
92
+ const size = readVarint();
93
+ if (!size) {
94
+ return {};
95
+ }
96
+ const header = readByte();
97
+ const keyType = (header >> 4) & 0xf;
98
+ const valueType = header & 0xf;
99
+ const map = {};
100
+ if (size < 0 || size > 100000) {
101
+ throw new Error(`Invalid Length: map=${size} pos=${pos} field=${lastFieldId} type=${lastType}`);
102
+ }
103
+ for (let i = 0; i < size; i++) {
104
+ const key = readValue(keyType);
105
+ map[Buffer.isBuffer(key) ? key.toString('utf-8') : String(key)] =
106
+ readValue(valueType);
107
+ }
108
+ return map;
109
+ }
110
+ /**
111
+ * Read one TCompact DOUBLE value.
112
+ *
113
+ * @returns Parsed floating-point value.
114
+ */
115
+ function readDouble() {
116
+ const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
117
+ const value = view.getFloat64(pos, true);
118
+ pos += 8;
119
+ return value;
120
+ }
121
+ const compactTypeReaders = {
122
+ readNullValue: () => null,
123
+ readTrueValue: () => true,
124
+ readFalseValue: () => false,
125
+ readByteValue: () => readByte(),
126
+ readI16Value: () => readZigzagInt(),
127
+ readI32Value: () => readZigzagInt(),
128
+ readI64Value: () => readZigzagBigInt(),
129
+ readDoubleValue: () => readDouble(),
130
+ readStringValue: () => readString(),
131
+ readCollectionValue: () => readCollection(readByte()),
132
+ readMapValue: () => readMap(),
133
+ readStructValue: () => readStruct(),
134
+ };
135
+ /**
136
+ * Read one compact field value.
137
+ *
138
+ * @param compactType - Compact wire type.
139
+ * @returns Parsed field value.
140
+ */
141
+ function readValue(compactType) {
142
+ const definition = getCompactStructTypeDefinition(compactType);
143
+ if (!definition) {
144
+ throw new Error(`Unknown compact type ${compactType} at pos ${pos}`);
145
+ }
146
+ return compactTypeReaders[definition.handler]();
147
+ }
148
+ /**
149
+ * Read one TCompact struct body.
150
+ *
151
+ * @returns Parsed struct fields keyed by field ID.
152
+ */
153
+ function readStruct() {
154
+ const fields = {};
155
+ let localLastFieldId = 0;
156
+ while (pos < buf.length) {
157
+ const header = readByte();
158
+ if (!header) {
159
+ break;
160
+ }
161
+ const compactType = header & 0xf;
162
+ const delta = (header >> 4) & 0xf;
163
+ const fieldId = delta ? localLastFieldId + delta : readZigzagInt();
164
+ localLastFieldId = fieldId;
165
+ lastFieldId = fieldId;
166
+ lastType = compactType;
167
+ fields[fieldId] = readValue(compactType);
168
+ }
169
+ return fields;
170
+ }
171
+ return readStruct();
172
+ }