boom-format 0.9.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.
- package/LICENSE +127 -0
- package/README.md +1079 -0
- package/SPECIFICATION.md +404 -0
- package/deno.json +15 -0
- package/dist/boom.min.cjs +17 -0
- package/dist/boom.min.js +1 -0
- package/dist/boom.obf.js +1 -0
- package/dist/chunk-5PQH6SJJ.js +5148 -0
- package/dist/cli.cjs +4241 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.global.js +4249 -0
- package/dist/cli.js +313 -0
- package/dist/index.cjs +5211 -0
- package/dist/index.d.cts +779 -0
- package/dist/index.d.ts +779 -0
- package/dist/index.global.js +5172 -0
- package/dist/index.js +82 -0
- package/package.json +96 -0
- package/samples/README.md +114 -0
- package/samples/api-response.boom +0 -0
- package/samples/api-response.boom.txt +1 -0
- package/samples/api-response.json +19 -0
- package/samples/config.boom +0 -0
- package/samples/config.boom.txt +1 -0
- package/samples/config.json +22 -0
- package/samples/users.boom +0 -0
- package/samples/users.boom.txt +1 -0
- package/samples/users.json +31 -0
|
@@ -0,0 +1,4249 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var Boom = (() => {
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
11
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
12
|
+
}) : x)(function(x) {
|
|
13
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
14
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
15
|
+
});
|
|
16
|
+
var __copyProps = (to, from, except, desc) => {
|
|
17
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
|
+
for (let key of __getOwnPropNames(from))
|
|
19
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
20
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
21
|
+
}
|
|
22
|
+
return to;
|
|
23
|
+
};
|
|
24
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
25
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
26
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
27
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
28
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
29
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
30
|
+
mod
|
|
31
|
+
));
|
|
32
|
+
|
|
33
|
+
// src/cli.ts
|
|
34
|
+
var fs = __toESM(__require("fs"), 1);
|
|
35
|
+
var path = __toESM(__require("path"), 1);
|
|
36
|
+
|
|
37
|
+
// src/errors.ts
|
|
38
|
+
var BoomError = class _BoomError extends Error {
|
|
39
|
+
constructor(message) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.name = "BoomError";
|
|
42
|
+
Object.setPrototypeOf(this, _BoomError.prototype);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// src/core.ts
|
|
47
|
+
var VERSION = 1;
|
|
48
|
+
var BOOM_DICTIONARY_V1 = Object.freeze([
|
|
49
|
+
// 0-31: Most common keys (highest frequency - 1 byte encoding)
|
|
50
|
+
"id",
|
|
51
|
+
"name",
|
|
52
|
+
"type",
|
|
53
|
+
"content",
|
|
54
|
+
"data",
|
|
55
|
+
"value",
|
|
56
|
+
"text",
|
|
57
|
+
"message",
|
|
58
|
+
"status",
|
|
59
|
+
"error",
|
|
60
|
+
"result",
|
|
61
|
+
"code",
|
|
62
|
+
"key",
|
|
63
|
+
"index",
|
|
64
|
+
"role",
|
|
65
|
+
"model",
|
|
66
|
+
"user",
|
|
67
|
+
"items",
|
|
68
|
+
"count",
|
|
69
|
+
"total",
|
|
70
|
+
"page",
|
|
71
|
+
"size",
|
|
72
|
+
"url",
|
|
73
|
+
"path",
|
|
74
|
+
"title",
|
|
75
|
+
"body",
|
|
76
|
+
"query",
|
|
77
|
+
"token",
|
|
78
|
+
"version",
|
|
79
|
+
"created",
|
|
80
|
+
"updated",
|
|
81
|
+
"source",
|
|
82
|
+
// 32-63: API response fields
|
|
83
|
+
"success",
|
|
84
|
+
"response",
|
|
85
|
+
"request",
|
|
86
|
+
"payload",
|
|
87
|
+
"params",
|
|
88
|
+
"headers",
|
|
89
|
+
"method",
|
|
90
|
+
"endpoint",
|
|
91
|
+
"description",
|
|
92
|
+
"label",
|
|
93
|
+
"meta",
|
|
94
|
+
"info",
|
|
95
|
+
"details",
|
|
96
|
+
"options",
|
|
97
|
+
"config",
|
|
98
|
+
"settings",
|
|
99
|
+
"enabled",
|
|
100
|
+
"disabled",
|
|
101
|
+
"active",
|
|
102
|
+
"visible",
|
|
103
|
+
"required",
|
|
104
|
+
"optional",
|
|
105
|
+
"default",
|
|
106
|
+
"custom",
|
|
107
|
+
"input",
|
|
108
|
+
"output",
|
|
109
|
+
"format",
|
|
110
|
+
"encoding",
|
|
111
|
+
"language",
|
|
112
|
+
"locale",
|
|
113
|
+
"timezone",
|
|
114
|
+
"currency",
|
|
115
|
+
// 64-95: AI/LLM streaming fields (OpenAI, Anthropic, Cohere, etc.)
|
|
116
|
+
"choices",
|
|
117
|
+
"delta",
|
|
118
|
+
"finish_reason",
|
|
119
|
+
"usage",
|
|
120
|
+
"prompt_tokens",
|
|
121
|
+
"completion_tokens",
|
|
122
|
+
"total_tokens",
|
|
123
|
+
"messages",
|
|
124
|
+
"assistant",
|
|
125
|
+
"system",
|
|
126
|
+
"function",
|
|
127
|
+
"tool",
|
|
128
|
+
"tools",
|
|
129
|
+
"tool_calls",
|
|
130
|
+
"tool_call",
|
|
131
|
+
"arguments",
|
|
132
|
+
"stream",
|
|
133
|
+
"chunk",
|
|
134
|
+
"object",
|
|
135
|
+
"chat",
|
|
136
|
+
"completion",
|
|
137
|
+
"completions",
|
|
138
|
+
"embedding",
|
|
139
|
+
"embeddings",
|
|
140
|
+
"logprobs",
|
|
141
|
+
"top_logprobs",
|
|
142
|
+
"stop",
|
|
143
|
+
"stop_reason",
|
|
144
|
+
"stop_sequence",
|
|
145
|
+
"max_tokens",
|
|
146
|
+
"temperature",
|
|
147
|
+
"top_p",
|
|
148
|
+
// 96-127: Status and state values (1 byte encoding)
|
|
149
|
+
"pending",
|
|
150
|
+
"completed",
|
|
151
|
+
"failed",
|
|
152
|
+
"cancelled",
|
|
153
|
+
"processing",
|
|
154
|
+
"queued",
|
|
155
|
+
"running",
|
|
156
|
+
"stopped",
|
|
157
|
+
"ok",
|
|
158
|
+
"done",
|
|
159
|
+
"ready",
|
|
160
|
+
"loading",
|
|
161
|
+
"waiting",
|
|
162
|
+
"blocked",
|
|
163
|
+
"paused",
|
|
164
|
+
"resumed",
|
|
165
|
+
"open",
|
|
166
|
+
"closed",
|
|
167
|
+
"connected",
|
|
168
|
+
"disconnected",
|
|
169
|
+
"online",
|
|
170
|
+
"offline",
|
|
171
|
+
"available",
|
|
172
|
+
"unavailable",
|
|
173
|
+
"valid",
|
|
174
|
+
"invalid",
|
|
175
|
+
"verified",
|
|
176
|
+
"unverified",
|
|
177
|
+
"approved",
|
|
178
|
+
"rejected",
|
|
179
|
+
"expired",
|
|
180
|
+
"revoked",
|
|
181
|
+
// 128-159: HTTP and headers
|
|
182
|
+
"GET",
|
|
183
|
+
"POST",
|
|
184
|
+
"PUT",
|
|
185
|
+
"DELETE",
|
|
186
|
+
"PATCH",
|
|
187
|
+
"HEAD",
|
|
188
|
+
"OPTIONS",
|
|
189
|
+
"CONNECT",
|
|
190
|
+
"content-type",
|
|
191
|
+
"authorization",
|
|
192
|
+
"accept",
|
|
193
|
+
"accept-encoding",
|
|
194
|
+
"cache-control",
|
|
195
|
+
"user-agent",
|
|
196
|
+
"origin",
|
|
197
|
+
"referer",
|
|
198
|
+
"application/json",
|
|
199
|
+
"application/octet-stream",
|
|
200
|
+
"text/plain",
|
|
201
|
+
"text/html",
|
|
202
|
+
"multipart/form-data",
|
|
203
|
+
"Bearer",
|
|
204
|
+
"Basic",
|
|
205
|
+
"gzip",
|
|
206
|
+
"x-request-id",
|
|
207
|
+
"x-correlation-id",
|
|
208
|
+
"x-api-key",
|
|
209
|
+
"x-auth-token",
|
|
210
|
+
"etag",
|
|
211
|
+
"last-modified",
|
|
212
|
+
"if-none-match",
|
|
213
|
+
"if-modified-since",
|
|
214
|
+
// 160-191: Timestamps and dates
|
|
215
|
+
"created_at",
|
|
216
|
+
"updated_at",
|
|
217
|
+
"deleted_at",
|
|
218
|
+
"expires_at",
|
|
219
|
+
"started_at",
|
|
220
|
+
"ended_at",
|
|
221
|
+
"published_at",
|
|
222
|
+
"modified_at",
|
|
223
|
+
"createdAt",
|
|
224
|
+
"updatedAt",
|
|
225
|
+
"deletedAt",
|
|
226
|
+
"expiresAt",
|
|
227
|
+
"startedAt",
|
|
228
|
+
"endedAt",
|
|
229
|
+
"publishedAt",
|
|
230
|
+
"modifiedAt",
|
|
231
|
+
"start_date",
|
|
232
|
+
"end_date",
|
|
233
|
+
"due_date",
|
|
234
|
+
"birth_date",
|
|
235
|
+
"timestamp",
|
|
236
|
+
"datetime",
|
|
237
|
+
"date",
|
|
238
|
+
"time",
|
|
239
|
+
"year",
|
|
240
|
+
"month",
|
|
241
|
+
"day",
|
|
242
|
+
"hour",
|
|
243
|
+
"minute",
|
|
244
|
+
"second",
|
|
245
|
+
"millisecond",
|
|
246
|
+
"duration",
|
|
247
|
+
// 192-223: User/auth fields
|
|
248
|
+
"username",
|
|
249
|
+
"password",
|
|
250
|
+
"email",
|
|
251
|
+
"phone",
|
|
252
|
+
"address",
|
|
253
|
+
"avatar",
|
|
254
|
+
"profile",
|
|
255
|
+
"session",
|
|
256
|
+
"firstName",
|
|
257
|
+
"lastName",
|
|
258
|
+
"fullName",
|
|
259
|
+
"displayName",
|
|
260
|
+
"first_name",
|
|
261
|
+
"last_name",
|
|
262
|
+
"full_name",
|
|
263
|
+
"display_name",
|
|
264
|
+
"roles",
|
|
265
|
+
"permissions",
|
|
266
|
+
"groups",
|
|
267
|
+
"teams",
|
|
268
|
+
"organization",
|
|
269
|
+
"company",
|
|
270
|
+
"department",
|
|
271
|
+
"position",
|
|
272
|
+
"access_token",
|
|
273
|
+
"refresh_token",
|
|
274
|
+
"id_token",
|
|
275
|
+
"api_key",
|
|
276
|
+
"client_id",
|
|
277
|
+
"client_secret",
|
|
278
|
+
"scope",
|
|
279
|
+
"grant_type",
|
|
280
|
+
// 224-255: Data types and formats
|
|
281
|
+
"string",
|
|
282
|
+
"number",
|
|
283
|
+
"boolean",
|
|
284
|
+
"integer",
|
|
285
|
+
"float",
|
|
286
|
+
"double",
|
|
287
|
+
"decimal",
|
|
288
|
+
"bigint",
|
|
289
|
+
"array",
|
|
290
|
+
"object",
|
|
291
|
+
"null",
|
|
292
|
+
"undefined",
|
|
293
|
+
"binary",
|
|
294
|
+
"base64",
|
|
295
|
+
"hex",
|
|
296
|
+
"uuid",
|
|
297
|
+
"json",
|
|
298
|
+
"xml",
|
|
299
|
+
"html",
|
|
300
|
+
"csv",
|
|
301
|
+
"yaml",
|
|
302
|
+
"markdown",
|
|
303
|
+
"plain",
|
|
304
|
+
"rich",
|
|
305
|
+
"utf8",
|
|
306
|
+
"utf-8",
|
|
307
|
+
"ascii",
|
|
308
|
+
"latin1",
|
|
309
|
+
"iso-8859-1",
|
|
310
|
+
"unicode",
|
|
311
|
+
"emoji",
|
|
312
|
+
"symbol",
|
|
313
|
+
// 256-287: Error handling
|
|
314
|
+
"errors",
|
|
315
|
+
"warnings",
|
|
316
|
+
"exception",
|
|
317
|
+
"stack",
|
|
318
|
+
"trace",
|
|
319
|
+
"cause",
|
|
320
|
+
"reason",
|
|
321
|
+
"context",
|
|
322
|
+
"error_code",
|
|
323
|
+
"error_message",
|
|
324
|
+
"error_type",
|
|
325
|
+
"error_details",
|
|
326
|
+
"errorCode",
|
|
327
|
+
"errorMessage",
|
|
328
|
+
"errorType",
|
|
329
|
+
"errorDetails",
|
|
330
|
+
"not_found",
|
|
331
|
+
"unauthorized",
|
|
332
|
+
"forbidden",
|
|
333
|
+
"bad_request",
|
|
334
|
+
"server_error",
|
|
335
|
+
"timeout",
|
|
336
|
+
"conflict",
|
|
337
|
+
"rate_limit",
|
|
338
|
+
"notFound",
|
|
339
|
+
"badRequest",
|
|
340
|
+
"serverError",
|
|
341
|
+
"rateLimit",
|
|
342
|
+
"validation_error",
|
|
343
|
+
"parse_error",
|
|
344
|
+
"network_error",
|
|
345
|
+
"unknown_error",
|
|
346
|
+
// 288-319: Collections and pagination
|
|
347
|
+
"list",
|
|
348
|
+
"items",
|
|
349
|
+
"records",
|
|
350
|
+
"entries",
|
|
351
|
+
"rows",
|
|
352
|
+
"columns",
|
|
353
|
+
"fields",
|
|
354
|
+
"values",
|
|
355
|
+
"limit",
|
|
356
|
+
"offset",
|
|
357
|
+
"cursor",
|
|
358
|
+
"next_cursor",
|
|
359
|
+
"prev_cursor",
|
|
360
|
+
"has_more",
|
|
361
|
+
"total_count",
|
|
362
|
+
"page_count",
|
|
363
|
+
"first",
|
|
364
|
+
"last",
|
|
365
|
+
"next",
|
|
366
|
+
"previous",
|
|
367
|
+
"current",
|
|
368
|
+
"per_page",
|
|
369
|
+
"page_size",
|
|
370
|
+
"page_number",
|
|
371
|
+
"sort",
|
|
372
|
+
"order",
|
|
373
|
+
"filter",
|
|
374
|
+
"search",
|
|
375
|
+
"asc",
|
|
376
|
+
"desc",
|
|
377
|
+
"ascending",
|
|
378
|
+
"descending",
|
|
379
|
+
// 320-351: Additional common fields
|
|
380
|
+
"category",
|
|
381
|
+
"categories",
|
|
382
|
+
"tag",
|
|
383
|
+
"tags",
|
|
384
|
+
"parent",
|
|
385
|
+
"children",
|
|
386
|
+
"ancestors",
|
|
387
|
+
"descendants",
|
|
388
|
+
"price",
|
|
389
|
+
"amount",
|
|
390
|
+
"quantity",
|
|
391
|
+
"unit",
|
|
392
|
+
"discount",
|
|
393
|
+
"tax",
|
|
394
|
+
"subtotal",
|
|
395
|
+
"grand_total",
|
|
396
|
+
"image",
|
|
397
|
+
"images",
|
|
398
|
+
"file",
|
|
399
|
+
"files",
|
|
400
|
+
"document",
|
|
401
|
+
"documents",
|
|
402
|
+
"attachment",
|
|
403
|
+
"attachments",
|
|
404
|
+
"link",
|
|
405
|
+
"links",
|
|
406
|
+
"href",
|
|
407
|
+
"ref",
|
|
408
|
+
"reference",
|
|
409
|
+
"references",
|
|
410
|
+
"relation",
|
|
411
|
+
"relations",
|
|
412
|
+
// 352-383: Events and actions
|
|
413
|
+
"event",
|
|
414
|
+
"events",
|
|
415
|
+
"action",
|
|
416
|
+
"actions",
|
|
417
|
+
"trigger",
|
|
418
|
+
"handler",
|
|
419
|
+
"callback",
|
|
420
|
+
"listener",
|
|
421
|
+
"click",
|
|
422
|
+
"submit",
|
|
423
|
+
"change",
|
|
424
|
+
"load",
|
|
425
|
+
"error",
|
|
426
|
+
"success",
|
|
427
|
+
"start",
|
|
428
|
+
"end",
|
|
429
|
+
"create",
|
|
430
|
+
"read",
|
|
431
|
+
"update",
|
|
432
|
+
"delete",
|
|
433
|
+
"insert",
|
|
434
|
+
"remove",
|
|
435
|
+
"add",
|
|
436
|
+
"set",
|
|
437
|
+
"get",
|
|
438
|
+
"put",
|
|
439
|
+
"post",
|
|
440
|
+
"patch",
|
|
441
|
+
"fetch",
|
|
442
|
+
"send",
|
|
443
|
+
"receive",
|
|
444
|
+
"process",
|
|
445
|
+
// 384-415: Metrics and analytics
|
|
446
|
+
"metric",
|
|
447
|
+
"metrics",
|
|
448
|
+
"stat",
|
|
449
|
+
"stats",
|
|
450
|
+
"analytics",
|
|
451
|
+
"tracking",
|
|
452
|
+
"telemetry",
|
|
453
|
+
"logging",
|
|
454
|
+
"latency",
|
|
455
|
+
"throughput",
|
|
456
|
+
"bandwidth",
|
|
457
|
+
"cpu",
|
|
458
|
+
"memory",
|
|
459
|
+
"disk",
|
|
460
|
+
"network",
|
|
461
|
+
"io",
|
|
462
|
+
"requests",
|
|
463
|
+
"responses",
|
|
464
|
+
"errors",
|
|
465
|
+
"successes",
|
|
466
|
+
"failures",
|
|
467
|
+
"retries",
|
|
468
|
+
"timeouts",
|
|
469
|
+
"rate",
|
|
470
|
+
"min",
|
|
471
|
+
"max",
|
|
472
|
+
"avg",
|
|
473
|
+
"sum",
|
|
474
|
+
"p50",
|
|
475
|
+
"p90",
|
|
476
|
+
"p95",
|
|
477
|
+
"p99"
|
|
478
|
+
]);
|
|
479
|
+
var DICTIONARY_LOOKUP = new Map(
|
|
480
|
+
BOOM_DICTIONARY_V1.map((str, idx) => [str, idx])
|
|
481
|
+
);
|
|
482
|
+
var DEFAULT_OPTIONS = {
|
|
483
|
+
maxDepth: 64,
|
|
484
|
+
maxStringLength: 16 * 1024 * 1024,
|
|
485
|
+
maxArrayLength: 1e6,
|
|
486
|
+
enableInterning: true,
|
|
487
|
+
skipHeader: false,
|
|
488
|
+
forCompression: false,
|
|
489
|
+
useBuiltInDictionary: true,
|
|
490
|
+
sharedDictionary: void 0,
|
|
491
|
+
strictBinaryMode: false
|
|
492
|
+
};
|
|
493
|
+
function mergeOptions(defaults, options) {
|
|
494
|
+
return { ...defaults, ...options };
|
|
495
|
+
}
|
|
496
|
+
function zigzagDecode(value) {
|
|
497
|
+
return value >>> 1 ^ -(value & 1);
|
|
498
|
+
}
|
|
499
|
+
var ByteWriter = class {
|
|
500
|
+
buffer;
|
|
501
|
+
view;
|
|
502
|
+
pos = 0;
|
|
503
|
+
capacity;
|
|
504
|
+
constructor(initialCapacity = 8192) {
|
|
505
|
+
this.capacity = initialCapacity;
|
|
506
|
+
this.buffer = new Uint8Array(initialCapacity);
|
|
507
|
+
this.view = new DataView(this.buffer.buffer);
|
|
508
|
+
}
|
|
509
|
+
// Inline grow - only called when needed
|
|
510
|
+
grow(needed) {
|
|
511
|
+
let newCapacity = this.capacity << 1;
|
|
512
|
+
const required = this.pos + needed;
|
|
513
|
+
while (newCapacity < required) newCapacity <<= 1;
|
|
514
|
+
const newBuffer = new Uint8Array(newCapacity);
|
|
515
|
+
newBuffer.set(this.buffer.subarray(0, this.pos));
|
|
516
|
+
this.buffer = newBuffer;
|
|
517
|
+
this.view = new DataView(this.buffer.buffer);
|
|
518
|
+
this.capacity = newCapacity;
|
|
519
|
+
}
|
|
520
|
+
write(data) {
|
|
521
|
+
const len = data.length;
|
|
522
|
+
if (this.pos + len > this.capacity) this.grow(len);
|
|
523
|
+
this.buffer.set(data, this.pos);
|
|
524
|
+
this.pos += len;
|
|
525
|
+
}
|
|
526
|
+
writeByte(value) {
|
|
527
|
+
if (this.pos >= this.capacity) this.grow(1);
|
|
528
|
+
this.buffer[this.pos++] = value;
|
|
529
|
+
}
|
|
530
|
+
writeInt8(value) {
|
|
531
|
+
if (this.pos >= this.capacity) this.grow(1);
|
|
532
|
+
this.buffer[this.pos++] = value & 255;
|
|
533
|
+
}
|
|
534
|
+
writeInt16LE(value) {
|
|
535
|
+
if (this.pos + 2 > this.capacity) this.grow(2);
|
|
536
|
+
const buf = this.buffer;
|
|
537
|
+
const p = this.pos;
|
|
538
|
+
buf[p] = value & 255;
|
|
539
|
+
buf[p + 1] = value >> 8 & 255;
|
|
540
|
+
this.pos = p + 2;
|
|
541
|
+
}
|
|
542
|
+
writeInt32LE(value) {
|
|
543
|
+
if (this.pos + 4 > this.capacity) this.grow(4);
|
|
544
|
+
const buf = this.buffer;
|
|
545
|
+
const p = this.pos;
|
|
546
|
+
buf[p] = value & 255;
|
|
547
|
+
buf[p + 1] = value >> 8 & 255;
|
|
548
|
+
buf[p + 2] = value >> 16 & 255;
|
|
549
|
+
buf[p + 3] = value >> 24 & 255;
|
|
550
|
+
this.pos = p + 4;
|
|
551
|
+
}
|
|
552
|
+
writeBigInt64LE(value) {
|
|
553
|
+
if (this.pos + 8 > this.capacity) this.grow(8);
|
|
554
|
+
this.view.setBigInt64(this.pos, value, true);
|
|
555
|
+
this.pos += 8;
|
|
556
|
+
}
|
|
557
|
+
writeBigUInt64LE(value) {
|
|
558
|
+
if (this.pos + 8 > this.capacity) this.grow(8);
|
|
559
|
+
this.view.setBigUint64(this.pos, value, true);
|
|
560
|
+
this.pos += 8;
|
|
561
|
+
}
|
|
562
|
+
writeFloat32LE(value) {
|
|
563
|
+
if (this.pos + 4 > this.capacity) this.grow(4);
|
|
564
|
+
this.view.setFloat32(this.pos, value, true);
|
|
565
|
+
this.pos += 4;
|
|
566
|
+
}
|
|
567
|
+
writeFloat64LE(value) {
|
|
568
|
+
if (this.pos + 8 > this.capacity) this.grow(8);
|
|
569
|
+
this.view.setFloat64(this.pos, value, true);
|
|
570
|
+
this.pos += 8;
|
|
571
|
+
}
|
|
572
|
+
// Inline varint - critical hot path
|
|
573
|
+
writeVarint(value) {
|
|
574
|
+
if (this.pos + 5 > this.capacity) this.grow(5);
|
|
575
|
+
const buf = this.buffer;
|
|
576
|
+
let p = this.pos;
|
|
577
|
+
let v = value >>> 0;
|
|
578
|
+
while (v > 127) {
|
|
579
|
+
buf[p++] = v & 127 | 128;
|
|
580
|
+
v >>>= 7;
|
|
581
|
+
}
|
|
582
|
+
buf[p++] = v;
|
|
583
|
+
this.pos = p;
|
|
584
|
+
}
|
|
585
|
+
// Fast path for small varints (most common case)
|
|
586
|
+
writeVarintSmall(value) {
|
|
587
|
+
if (this.pos + 2 > this.capacity) this.grow(2);
|
|
588
|
+
const buf = this.buffer;
|
|
589
|
+
if (value < 128) {
|
|
590
|
+
buf[this.pos++] = value;
|
|
591
|
+
} else if (value < 16384) {
|
|
592
|
+
buf[this.pos++] = value & 127 | 128;
|
|
593
|
+
buf[this.pos++] = value >>> 7;
|
|
594
|
+
} else {
|
|
595
|
+
this.writeVarint(value);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
toUint8Array() {
|
|
599
|
+
return this.buffer.subarray(0, this.pos);
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
var ByteReader = class {
|
|
603
|
+
view;
|
|
604
|
+
offset = 0;
|
|
605
|
+
buf;
|
|
606
|
+
len;
|
|
607
|
+
constructor(buffer) {
|
|
608
|
+
this.buf = buffer;
|
|
609
|
+
this.len = buffer.length;
|
|
610
|
+
this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
611
|
+
}
|
|
612
|
+
get remaining() {
|
|
613
|
+
return this.len - this.offset;
|
|
614
|
+
}
|
|
615
|
+
readByte() {
|
|
616
|
+
return this.buf[this.offset++];
|
|
617
|
+
}
|
|
618
|
+
readBytes(count) {
|
|
619
|
+
const start = this.offset;
|
|
620
|
+
this.offset += count;
|
|
621
|
+
return this.buf.subarray(start, this.offset);
|
|
622
|
+
}
|
|
623
|
+
readInt8() {
|
|
624
|
+
const v = this.buf[this.offset++];
|
|
625
|
+
return v > 127 ? v - 256 : v;
|
|
626
|
+
}
|
|
627
|
+
readInt16LE() {
|
|
628
|
+
const buf = this.buf;
|
|
629
|
+
const p = this.offset;
|
|
630
|
+
this.offset = p + 2;
|
|
631
|
+
const v = buf[p] | buf[p + 1] << 8;
|
|
632
|
+
return v > 32767 ? v - 65536 : v;
|
|
633
|
+
}
|
|
634
|
+
readInt32LE() {
|
|
635
|
+
const buf = this.buf;
|
|
636
|
+
const p = this.offset;
|
|
637
|
+
this.offset = p + 4;
|
|
638
|
+
return buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24;
|
|
639
|
+
}
|
|
640
|
+
readBigInt64LE() {
|
|
641
|
+
const value = this.view.getBigInt64(this.offset, true);
|
|
642
|
+
this.offset += 8;
|
|
643
|
+
return value;
|
|
644
|
+
}
|
|
645
|
+
readUInt8() {
|
|
646
|
+
return this.buf[this.offset++];
|
|
647
|
+
}
|
|
648
|
+
readUInt16LE() {
|
|
649
|
+
const buf = this.buf;
|
|
650
|
+
const p = this.offset;
|
|
651
|
+
this.offset = p + 2;
|
|
652
|
+
return buf[p] | buf[p + 1] << 8;
|
|
653
|
+
}
|
|
654
|
+
readUInt32LE() {
|
|
655
|
+
const buf = this.buf;
|
|
656
|
+
const p = this.offset;
|
|
657
|
+
this.offset = p + 4;
|
|
658
|
+
return (buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24) >>> 0;
|
|
659
|
+
}
|
|
660
|
+
readBigUInt64LE() {
|
|
661
|
+
const value = this.view.getBigUint64(this.offset, true);
|
|
662
|
+
this.offset += 8;
|
|
663
|
+
return value;
|
|
664
|
+
}
|
|
665
|
+
readFloat32LE() {
|
|
666
|
+
const value = this.view.getFloat32(this.offset, true);
|
|
667
|
+
this.offset += 4;
|
|
668
|
+
return value;
|
|
669
|
+
}
|
|
670
|
+
readFloat64LE() {
|
|
671
|
+
const value = this.view.getFloat64(this.offset, true);
|
|
672
|
+
this.offset += 8;
|
|
673
|
+
return value;
|
|
674
|
+
}
|
|
675
|
+
// Inline varint for maximum speed
|
|
676
|
+
readVarint() {
|
|
677
|
+
const buf = this.buf;
|
|
678
|
+
let p = this.offset;
|
|
679
|
+
let b = buf[p++];
|
|
680
|
+
if (b < 128) {
|
|
681
|
+
this.offset = p;
|
|
682
|
+
return b;
|
|
683
|
+
}
|
|
684
|
+
let result = b & 127;
|
|
685
|
+
b = buf[p++];
|
|
686
|
+
if (b < 128) {
|
|
687
|
+
this.offset = p;
|
|
688
|
+
return result | b << 7;
|
|
689
|
+
}
|
|
690
|
+
result |= (b & 127) << 7;
|
|
691
|
+
b = buf[p++];
|
|
692
|
+
if (b < 128) {
|
|
693
|
+
this.offset = p;
|
|
694
|
+
return result | b << 14;
|
|
695
|
+
}
|
|
696
|
+
result |= (b & 127) << 14;
|
|
697
|
+
b = buf[p++];
|
|
698
|
+
if (b < 128) {
|
|
699
|
+
this.offset = p;
|
|
700
|
+
return result | b << 21;
|
|
701
|
+
}
|
|
702
|
+
result |= (b & 127) << 21;
|
|
703
|
+
b = buf[p++];
|
|
704
|
+
this.offset = p;
|
|
705
|
+
return (result | b << 28) >>> 0;
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
var textEncoder = new TextEncoder();
|
|
709
|
+
var SMALL_BUF_SIZE = 4096;
|
|
710
|
+
var LARGE_BUF_SIZE = 65536;
|
|
711
|
+
var sharedSmallBuf = new Uint8Array(SMALL_BUF_SIZE);
|
|
712
|
+
var sharedSmallView = new DataView(sharedSmallBuf.buffer);
|
|
713
|
+
var sharedLargeBuf = new Uint8Array(LARGE_BUF_SIZE);
|
|
714
|
+
var sharedLargeView = new DataView(sharedLargeBuf.buffer);
|
|
715
|
+
var sharedDecodeView = null;
|
|
716
|
+
var sharedDecodeBuf = null;
|
|
717
|
+
function getDecodeView(buf) {
|
|
718
|
+
if (sharedDecodeBuf !== buf) {
|
|
719
|
+
sharedDecodeBuf = buf;
|
|
720
|
+
sharedDecodeView = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
721
|
+
}
|
|
722
|
+
return sharedDecodeView;
|
|
723
|
+
}
|
|
724
|
+
function isAscii(s) {
|
|
725
|
+
for (let i = 0; i < s.length; i++) {
|
|
726
|
+
if (s.charCodeAt(i) > 127) return false;
|
|
727
|
+
}
|
|
728
|
+
return true;
|
|
729
|
+
}
|
|
730
|
+
function ultraFastEncodeTiny(obj) {
|
|
731
|
+
const buf = sharedSmallBuf;
|
|
732
|
+
buf[0] = 66;
|
|
733
|
+
buf[1] = 79;
|
|
734
|
+
buf[2] = 79;
|
|
735
|
+
buf[3] = 77;
|
|
736
|
+
buf[4] = 1;
|
|
737
|
+
buf[5] = 0;
|
|
738
|
+
buf[6] = 80;
|
|
739
|
+
let pos = 8;
|
|
740
|
+
let count = 0;
|
|
741
|
+
for (const k in obj) {
|
|
742
|
+
count++;
|
|
743
|
+
if (count > 6) return null;
|
|
744
|
+
const klen = k.length;
|
|
745
|
+
if (klen > 20) return null;
|
|
746
|
+
buf[pos++] = 48;
|
|
747
|
+
buf[pos++] = klen;
|
|
748
|
+
for (let i = 0; i < klen; i++) {
|
|
749
|
+
const c = k.charCodeAt(i);
|
|
750
|
+
if (c > 127) return null;
|
|
751
|
+
buf[pos++] = c;
|
|
752
|
+
}
|
|
753
|
+
const v = obj[k];
|
|
754
|
+
if (v === null) {
|
|
755
|
+
buf[pos++] = 0;
|
|
756
|
+
} else if (v === true) {
|
|
757
|
+
buf[pos++] = 2;
|
|
758
|
+
} else if (v === false) {
|
|
759
|
+
buf[pos++] = 1;
|
|
760
|
+
} else {
|
|
761
|
+
const t = typeof v;
|
|
762
|
+
if (t === "number") {
|
|
763
|
+
const n = v;
|
|
764
|
+
if ((n | 0) === n) {
|
|
765
|
+
if (n >= -128 && n <= 127) {
|
|
766
|
+
buf[pos++] = 16;
|
|
767
|
+
buf[pos++] = n & 255;
|
|
768
|
+
} else if (n >= -32768 && n <= 32767) {
|
|
769
|
+
buf[pos++] = 17;
|
|
770
|
+
buf[pos++] = n & 255;
|
|
771
|
+
buf[pos++] = n >> 8 & 255;
|
|
772
|
+
} else {
|
|
773
|
+
buf[pos++] = 18;
|
|
774
|
+
buf[pos++] = n & 255;
|
|
775
|
+
buf[pos++] = n >> 8 & 255;
|
|
776
|
+
buf[pos++] = n >> 16 & 255;
|
|
777
|
+
buf[pos++] = n >> 24 & 255;
|
|
778
|
+
}
|
|
779
|
+
} else {
|
|
780
|
+
buf[pos++] = 33;
|
|
781
|
+
sharedSmallView.setFloat64(pos, n, true);
|
|
782
|
+
pos += 8;
|
|
783
|
+
}
|
|
784
|
+
} else if (t === "string") {
|
|
785
|
+
const s = v;
|
|
786
|
+
const slen = s.length;
|
|
787
|
+
if (slen > 100) return null;
|
|
788
|
+
buf[pos++] = 48;
|
|
789
|
+
buf[pos++] = slen;
|
|
790
|
+
for (let i = 0; i < slen; i++) {
|
|
791
|
+
const c = s.charCodeAt(i);
|
|
792
|
+
if (c > 127) return null;
|
|
793
|
+
buf[pos++] = c;
|
|
794
|
+
}
|
|
795
|
+
} else {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
buf[7] = count;
|
|
801
|
+
return buf.slice(0, pos);
|
|
802
|
+
}
|
|
803
|
+
function writeAsciiInline(buf, pos, s) {
|
|
804
|
+
const len = s.length;
|
|
805
|
+
switch (len) {
|
|
806
|
+
case 1:
|
|
807
|
+
buf[pos] = s.charCodeAt(0);
|
|
808
|
+
return;
|
|
809
|
+
case 2:
|
|
810
|
+
buf[pos] = s.charCodeAt(0);
|
|
811
|
+
buf[pos + 1] = s.charCodeAt(1);
|
|
812
|
+
return;
|
|
813
|
+
case 3:
|
|
814
|
+
buf[pos] = s.charCodeAt(0);
|
|
815
|
+
buf[pos + 1] = s.charCodeAt(1);
|
|
816
|
+
buf[pos + 2] = s.charCodeAt(2);
|
|
817
|
+
return;
|
|
818
|
+
case 4:
|
|
819
|
+
buf[pos] = s.charCodeAt(0);
|
|
820
|
+
buf[pos + 1] = s.charCodeAt(1);
|
|
821
|
+
buf[pos + 2] = s.charCodeAt(2);
|
|
822
|
+
buf[pos + 3] = s.charCodeAt(3);
|
|
823
|
+
return;
|
|
824
|
+
default:
|
|
825
|
+
for (let i = 0; i < len; i++) buf[pos + i] = s.charCodeAt(i);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
function tryFastEncodeSmallInline(obj, keyCount) {
|
|
829
|
+
for (const k in obj) {
|
|
830
|
+
if (k.length > 127 || !isAscii(k)) return null;
|
|
831
|
+
const v = obj[k];
|
|
832
|
+
if (v === null || v === true || v === false) continue;
|
|
833
|
+
const t = typeof v;
|
|
834
|
+
if (t === "number" || t === "boolean") continue;
|
|
835
|
+
if (t === "string") {
|
|
836
|
+
const s = v;
|
|
837
|
+
if (s.length > 127 || !isAscii(s)) return null;
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
if (t === "object") {
|
|
841
|
+
if (Array.isArray(v) || v instanceof Uint8Array) return null;
|
|
842
|
+
const nested = v;
|
|
843
|
+
let ncount = 0;
|
|
844
|
+
for (const nk in nested) {
|
|
845
|
+
ncount++;
|
|
846
|
+
if (ncount > 10) return null;
|
|
847
|
+
if (nk.length > 127 || !isAscii(nk)) return null;
|
|
848
|
+
const nv = nested[nk];
|
|
849
|
+
if (nv === null || nv === true || nv === false) continue;
|
|
850
|
+
const nt = typeof nv;
|
|
851
|
+
if (nt === "number" || nt === "boolean") continue;
|
|
852
|
+
if (nt === "string") {
|
|
853
|
+
const ns = nv;
|
|
854
|
+
if (ns.length > 127 || !isAscii(ns)) return null;
|
|
855
|
+
continue;
|
|
856
|
+
}
|
|
857
|
+
return null;
|
|
858
|
+
}
|
|
859
|
+
} else {
|
|
860
|
+
return null;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const buf = sharedSmallBuf;
|
|
864
|
+
const view = sharedSmallView;
|
|
865
|
+
buf[0] = 66;
|
|
866
|
+
buf[1] = 79;
|
|
867
|
+
buf[2] = 79;
|
|
868
|
+
buf[3] = 77;
|
|
869
|
+
buf[4] = 1;
|
|
870
|
+
buf[5] = 0;
|
|
871
|
+
buf[6] = 80;
|
|
872
|
+
buf[7] = keyCount;
|
|
873
|
+
let pos = 8;
|
|
874
|
+
for (const k in obj) {
|
|
875
|
+
const kl = k.length;
|
|
876
|
+
buf[pos++] = 48;
|
|
877
|
+
buf[pos++] = kl;
|
|
878
|
+
writeAsciiInline(buf, pos, k);
|
|
879
|
+
pos += kl;
|
|
880
|
+
const v = obj[k];
|
|
881
|
+
if (v === null) {
|
|
882
|
+
buf[pos++] = 0;
|
|
883
|
+
} else if (v === true) {
|
|
884
|
+
buf[pos++] = 2;
|
|
885
|
+
} else if (v === false) {
|
|
886
|
+
buf[pos++] = 1;
|
|
887
|
+
} else {
|
|
888
|
+
const t = typeof v;
|
|
889
|
+
if (t === "string") {
|
|
890
|
+
const s = v;
|
|
891
|
+
const sl = s.length;
|
|
892
|
+
buf[pos++] = 48;
|
|
893
|
+
buf[pos++] = sl;
|
|
894
|
+
writeAsciiInline(buf, pos, s);
|
|
895
|
+
pos += sl;
|
|
896
|
+
} else if (t === "number") {
|
|
897
|
+
const n = v;
|
|
898
|
+
if ((n | 0) === n && n >= -128 && n <= 127) {
|
|
899
|
+
buf[pos++] = 16;
|
|
900
|
+
buf[pos++] = n & 255;
|
|
901
|
+
} else if ((n | 0) === n) {
|
|
902
|
+
buf[pos++] = 18;
|
|
903
|
+
buf[pos++] = n & 255;
|
|
904
|
+
buf[pos++] = n >> 8 & 255;
|
|
905
|
+
buf[pos++] = n >> 16 & 255;
|
|
906
|
+
buf[pos++] = n >> 24 & 255;
|
|
907
|
+
} else {
|
|
908
|
+
buf[pos++] = 33;
|
|
909
|
+
view.setFloat64(pos, n, true);
|
|
910
|
+
pos += 8;
|
|
911
|
+
}
|
|
912
|
+
} else {
|
|
913
|
+
const nested = v;
|
|
914
|
+
let nkCount = 0;
|
|
915
|
+
for (const _ in nested) nkCount++;
|
|
916
|
+
buf[pos++] = 80;
|
|
917
|
+
buf[pos++] = nkCount;
|
|
918
|
+
for (const nk in nested) {
|
|
919
|
+
const nkl = nk.length;
|
|
920
|
+
buf[pos++] = 48;
|
|
921
|
+
buf[pos++] = nkl;
|
|
922
|
+
writeAsciiInline(buf, pos, nk);
|
|
923
|
+
pos += nkl;
|
|
924
|
+
const nv = nested[nk];
|
|
925
|
+
if (nv === null) {
|
|
926
|
+
buf[pos++] = 0;
|
|
927
|
+
} else if (nv === true) {
|
|
928
|
+
buf[pos++] = 2;
|
|
929
|
+
} else if (nv === false) {
|
|
930
|
+
buf[pos++] = 1;
|
|
931
|
+
} else {
|
|
932
|
+
const nt = typeof nv;
|
|
933
|
+
if (nt === "string") {
|
|
934
|
+
const ns = nv;
|
|
935
|
+
const nsl = ns.length;
|
|
936
|
+
buf[pos++] = 48;
|
|
937
|
+
buf[pos++] = nsl;
|
|
938
|
+
writeAsciiInline(buf, pos, ns);
|
|
939
|
+
pos += nsl;
|
|
940
|
+
} else {
|
|
941
|
+
const nn = nv;
|
|
942
|
+
if ((nn | 0) === nn && nn >= -128 && nn <= 127) {
|
|
943
|
+
buf[pos++] = 16;
|
|
944
|
+
buf[pos++] = nn & 255;
|
|
945
|
+
} else if ((nn | 0) === nn) {
|
|
946
|
+
buf[pos++] = 18;
|
|
947
|
+
buf[pos++] = nn & 255;
|
|
948
|
+
buf[pos++] = nn >> 8 & 255;
|
|
949
|
+
buf[pos++] = nn >> 16 & 255;
|
|
950
|
+
buf[pos++] = nn >> 24 & 255;
|
|
951
|
+
} else {
|
|
952
|
+
buf[pos++] = 33;
|
|
953
|
+
view.setFloat64(pos, nn, true);
|
|
954
|
+
pos += 8;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
return buf.slice(0, pos);
|
|
963
|
+
}
|
|
964
|
+
function tryFastEncodeArrayOfObjects(arr) {
|
|
965
|
+
const len = arr.length;
|
|
966
|
+
if (len === 0) return null;
|
|
967
|
+
const first = arr[0];
|
|
968
|
+
if (typeof first !== "object" || first === null || Array.isArray(first)) return null;
|
|
969
|
+
if (len >= 2) {
|
|
970
|
+
const firstKeys = Object.keys(first).sort().join(",");
|
|
971
|
+
const second = arr[1];
|
|
972
|
+
if (typeof second === "object" && second !== null && !Array.isArray(second)) {
|
|
973
|
+
const secondKeys = Object.keys(second).sort().join(",");
|
|
974
|
+
if (firstKeys === secondKeys) {
|
|
975
|
+
return null;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
let buf = len > 50 ? sharedLargeBuf : sharedSmallBuf;
|
|
980
|
+
let view = len > 50 ? sharedLargeView : sharedSmallView;
|
|
981
|
+
let capacity = buf.length;
|
|
982
|
+
const stringTable = /* @__PURE__ */ Object.create(null);
|
|
983
|
+
let stringCount = 0;
|
|
984
|
+
buf[0] = 66;
|
|
985
|
+
buf[1] = 79;
|
|
986
|
+
buf[2] = 79;
|
|
987
|
+
buf[3] = 77;
|
|
988
|
+
buf[4] = 1;
|
|
989
|
+
buf[5] = 0;
|
|
990
|
+
buf[6] = 64;
|
|
991
|
+
let pos = 7;
|
|
992
|
+
if (len < 128) {
|
|
993
|
+
buf[pos++] = len;
|
|
994
|
+
} else {
|
|
995
|
+
let v = len;
|
|
996
|
+
while (v > 127) {
|
|
997
|
+
buf[pos++] = v & 127 | 128;
|
|
998
|
+
v >>>= 7;
|
|
999
|
+
}
|
|
1000
|
+
buf[pos++] = v;
|
|
1001
|
+
}
|
|
1002
|
+
function grow(need) {
|
|
1003
|
+
const required = pos + need;
|
|
1004
|
+
while (capacity < required) capacity <<= 1;
|
|
1005
|
+
const newBuf = new Uint8Array(capacity);
|
|
1006
|
+
newBuf.set(buf.subarray(0, pos));
|
|
1007
|
+
buf = newBuf;
|
|
1008
|
+
view = new DataView(buf.buffer);
|
|
1009
|
+
}
|
|
1010
|
+
for (let i = 0; i < len; i++) {
|
|
1011
|
+
const item = arr[i];
|
|
1012
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) return null;
|
|
1013
|
+
const obj = item;
|
|
1014
|
+
let keyCount = 0;
|
|
1015
|
+
for (const _ in obj) keyCount++;
|
|
1016
|
+
if (pos + 2 > capacity) grow(256);
|
|
1017
|
+
buf[pos++] = 80;
|
|
1018
|
+
buf[pos++] = keyCount;
|
|
1019
|
+
for (const k in obj) {
|
|
1020
|
+
const keyRef = stringTable[k];
|
|
1021
|
+
if (keyRef !== void 0) {
|
|
1022
|
+
if (pos + 2 > capacity) grow(64);
|
|
1023
|
+
buf[pos++] = 96;
|
|
1024
|
+
buf[pos++] = keyRef;
|
|
1025
|
+
} else {
|
|
1026
|
+
const kl = k.length;
|
|
1027
|
+
if (kl > 127) return null;
|
|
1028
|
+
stringTable[k] = stringCount++;
|
|
1029
|
+
if (pos + 2 + kl > capacity) grow(64 + kl);
|
|
1030
|
+
buf[pos++] = 48;
|
|
1031
|
+
buf[pos++] = kl;
|
|
1032
|
+
for (let j = 0; j < kl; j++) {
|
|
1033
|
+
const c = k.charCodeAt(j);
|
|
1034
|
+
if (c > 127) return null;
|
|
1035
|
+
buf[pos++] = c;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
const v = obj[k];
|
|
1039
|
+
if (v === null) {
|
|
1040
|
+
buf[pos++] = 0;
|
|
1041
|
+
} else if (v === true) {
|
|
1042
|
+
buf[pos++] = 2;
|
|
1043
|
+
} else if (v === false) {
|
|
1044
|
+
buf[pos++] = 1;
|
|
1045
|
+
} else {
|
|
1046
|
+
const t = typeof v;
|
|
1047
|
+
if (t === "string") {
|
|
1048
|
+
const s = v;
|
|
1049
|
+
const sl = s.length;
|
|
1050
|
+
const valRef = stringTable[s];
|
|
1051
|
+
if (valRef !== void 0) {
|
|
1052
|
+
if (pos + 2 > capacity) grow(64);
|
|
1053
|
+
buf[pos++] = 96;
|
|
1054
|
+
buf[pos++] = valRef;
|
|
1055
|
+
continue;
|
|
1056
|
+
}
|
|
1057
|
+
stringTable[s] = stringCount++;
|
|
1058
|
+
if (pos + 2 + sl > capacity) grow(64 + sl);
|
|
1059
|
+
buf[pos++] = 48;
|
|
1060
|
+
if (sl < 128) {
|
|
1061
|
+
buf[pos++] = sl;
|
|
1062
|
+
} else {
|
|
1063
|
+
let lv = sl;
|
|
1064
|
+
while (lv > 127) {
|
|
1065
|
+
buf[pos++] = lv & 127 | 128;
|
|
1066
|
+
lv >>>= 7;
|
|
1067
|
+
}
|
|
1068
|
+
buf[pos++] = lv;
|
|
1069
|
+
}
|
|
1070
|
+
for (let j = 0; j < sl; j++) {
|
|
1071
|
+
const c = s.charCodeAt(j);
|
|
1072
|
+
if (c > 127) return null;
|
|
1073
|
+
buf[pos++] = c;
|
|
1074
|
+
}
|
|
1075
|
+
} else if (t === "number") {
|
|
1076
|
+
const n = v;
|
|
1077
|
+
if ((n | 0) === n) {
|
|
1078
|
+
if (n >= -128 && n <= 127) {
|
|
1079
|
+
if (pos + 2 > capacity) grow(16);
|
|
1080
|
+
buf[pos++] = 16;
|
|
1081
|
+
buf[pos++] = n & 255;
|
|
1082
|
+
} else if (n >= -32768 && n <= 32767) {
|
|
1083
|
+
if (pos + 3 > capacity) grow(16);
|
|
1084
|
+
buf[pos++] = 17;
|
|
1085
|
+
buf[pos++] = n & 255;
|
|
1086
|
+
buf[pos++] = n >> 8 & 255;
|
|
1087
|
+
} else {
|
|
1088
|
+
if (pos + 5 > capacity) grow(16);
|
|
1089
|
+
buf[pos++] = 18;
|
|
1090
|
+
buf[pos++] = n & 255;
|
|
1091
|
+
buf[pos++] = n >> 8 & 255;
|
|
1092
|
+
buf[pos++] = n >> 16 & 255;
|
|
1093
|
+
buf[pos++] = n >> 24 & 255;
|
|
1094
|
+
}
|
|
1095
|
+
} else {
|
|
1096
|
+
if (pos + 9 > capacity) grow(16);
|
|
1097
|
+
buf[pos++] = 33;
|
|
1098
|
+
view.setFloat64(pos, n, true);
|
|
1099
|
+
pos += 8;
|
|
1100
|
+
}
|
|
1101
|
+
} else if (t === "object") {
|
|
1102
|
+
return null;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return buf.subarray(0, pos);
|
|
1108
|
+
}
|
|
1109
|
+
function tryFastEncodeArray(arr) {
|
|
1110
|
+
const len = arr.length;
|
|
1111
|
+
if (len > 127) return null;
|
|
1112
|
+
const buf = sharedSmallBuf;
|
|
1113
|
+
const view = sharedSmallView;
|
|
1114
|
+
buf[0] = 66;
|
|
1115
|
+
buf[1] = 79;
|
|
1116
|
+
buf[2] = 79;
|
|
1117
|
+
buf[3] = 77;
|
|
1118
|
+
buf[4] = 1;
|
|
1119
|
+
buf[5] = 0;
|
|
1120
|
+
if (len >= 4) {
|
|
1121
|
+
const first = arr[0];
|
|
1122
|
+
const firstType = typeof first;
|
|
1123
|
+
if (firstType === "boolean") {
|
|
1124
|
+
let allBool = true;
|
|
1125
|
+
for (let i = 1; i < len && allBool; i++) {
|
|
1126
|
+
if (typeof arr[i] !== "boolean") allBool = false;
|
|
1127
|
+
}
|
|
1128
|
+
if (allBool) {
|
|
1129
|
+
const byteCount = Math.ceil(len / 8);
|
|
1130
|
+
buf[6] = 133 /* PACKED_BOOL */;
|
|
1131
|
+
buf[7] = len;
|
|
1132
|
+
let pos2 = 8;
|
|
1133
|
+
for (let byteIdx = 0; byteIdx < byteCount; byteIdx++) {
|
|
1134
|
+
let byte = 0;
|
|
1135
|
+
const baseIdx = byteIdx * 8;
|
|
1136
|
+
for (let bit = 0; bit < 8 && baseIdx + bit < len; bit++) {
|
|
1137
|
+
if (arr[baseIdx + bit]) byte |= 1 << bit;
|
|
1138
|
+
}
|
|
1139
|
+
buf[pos2++] = byte;
|
|
1140
|
+
}
|
|
1141
|
+
return buf.slice(0, pos2);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
if (firstType === "number") {
|
|
1145
|
+
let minVal = first;
|
|
1146
|
+
let maxVal = first;
|
|
1147
|
+
let allInt = Number.isInteger(first);
|
|
1148
|
+
let allNum = true;
|
|
1149
|
+
for (let i = 1; i < len && allNum; i++) {
|
|
1150
|
+
const n = arr[i];
|
|
1151
|
+
if (typeof n !== "number") {
|
|
1152
|
+
allNum = false;
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1155
|
+
const num = n;
|
|
1156
|
+
if (num < minVal) minVal = num;
|
|
1157
|
+
if (num > maxVal) maxVal = num;
|
|
1158
|
+
if (allInt && !Number.isInteger(num)) allInt = false;
|
|
1159
|
+
}
|
|
1160
|
+
if (allNum) {
|
|
1161
|
+
if (allInt && minVal >= -128 && maxVal <= 127) {
|
|
1162
|
+
buf[6] = 128 /* PACKED_INT8 */;
|
|
1163
|
+
buf[7] = len;
|
|
1164
|
+
let pos2 = 8;
|
|
1165
|
+
for (let i = 0; i < len; i++) buf[pos2++] = arr[i] & 255;
|
|
1166
|
+
return buf.slice(0, pos2);
|
|
1167
|
+
} else if (allInt && minVal >= -32768 && maxVal <= 32767) {
|
|
1168
|
+
buf[6] = 129 /* PACKED_INT16 */;
|
|
1169
|
+
buf[7] = len;
|
|
1170
|
+
let pos2 = 8;
|
|
1171
|
+
for (let i = 0; i < len; i++) {
|
|
1172
|
+
const n = arr[i];
|
|
1173
|
+
buf[pos2++] = n & 255;
|
|
1174
|
+
buf[pos2++] = n >> 8 & 255;
|
|
1175
|
+
}
|
|
1176
|
+
return buf.slice(0, pos2);
|
|
1177
|
+
} else if (allInt && minVal >= -2147483648 && maxVal <= 2147483647) {
|
|
1178
|
+
buf[6] = 130 /* PACKED_INT32 */;
|
|
1179
|
+
buf[7] = len;
|
|
1180
|
+
let pos2 = 8;
|
|
1181
|
+
for (let i = 0; i < len; i++) {
|
|
1182
|
+
const n = arr[i];
|
|
1183
|
+
buf[pos2++] = n & 255;
|
|
1184
|
+
buf[pos2++] = n >> 8 & 255;
|
|
1185
|
+
buf[pos2++] = n >> 16 & 255;
|
|
1186
|
+
buf[pos2++] = n >> 24 & 255;
|
|
1187
|
+
}
|
|
1188
|
+
return buf.slice(0, pos2);
|
|
1189
|
+
} else {
|
|
1190
|
+
buf[6] = 132 /* PACKED_FLOAT64 */;
|
|
1191
|
+
buf[7] = len;
|
|
1192
|
+
let pos2 = 8;
|
|
1193
|
+
for (let i = 0; i < len; i++) {
|
|
1194
|
+
view.setFloat64(pos2, arr[i], true);
|
|
1195
|
+
pos2 += 8;
|
|
1196
|
+
}
|
|
1197
|
+
return buf.slice(0, pos2);
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
buf[6] = 64;
|
|
1203
|
+
buf[7] = len;
|
|
1204
|
+
let pos = 8;
|
|
1205
|
+
for (let i = 0; i < len; i++) {
|
|
1206
|
+
const v = arr[i];
|
|
1207
|
+
const t = typeof v;
|
|
1208
|
+
if (t === "number") {
|
|
1209
|
+
const n = v;
|
|
1210
|
+
if ((n | 0) === n && n >= -128 && n <= 127) {
|
|
1211
|
+
buf[pos++] = 16;
|
|
1212
|
+
buf[pos++] = n & 255;
|
|
1213
|
+
} else if ((n | 0) === n) {
|
|
1214
|
+
buf[pos++] = 18;
|
|
1215
|
+
buf[pos++] = n & 255;
|
|
1216
|
+
buf[pos++] = n >> 8 & 255;
|
|
1217
|
+
buf[pos++] = n >> 16 & 255;
|
|
1218
|
+
buf[pos++] = n >> 24 & 255;
|
|
1219
|
+
} else {
|
|
1220
|
+
buf[pos++] = 33;
|
|
1221
|
+
view.setFloat64(pos, n, true);
|
|
1222
|
+
pos += 8;
|
|
1223
|
+
}
|
|
1224
|
+
} else if (t === "string") {
|
|
1225
|
+
const s = v;
|
|
1226
|
+
const sl = s.length;
|
|
1227
|
+
if (sl > 127 || !isAscii(s)) return null;
|
|
1228
|
+
buf[pos++] = 48;
|
|
1229
|
+
buf[pos++] = sl;
|
|
1230
|
+
writeAsciiInline(buf, pos, s);
|
|
1231
|
+
pos += sl;
|
|
1232
|
+
} else if (t === "boolean") {
|
|
1233
|
+
buf[pos++] = v ? 2 : 1;
|
|
1234
|
+
} else if (v === null) {
|
|
1235
|
+
buf[pos++] = 0;
|
|
1236
|
+
} else {
|
|
1237
|
+
return null;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
return buf.slice(0, pos);
|
|
1241
|
+
}
|
|
1242
|
+
function fastEncode(value) {
|
|
1243
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof Uint8Array)) {
|
|
1244
|
+
const obj = value;
|
|
1245
|
+
const ultraResult = ultraFastEncodeTiny(obj);
|
|
1246
|
+
if (ultraResult) return ultraResult;
|
|
1247
|
+
let keyCount = 0;
|
|
1248
|
+
for (const _ in obj) keyCount++;
|
|
1249
|
+
if (keyCount <= 6) {
|
|
1250
|
+
const result = tryFastEncodeSmallInline(obj, keyCount);
|
|
1251
|
+
if (result) return result;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
1255
|
+
if (typeof value[0] === "object" && value[0] !== null && !Array.isArray(value[0])) {
|
|
1256
|
+
const result = tryFastEncodeArrayOfObjects(value);
|
|
1257
|
+
if (result) return result;
|
|
1258
|
+
}
|
|
1259
|
+
if (value.length <= 127) {
|
|
1260
|
+
const result = tryFastEncodeArray(value);
|
|
1261
|
+
if (result) return result;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
let buf = sharedLargeBuf;
|
|
1265
|
+
let view = sharedLargeView;
|
|
1266
|
+
let capacity = buf.length;
|
|
1267
|
+
let pos = 0;
|
|
1268
|
+
let depth = 0;
|
|
1269
|
+
const maxDepth = 64;
|
|
1270
|
+
const stringTable = /* @__PURE__ */ Object.create(null);
|
|
1271
|
+
let stringCount = 0;
|
|
1272
|
+
function grow(need) {
|
|
1273
|
+
const required = pos + need;
|
|
1274
|
+
while (capacity < required) capacity <<= 1;
|
|
1275
|
+
const newBuf = new Uint8Array(capacity);
|
|
1276
|
+
newBuf.set(buf.subarray(0, pos));
|
|
1277
|
+
buf = newBuf;
|
|
1278
|
+
view = new DataView(buf.buffer);
|
|
1279
|
+
}
|
|
1280
|
+
function writeValue(v) {
|
|
1281
|
+
if (v === null) {
|
|
1282
|
+
if (pos >= capacity) grow(1);
|
|
1283
|
+
buf[pos++] = 0 /* NULL */;
|
|
1284
|
+
return;
|
|
1285
|
+
}
|
|
1286
|
+
switch (typeof v) {
|
|
1287
|
+
case "string": {
|
|
1288
|
+
const dictIdx = DICTIONARY_LOOKUP.get(v);
|
|
1289
|
+
if (dictIdx !== void 0) {
|
|
1290
|
+
if (pos + 4 > capacity) grow(4);
|
|
1291
|
+
buf[pos++] = 97 /* DICT_REF */;
|
|
1292
|
+
if (dictIdx < 128) buf[pos++] = dictIdx;
|
|
1293
|
+
else {
|
|
1294
|
+
let val = dictIdx >>> 0;
|
|
1295
|
+
while (val > 127) {
|
|
1296
|
+
buf[pos++] = val & 127 | 128;
|
|
1297
|
+
val >>>= 7;
|
|
1298
|
+
}
|
|
1299
|
+
buf[pos++] = val;
|
|
1300
|
+
}
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
const ref = stringTable[v];
|
|
1304
|
+
if (ref !== void 0) {
|
|
1305
|
+
if (pos + 6 > capacity) grow(6);
|
|
1306
|
+
buf[pos++] = 96 /* REF */;
|
|
1307
|
+
if (ref < 128) buf[pos++] = ref;
|
|
1308
|
+
else {
|
|
1309
|
+
let val = ref >>> 0;
|
|
1310
|
+
while (val > 127) {
|
|
1311
|
+
buf[pos++] = val & 127 | 128;
|
|
1312
|
+
val >>>= 7;
|
|
1313
|
+
}
|
|
1314
|
+
buf[pos++] = val;
|
|
1315
|
+
}
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
stringTable[v] = stringCount++;
|
|
1319
|
+
const len = v.length;
|
|
1320
|
+
if (len <= 8 && isAscii(v)) {
|
|
1321
|
+
if (pos + 10 > capacity) grow(10);
|
|
1322
|
+
buf[pos++] = 48;
|
|
1323
|
+
buf[pos++] = len;
|
|
1324
|
+
switch (len) {
|
|
1325
|
+
case 1:
|
|
1326
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1327
|
+
break;
|
|
1328
|
+
case 2:
|
|
1329
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1330
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1331
|
+
break;
|
|
1332
|
+
case 3:
|
|
1333
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1334
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1335
|
+
buf[pos++] = v.charCodeAt(2);
|
|
1336
|
+
break;
|
|
1337
|
+
case 4:
|
|
1338
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1339
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1340
|
+
buf[pos++] = v.charCodeAt(2);
|
|
1341
|
+
buf[pos++] = v.charCodeAt(3);
|
|
1342
|
+
break;
|
|
1343
|
+
case 5:
|
|
1344
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1345
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1346
|
+
buf[pos++] = v.charCodeAt(2);
|
|
1347
|
+
buf[pos++] = v.charCodeAt(3);
|
|
1348
|
+
buf[pos++] = v.charCodeAt(4);
|
|
1349
|
+
break;
|
|
1350
|
+
case 6:
|
|
1351
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1352
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1353
|
+
buf[pos++] = v.charCodeAt(2);
|
|
1354
|
+
buf[pos++] = v.charCodeAt(3);
|
|
1355
|
+
buf[pos++] = v.charCodeAt(4);
|
|
1356
|
+
buf[pos++] = v.charCodeAt(5);
|
|
1357
|
+
break;
|
|
1358
|
+
case 7:
|
|
1359
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1360
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1361
|
+
buf[pos++] = v.charCodeAt(2);
|
|
1362
|
+
buf[pos++] = v.charCodeAt(3);
|
|
1363
|
+
buf[pos++] = v.charCodeAt(4);
|
|
1364
|
+
buf[pos++] = v.charCodeAt(5);
|
|
1365
|
+
buf[pos++] = v.charCodeAt(6);
|
|
1366
|
+
break;
|
|
1367
|
+
case 8:
|
|
1368
|
+
buf[pos++] = v.charCodeAt(0);
|
|
1369
|
+
buf[pos++] = v.charCodeAt(1);
|
|
1370
|
+
buf[pos++] = v.charCodeAt(2);
|
|
1371
|
+
buf[pos++] = v.charCodeAt(3);
|
|
1372
|
+
buf[pos++] = v.charCodeAt(4);
|
|
1373
|
+
buf[pos++] = v.charCodeAt(5);
|
|
1374
|
+
buf[pos++] = v.charCodeAt(6);
|
|
1375
|
+
buf[pos++] = v.charCodeAt(7);
|
|
1376
|
+
break;
|
|
1377
|
+
}
|
|
1378
|
+
return;
|
|
1379
|
+
}
|
|
1380
|
+
const bytes = textEncoder.encode(v);
|
|
1381
|
+
const blen = bytes.length;
|
|
1382
|
+
if (pos + 6 + blen > capacity) grow(6 + blen);
|
|
1383
|
+
buf[pos++] = 48 /* STRING */;
|
|
1384
|
+
if (blen < 128) buf[pos++] = blen;
|
|
1385
|
+
else {
|
|
1386
|
+
let val = blen >>> 0;
|
|
1387
|
+
while (val > 127) {
|
|
1388
|
+
buf[pos++] = val & 127 | 128;
|
|
1389
|
+
val >>>= 7;
|
|
1390
|
+
}
|
|
1391
|
+
buf[pos++] = val;
|
|
1392
|
+
}
|
|
1393
|
+
buf.set(bytes, pos);
|
|
1394
|
+
pos += blen;
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1397
|
+
case "number": {
|
|
1398
|
+
const n = v;
|
|
1399
|
+
if ((n | 0) === n) {
|
|
1400
|
+
if (n >= -128 && n <= 127) {
|
|
1401
|
+
if (pos + 2 > capacity) grow(2);
|
|
1402
|
+
buf[pos++] = 16 /* INT8 */;
|
|
1403
|
+
buf[pos++] = n & 255;
|
|
1404
|
+
} else if (n >= -32768 && n <= 32767) {
|
|
1405
|
+
if (pos + 3 > capacity) grow(3);
|
|
1406
|
+
buf[pos++] = 17 /* INT16 */;
|
|
1407
|
+
buf[pos++] = n & 255;
|
|
1408
|
+
buf[pos++] = n >> 8 & 255;
|
|
1409
|
+
} else {
|
|
1410
|
+
if (pos + 5 > capacity) grow(5);
|
|
1411
|
+
buf[pos++] = 18 /* INT32 */;
|
|
1412
|
+
buf[pos++] = n & 255;
|
|
1413
|
+
buf[pos++] = n >> 8 & 255;
|
|
1414
|
+
buf[pos++] = n >> 16 & 255;
|
|
1415
|
+
buf[pos++] = n >> 24 & 255;
|
|
1416
|
+
}
|
|
1417
|
+
} else {
|
|
1418
|
+
if (pos + 9 > capacity) grow(9);
|
|
1419
|
+
buf[pos++] = 33 /* FLOAT64 */;
|
|
1420
|
+
view.setFloat64(pos, n, true);
|
|
1421
|
+
pos += 8;
|
|
1422
|
+
}
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
case "boolean":
|
|
1426
|
+
if (pos >= capacity) grow(1);
|
|
1427
|
+
buf[pos++] = v ? 2 /* TRUE */ : 1 /* FALSE */;
|
|
1428
|
+
return;
|
|
1429
|
+
case "object": {
|
|
1430
|
+
if (Array.isArray(v)) {
|
|
1431
|
+
depth++;
|
|
1432
|
+
if (depth > maxDepth) throw new BoomError(`Maximum nesting depth of ${maxDepth} exceeded`);
|
|
1433
|
+
const len = v.length;
|
|
1434
|
+
if (len >= 4) {
|
|
1435
|
+
const first = v[0];
|
|
1436
|
+
const firstType = typeof first;
|
|
1437
|
+
if (firstType === "boolean") {
|
|
1438
|
+
let allBool = true;
|
|
1439
|
+
for (let i = 1; i < len && allBool; i++) {
|
|
1440
|
+
if (typeof v[i] !== "boolean") allBool = false;
|
|
1441
|
+
}
|
|
1442
|
+
if (allBool) {
|
|
1443
|
+
const byteCount = Math.ceil(len / 8);
|
|
1444
|
+
if (pos + 3 + byteCount > capacity) grow(3 + byteCount);
|
|
1445
|
+
buf[pos++] = 133 /* PACKED_BOOL */;
|
|
1446
|
+
if (len < 128) buf[pos++] = len;
|
|
1447
|
+
else {
|
|
1448
|
+
let c = len >>> 0;
|
|
1449
|
+
while (c > 127) {
|
|
1450
|
+
buf[pos++] = c & 127 | 128;
|
|
1451
|
+
c >>>= 7;
|
|
1452
|
+
}
|
|
1453
|
+
buf[pos++] = c;
|
|
1454
|
+
}
|
|
1455
|
+
for (let byteIdx = 0; byteIdx < byteCount; byteIdx++) {
|
|
1456
|
+
let byte = 0;
|
|
1457
|
+
const baseIdx = byteIdx * 8;
|
|
1458
|
+
for (let bit = 0; bit < 8 && baseIdx + bit < len; bit++) {
|
|
1459
|
+
if (v[baseIdx + bit]) byte |= 1 << bit;
|
|
1460
|
+
}
|
|
1461
|
+
buf[pos++] = byte;
|
|
1462
|
+
}
|
|
1463
|
+
depth--;
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
if (firstType === "number") {
|
|
1468
|
+
let minVal = first;
|
|
1469
|
+
let maxVal = first;
|
|
1470
|
+
let allInt = Number.isInteger(first);
|
|
1471
|
+
let allNum = true;
|
|
1472
|
+
for (let i = 1; i < len && allNum; i++) {
|
|
1473
|
+
const n = v[i];
|
|
1474
|
+
if (typeof n !== "number") {
|
|
1475
|
+
allNum = false;
|
|
1476
|
+
break;
|
|
1477
|
+
}
|
|
1478
|
+
const num = n;
|
|
1479
|
+
if (num < minVal) minVal = num;
|
|
1480
|
+
if (num > maxVal) maxVal = num;
|
|
1481
|
+
if (allInt && !Number.isInteger(num)) allInt = false;
|
|
1482
|
+
}
|
|
1483
|
+
if (allNum) {
|
|
1484
|
+
if (allInt && minVal >= -128 && maxVal <= 127) {
|
|
1485
|
+
if (pos + 3 + len > capacity) grow(3 + len);
|
|
1486
|
+
buf[pos++] = 128 /* PACKED_INT8 */;
|
|
1487
|
+
if (len < 128) buf[pos++] = len;
|
|
1488
|
+
else {
|
|
1489
|
+
let c = len >>> 0;
|
|
1490
|
+
while (c > 127) {
|
|
1491
|
+
buf[pos++] = c & 127 | 128;
|
|
1492
|
+
c >>>= 7;
|
|
1493
|
+
}
|
|
1494
|
+
buf[pos++] = c;
|
|
1495
|
+
}
|
|
1496
|
+
for (let i = 0; i < len; i++) buf[pos++] = v[i] & 255;
|
|
1497
|
+
depth--;
|
|
1498
|
+
return;
|
|
1499
|
+
} else if (allInt && minVal >= -32768 && maxVal <= 32767) {
|
|
1500
|
+
if (pos + 3 + len * 2 > capacity) grow(3 + len * 2);
|
|
1501
|
+
buf[pos++] = 129 /* PACKED_INT16 */;
|
|
1502
|
+
if (len < 128) buf[pos++] = len;
|
|
1503
|
+
else {
|
|
1504
|
+
let c = len >>> 0;
|
|
1505
|
+
while (c > 127) {
|
|
1506
|
+
buf[pos++] = c & 127 | 128;
|
|
1507
|
+
c >>>= 7;
|
|
1508
|
+
}
|
|
1509
|
+
buf[pos++] = c;
|
|
1510
|
+
}
|
|
1511
|
+
for (let i = 0; i < len; i++) {
|
|
1512
|
+
const n = v[i];
|
|
1513
|
+
buf[pos++] = n & 255;
|
|
1514
|
+
buf[pos++] = n >> 8 & 255;
|
|
1515
|
+
}
|
|
1516
|
+
depth--;
|
|
1517
|
+
return;
|
|
1518
|
+
} else if (allInt && minVal >= -2147483648 && maxVal <= 2147483647) {
|
|
1519
|
+
if (pos + 3 + len * 4 > capacity) grow(3 + len * 4);
|
|
1520
|
+
buf[pos++] = 130 /* PACKED_INT32 */;
|
|
1521
|
+
if (len < 128) buf[pos++] = len;
|
|
1522
|
+
else {
|
|
1523
|
+
let c = len >>> 0;
|
|
1524
|
+
while (c > 127) {
|
|
1525
|
+
buf[pos++] = c & 127 | 128;
|
|
1526
|
+
c >>>= 7;
|
|
1527
|
+
}
|
|
1528
|
+
buf[pos++] = c;
|
|
1529
|
+
}
|
|
1530
|
+
for (let i = 0; i < len; i++) {
|
|
1531
|
+
const n = v[i];
|
|
1532
|
+
buf[pos++] = n & 255;
|
|
1533
|
+
buf[pos++] = n >> 8 & 255;
|
|
1534
|
+
buf[pos++] = n >> 16 & 255;
|
|
1535
|
+
buf[pos++] = n >> 24 & 255;
|
|
1536
|
+
}
|
|
1537
|
+
depth--;
|
|
1538
|
+
return;
|
|
1539
|
+
} else {
|
|
1540
|
+
if (pos + 3 + len * 8 > capacity) grow(3 + len * 8);
|
|
1541
|
+
buf[pos++] = 132 /* PACKED_FLOAT64 */;
|
|
1542
|
+
if (len < 128) buf[pos++] = len;
|
|
1543
|
+
else {
|
|
1544
|
+
let c = len >>> 0;
|
|
1545
|
+
while (c > 127) {
|
|
1546
|
+
buf[pos++] = c & 127 | 128;
|
|
1547
|
+
c >>>= 7;
|
|
1548
|
+
}
|
|
1549
|
+
buf[pos++] = c;
|
|
1550
|
+
}
|
|
1551
|
+
for (let i = 0; i < len; i++) {
|
|
1552
|
+
view.setFloat64(pos, v[i], true);
|
|
1553
|
+
pos += 8;
|
|
1554
|
+
}
|
|
1555
|
+
depth--;
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
if (pos + 6 > capacity) grow(6);
|
|
1562
|
+
buf[pos++] = 64 /* ARRAY */;
|
|
1563
|
+
if (len < 128) buf[pos++] = len;
|
|
1564
|
+
else {
|
|
1565
|
+
let val = len >>> 0;
|
|
1566
|
+
while (val > 127) {
|
|
1567
|
+
buf[pos++] = val & 127 | 128;
|
|
1568
|
+
val >>>= 7;
|
|
1569
|
+
}
|
|
1570
|
+
buf[pos++] = val;
|
|
1571
|
+
}
|
|
1572
|
+
if (len > 0 && typeof v[0] === "object" && v[0] !== null && !Array.isArray(v[0]) && !(v[0] instanceof Uint8Array)) {
|
|
1573
|
+
const first = v[0];
|
|
1574
|
+
const objKeys = Object.keys(first);
|
|
1575
|
+
const klen = objKeys.length;
|
|
1576
|
+
let allFlat = klen <= 8;
|
|
1577
|
+
if (allFlat) {
|
|
1578
|
+
for (let ki = 0; ki < klen; ki++) {
|
|
1579
|
+
const fv = first[objKeys[ki]];
|
|
1580
|
+
const ft = typeof fv;
|
|
1581
|
+
if (ft === "object" && fv !== null) {
|
|
1582
|
+
allFlat = false;
|
|
1583
|
+
break;
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
if (allFlat) {
|
|
1588
|
+
const estimatedSize = len * (2 + klen * 24) + 512;
|
|
1589
|
+
if (pos + estimatedSize > capacity) grow(estimatedSize);
|
|
1590
|
+
const keyRefs = new Array(klen);
|
|
1591
|
+
let keysRegistered = false;
|
|
1592
|
+
for (let i = 0; i < len; i++) {
|
|
1593
|
+
const elem = v[i];
|
|
1594
|
+
if (typeof elem !== "object" || elem === null || Array.isArray(elem)) {
|
|
1595
|
+
writeValue(elem);
|
|
1596
|
+
continue;
|
|
1597
|
+
}
|
|
1598
|
+
const obj = elem;
|
|
1599
|
+
if (pos + 6 > capacity) grow(6);
|
|
1600
|
+
buf[pos++] = 80 /* OBJECT */;
|
|
1601
|
+
buf[pos++] = klen;
|
|
1602
|
+
for (let ki = 0; ki < klen; ki++) {
|
|
1603
|
+
const key = objKeys[ki];
|
|
1604
|
+
if (keysRegistered) {
|
|
1605
|
+
if (pos + 2 > capacity) grow(2);
|
|
1606
|
+
buf[pos++] = 96;
|
|
1607
|
+
buf[pos++] = keyRefs[ki];
|
|
1608
|
+
} else {
|
|
1609
|
+
const existing = stringTable[key];
|
|
1610
|
+
if (existing !== void 0) {
|
|
1611
|
+
keyRefs[ki] = existing;
|
|
1612
|
+
if (pos + 2 > capacity) grow(2);
|
|
1613
|
+
buf[pos++] = 96;
|
|
1614
|
+
buf[pos++] = existing;
|
|
1615
|
+
} else {
|
|
1616
|
+
keyRefs[ki] = stringCount;
|
|
1617
|
+
stringTable[key] = stringCount++;
|
|
1618
|
+
const keyLen = key.length;
|
|
1619
|
+
if (pos + 2 + keyLen > capacity) grow(2 + keyLen);
|
|
1620
|
+
buf[pos++] = 48;
|
|
1621
|
+
buf[pos++] = keyLen;
|
|
1622
|
+
writeAsciiInline(buf, pos, key);
|
|
1623
|
+
pos += keyLen;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
const val = obj[key];
|
|
1627
|
+
const vt = typeof val;
|
|
1628
|
+
if (vt === "string") {
|
|
1629
|
+
const s = val;
|
|
1630
|
+
const sl = s.length;
|
|
1631
|
+
const sref = stringTable[s];
|
|
1632
|
+
if (sref !== void 0) {
|
|
1633
|
+
if (pos + 6 > capacity) grow(6);
|
|
1634
|
+
buf[pos++] = 96;
|
|
1635
|
+
if (sref < 128) buf[pos++] = sref;
|
|
1636
|
+
else {
|
|
1637
|
+
let rv = sref >>> 0;
|
|
1638
|
+
while (rv > 127) {
|
|
1639
|
+
buf[pos++] = rv & 127 | 128;
|
|
1640
|
+
rv >>>= 7;
|
|
1641
|
+
}
|
|
1642
|
+
buf[pos++] = rv;
|
|
1643
|
+
}
|
|
1644
|
+
} else {
|
|
1645
|
+
stringTable[s] = stringCount++;
|
|
1646
|
+
if (pos + 2 + sl > capacity) grow(2 + sl);
|
|
1647
|
+
buf[pos++] = 48;
|
|
1648
|
+
buf[pos++] = sl;
|
|
1649
|
+
writeAsciiInline(buf, pos, s);
|
|
1650
|
+
pos += sl;
|
|
1651
|
+
}
|
|
1652
|
+
} else if (vt === "number") {
|
|
1653
|
+
const n = val;
|
|
1654
|
+
if ((n | 0) === n && n >= -128 && n <= 127) {
|
|
1655
|
+
if (pos + 2 > capacity) grow(2);
|
|
1656
|
+
buf[pos++] = 16;
|
|
1657
|
+
buf[pos++] = n & 255;
|
|
1658
|
+
} else if ((n | 0) === n) {
|
|
1659
|
+
if (pos + 5 > capacity) grow(5);
|
|
1660
|
+
buf[pos++] = 18;
|
|
1661
|
+
buf[pos++] = n & 255;
|
|
1662
|
+
buf[pos++] = n >> 8 & 255;
|
|
1663
|
+
buf[pos++] = n >> 16 & 255;
|
|
1664
|
+
buf[pos++] = n >> 24 & 255;
|
|
1665
|
+
} else {
|
|
1666
|
+
if (pos + 9 > capacity) grow(9);
|
|
1667
|
+
buf[pos++] = 33;
|
|
1668
|
+
view.setFloat64(pos, n, true);
|
|
1669
|
+
pos += 8;
|
|
1670
|
+
}
|
|
1671
|
+
} else if (vt === "boolean") {
|
|
1672
|
+
if (pos >= capacity) grow(1);
|
|
1673
|
+
buf[pos++] = val ? 2 : 1;
|
|
1674
|
+
} else if (val === null) {
|
|
1675
|
+
if (pos >= capacity) grow(1);
|
|
1676
|
+
buf[pos++] = 0;
|
|
1677
|
+
} else {
|
|
1678
|
+
writeValue(val);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
keysRegistered = true;
|
|
1682
|
+
}
|
|
1683
|
+
depth--;
|
|
1684
|
+
return;
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
for (let i = 0; i < len; i++) writeValue(v[i]);
|
|
1688
|
+
depth--;
|
|
1689
|
+
} else if (v instanceof Uint8Array) {
|
|
1690
|
+
const len = v.length;
|
|
1691
|
+
if (pos + 6 + len > capacity) grow(6 + len);
|
|
1692
|
+
buf[pos++] = 49 /* BINARY */;
|
|
1693
|
+
if (len < 128) buf[pos++] = len;
|
|
1694
|
+
else {
|
|
1695
|
+
let val = len >>> 0;
|
|
1696
|
+
while (val > 127) {
|
|
1697
|
+
buf[pos++] = val & 127 | 128;
|
|
1698
|
+
val >>>= 7;
|
|
1699
|
+
}
|
|
1700
|
+
buf[pos++] = val;
|
|
1701
|
+
}
|
|
1702
|
+
buf.set(v, pos);
|
|
1703
|
+
pos += len;
|
|
1704
|
+
} else {
|
|
1705
|
+
depth++;
|
|
1706
|
+
if (depth > maxDepth) throw new BoomError(`Maximum nesting depth of ${maxDepth} exceeded`);
|
|
1707
|
+
const keys = Object.keys(v);
|
|
1708
|
+
const klen = keys.length;
|
|
1709
|
+
if (pos + 6 > capacity) grow(6);
|
|
1710
|
+
buf[pos++] = 80 /* OBJECT */;
|
|
1711
|
+
if (klen < 128) buf[pos++] = klen;
|
|
1712
|
+
else {
|
|
1713
|
+
let val = klen >>> 0;
|
|
1714
|
+
while (val > 127) {
|
|
1715
|
+
buf[pos++] = val & 127 | 128;
|
|
1716
|
+
val >>>= 7;
|
|
1717
|
+
}
|
|
1718
|
+
buf[pos++] = val;
|
|
1719
|
+
}
|
|
1720
|
+
for (let i = 0; i < klen; i++) {
|
|
1721
|
+
const key = keys[i];
|
|
1722
|
+
const ref = stringTable[key];
|
|
1723
|
+
if (ref !== void 0) {
|
|
1724
|
+
if (pos + 2 > capacity) grow(2);
|
|
1725
|
+
buf[pos++] = 96;
|
|
1726
|
+
buf[pos++] = ref;
|
|
1727
|
+
} else {
|
|
1728
|
+
stringTable[key] = stringCount++;
|
|
1729
|
+
const keyBytes = textEncoder.encode(key);
|
|
1730
|
+
const kl = keyBytes.length;
|
|
1731
|
+
if (pos + 2 + kl > capacity) grow(2 + kl);
|
|
1732
|
+
buf[pos++] = 48;
|
|
1733
|
+
buf[pos++] = kl;
|
|
1734
|
+
buf.set(keyBytes, pos);
|
|
1735
|
+
pos += kl;
|
|
1736
|
+
}
|
|
1737
|
+
writeValue(v[key]);
|
|
1738
|
+
}
|
|
1739
|
+
depth--;
|
|
1740
|
+
}
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
case "bigint": {
|
|
1744
|
+
if (pos + 9 > capacity) grow(9);
|
|
1745
|
+
buf[pos++] = v >= 0n ? 23 /* UINT64 */ : 19 /* INT64 */;
|
|
1746
|
+
view.setBigInt64(pos, v, true);
|
|
1747
|
+
pos += 8;
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1750
|
+
default:
|
|
1751
|
+
if (pos >= capacity) grow(1);
|
|
1752
|
+
buf[pos++] = 0 /* NULL */;
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
buf[pos++] = 66;
|
|
1756
|
+
buf[pos++] = 79;
|
|
1757
|
+
buf[pos++] = 79;
|
|
1758
|
+
buf[pos++] = 77;
|
|
1759
|
+
buf[pos++] = VERSION;
|
|
1760
|
+
buf[pos++] = 0;
|
|
1761
|
+
writeValue(value);
|
|
1762
|
+
return buf.slice(0, pos);
|
|
1763
|
+
}
|
|
1764
|
+
var textDecoder = new TextDecoder();
|
|
1765
|
+
var NEED_FULL_DECODE = /* @__PURE__ */ Symbol("NEED_FULL_DECODE");
|
|
1766
|
+
function tryDecodeTinyObject(buf) {
|
|
1767
|
+
let pos = 6;
|
|
1768
|
+
const type = buf[pos++];
|
|
1769
|
+
if (type !== 80) return NEED_FULL_DECODE;
|
|
1770
|
+
const count = buf[pos++];
|
|
1771
|
+
if (count > 8) return NEED_FULL_DECODE;
|
|
1772
|
+
const obj = {};
|
|
1773
|
+
for (let i = 0; i < count; i++) {
|
|
1774
|
+
if (buf[pos++] !== 48) return NEED_FULL_DECODE;
|
|
1775
|
+
const klen = buf[pos++];
|
|
1776
|
+
if (klen > 16) return NEED_FULL_DECODE;
|
|
1777
|
+
let key;
|
|
1778
|
+
switch (klen) {
|
|
1779
|
+
case 1:
|
|
1780
|
+
key = String.fromCharCode(buf[pos]);
|
|
1781
|
+
break;
|
|
1782
|
+
case 2:
|
|
1783
|
+
key = String.fromCharCode(buf[pos], buf[pos + 1]);
|
|
1784
|
+
break;
|
|
1785
|
+
case 3:
|
|
1786
|
+
key = String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2]);
|
|
1787
|
+
break;
|
|
1788
|
+
case 4:
|
|
1789
|
+
key = String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3]);
|
|
1790
|
+
break;
|
|
1791
|
+
case 5:
|
|
1792
|
+
key = String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4]);
|
|
1793
|
+
break;
|
|
1794
|
+
case 6:
|
|
1795
|
+
key = String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5]);
|
|
1796
|
+
break;
|
|
1797
|
+
default:
|
|
1798
|
+
key = ultraDecodeStr(buf, pos, klen);
|
|
1799
|
+
}
|
|
1800
|
+
pos += klen;
|
|
1801
|
+
const vtype = buf[pos++];
|
|
1802
|
+
if (vtype === 48) {
|
|
1803
|
+
const vlen = buf[pos++];
|
|
1804
|
+
switch (vlen) {
|
|
1805
|
+
case 1:
|
|
1806
|
+
obj[key] = String.fromCharCode(buf[pos]);
|
|
1807
|
+
break;
|
|
1808
|
+
case 2:
|
|
1809
|
+
obj[key] = String.fromCharCode(buf[pos], buf[pos + 1]);
|
|
1810
|
+
break;
|
|
1811
|
+
case 3:
|
|
1812
|
+
obj[key] = String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2]);
|
|
1813
|
+
break;
|
|
1814
|
+
case 4:
|
|
1815
|
+
obj[key] = String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3]);
|
|
1816
|
+
break;
|
|
1817
|
+
default:
|
|
1818
|
+
obj[key] = ultraDecodeStr(buf, pos, vlen);
|
|
1819
|
+
}
|
|
1820
|
+
pos += vlen;
|
|
1821
|
+
} else if (vtype === 16) {
|
|
1822
|
+
const v = buf[pos++];
|
|
1823
|
+
obj[key] = v > 127 ? v - 256 : v;
|
|
1824
|
+
} else if (vtype === 2) {
|
|
1825
|
+
obj[key] = true;
|
|
1826
|
+
} else if (vtype === 1) {
|
|
1827
|
+
obj[key] = false;
|
|
1828
|
+
} else if (vtype === 0) {
|
|
1829
|
+
obj[key] = null;
|
|
1830
|
+
} else if (vtype === 17) {
|
|
1831
|
+
const v = buf[pos] | buf[pos + 1] << 8;
|
|
1832
|
+
obj[key] = v > 32767 ? v - 65536 : v;
|
|
1833
|
+
pos += 2;
|
|
1834
|
+
} else if (vtype === 18) {
|
|
1835
|
+
obj[key] = buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24;
|
|
1836
|
+
pos += 4;
|
|
1837
|
+
} else if (vtype === 33) {
|
|
1838
|
+
obj[key] = getDecodeView(buf).getFloat64(pos, true);
|
|
1839
|
+
pos += 8;
|
|
1840
|
+
} else {
|
|
1841
|
+
return NEED_FULL_DECODE;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
return obj;
|
|
1845
|
+
}
|
|
1846
|
+
function isAsciiBytes(buf, pos, len) {
|
|
1847
|
+
for (let i = 0; i < len; i++) {
|
|
1848
|
+
if (buf[pos + i] > 127) return false;
|
|
1849
|
+
}
|
|
1850
|
+
return true;
|
|
1851
|
+
}
|
|
1852
|
+
function ultraDecodeStr(buf, pos, len) {
|
|
1853
|
+
switch (len) {
|
|
1854
|
+
case 1:
|
|
1855
|
+
return String.fromCharCode(buf[pos]);
|
|
1856
|
+
case 2:
|
|
1857
|
+
return String.fromCharCode(buf[pos], buf[pos + 1]);
|
|
1858
|
+
case 3:
|
|
1859
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2]);
|
|
1860
|
+
case 4:
|
|
1861
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3]);
|
|
1862
|
+
case 5:
|
|
1863
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4]);
|
|
1864
|
+
case 6:
|
|
1865
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5]);
|
|
1866
|
+
case 7:
|
|
1867
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5], buf[pos + 6]);
|
|
1868
|
+
case 8:
|
|
1869
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5], buf[pos + 6], buf[pos + 7]);
|
|
1870
|
+
}
|
|
1871
|
+
for (let i = 0; i < len; i++) {
|
|
1872
|
+
if (buf[pos + i] > 127) {
|
|
1873
|
+
return textDecoder.decode(buf.subarray(pos, pos + len));
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
let s = "";
|
|
1877
|
+
for (let i = 0; i < len; i++) s += String.fromCharCode(buf[pos + i]);
|
|
1878
|
+
return s;
|
|
1879
|
+
}
|
|
1880
|
+
function decodeStr(buf, pos, len) {
|
|
1881
|
+
if (len <= 8) {
|
|
1882
|
+
if (isAsciiBytes(buf, pos, len)) {
|
|
1883
|
+
switch (len) {
|
|
1884
|
+
case 1:
|
|
1885
|
+
return String.fromCharCode(buf[pos]);
|
|
1886
|
+
case 2:
|
|
1887
|
+
return String.fromCharCode(buf[pos], buf[pos + 1]);
|
|
1888
|
+
case 3:
|
|
1889
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2]);
|
|
1890
|
+
case 4:
|
|
1891
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3]);
|
|
1892
|
+
case 5:
|
|
1893
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4]);
|
|
1894
|
+
case 6:
|
|
1895
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5]);
|
|
1896
|
+
case 7:
|
|
1897
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5], buf[pos + 6]);
|
|
1898
|
+
case 8:
|
|
1899
|
+
return String.fromCharCode(buf[pos], buf[pos + 1], buf[pos + 2], buf[pos + 3], buf[pos + 4], buf[pos + 5], buf[pos + 6], buf[pos + 7]);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
return textDecoder.decode(buf.subarray(pos, pos + len));
|
|
1903
|
+
}
|
|
1904
|
+
if (len <= 32 && isAsciiBytes(buf, pos, len)) {
|
|
1905
|
+
let s = "";
|
|
1906
|
+
let i = 0;
|
|
1907
|
+
for (; i + 8 <= len; i += 8) {
|
|
1908
|
+
s += String.fromCharCode(
|
|
1909
|
+
buf[pos + i],
|
|
1910
|
+
buf[pos + i + 1],
|
|
1911
|
+
buf[pos + i + 2],
|
|
1912
|
+
buf[pos + i + 3],
|
|
1913
|
+
buf[pos + i + 4],
|
|
1914
|
+
buf[pos + i + 5],
|
|
1915
|
+
buf[pos + i + 6],
|
|
1916
|
+
buf[pos + i + 7]
|
|
1917
|
+
);
|
|
1918
|
+
}
|
|
1919
|
+
for (; i < len; i++) {
|
|
1920
|
+
s += String.fromCharCode(buf[pos + i]);
|
|
1921
|
+
}
|
|
1922
|
+
return s;
|
|
1923
|
+
}
|
|
1924
|
+
return textDecoder.decode(buf.subarray(pos, pos + len));
|
|
1925
|
+
}
|
|
1926
|
+
function fastDecodeSmall(buffer) {
|
|
1927
|
+
const buf = buffer;
|
|
1928
|
+
let pos = 6;
|
|
1929
|
+
const type = buf[pos++];
|
|
1930
|
+
if (type === 80) {
|
|
1931
|
+
const count = buf[pos++];
|
|
1932
|
+
const obj = {};
|
|
1933
|
+
for (let i = 0; i < count; i++) {
|
|
1934
|
+
pos++;
|
|
1935
|
+
const klen = buf[pos++];
|
|
1936
|
+
const key = decodeStr(buf, pos, klen);
|
|
1937
|
+
pos += klen;
|
|
1938
|
+
const vtype = buf[pos++];
|
|
1939
|
+
if (vtype === 48) {
|
|
1940
|
+
const vlen = buf[pos++];
|
|
1941
|
+
obj[key] = decodeStr(buf, pos, vlen);
|
|
1942
|
+
pos += vlen;
|
|
1943
|
+
} else if (vtype === 16) {
|
|
1944
|
+
const v = buf[pos++];
|
|
1945
|
+
obj[key] = v > 127 ? v - 256 : v;
|
|
1946
|
+
} else if (vtype === 17) {
|
|
1947
|
+
const v = buf[pos] | buf[pos + 1] << 8;
|
|
1948
|
+
obj[key] = v > 32767 ? v - 65536 : v;
|
|
1949
|
+
pos += 2;
|
|
1950
|
+
} else if (vtype === 18) {
|
|
1951
|
+
obj[key] = buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24;
|
|
1952
|
+
pos += 4;
|
|
1953
|
+
} else if (vtype === 33) {
|
|
1954
|
+
obj[key] = getDecodeView(buf).getFloat64(pos, true);
|
|
1955
|
+
pos += 8;
|
|
1956
|
+
} else if (vtype === 2) {
|
|
1957
|
+
obj[key] = true;
|
|
1958
|
+
} else if (vtype === 1) {
|
|
1959
|
+
obj[key] = false;
|
|
1960
|
+
} else if (vtype === 23) {
|
|
1961
|
+
obj[key] = getDecodeView(buf).getBigUint64(pos, true);
|
|
1962
|
+
pos += 8;
|
|
1963
|
+
} else if (vtype === 19 || vtype === 25) {
|
|
1964
|
+
obj[key] = getDecodeView(buf).getBigInt64(pos, true);
|
|
1965
|
+
pos += 8;
|
|
1966
|
+
} else if (vtype === 80) {
|
|
1967
|
+
const ncount = buf[pos++];
|
|
1968
|
+
const nobj = {};
|
|
1969
|
+
for (let ni = 0; ni < ncount; ni++) {
|
|
1970
|
+
pos++;
|
|
1971
|
+
const nklen = buf[pos++];
|
|
1972
|
+
const nkey = decodeStr(buf, pos, nklen);
|
|
1973
|
+
pos += nklen;
|
|
1974
|
+
const nvtype = buf[pos++];
|
|
1975
|
+
if (nvtype === 48) {
|
|
1976
|
+
const nvlen = buf[pos++];
|
|
1977
|
+
nobj[nkey] = decodeStr(buf, pos, nvlen);
|
|
1978
|
+
pos += nvlen;
|
|
1979
|
+
} else if (nvtype === 16) {
|
|
1980
|
+
const v = buf[pos++];
|
|
1981
|
+
nobj[nkey] = v > 127 ? v - 256 : v;
|
|
1982
|
+
} else if (nvtype === 17) {
|
|
1983
|
+
const v = buf[pos] | buf[pos + 1] << 8;
|
|
1984
|
+
nobj[nkey] = v > 32767 ? v - 65536 : v;
|
|
1985
|
+
pos += 2;
|
|
1986
|
+
} else if (nvtype === 18) {
|
|
1987
|
+
nobj[nkey] = buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24;
|
|
1988
|
+
pos += 4;
|
|
1989
|
+
} else if (nvtype === 33) {
|
|
1990
|
+
nobj[nkey] = getDecodeView(buf).getFloat64(pos, true);
|
|
1991
|
+
pos += 8;
|
|
1992
|
+
} else if (nvtype === 23) {
|
|
1993
|
+
nobj[nkey] = getDecodeView(buf).getBigUint64(pos, true);
|
|
1994
|
+
pos += 8;
|
|
1995
|
+
} else if (nvtype === 19 || nvtype === 25) {
|
|
1996
|
+
nobj[nkey] = getDecodeView(buf).getBigInt64(pos, true);
|
|
1997
|
+
pos += 8;
|
|
1998
|
+
} else if (nvtype === 2) {
|
|
1999
|
+
nobj[nkey] = true;
|
|
2000
|
+
} else if (nvtype === 1) {
|
|
2001
|
+
nobj[nkey] = false;
|
|
2002
|
+
} else if (nvtype === 0) {
|
|
2003
|
+
nobj[nkey] = null;
|
|
2004
|
+
} else {
|
|
2005
|
+
return NEED_FULL_DECODE;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
obj[key] = nobj;
|
|
2009
|
+
} else if (vtype === 0) {
|
|
2010
|
+
obj[key] = null;
|
|
2011
|
+
} else {
|
|
2012
|
+
return NEED_FULL_DECODE;
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
return obj;
|
|
2016
|
+
}
|
|
2017
|
+
if (type === 64) {
|
|
2018
|
+
const count = buf[pos++];
|
|
2019
|
+
const arr = new Array(count);
|
|
2020
|
+
for (let i = 0; i < count; i++) {
|
|
2021
|
+
const vtype = buf[pos++];
|
|
2022
|
+
if (vtype === 16) {
|
|
2023
|
+
const v = buf[pos++];
|
|
2024
|
+
arr[i] = v > 127 ? v - 256 : v;
|
|
2025
|
+
} else if (vtype === 48) {
|
|
2026
|
+
const len = buf[pos++];
|
|
2027
|
+
arr[i] = decodeStr(buf, pos, len);
|
|
2028
|
+
pos += len;
|
|
2029
|
+
} else if (vtype === 17) {
|
|
2030
|
+
const v = buf[pos] | buf[pos + 1] << 8;
|
|
2031
|
+
arr[i] = v > 32767 ? v - 65536 : v;
|
|
2032
|
+
pos += 2;
|
|
2033
|
+
} else if (vtype === 18) {
|
|
2034
|
+
arr[i] = buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24;
|
|
2035
|
+
pos += 4;
|
|
2036
|
+
} else if (vtype === 33) {
|
|
2037
|
+
arr[i] = getDecodeView(buf).getFloat64(pos, true);
|
|
2038
|
+
pos += 8;
|
|
2039
|
+
} else if (vtype === 64) {
|
|
2040
|
+
return NEED_FULL_DECODE;
|
|
2041
|
+
} else if (vtype === 80) {
|
|
2042
|
+
return NEED_FULL_DECODE;
|
|
2043
|
+
} else if (vtype === 2) {
|
|
2044
|
+
arr[i] = true;
|
|
2045
|
+
} else if (vtype === 1) {
|
|
2046
|
+
arr[i] = false;
|
|
2047
|
+
} else if (vtype === 0) {
|
|
2048
|
+
arr[i] = null;
|
|
2049
|
+
} else {
|
|
2050
|
+
return NEED_FULL_DECODE;
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
return arr;
|
|
2054
|
+
}
|
|
2055
|
+
if (type === 48) {
|
|
2056
|
+
const len = buf[pos++];
|
|
2057
|
+
return decodeStr(buf, pos, len);
|
|
2058
|
+
}
|
|
2059
|
+
if (type === 16) {
|
|
2060
|
+
const v = buf[pos];
|
|
2061
|
+
return v > 127 ? v - 256 : v;
|
|
2062
|
+
}
|
|
2063
|
+
if (type === 2) return true;
|
|
2064
|
+
if (type === 1) return false;
|
|
2065
|
+
return null;
|
|
2066
|
+
}
|
|
2067
|
+
function fastDecodeArrayOfObjects(buffer, startPos, count) {
|
|
2068
|
+
const buf = buffer;
|
|
2069
|
+
let pos = startPos;
|
|
2070
|
+
const arr = new Array(count);
|
|
2071
|
+
const view = getDecodeView(buf);
|
|
2072
|
+
const stringTable = [];
|
|
2073
|
+
for (let i = 0; i < count; i++) {
|
|
2074
|
+
const objMarker = buf[pos++];
|
|
2075
|
+
if (objMarker !== 80) return NEED_FULL_DECODE;
|
|
2076
|
+
const keyCount = buf[pos++];
|
|
2077
|
+
const obj = {};
|
|
2078
|
+
for (let j = 0; j < keyCount; j++) {
|
|
2079
|
+
const keyType = buf[pos++];
|
|
2080
|
+
let key;
|
|
2081
|
+
if (keyType === 48) {
|
|
2082
|
+
const klen = buf[pos++];
|
|
2083
|
+
key = decodeStr(buf, pos, klen);
|
|
2084
|
+
pos += klen;
|
|
2085
|
+
stringTable.push(key);
|
|
2086
|
+
} else if (keyType === 96) {
|
|
2087
|
+
const ref = buf[pos++];
|
|
2088
|
+
key = stringTable[ref];
|
|
2089
|
+
if (!key) return NEED_FULL_DECODE;
|
|
2090
|
+
} else if (keyType === 97) {
|
|
2091
|
+
const ref = buf[pos++];
|
|
2092
|
+
key = BOOM_DICTIONARY_V1[ref];
|
|
2093
|
+
} else {
|
|
2094
|
+
return NEED_FULL_DECODE;
|
|
2095
|
+
}
|
|
2096
|
+
const vtype = buf[pos++];
|
|
2097
|
+
if (vtype === 48) {
|
|
2098
|
+
const vlen = buf[pos++];
|
|
2099
|
+
const val = decodeStr(buf, pos, vlen);
|
|
2100
|
+
pos += vlen;
|
|
2101
|
+
stringTable.push(val);
|
|
2102
|
+
obj[key] = val;
|
|
2103
|
+
} else if (vtype === 96) {
|
|
2104
|
+
const ref = buf[pos++];
|
|
2105
|
+
obj[key] = stringTable[ref];
|
|
2106
|
+
} else if (vtype === 97) {
|
|
2107
|
+
const ref = buf[pos++];
|
|
2108
|
+
obj[key] = BOOM_DICTIONARY_V1[ref];
|
|
2109
|
+
} else if (vtype === 16) {
|
|
2110
|
+
const v = buf[pos++];
|
|
2111
|
+
obj[key] = v > 127 ? v - 256 : v;
|
|
2112
|
+
} else if (vtype === 17) {
|
|
2113
|
+
const v = buf[pos] | buf[pos + 1] << 8;
|
|
2114
|
+
obj[key] = v > 32767 ? v - 65536 : v;
|
|
2115
|
+
pos += 2;
|
|
2116
|
+
} else if (vtype === 18) {
|
|
2117
|
+
obj[key] = buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24;
|
|
2118
|
+
pos += 4;
|
|
2119
|
+
} else if (vtype === 33) {
|
|
2120
|
+
obj[key] = view.getFloat64(pos, true);
|
|
2121
|
+
pos += 8;
|
|
2122
|
+
} else if (vtype === 2) {
|
|
2123
|
+
obj[key] = true;
|
|
2124
|
+
} else if (vtype === 1) {
|
|
2125
|
+
obj[key] = false;
|
|
2126
|
+
} else if (vtype === 0) {
|
|
2127
|
+
obj[key] = null;
|
|
2128
|
+
} else {
|
|
2129
|
+
return NEED_FULL_DECODE;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
arr[i] = obj;
|
|
2133
|
+
}
|
|
2134
|
+
return arr;
|
|
2135
|
+
}
|
|
2136
|
+
function fastDecode(buffer) {
|
|
2137
|
+
if (buffer.length < 6 || buffer[0] !== 66 || buffer[1] !== 79 || buffer[2] !== 79 || buffer[3] !== 77) {
|
|
2138
|
+
if (buffer.length < 6) throw new BoomError("Buffer too short for BOOM header");
|
|
2139
|
+
throw new BoomError("Invalid BOOM magic bytes");
|
|
2140
|
+
}
|
|
2141
|
+
if (buffer[4] !== VERSION) {
|
|
2142
|
+
throw new BoomError(`Unsupported BOOM version: ${buffer[4]}`);
|
|
2143
|
+
}
|
|
2144
|
+
const len = buffer.length;
|
|
2145
|
+
if (len < 64) {
|
|
2146
|
+
const result = tryDecodeTinyObject(buffer);
|
|
2147
|
+
if (result !== NEED_FULL_DECODE) return result;
|
|
2148
|
+
}
|
|
2149
|
+
const type = buffer[6];
|
|
2150
|
+
if (type === 64) {
|
|
2151
|
+
let pos2 = 7;
|
|
2152
|
+
let b = buffer[pos2++];
|
|
2153
|
+
let count = b & 127;
|
|
2154
|
+
if (b >= 128) {
|
|
2155
|
+
b = buffer[pos2++];
|
|
2156
|
+
count |= (b & 127) << 7;
|
|
2157
|
+
if (b >= 128) {
|
|
2158
|
+
b = buffer[pos2++];
|
|
2159
|
+
count |= (b & 127) << 14;
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
if (count > 0) {
|
|
2163
|
+
const firstType = buffer[pos2];
|
|
2164
|
+
if (firstType === 80) {
|
|
2165
|
+
const result = fastDecodeArrayOfObjects(buffer, pos2, count);
|
|
2166
|
+
if (result !== NEED_FULL_DECODE) return result;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
if (type === 80) {
|
|
2171
|
+
const keyCount = buffer[7];
|
|
2172
|
+
if (keyCount <= 10 && len < 512) {
|
|
2173
|
+
let isFlat = true;
|
|
2174
|
+
let pos2 = 8;
|
|
2175
|
+
for (let k = 0; k < keyCount && pos2 < len && isFlat; k++) {
|
|
2176
|
+
if (buffer[pos2] !== 48) {
|
|
2177
|
+
isFlat = false;
|
|
2178
|
+
break;
|
|
2179
|
+
}
|
|
2180
|
+
pos2++;
|
|
2181
|
+
const klen = buffer[pos2++];
|
|
2182
|
+
pos2 += klen;
|
|
2183
|
+
const vtype = buffer[pos2++];
|
|
2184
|
+
if (vtype === 64) {
|
|
2185
|
+
isFlat = false;
|
|
2186
|
+
break;
|
|
2187
|
+
}
|
|
2188
|
+
if (vtype === 48) {
|
|
2189
|
+
const vlen = buffer[pos2++];
|
|
2190
|
+
pos2 += vlen;
|
|
2191
|
+
} else if (vtype === 80) {
|
|
2192
|
+
const ncount = buffer[pos2++];
|
|
2193
|
+
for (let nk = 0; nk < ncount && pos2 < len; nk++) {
|
|
2194
|
+
if (buffer[pos2] !== 48) {
|
|
2195
|
+
isFlat = false;
|
|
2196
|
+
break;
|
|
2197
|
+
}
|
|
2198
|
+
pos2++;
|
|
2199
|
+
const nklen = buffer[pos2++];
|
|
2200
|
+
pos2 += nklen;
|
|
2201
|
+
const nvtype = buffer[pos2++];
|
|
2202
|
+
if (nvtype === 80 || nvtype === 64) {
|
|
2203
|
+
isFlat = false;
|
|
2204
|
+
break;
|
|
2205
|
+
}
|
|
2206
|
+
if (nvtype === 48) {
|
|
2207
|
+
const nvlen = buffer[pos2++];
|
|
2208
|
+
pos2 += nvlen;
|
|
2209
|
+
} else if (nvtype === 16) pos2 += 1;
|
|
2210
|
+
else if (nvtype === 18) pos2 += 4;
|
|
2211
|
+
else if (nvtype === 33) pos2 += 8;
|
|
2212
|
+
}
|
|
2213
|
+
} else if (vtype === 16) pos2 += 1;
|
|
2214
|
+
else if (vtype === 17) pos2 += 2;
|
|
2215
|
+
else if (vtype === 18) pos2 += 4;
|
|
2216
|
+
else if (vtype === 33 || vtype === 19 || vtype === 23 || vtype === 25) pos2 += 8;
|
|
2217
|
+
else if (vtype === 96) pos2 += 1;
|
|
2218
|
+
}
|
|
2219
|
+
if (isFlat) {
|
|
2220
|
+
const result = fastDecodeSmall(buffer);
|
|
2221
|
+
if (result !== NEED_FULL_DECODE) return result;
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
const buf = buffer;
|
|
2226
|
+
const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
2227
|
+
let pos = 6;
|
|
2228
|
+
const stringTable = [];
|
|
2229
|
+
let depth = 0;
|
|
2230
|
+
const maxDepth = 64;
|
|
2231
|
+
function readVarint() {
|
|
2232
|
+
let b = buf[pos++];
|
|
2233
|
+
if (b < 128) return b;
|
|
2234
|
+
let result = b & 127;
|
|
2235
|
+
b = buf[pos++];
|
|
2236
|
+
if (b < 128) return result | b << 7;
|
|
2237
|
+
result |= (b & 127) << 7;
|
|
2238
|
+
b = buf[pos++];
|
|
2239
|
+
if (b < 128) return result | b << 14;
|
|
2240
|
+
result |= (b & 127) << 14;
|
|
2241
|
+
b = buf[pos++];
|
|
2242
|
+
if (b < 128) return result | b << 21;
|
|
2243
|
+
result |= (b & 127) << 21;
|
|
2244
|
+
b = buf[pos++];
|
|
2245
|
+
return (result | b << 28) >>> 0;
|
|
2246
|
+
}
|
|
2247
|
+
function readString() {
|
|
2248
|
+
const length = readVarint();
|
|
2249
|
+
const start = pos;
|
|
2250
|
+
pos += length;
|
|
2251
|
+
if (length <= 8) {
|
|
2252
|
+
const str2 = decodeStr(buf, start, length);
|
|
2253
|
+
stringTable.push(str2);
|
|
2254
|
+
return str2;
|
|
2255
|
+
}
|
|
2256
|
+
if (length < 128) {
|
|
2257
|
+
let isAscii2 = true;
|
|
2258
|
+
for (let i = start; i < pos; i++) {
|
|
2259
|
+
if (buf[i] > 127) {
|
|
2260
|
+
isAscii2 = false;
|
|
2261
|
+
break;
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
if (isAscii2) {
|
|
2265
|
+
const str2 = String.fromCharCode.apply(null, buf.subarray(start, pos));
|
|
2266
|
+
stringTable.push(str2);
|
|
2267
|
+
return str2;
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
const str = textDecoder.decode(buf.subarray(start, pos));
|
|
2271
|
+
stringTable.push(str);
|
|
2272
|
+
return str;
|
|
2273
|
+
}
|
|
2274
|
+
function readValue() {
|
|
2275
|
+
const type2 = buf[pos++];
|
|
2276
|
+
switch (type2) {
|
|
2277
|
+
case 48 /* STRING */:
|
|
2278
|
+
return readString();
|
|
2279
|
+
case 16 /* INT8 */: {
|
|
2280
|
+
const v = buf[pos++];
|
|
2281
|
+
return v > 127 ? v - 256 : v;
|
|
2282
|
+
}
|
|
2283
|
+
case 18 /* INT32 */: {
|
|
2284
|
+
const p = pos;
|
|
2285
|
+
pos += 4;
|
|
2286
|
+
return buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24;
|
|
2287
|
+
}
|
|
2288
|
+
case 17 /* INT16 */: {
|
|
2289
|
+
const p = pos;
|
|
2290
|
+
pos += 2;
|
|
2291
|
+
const v = buf[p] | buf[p + 1] << 8;
|
|
2292
|
+
return v > 32767 ? v - 65536 : v;
|
|
2293
|
+
}
|
|
2294
|
+
case 80 /* OBJECT */: {
|
|
2295
|
+
depth++;
|
|
2296
|
+
if (depth > maxDepth) throw new BoomError(`Maximum nesting depth of ${maxDepth} exceeded`);
|
|
2297
|
+
const count = readVarint();
|
|
2298
|
+
const obj = {};
|
|
2299
|
+
for (let i = 0; i < count; i++) {
|
|
2300
|
+
const keyType = buf[pos++];
|
|
2301
|
+
const key = keyType === 48 /* STRING */ ? readString() : keyType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[readVarint()] : stringTable[readVarint()];
|
|
2302
|
+
obj[key] = readValue();
|
|
2303
|
+
}
|
|
2304
|
+
depth--;
|
|
2305
|
+
return obj;
|
|
2306
|
+
}
|
|
2307
|
+
case 64 /* ARRAY */: {
|
|
2308
|
+
depth++;
|
|
2309
|
+
if (depth > maxDepth) throw new BoomError(`Maximum nesting depth of ${maxDepth} exceeded`);
|
|
2310
|
+
const count = readVarint();
|
|
2311
|
+
const arr = new Array(count);
|
|
2312
|
+
for (let i = 0; i < count; i++) arr[i] = readValue();
|
|
2313
|
+
depth--;
|
|
2314
|
+
return arr;
|
|
2315
|
+
}
|
|
2316
|
+
case 96 /* REF */:
|
|
2317
|
+
return stringTable[readVarint()];
|
|
2318
|
+
case 97 /* DICT_REF */:
|
|
2319
|
+
return BOOM_DICTIONARY_V1[readVarint()];
|
|
2320
|
+
case 0 /* NULL */:
|
|
2321
|
+
return null;
|
|
2322
|
+
case 2 /* TRUE */:
|
|
2323
|
+
return true;
|
|
2324
|
+
case 1 /* FALSE */:
|
|
2325
|
+
return false;
|
|
2326
|
+
case 33 /* FLOAT64 */: {
|
|
2327
|
+
const v = view.getFloat64(pos, true);
|
|
2328
|
+
pos += 8;
|
|
2329
|
+
return v;
|
|
2330
|
+
}
|
|
2331
|
+
case 32 /* FLOAT32 */: {
|
|
2332
|
+
const v = view.getFloat32(pos, true);
|
|
2333
|
+
pos += 4;
|
|
2334
|
+
return v;
|
|
2335
|
+
}
|
|
2336
|
+
case 49 /* BINARY */: {
|
|
2337
|
+
const len2 = readVarint();
|
|
2338
|
+
const start = pos;
|
|
2339
|
+
pos += len2;
|
|
2340
|
+
return new Uint8Array(buf.subarray(start, pos));
|
|
2341
|
+
}
|
|
2342
|
+
case 23 /* UINT64 */: {
|
|
2343
|
+
const v = view.getBigUint64(pos, true);
|
|
2344
|
+
pos += 8;
|
|
2345
|
+
return v;
|
|
2346
|
+
}
|
|
2347
|
+
case 19 /* INT64 */: {
|
|
2348
|
+
const v = view.getBigInt64(pos, true);
|
|
2349
|
+
pos += 8;
|
|
2350
|
+
return v;
|
|
2351
|
+
}
|
|
2352
|
+
case 112 /* TABLE */: {
|
|
2353
|
+
depth++;
|
|
2354
|
+
if (depth > maxDepth) throw new BoomError(`Maximum nesting depth of ${maxDepth} exceeded`);
|
|
2355
|
+
const rowCount = readVarint();
|
|
2356
|
+
const colCount = readVarint();
|
|
2357
|
+
const keys = [];
|
|
2358
|
+
for (let i = 0; i < colCount; i++) {
|
|
2359
|
+
const keyType = buf[pos++];
|
|
2360
|
+
keys.push(keyType === 48 /* STRING */ ? readString() : keyType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[readVarint()] : stringTable[readVarint()]);
|
|
2361
|
+
}
|
|
2362
|
+
const colSchemas = [];
|
|
2363
|
+
for (let i = 0; i < colCount; i++) {
|
|
2364
|
+
const colType = buf[pos++];
|
|
2365
|
+
const schema = { type: colType };
|
|
2366
|
+
if (colType === 114 /* NESTED_OBJECT */) {
|
|
2367
|
+
const nestedColCount = readVarint();
|
|
2368
|
+
schema.nestedKeys = [];
|
|
2369
|
+
schema.nestedTypes = [];
|
|
2370
|
+
for (let j = 0; j < nestedColCount; j++) {
|
|
2371
|
+
const nestedKeyType = buf[pos++];
|
|
2372
|
+
schema.nestedKeys.push(nestedKeyType === 48 /* STRING */ ? readString() : nestedKeyType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[readVarint()] : stringTable[readVarint()]);
|
|
2373
|
+
}
|
|
2374
|
+
for (let j = 0; j < nestedColCount; j++) {
|
|
2375
|
+
schema.nestedTypes.push(buf[pos++]);
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
colSchemas.push(schema);
|
|
2379
|
+
}
|
|
2380
|
+
const rows = [];
|
|
2381
|
+
for (let r = 0; r < rowCount; r++) {
|
|
2382
|
+
const row = {};
|
|
2383
|
+
for (let c = 0; c < colCount; c++) {
|
|
2384
|
+
const key = keys[c];
|
|
2385
|
+
const schema = colSchemas[c];
|
|
2386
|
+
switch (schema.type) {
|
|
2387
|
+
case 133 /* PACKED_BOOL */:
|
|
2388
|
+
row[key] = buf[pos++] !== 0;
|
|
2389
|
+
break;
|
|
2390
|
+
case 128 /* PACKED_INT8 */: {
|
|
2391
|
+
const v = buf[pos++];
|
|
2392
|
+
row[key] = v > 127 ? v - 256 : v;
|
|
2393
|
+
break;
|
|
2394
|
+
}
|
|
2395
|
+
case 129 /* PACKED_INT16 */: {
|
|
2396
|
+
const p = pos;
|
|
2397
|
+
pos += 2;
|
|
2398
|
+
const v = buf[p] | buf[p + 1] << 8;
|
|
2399
|
+
row[key] = v > 32767 ? v - 65536 : v;
|
|
2400
|
+
break;
|
|
2401
|
+
}
|
|
2402
|
+
case 130 /* PACKED_INT32 */: {
|
|
2403
|
+
const p = pos;
|
|
2404
|
+
pos += 4;
|
|
2405
|
+
row[key] = buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24;
|
|
2406
|
+
break;
|
|
2407
|
+
}
|
|
2408
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
2409
|
+
row[key] = view.getFloat64(pos, true);
|
|
2410
|
+
pos += 8;
|
|
2411
|
+
break;
|
|
2412
|
+
case 48 /* STRING */: {
|
|
2413
|
+
const strType = buf[pos++];
|
|
2414
|
+
row[key] = strType === 48 /* STRING */ ? readString() : strType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[readVarint()] : stringTable[readVarint()];
|
|
2415
|
+
break;
|
|
2416
|
+
}
|
|
2417
|
+
case 113 /* NESTED_TABLE */: {
|
|
2418
|
+
const itemCount = readVarint();
|
|
2419
|
+
const nestedArr = [];
|
|
2420
|
+
for (let j = 0; j < itemCount; j++) nestedArr.push(readValue());
|
|
2421
|
+
row[key] = nestedArr;
|
|
2422
|
+
break;
|
|
2423
|
+
}
|
|
2424
|
+
case 114 /* NESTED_OBJECT */: {
|
|
2425
|
+
const nestedObj = {};
|
|
2426
|
+
for (let j = 0; j < schema.nestedKeys.length; j++) {
|
|
2427
|
+
const nestedKey = schema.nestedKeys[j];
|
|
2428
|
+
const nestedType = schema.nestedTypes[j];
|
|
2429
|
+
switch (nestedType) {
|
|
2430
|
+
case 133 /* PACKED_BOOL */:
|
|
2431
|
+
nestedObj[nestedKey] = buf[pos++] !== 0;
|
|
2432
|
+
break;
|
|
2433
|
+
case 128 /* PACKED_INT8 */: {
|
|
2434
|
+
const v = buf[pos++];
|
|
2435
|
+
nestedObj[nestedKey] = v > 127 ? v - 256 : v;
|
|
2436
|
+
break;
|
|
2437
|
+
}
|
|
2438
|
+
case 129 /* PACKED_INT16 */: {
|
|
2439
|
+
const p = pos;
|
|
2440
|
+
pos += 2;
|
|
2441
|
+
const v = buf[p] | buf[p + 1] << 8;
|
|
2442
|
+
nestedObj[nestedKey] = v > 32767 ? v - 65536 : v;
|
|
2443
|
+
break;
|
|
2444
|
+
}
|
|
2445
|
+
case 130 /* PACKED_INT32 */: {
|
|
2446
|
+
const p = pos;
|
|
2447
|
+
pos += 4;
|
|
2448
|
+
nestedObj[nestedKey] = buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24;
|
|
2449
|
+
break;
|
|
2450
|
+
}
|
|
2451
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
2452
|
+
nestedObj[nestedKey] = view.getFloat64(pos, true);
|
|
2453
|
+
pos += 8;
|
|
2454
|
+
break;
|
|
2455
|
+
case 48 /* STRING */: {
|
|
2456
|
+
const strType = buf[pos++];
|
|
2457
|
+
nestedObj[nestedKey] = strType === 48 /* STRING */ ? readString() : strType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[readVarint()] : stringTable[readVarint()];
|
|
2458
|
+
break;
|
|
2459
|
+
}
|
|
2460
|
+
default:
|
|
2461
|
+
nestedObj[nestedKey] = readValue();
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
row[key] = nestedObj;
|
|
2465
|
+
break;
|
|
2466
|
+
}
|
|
2467
|
+
default:
|
|
2468
|
+
row[key] = readValue();
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
rows.push(row);
|
|
2472
|
+
}
|
|
2473
|
+
depth--;
|
|
2474
|
+
return rows;
|
|
2475
|
+
}
|
|
2476
|
+
case 115 /* COLUMNAR */: {
|
|
2477
|
+
depth++;
|
|
2478
|
+
if (depth > maxDepth) throw new BoomError(`Maximum nesting depth of ${maxDepth} exceeded`);
|
|
2479
|
+
const rowCount = readVarint();
|
|
2480
|
+
const colCount = readVarint();
|
|
2481
|
+
const keys = [];
|
|
2482
|
+
for (let i = 0; i < colCount; i++) {
|
|
2483
|
+
const len2 = readVarint();
|
|
2484
|
+
const start = pos;
|
|
2485
|
+
pos += len2;
|
|
2486
|
+
keys.push(textDecoder.decode(buf.subarray(start, pos)));
|
|
2487
|
+
}
|
|
2488
|
+
const colTypes = [];
|
|
2489
|
+
for (let i = 0; i < colCount; i++) colTypes.push(buf[pos++]);
|
|
2490
|
+
const rows = [];
|
|
2491
|
+
for (let r = 0; r < rowCount; r++) rows.push({});
|
|
2492
|
+
for (let c = 0; c < colCount; c++) {
|
|
2493
|
+
const key = keys[c];
|
|
2494
|
+
const colType = colTypes[c];
|
|
2495
|
+
switch (colType) {
|
|
2496
|
+
case 116 /* RLE_CONST */: {
|
|
2497
|
+
const constValue = readValue();
|
|
2498
|
+
for (let r = 0; r < rowCount; r++) rows[r][key] = constValue;
|
|
2499
|
+
break;
|
|
2500
|
+
}
|
|
2501
|
+
case 133 /* PACKED_BOOL */: {
|
|
2502
|
+
for (let i = 0; i < rowCount; i += 8) {
|
|
2503
|
+
const byte = buf[pos++];
|
|
2504
|
+
for (let j = 0; j < 8 && i + j < rowCount; j++) {
|
|
2505
|
+
rows[i + j][key] = (byte & 1 << j) !== 0;
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
break;
|
|
2509
|
+
}
|
|
2510
|
+
case 128 /* PACKED_INT8 */:
|
|
2511
|
+
for (let r = 0; r < rowCount; r++) {
|
|
2512
|
+
const v = buf[pos++];
|
|
2513
|
+
rows[r][key] = v > 127 ? v - 256 : v;
|
|
2514
|
+
}
|
|
2515
|
+
break;
|
|
2516
|
+
case 129 /* PACKED_INT16 */:
|
|
2517
|
+
for (let r = 0; r < rowCount; r++) {
|
|
2518
|
+
const p = pos;
|
|
2519
|
+
pos += 2;
|
|
2520
|
+
const v = buf[p] | buf[p + 1] << 8;
|
|
2521
|
+
rows[r][key] = v > 32767 ? v - 65536 : v;
|
|
2522
|
+
}
|
|
2523
|
+
break;
|
|
2524
|
+
case 130 /* PACKED_INT32 */:
|
|
2525
|
+
for (let r = 0; r < rowCount; r++) {
|
|
2526
|
+
const p = pos;
|
|
2527
|
+
pos += 4;
|
|
2528
|
+
rows[r][key] = buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24;
|
|
2529
|
+
}
|
|
2530
|
+
break;
|
|
2531
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
2532
|
+
for (let r = 0; r < rowCount; r++) {
|
|
2533
|
+
rows[r][key] = view.getFloat64(pos, true);
|
|
2534
|
+
pos += 8;
|
|
2535
|
+
}
|
|
2536
|
+
break;
|
|
2537
|
+
case 48 /* STRING */:
|
|
2538
|
+
for (let r = 0; r < rowCount; r++) {
|
|
2539
|
+
const strType = buf[pos++];
|
|
2540
|
+
rows[r][key] = strType === 48 /* STRING */ ? readString() : strType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[readVarint()] : stringTable[readVarint()];
|
|
2541
|
+
}
|
|
2542
|
+
break;
|
|
2543
|
+
default:
|
|
2544
|
+
for (let r = 0; r < rowCount; r++) rows[r][key] = readValue();
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
depth--;
|
|
2548
|
+
return rows;
|
|
2549
|
+
}
|
|
2550
|
+
case 133 /* PACKED_BOOL */: {
|
|
2551
|
+
const count = readVarint();
|
|
2552
|
+
const result = [];
|
|
2553
|
+
const byteCount = Math.ceil(count / 8);
|
|
2554
|
+
for (let i = 0; i < byteCount; i++) {
|
|
2555
|
+
const byte = buf[pos++];
|
|
2556
|
+
for (let j = 0; j < 8 && result.length < count; j++) {
|
|
2557
|
+
result.push((byte & 1 << j) !== 0);
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
return result;
|
|
2561
|
+
}
|
|
2562
|
+
case 128 /* PACKED_INT8 */: {
|
|
2563
|
+
const count = readVarint();
|
|
2564
|
+
const result = [];
|
|
2565
|
+
for (let i = 0; i < count; i++) {
|
|
2566
|
+
const v = buf[pos++];
|
|
2567
|
+
result.push(v > 127 ? v - 256 : v);
|
|
2568
|
+
}
|
|
2569
|
+
return result;
|
|
2570
|
+
}
|
|
2571
|
+
case 129 /* PACKED_INT16 */: {
|
|
2572
|
+
const count = readVarint();
|
|
2573
|
+
const result = [];
|
|
2574
|
+
for (let i = 0; i < count; i++) {
|
|
2575
|
+
const p = pos;
|
|
2576
|
+
pos += 2;
|
|
2577
|
+
const v = buf[p] | buf[p + 1] << 8;
|
|
2578
|
+
result.push(v > 32767 ? v - 65536 : v);
|
|
2579
|
+
}
|
|
2580
|
+
return result;
|
|
2581
|
+
}
|
|
2582
|
+
case 130 /* PACKED_INT32 */: {
|
|
2583
|
+
const count = readVarint();
|
|
2584
|
+
const result = [];
|
|
2585
|
+
for (let i = 0; i < count; i++) {
|
|
2586
|
+
const p = pos;
|
|
2587
|
+
pos += 4;
|
|
2588
|
+
result.push(buf[p] | buf[p + 1] << 8 | buf[p + 2] << 16 | buf[p + 3] << 24);
|
|
2589
|
+
}
|
|
2590
|
+
return result;
|
|
2591
|
+
}
|
|
2592
|
+
case 131 /* PACKED_FLOAT32 */: {
|
|
2593
|
+
const count = readVarint();
|
|
2594
|
+
const result = [];
|
|
2595
|
+
for (let i = 0; i < count; i++) {
|
|
2596
|
+
result.push(view.getFloat32(pos, true));
|
|
2597
|
+
pos += 4;
|
|
2598
|
+
}
|
|
2599
|
+
return result;
|
|
2600
|
+
}
|
|
2601
|
+
case 132 /* PACKED_FLOAT64 */: {
|
|
2602
|
+
const count = readVarint();
|
|
2603
|
+
const result = [];
|
|
2604
|
+
for (let i = 0; i < count; i++) {
|
|
2605
|
+
result.push(view.getFloat64(pos, true));
|
|
2606
|
+
pos += 8;
|
|
2607
|
+
}
|
|
2608
|
+
return result;
|
|
2609
|
+
}
|
|
2610
|
+
default:
|
|
2611
|
+
throw new BoomError(`Unknown type: 0x${type2.toString(16)}`);
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
return readValue();
|
|
2615
|
+
}
|
|
2616
|
+
var BoomBinaryEncoder = class _BoomBinaryEncoder {
|
|
2617
|
+
writer = new ByteWriter();
|
|
2618
|
+
stringTable = /* @__PURE__ */ new Map();
|
|
2619
|
+
stringCount = 0;
|
|
2620
|
+
options;
|
|
2621
|
+
depth = 0;
|
|
2622
|
+
enableInterning;
|
|
2623
|
+
constructor(options = {}) {
|
|
2624
|
+
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
2625
|
+
this.enableInterning = this.options.enableInterning;
|
|
2626
|
+
}
|
|
2627
|
+
encode(value) {
|
|
2628
|
+
if (this.enableInterning && this.options.maxDepth === 64) {
|
|
2629
|
+
if (Array.isArray(value) && value.length >= 2 && this.isUniformObjectArray(value)) {
|
|
2630
|
+
} else {
|
|
2631
|
+
return fastEncode(value);
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
this.writer = new ByteWriter();
|
|
2635
|
+
this.stringTable = /* @__PURE__ */ new Map();
|
|
2636
|
+
this.stringCount = 0;
|
|
2637
|
+
this.depth = 0;
|
|
2638
|
+
const w = this.writer;
|
|
2639
|
+
if (w.pos + 6 > w.buffer.length) w["grow"](6);
|
|
2640
|
+
const buf = w.buffer;
|
|
2641
|
+
buf[w.pos++] = 66;
|
|
2642
|
+
buf[w.pos++] = 79;
|
|
2643
|
+
buf[w.pos++] = 79;
|
|
2644
|
+
buf[w.pos++] = 77;
|
|
2645
|
+
buf[w.pos++] = VERSION;
|
|
2646
|
+
buf[w.pos++] = 0;
|
|
2647
|
+
this.encodeValue(value);
|
|
2648
|
+
return this.writer.toUint8Array();
|
|
2649
|
+
}
|
|
2650
|
+
encodeValue(value) {
|
|
2651
|
+
if (value === null) {
|
|
2652
|
+
this.writer.writeByte(0 /* NULL */);
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
const ctor = value.constructor;
|
|
2656
|
+
if (ctor === String) {
|
|
2657
|
+
this.encodeString(value);
|
|
2658
|
+
return;
|
|
2659
|
+
}
|
|
2660
|
+
if (ctor === Number) {
|
|
2661
|
+
this.encodeNumber(value);
|
|
2662
|
+
return;
|
|
2663
|
+
}
|
|
2664
|
+
if (ctor === Array) {
|
|
2665
|
+
this.encodeArray(value);
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2668
|
+
if (ctor === Object) {
|
|
2669
|
+
this.encodeObject(value);
|
|
2670
|
+
return;
|
|
2671
|
+
}
|
|
2672
|
+
if (ctor === Boolean) {
|
|
2673
|
+
this.writer.writeByte(value ? 2 /* TRUE */ : 1 /* FALSE */);
|
|
2674
|
+
return;
|
|
2675
|
+
}
|
|
2676
|
+
if (value instanceof Uint8Array) {
|
|
2677
|
+
this.encodeBinary(value);
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
if (typeof value === "bigint") {
|
|
2681
|
+
this.encodeBigInt(value);
|
|
2682
|
+
return;
|
|
2683
|
+
}
|
|
2684
|
+
if (value === void 0) {
|
|
2685
|
+
this.writer.writeByte(0 /* NULL */);
|
|
2686
|
+
return;
|
|
2687
|
+
}
|
|
2688
|
+
throw new BoomError(`Unsupported type: ${typeof value}`);
|
|
2689
|
+
}
|
|
2690
|
+
encodeNumber(value) {
|
|
2691
|
+
const w = this.writer;
|
|
2692
|
+
if ((value | 0) === value) {
|
|
2693
|
+
if (value >= -128 && value <= 127) {
|
|
2694
|
+
if (w.pos + 2 > w.buffer.length) w["grow"](2);
|
|
2695
|
+
w.buffer[w.pos++] = 16 /* INT8 */;
|
|
2696
|
+
w.buffer[w.pos++] = value & 255;
|
|
2697
|
+
} else if (value >= -32768 && value <= 32767) {
|
|
2698
|
+
if (w.pos + 3 > w.buffer.length) w["grow"](3);
|
|
2699
|
+
const buf = w.buffer;
|
|
2700
|
+
buf[w.pos++] = 17 /* INT16 */;
|
|
2701
|
+
buf[w.pos++] = value & 255;
|
|
2702
|
+
buf[w.pos++] = value >> 8 & 255;
|
|
2703
|
+
} else {
|
|
2704
|
+
if (w.pos + 5 > w.buffer.length) w["grow"](5);
|
|
2705
|
+
const buf = w.buffer;
|
|
2706
|
+
buf[w.pos++] = 18 /* INT32 */;
|
|
2707
|
+
buf[w.pos++] = value & 255;
|
|
2708
|
+
buf[w.pos++] = value >> 8 & 255;
|
|
2709
|
+
buf[w.pos++] = value >> 16 & 255;
|
|
2710
|
+
buf[w.pos++] = value >> 24 & 255;
|
|
2711
|
+
}
|
|
2712
|
+
} else {
|
|
2713
|
+
w.writeByte(33 /* FLOAT64 */);
|
|
2714
|
+
w.writeFloat64LE(value);
|
|
2715
|
+
}
|
|
2716
|
+
}
|
|
2717
|
+
encodeBigInt(value) {
|
|
2718
|
+
if (value >= 0n && value <= 0xFFFFFFFFFFFFFFFFn) {
|
|
2719
|
+
this.writer.writeByte(23 /* UINT64 */);
|
|
2720
|
+
this.writer.writeBigUInt64LE(value);
|
|
2721
|
+
} else if (value >= -0x8000000000000000n && value <= 0x7FFFFFFFFFFFFFFFn) {
|
|
2722
|
+
this.writer.writeByte(19 /* INT64 */);
|
|
2723
|
+
this.writer.writeBigInt64LE(value);
|
|
2724
|
+
} else {
|
|
2725
|
+
throw new BoomError("BigInt out of range for int64/uint64");
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
// Reuse TextEncoder for performance
|
|
2729
|
+
static textEncoder = new TextEncoder();
|
|
2730
|
+
encodeString(value) {
|
|
2731
|
+
const dictIdx = DICTIONARY_LOOKUP.get(value);
|
|
2732
|
+
if (dictIdx !== void 0) {
|
|
2733
|
+
const w = this.writer;
|
|
2734
|
+
if (w.pos + 4 > w.buffer.length) w["grow"](4);
|
|
2735
|
+
w.buffer[w.pos++] = 97 /* DICT_REF */;
|
|
2736
|
+
if (dictIdx < 128) {
|
|
2737
|
+
w.buffer[w.pos++] = dictIdx;
|
|
2738
|
+
} else {
|
|
2739
|
+
w.writeVarint(dictIdx);
|
|
2740
|
+
}
|
|
2741
|
+
return;
|
|
2742
|
+
}
|
|
2743
|
+
if (this.enableInterning) {
|
|
2744
|
+
const existingIndex = this.stringTable.get(value);
|
|
2745
|
+
if (existingIndex !== void 0) {
|
|
2746
|
+
const w = this.writer;
|
|
2747
|
+
if (w.pos + 6 > w.buffer.length) w["grow"](6);
|
|
2748
|
+
w.buffer[w.pos++] = 96 /* REF */;
|
|
2749
|
+
if (existingIndex < 128) {
|
|
2750
|
+
w.buffer[w.pos++] = existingIndex;
|
|
2751
|
+
} else {
|
|
2752
|
+
w.writeVarint(existingIndex);
|
|
2753
|
+
}
|
|
2754
|
+
return;
|
|
2755
|
+
}
|
|
2756
|
+
this.stringTable.set(value, this.stringCount++);
|
|
2757
|
+
}
|
|
2758
|
+
const len = value.length;
|
|
2759
|
+
if (len < 64) {
|
|
2760
|
+
let isAscii2 = true;
|
|
2761
|
+
for (let i = 0; i < len; i++) {
|
|
2762
|
+
if (value.charCodeAt(i) > 127) {
|
|
2763
|
+
isAscii2 = false;
|
|
2764
|
+
break;
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
if (isAscii2) {
|
|
2768
|
+
const w = this.writer;
|
|
2769
|
+
const needed = 2 + len;
|
|
2770
|
+
if (w.pos + needed > w.buffer.length) w["grow"](needed);
|
|
2771
|
+
const buf = w.buffer;
|
|
2772
|
+
buf[w.pos++] = 48 /* STRING */;
|
|
2773
|
+
buf[w.pos++] = len;
|
|
2774
|
+
for (let i = 0; i < len; i++) {
|
|
2775
|
+
buf[w.pos++] = value.charCodeAt(i);
|
|
2776
|
+
}
|
|
2777
|
+
return;
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
const bytes = _BoomBinaryEncoder.textEncoder.encode(value);
|
|
2781
|
+
this.writer.writeByte(48 /* STRING */);
|
|
2782
|
+
this.writer.writeVarint(bytes.length);
|
|
2783
|
+
this.writer.write(bytes);
|
|
2784
|
+
}
|
|
2785
|
+
encodeBinary(value) {
|
|
2786
|
+
this.writer.writeByte(49 /* BINARY */);
|
|
2787
|
+
this.writer.writeVarint(value.length);
|
|
2788
|
+
this.writer.write(value);
|
|
2789
|
+
}
|
|
2790
|
+
encodeArray(value) {
|
|
2791
|
+
if (value.length > this.options.maxArrayLength) {
|
|
2792
|
+
throw new BoomError(`Array exceeds maximum length of ${this.options.maxArrayLength}`);
|
|
2793
|
+
}
|
|
2794
|
+
this.depth++;
|
|
2795
|
+
if (this.depth > this.options.maxDepth) {
|
|
2796
|
+
throw new BoomError(`Maximum nesting depth of ${this.options.maxDepth} exceeded`);
|
|
2797
|
+
}
|
|
2798
|
+
if (value.length >= 2 && this.isUniformObjectArray(value)) {
|
|
2799
|
+
this.encodeColumnar(value);
|
|
2800
|
+
this.depth--;
|
|
2801
|
+
return;
|
|
2802
|
+
}
|
|
2803
|
+
if (value.length >= 4) {
|
|
2804
|
+
const packedResult = this.tryPackedArray(value);
|
|
2805
|
+
if (packedResult) {
|
|
2806
|
+
this.writer.write(packedResult);
|
|
2807
|
+
this.depth--;
|
|
2808
|
+
return;
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
this.writer.writeByte(64 /* ARRAY */);
|
|
2812
|
+
this.writer.writeVarint(value.length);
|
|
2813
|
+
for (const item of value) {
|
|
2814
|
+
this.encodeValue(item);
|
|
2815
|
+
}
|
|
2816
|
+
this.depth--;
|
|
2817
|
+
}
|
|
2818
|
+
isUniformObjectArray(arr) {
|
|
2819
|
+
if (arr.length < 2) return false;
|
|
2820
|
+
const first = arr[0];
|
|
2821
|
+
if (typeof first !== "object" || first === null || Array.isArray(first) || first instanceof Uint8Array) {
|
|
2822
|
+
return false;
|
|
2823
|
+
}
|
|
2824
|
+
const keys = Object.keys(first);
|
|
2825
|
+
const keyCount = keys.length;
|
|
2826
|
+
if (keyCount === 0) return false;
|
|
2827
|
+
const keySet = new Set(keys);
|
|
2828
|
+
for (let i = 1; i < arr.length; i++) {
|
|
2829
|
+
const item = arr[i];
|
|
2830
|
+
if (typeof item !== "object" || item === null || Array.isArray(item) || item instanceof Uint8Array) {
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
const itemKeys = Object.keys(item);
|
|
2834
|
+
if (itemKeys.length !== keyCount) return false;
|
|
2835
|
+
for (let j = 0; j < keyCount; j++) {
|
|
2836
|
+
if (!keySet.has(itemKeys[j])) return false;
|
|
2837
|
+
}
|
|
2838
|
+
}
|
|
2839
|
+
return true;
|
|
2840
|
+
}
|
|
2841
|
+
/**
|
|
2842
|
+
* Column-major table encoding for optimal compression.
|
|
2843
|
+
* Instead of encoding row-by-row: row1[col1,col2], row2[col1,col2]...
|
|
2844
|
+
* We encode column-by-column: col1[row1,row2...], col2[row1,row2...]...
|
|
2845
|
+
*
|
|
2846
|
+
* This dramatically improves compression because:
|
|
2847
|
+
* 1. All integers are grouped together (compressors see patterns)
|
|
2848
|
+
* 2. All strings are grouped together (repeated patterns found)
|
|
2849
|
+
* 3. All booleans can be bit-packed efficiently
|
|
2850
|
+
* 4. Type markers are at the start, not scattered throughout
|
|
2851
|
+
*/
|
|
2852
|
+
encodeColumnar(rows) {
|
|
2853
|
+
const keys = Object.keys(rows[0]);
|
|
2854
|
+
this.writer.writeByte(115 /* COLUMNAR */);
|
|
2855
|
+
this.writer.writeVarint(rows.length);
|
|
2856
|
+
this.writer.writeVarint(keys.length);
|
|
2857
|
+
const textEncoder2 = _BoomBinaryEncoder.textEncoder;
|
|
2858
|
+
for (const key of keys) {
|
|
2859
|
+
const bytes = textEncoder2.encode(key);
|
|
2860
|
+
this.writer.writeVarint(bytes.length);
|
|
2861
|
+
this.writer.write(bytes);
|
|
2862
|
+
}
|
|
2863
|
+
const columnInfos = keys.map((key) => {
|
|
2864
|
+
let allInt8 = true, allInt16 = true, allInt32 = true;
|
|
2865
|
+
let allFloat = true, allBool = true, allString = true;
|
|
2866
|
+
const firstVal = rows[0][key];
|
|
2867
|
+
let isConstant = true;
|
|
2868
|
+
for (const row of rows) {
|
|
2869
|
+
const val = row[key];
|
|
2870
|
+
if (isConstant && val !== firstVal) {
|
|
2871
|
+
if (typeof val !== typeof firstVal || JSON.stringify(val) !== JSON.stringify(firstVal)) {
|
|
2872
|
+
isConstant = false;
|
|
2873
|
+
}
|
|
2874
|
+
}
|
|
2875
|
+
if (typeof val !== "boolean") allBool = false;
|
|
2876
|
+
if (typeof val !== "string") allString = false;
|
|
2877
|
+
if (typeof val !== "number") {
|
|
2878
|
+
allInt8 = allInt16 = allInt32 = allFloat = false;
|
|
2879
|
+
} else if (!Number.isInteger(val)) {
|
|
2880
|
+
allInt8 = allInt16 = allInt32 = false;
|
|
2881
|
+
} else {
|
|
2882
|
+
if (val < -128 || val > 127) allInt8 = false;
|
|
2883
|
+
if (val < -32768 || val > 32767) allInt16 = false;
|
|
2884
|
+
if (val < -2147483648 || val > 2147483647) allInt32 = false;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
const baseType = allBool ? "bool" : allInt8 ? "int8" : allInt16 ? "int16" : allInt32 ? "int32" : allFloat ? "float" : allString ? "string" : "mixed";
|
|
2888
|
+
return {
|
|
2889
|
+
type: baseType,
|
|
2890
|
+
isConstant: isConstant && rows.length > 1,
|
|
2891
|
+
// Only use RLE if more than 1 row
|
|
2892
|
+
constantValue: isConstant ? firstVal : void 0
|
|
2893
|
+
};
|
|
2894
|
+
});
|
|
2895
|
+
for (const colInfo of columnInfos) {
|
|
2896
|
+
if (colInfo.isConstant) {
|
|
2897
|
+
this.writer.writeByte(116 /* RLE_CONST */);
|
|
2898
|
+
} else {
|
|
2899
|
+
const typeMarker = colInfo.type === "bool" ? 133 /* PACKED_BOOL */ : colInfo.type === "int8" ? 128 /* PACKED_INT8 */ : colInfo.type === "int16" ? 129 /* PACKED_INT16 */ : colInfo.type === "int32" ? 130 /* PACKED_INT32 */ : colInfo.type === "float" ? 132 /* PACKED_FLOAT64 */ : colInfo.type === "string" ? 48 /* STRING */ : 64 /* ARRAY */;
|
|
2900
|
+
this.writer.writeByte(typeMarker);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
for (let colIdx = 0; colIdx < keys.length; colIdx++) {
|
|
2904
|
+
const key = keys[colIdx];
|
|
2905
|
+
const colInfo = columnInfos[colIdx];
|
|
2906
|
+
if (colInfo.isConstant) {
|
|
2907
|
+
this.encodeValue(colInfo.constantValue);
|
|
2908
|
+
continue;
|
|
2909
|
+
}
|
|
2910
|
+
switch (colInfo.type) {
|
|
2911
|
+
case "bool":
|
|
2912
|
+
for (let i = 0; i < rows.length; i += 8) {
|
|
2913
|
+
let byte = 0;
|
|
2914
|
+
for (let j = 0; j < 8 && i + j < rows.length; j++) {
|
|
2915
|
+
if (rows[i + j][key]) byte |= 1 << j;
|
|
2916
|
+
}
|
|
2917
|
+
this.writer.writeByte(byte);
|
|
2918
|
+
}
|
|
2919
|
+
break;
|
|
2920
|
+
case "int8":
|
|
2921
|
+
for (const row of rows) {
|
|
2922
|
+
this.writer.writeInt8(row[key]);
|
|
2923
|
+
}
|
|
2924
|
+
break;
|
|
2925
|
+
case "int16":
|
|
2926
|
+
for (const row of rows) {
|
|
2927
|
+
this.writer.writeInt16LE(row[key]);
|
|
2928
|
+
}
|
|
2929
|
+
break;
|
|
2930
|
+
case "int32":
|
|
2931
|
+
for (const row of rows) {
|
|
2932
|
+
this.writer.writeInt32LE(row[key]);
|
|
2933
|
+
}
|
|
2934
|
+
break;
|
|
2935
|
+
case "float":
|
|
2936
|
+
for (const row of rows) {
|
|
2937
|
+
this.writer.writeFloat64LE(row[key]);
|
|
2938
|
+
}
|
|
2939
|
+
break;
|
|
2940
|
+
case "string":
|
|
2941
|
+
for (const row of rows) {
|
|
2942
|
+
this.encodeString(row[key]);
|
|
2943
|
+
}
|
|
2944
|
+
break;
|
|
2945
|
+
default:
|
|
2946
|
+
for (const row of rows) {
|
|
2947
|
+
this.encodeValue(row[key]);
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
}
|
|
2952
|
+
tryPackedArray(arr) {
|
|
2953
|
+
let allInt8 = true, allInt16 = true, allInt32 = true;
|
|
2954
|
+
let allFloat32 = true, allBool = true;
|
|
2955
|
+
for (const item of arr) {
|
|
2956
|
+
if (typeof item === "boolean") {
|
|
2957
|
+
allInt8 = allInt16 = allInt32 = allFloat32 = false;
|
|
2958
|
+
} else if (typeof item === "number") {
|
|
2959
|
+
allBool = false;
|
|
2960
|
+
if (!Number.isInteger(item)) {
|
|
2961
|
+
allInt8 = allInt16 = allInt32 = false;
|
|
2962
|
+
const f32 = new Float32Array([item])[0];
|
|
2963
|
+
if (f32 !== item) allFloat32 = false;
|
|
2964
|
+
} else {
|
|
2965
|
+
allFloat32 = false;
|
|
2966
|
+
if (item < -128 || item > 127) allInt8 = false;
|
|
2967
|
+
if (item < -32768 || item > 32767) allInt16 = false;
|
|
2968
|
+
if (item < -2147483648 || item > 2147483647) allInt32 = false;
|
|
2969
|
+
}
|
|
2970
|
+
} else {
|
|
2971
|
+
return null;
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
const writer = new ByteWriter();
|
|
2975
|
+
if (allBool) {
|
|
2976
|
+
writer.writeByte(133 /* PACKED_BOOL */);
|
|
2977
|
+
writer.writeVarint(arr.length);
|
|
2978
|
+
for (let i = 0; i < arr.length; i += 8) {
|
|
2979
|
+
let byte = 0;
|
|
2980
|
+
for (let j = 0; j < 8 && i + j < arr.length; j++) {
|
|
2981
|
+
if (arr[i + j]) byte |= 1 << j;
|
|
2982
|
+
}
|
|
2983
|
+
writer.writeByte(byte);
|
|
2984
|
+
}
|
|
2985
|
+
return writer.toUint8Array();
|
|
2986
|
+
}
|
|
2987
|
+
if (allInt8) {
|
|
2988
|
+
writer.writeByte(128 /* PACKED_INT8 */);
|
|
2989
|
+
writer.writeVarint(arr.length);
|
|
2990
|
+
for (const item of arr) {
|
|
2991
|
+
writer.writeInt8(item);
|
|
2992
|
+
}
|
|
2993
|
+
return writer.toUint8Array();
|
|
2994
|
+
}
|
|
2995
|
+
if (allInt16) {
|
|
2996
|
+
writer.writeByte(129 /* PACKED_INT16 */);
|
|
2997
|
+
writer.writeVarint(arr.length);
|
|
2998
|
+
for (const item of arr) {
|
|
2999
|
+
writer.writeInt16LE(item);
|
|
3000
|
+
}
|
|
3001
|
+
return writer.toUint8Array();
|
|
3002
|
+
}
|
|
3003
|
+
if (allInt32) {
|
|
3004
|
+
writer.writeByte(130 /* PACKED_INT32 */);
|
|
3005
|
+
writer.writeVarint(arr.length);
|
|
3006
|
+
for (const item of arr) {
|
|
3007
|
+
writer.writeInt32LE(item);
|
|
3008
|
+
}
|
|
3009
|
+
return writer.toUint8Array();
|
|
3010
|
+
}
|
|
3011
|
+
if (allFloat32) {
|
|
3012
|
+
writer.writeByte(131 /* PACKED_FLOAT32 */);
|
|
3013
|
+
writer.writeVarint(arr.length);
|
|
3014
|
+
for (const item of arr) {
|
|
3015
|
+
writer.writeFloat32LE(item);
|
|
3016
|
+
}
|
|
3017
|
+
return writer.toUint8Array();
|
|
3018
|
+
}
|
|
3019
|
+
return null;
|
|
3020
|
+
}
|
|
3021
|
+
encodeObject(value) {
|
|
3022
|
+
const keys = Object.keys(value);
|
|
3023
|
+
if (keys.length > this.options.maxArrayLength) {
|
|
3024
|
+
throw new BoomError(`Object exceeds maximum key count of ${this.options.maxArrayLength}`);
|
|
3025
|
+
}
|
|
3026
|
+
this.depth++;
|
|
3027
|
+
if (this.depth > this.options.maxDepth) {
|
|
3028
|
+
throw new BoomError(`Maximum nesting depth of ${this.options.maxDepth} exceeded`);
|
|
3029
|
+
}
|
|
3030
|
+
this.writer.writeByte(80 /* OBJECT */);
|
|
3031
|
+
this.writer.writeVarint(keys.length);
|
|
3032
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3033
|
+
const key = keys[i];
|
|
3034
|
+
this.encodeString(key);
|
|
3035
|
+
this.encodeValue(value[key]);
|
|
3036
|
+
}
|
|
3037
|
+
this.depth--;
|
|
3038
|
+
}
|
|
3039
|
+
};
|
|
3040
|
+
var BoomBinaryDecoder = class _BoomBinaryDecoder {
|
|
3041
|
+
reader;
|
|
3042
|
+
stringTable = [];
|
|
3043
|
+
options;
|
|
3044
|
+
depth = 0;
|
|
3045
|
+
enableInterning;
|
|
3046
|
+
// Reuse TextDecoder for performance
|
|
3047
|
+
static textDecoder = new TextDecoder();
|
|
3048
|
+
constructor(options = {}) {
|
|
3049
|
+
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
3050
|
+
this.enableInterning = this.options.enableInterning;
|
|
3051
|
+
}
|
|
3052
|
+
decode(buffer) {
|
|
3053
|
+
if (this.enableInterning && this.options.maxDepth === 64) {
|
|
3054
|
+
return fastDecode(buffer);
|
|
3055
|
+
}
|
|
3056
|
+
if (buffer.length < 6 || buffer[0] !== 66 || buffer[1] !== 79 || buffer[2] !== 79 || buffer[3] !== 77) {
|
|
3057
|
+
throw new BoomError("Invalid BOOM header");
|
|
3058
|
+
}
|
|
3059
|
+
if (buffer[4] !== VERSION) {
|
|
3060
|
+
throw new BoomError(`Unsupported BOOM version: ${buffer[4]}`);
|
|
3061
|
+
}
|
|
3062
|
+
this.reader = new ByteReader(buffer);
|
|
3063
|
+
this.reader.offset = 6;
|
|
3064
|
+
this.stringTable = [];
|
|
3065
|
+
this.depth = 0;
|
|
3066
|
+
return this.decodeValue();
|
|
3067
|
+
}
|
|
3068
|
+
decodeValue() {
|
|
3069
|
+
const r = this.reader;
|
|
3070
|
+
const type = r.readByte();
|
|
3071
|
+
if (type === 48 /* STRING */) return this.decodeString();
|
|
3072
|
+
if (type === 16 /* INT8 */) return r.readInt8();
|
|
3073
|
+
if (type === 18 /* INT32 */) return r.readInt32LE();
|
|
3074
|
+
if (type === 80 /* OBJECT */) return this.decodeObject();
|
|
3075
|
+
if (type === 64 /* ARRAY */) return this.decodeArray();
|
|
3076
|
+
if (type === 96 /* REF */) return this.stringTable[r.readVarint()];
|
|
3077
|
+
if (type === 0 /* NULL */) return null;
|
|
3078
|
+
if (type === 2 /* TRUE */) return true;
|
|
3079
|
+
if (type === 1 /* FALSE */) return false;
|
|
3080
|
+
if (type === 17 /* INT16 */) return r.readInt16LE();
|
|
3081
|
+
if (type === 33 /* FLOAT64 */) return r.readFloat64LE();
|
|
3082
|
+
switch (type) {
|
|
3083
|
+
case 19 /* INT64 */:
|
|
3084
|
+
return r.readBigInt64LE();
|
|
3085
|
+
case 20 /* UINT8 */:
|
|
3086
|
+
return r.readUInt8();
|
|
3087
|
+
case 21 /* UINT16 */:
|
|
3088
|
+
return r.readUInt16LE();
|
|
3089
|
+
case 22 /* UINT32 */:
|
|
3090
|
+
return r.readUInt32LE();
|
|
3091
|
+
case 23 /* UINT64 */:
|
|
3092
|
+
return r.readBigUInt64LE();
|
|
3093
|
+
case 24 /* VARINT */:
|
|
3094
|
+
return r.readVarint();
|
|
3095
|
+
case 25 /* SVARINT */:
|
|
3096
|
+
return zigzagDecode(r.readVarint());
|
|
3097
|
+
case 32 /* FLOAT32 */:
|
|
3098
|
+
return r.readFloat32LE();
|
|
3099
|
+
case 49 /* BINARY */:
|
|
3100
|
+
return this.decodeBinary();
|
|
3101
|
+
case 112 /* TABLE */:
|
|
3102
|
+
return this.decodeTable();
|
|
3103
|
+
case 115 /* COLUMNAR */:
|
|
3104
|
+
return this.decodeColumnar();
|
|
3105
|
+
case 133 /* PACKED_BOOL */:
|
|
3106
|
+
return this.decodePackedBool();
|
|
3107
|
+
case 128 /* PACKED_INT8 */:
|
|
3108
|
+
return this.decodePackedInt8();
|
|
3109
|
+
case 129 /* PACKED_INT16 */:
|
|
3110
|
+
return this.decodePackedInt16();
|
|
3111
|
+
case 130 /* PACKED_INT32 */:
|
|
3112
|
+
return this.decodePackedInt32();
|
|
3113
|
+
case 131 /* PACKED_FLOAT32 */:
|
|
3114
|
+
return this.decodePackedFloat32();
|
|
3115
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
3116
|
+
return this.decodePackedFloat64();
|
|
3117
|
+
default:
|
|
3118
|
+
throw new BoomError(`Unknown type marker: 0x${type.toString(16)}`);
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
decodeString() {
|
|
3122
|
+
const r = this.reader;
|
|
3123
|
+
const length = r.readVarint();
|
|
3124
|
+
if (length < 64) {
|
|
3125
|
+
const bytes2 = r.readBytes(length);
|
|
3126
|
+
let isAscii2 = true;
|
|
3127
|
+
for (let i = 0; i < length; i++) {
|
|
3128
|
+
if (bytes2[i] > 127) {
|
|
3129
|
+
isAscii2 = false;
|
|
3130
|
+
break;
|
|
3131
|
+
}
|
|
3132
|
+
}
|
|
3133
|
+
if (isAscii2) {
|
|
3134
|
+
let str3 = "";
|
|
3135
|
+
for (let i = 0; i < length; i++) {
|
|
3136
|
+
str3 += String.fromCharCode(bytes2[i]);
|
|
3137
|
+
}
|
|
3138
|
+
if (this.enableInterning) this.stringTable.push(str3);
|
|
3139
|
+
return str3;
|
|
3140
|
+
}
|
|
3141
|
+
const str2 = _BoomBinaryDecoder.textDecoder.decode(bytes2);
|
|
3142
|
+
if (this.enableInterning) this.stringTable.push(str2);
|
|
3143
|
+
return str2;
|
|
3144
|
+
}
|
|
3145
|
+
const bytes = r.readBytes(length);
|
|
3146
|
+
const str = _BoomBinaryDecoder.textDecoder.decode(bytes);
|
|
3147
|
+
if (this.enableInterning) this.stringTable.push(str);
|
|
3148
|
+
return str;
|
|
3149
|
+
}
|
|
3150
|
+
decodeBinary() {
|
|
3151
|
+
const length = this.reader.readVarint();
|
|
3152
|
+
return new Uint8Array(this.reader.readBytes(length));
|
|
3153
|
+
}
|
|
3154
|
+
decodeArray() {
|
|
3155
|
+
const r = this.reader;
|
|
3156
|
+
const count = r.readVarint();
|
|
3157
|
+
this.depth++;
|
|
3158
|
+
const arr = new Array(count);
|
|
3159
|
+
for (let i = 0; i < count; i++) {
|
|
3160
|
+
arr[i] = this.decodeValue();
|
|
3161
|
+
}
|
|
3162
|
+
this.depth--;
|
|
3163
|
+
return arr;
|
|
3164
|
+
}
|
|
3165
|
+
decodeObject() {
|
|
3166
|
+
const r = this.reader;
|
|
3167
|
+
const count = r.readVarint();
|
|
3168
|
+
const stringTable = this.stringTable;
|
|
3169
|
+
this.depth++;
|
|
3170
|
+
const obj = {};
|
|
3171
|
+
for (let i = 0; i < count; i++) {
|
|
3172
|
+
const keyType = r.readByte();
|
|
3173
|
+
const key = keyType === 48 /* STRING */ ? this.decodeString() : keyType === 96 /* REF */ ? stringTable[r.readVarint()] : keyType === 97 /* DICT_REF */ ? BOOM_DICTIONARY_V1[r.readVarint()] : (() => {
|
|
3174
|
+
throw new BoomError(`Invalid key type: 0x${keyType.toString(16)}`);
|
|
3175
|
+
})();
|
|
3176
|
+
obj[key] = this.decodeValue();
|
|
3177
|
+
}
|
|
3178
|
+
this.depth--;
|
|
3179
|
+
return obj;
|
|
3180
|
+
}
|
|
3181
|
+
decodeRef() {
|
|
3182
|
+
return this.stringTable[this.reader.readVarint()];
|
|
3183
|
+
}
|
|
3184
|
+
decodeTable() {
|
|
3185
|
+
const rowCount = this.reader.readVarint();
|
|
3186
|
+
const colCount = this.reader.readVarint();
|
|
3187
|
+
const keys = [];
|
|
3188
|
+
for (let i = 0; i < colCount; i++) {
|
|
3189
|
+
const keyType = this.reader.readByte();
|
|
3190
|
+
if (keyType === 48 /* STRING */) {
|
|
3191
|
+
keys.push(this.decodeString());
|
|
3192
|
+
} else if (keyType === 96 /* REF */) {
|
|
3193
|
+
keys.push(this.decodeRef());
|
|
3194
|
+
} else if (keyType === 97 /* DICT_REF */) {
|
|
3195
|
+
keys.push(BOOM_DICTIONARY_V1[this.reader.readVarint()]);
|
|
3196
|
+
} else {
|
|
3197
|
+
throw new BoomError(`Invalid table column name type: 0x${keyType.toString(16)}`);
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
const colSchemas = [];
|
|
3201
|
+
for (let i = 0; i < colCount; i++) {
|
|
3202
|
+
const colType = this.reader.readByte();
|
|
3203
|
+
const schema = { type: colType };
|
|
3204
|
+
if (colType === 114 /* NESTED_OBJECT */) {
|
|
3205
|
+
const nestedColCount = this.reader.readVarint();
|
|
3206
|
+
schema.nestedKeys = [];
|
|
3207
|
+
schema.nestedTypes = [];
|
|
3208
|
+
for (let j = 0; j < nestedColCount; j++) {
|
|
3209
|
+
const nestedKeyType = this.reader.readByte();
|
|
3210
|
+
if (nestedKeyType === 48 /* STRING */) {
|
|
3211
|
+
schema.nestedKeys.push(this.decodeString());
|
|
3212
|
+
} else if (nestedKeyType === 96 /* REF */) {
|
|
3213
|
+
schema.nestedKeys.push(this.decodeRef());
|
|
3214
|
+
} else if (nestedKeyType === 97 /* DICT_REF */) {
|
|
3215
|
+
schema.nestedKeys.push(BOOM_DICTIONARY_V1[this.reader.readVarint()]);
|
|
3216
|
+
} else {
|
|
3217
|
+
throw new BoomError(`Invalid nested key type: 0x${nestedKeyType.toString(16)}`);
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3220
|
+
for (let j = 0; j < nestedColCount; j++) {
|
|
3221
|
+
schema.nestedTypes.push(this.reader.readByte());
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
colSchemas.push(schema);
|
|
3225
|
+
}
|
|
3226
|
+
const rows = [];
|
|
3227
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3228
|
+
const row = {};
|
|
3229
|
+
for (let c = 0; c < colCount; c++) {
|
|
3230
|
+
const key = keys[c];
|
|
3231
|
+
const schema = colSchemas[c];
|
|
3232
|
+
switch (schema.type) {
|
|
3233
|
+
case 133 /* PACKED_BOOL */:
|
|
3234
|
+
row[key] = this.reader.readByte() !== 0;
|
|
3235
|
+
break;
|
|
3236
|
+
case 128 /* PACKED_INT8 */:
|
|
3237
|
+
row[key] = this.reader.readInt8();
|
|
3238
|
+
break;
|
|
3239
|
+
case 129 /* PACKED_INT16 */:
|
|
3240
|
+
row[key] = this.reader.readInt16LE();
|
|
3241
|
+
break;
|
|
3242
|
+
case 130 /* PACKED_INT32 */:
|
|
3243
|
+
row[key] = this.reader.readInt32LE();
|
|
3244
|
+
break;
|
|
3245
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
3246
|
+
row[key] = this.reader.readFloat64LE();
|
|
3247
|
+
break;
|
|
3248
|
+
case 48 /* STRING */: {
|
|
3249
|
+
const strType = this.reader.readByte();
|
|
3250
|
+
if (strType === 48 /* STRING */) {
|
|
3251
|
+
row[key] = this.decodeString();
|
|
3252
|
+
} else if (strType === 96 /* REF */) {
|
|
3253
|
+
row[key] = this.decodeRef();
|
|
3254
|
+
} else if (strType === 97 /* DICT_REF */) {
|
|
3255
|
+
row[key] = BOOM_DICTIONARY_V1[this.reader.readVarint()];
|
|
3256
|
+
} else {
|
|
3257
|
+
throw new BoomError(`Invalid string type in table: 0x${strType.toString(16)}`);
|
|
3258
|
+
}
|
|
3259
|
+
break;
|
|
3260
|
+
}
|
|
3261
|
+
case 114 /* NESTED_OBJECT */: {
|
|
3262
|
+
const nestedObj = {};
|
|
3263
|
+
for (let j = 0; j < schema.nestedKeys.length; j++) {
|
|
3264
|
+
const nestedKey = schema.nestedKeys[j];
|
|
3265
|
+
const nestedType = schema.nestedTypes[j];
|
|
3266
|
+
switch (nestedType) {
|
|
3267
|
+
case 133 /* PACKED_BOOL */:
|
|
3268
|
+
nestedObj[nestedKey] = this.reader.readByte() !== 0;
|
|
3269
|
+
break;
|
|
3270
|
+
case 128 /* PACKED_INT8 */:
|
|
3271
|
+
nestedObj[nestedKey] = this.reader.readInt8();
|
|
3272
|
+
break;
|
|
3273
|
+
case 129 /* PACKED_INT16 */:
|
|
3274
|
+
nestedObj[nestedKey] = this.reader.readInt16LE();
|
|
3275
|
+
break;
|
|
3276
|
+
case 130 /* PACKED_INT32 */:
|
|
3277
|
+
nestedObj[nestedKey] = this.reader.readInt32LE();
|
|
3278
|
+
break;
|
|
3279
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
3280
|
+
nestedObj[nestedKey] = this.reader.readFloat64LE();
|
|
3281
|
+
break;
|
|
3282
|
+
case 48 /* STRING */: {
|
|
3283
|
+
const strType = this.reader.readByte();
|
|
3284
|
+
if (strType === 48 /* STRING */) {
|
|
3285
|
+
nestedObj[nestedKey] = this.decodeString();
|
|
3286
|
+
} else if (strType === 96 /* REF */) {
|
|
3287
|
+
nestedObj[nestedKey] = this.decodeRef();
|
|
3288
|
+
} else if (strType === 97 /* DICT_REF */) {
|
|
3289
|
+
nestedObj[nestedKey] = BOOM_DICTIONARY_V1[this.reader.readVarint()];
|
|
3290
|
+
} else {
|
|
3291
|
+
throw new BoomError(`Invalid nested string type: 0x${strType.toString(16)}`);
|
|
3292
|
+
}
|
|
3293
|
+
break;
|
|
3294
|
+
}
|
|
3295
|
+
default:
|
|
3296
|
+
nestedObj[nestedKey] = this.decodeValue();
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
row[key] = nestedObj;
|
|
3300
|
+
break;
|
|
3301
|
+
}
|
|
3302
|
+
case 113 /* NESTED_TABLE */: {
|
|
3303
|
+
const itemCount = this.reader.readVarint();
|
|
3304
|
+
const nestedArr = [];
|
|
3305
|
+
for (let j = 0; j < itemCount; j++) {
|
|
3306
|
+
nestedArr.push(this.decodeValue());
|
|
3307
|
+
}
|
|
3308
|
+
row[key] = nestedArr;
|
|
3309
|
+
break;
|
|
3310
|
+
}
|
|
3311
|
+
default:
|
|
3312
|
+
row[key] = this.decodeValue();
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
rows.push(row);
|
|
3316
|
+
}
|
|
3317
|
+
return rows;
|
|
3318
|
+
}
|
|
3319
|
+
/**
|
|
3320
|
+
* Decode column-major table format.
|
|
3321
|
+
* Data is stored column-by-column for better compression.
|
|
3322
|
+
*/
|
|
3323
|
+
decodeColumnar() {
|
|
3324
|
+
const rowCount = this.reader.readVarint();
|
|
3325
|
+
const colCount = this.reader.readVarint();
|
|
3326
|
+
const keys = [];
|
|
3327
|
+
for (let i = 0; i < colCount; i++) {
|
|
3328
|
+
const len = this.reader.readVarint();
|
|
3329
|
+
const bytes = this.reader.readBytes(len);
|
|
3330
|
+
keys.push(_BoomBinaryDecoder.textDecoder.decode(bytes));
|
|
3331
|
+
}
|
|
3332
|
+
const colTypes = [];
|
|
3333
|
+
for (let i = 0; i < colCount; i++) {
|
|
3334
|
+
colTypes.push(this.reader.readByte());
|
|
3335
|
+
}
|
|
3336
|
+
const rows = [];
|
|
3337
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3338
|
+
rows.push({});
|
|
3339
|
+
}
|
|
3340
|
+
for (let c = 0; c < colCount; c++) {
|
|
3341
|
+
const key = keys[c];
|
|
3342
|
+
const colType = colTypes[c];
|
|
3343
|
+
switch (colType) {
|
|
3344
|
+
case 116 /* RLE_CONST */: {
|
|
3345
|
+
const constValue = this.decodeValue();
|
|
3346
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3347
|
+
rows[r][key] = constValue;
|
|
3348
|
+
}
|
|
3349
|
+
break;
|
|
3350
|
+
}
|
|
3351
|
+
case 133 /* PACKED_BOOL */: {
|
|
3352
|
+
for (let i = 0; i < rowCount; i += 8) {
|
|
3353
|
+
const byte = this.reader.readByte();
|
|
3354
|
+
for (let j = 0; j < 8 && i + j < rowCount; j++) {
|
|
3355
|
+
rows[i + j][key] = (byte & 1 << j) !== 0;
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
break;
|
|
3359
|
+
}
|
|
3360
|
+
case 128 /* PACKED_INT8 */:
|
|
3361
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3362
|
+
rows[r][key] = this.reader.readInt8();
|
|
3363
|
+
}
|
|
3364
|
+
break;
|
|
3365
|
+
case 129 /* PACKED_INT16 */:
|
|
3366
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3367
|
+
rows[r][key] = this.reader.readInt16LE();
|
|
3368
|
+
}
|
|
3369
|
+
break;
|
|
3370
|
+
case 130 /* PACKED_INT32 */:
|
|
3371
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3372
|
+
rows[r][key] = this.reader.readInt32LE();
|
|
3373
|
+
}
|
|
3374
|
+
break;
|
|
3375
|
+
case 132 /* PACKED_FLOAT64 */:
|
|
3376
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3377
|
+
rows[r][key] = this.reader.readFloat64LE();
|
|
3378
|
+
}
|
|
3379
|
+
break;
|
|
3380
|
+
case 48 /* STRING */:
|
|
3381
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3382
|
+
const strType = this.reader.readByte();
|
|
3383
|
+
if (strType === 48 /* STRING */) {
|
|
3384
|
+
rows[r][key] = this.decodeString();
|
|
3385
|
+
} else if (strType === 96 /* REF */) {
|
|
3386
|
+
rows[r][key] = this.decodeRef();
|
|
3387
|
+
} else if (strType === 97 /* DICT_REF */) {
|
|
3388
|
+
rows[r][key] = BOOM_DICTIONARY_V1[this.reader.readVarint()];
|
|
3389
|
+
} else {
|
|
3390
|
+
throw new BoomError(`Invalid string type in columnar: 0x${strType.toString(16)}`);
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
break;
|
|
3394
|
+
default:
|
|
3395
|
+
for (let r = 0; r < rowCount; r++) {
|
|
3396
|
+
rows[r][key] = this.decodeValue();
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
return rows;
|
|
3401
|
+
}
|
|
3402
|
+
decodePackedBool() {
|
|
3403
|
+
const count = this.reader.readVarint();
|
|
3404
|
+
const result = [];
|
|
3405
|
+
const byteCount = Math.ceil(count / 8);
|
|
3406
|
+
for (let i = 0; i < byteCount; i++) {
|
|
3407
|
+
const byte = this.reader.readByte();
|
|
3408
|
+
for (let j = 0; j < 8 && result.length < count; j++) {
|
|
3409
|
+
result.push((byte & 1 << j) !== 0);
|
|
3410
|
+
}
|
|
3411
|
+
}
|
|
3412
|
+
return result;
|
|
3413
|
+
}
|
|
3414
|
+
decodePackedInt8() {
|
|
3415
|
+
const count = this.reader.readVarint();
|
|
3416
|
+
const result = [];
|
|
3417
|
+
for (let i = 0; i < count; i++) {
|
|
3418
|
+
result.push(this.reader.readInt8());
|
|
3419
|
+
}
|
|
3420
|
+
return result;
|
|
3421
|
+
}
|
|
3422
|
+
decodePackedInt16() {
|
|
3423
|
+
const count = this.reader.readVarint();
|
|
3424
|
+
const result = [];
|
|
3425
|
+
for (let i = 0; i < count; i++) {
|
|
3426
|
+
result.push(this.reader.readInt16LE());
|
|
3427
|
+
}
|
|
3428
|
+
return result;
|
|
3429
|
+
}
|
|
3430
|
+
decodePackedInt32() {
|
|
3431
|
+
const count = this.reader.readVarint();
|
|
3432
|
+
const result = [];
|
|
3433
|
+
for (let i = 0; i < count; i++) {
|
|
3434
|
+
result.push(this.reader.readInt32LE());
|
|
3435
|
+
}
|
|
3436
|
+
return result;
|
|
3437
|
+
}
|
|
3438
|
+
decodePackedFloat32() {
|
|
3439
|
+
const count = this.reader.readVarint();
|
|
3440
|
+
const result = [];
|
|
3441
|
+
for (let i = 0; i < count; i++) {
|
|
3442
|
+
result.push(this.reader.readFloat32LE());
|
|
3443
|
+
}
|
|
3444
|
+
return result;
|
|
3445
|
+
}
|
|
3446
|
+
decodePackedFloat64() {
|
|
3447
|
+
const count = this.reader.readVarint();
|
|
3448
|
+
const result = [];
|
|
3449
|
+
for (let i = 0; i < count; i++) {
|
|
3450
|
+
result.push(this.reader.readFloat64LE());
|
|
3451
|
+
}
|
|
3452
|
+
return result;
|
|
3453
|
+
}
|
|
3454
|
+
};
|
|
3455
|
+
var BoomTextEncoder = class {
|
|
3456
|
+
indent = 0;
|
|
3457
|
+
options;
|
|
3458
|
+
constructor(options = {}) {
|
|
3459
|
+
this.options = {
|
|
3460
|
+
...DEFAULT_OPTIONS,
|
|
3461
|
+
compact: false,
|
|
3462
|
+
indentString: " ",
|
|
3463
|
+
...options
|
|
3464
|
+
};
|
|
3465
|
+
}
|
|
3466
|
+
encode(value) {
|
|
3467
|
+
this.indent = 0;
|
|
3468
|
+
return this.encodeValue(value);
|
|
3469
|
+
}
|
|
3470
|
+
get newline() {
|
|
3471
|
+
return this.options.compact ? " " : "\n";
|
|
3472
|
+
}
|
|
3473
|
+
get currentIndent() {
|
|
3474
|
+
return this.options.compact ? "" : this.options.indentString.repeat(this.indent);
|
|
3475
|
+
}
|
|
3476
|
+
encodeValue(value) {
|
|
3477
|
+
if (value === null || value === void 0) {
|
|
3478
|
+
return "null";
|
|
3479
|
+
}
|
|
3480
|
+
if (typeof value === "boolean") {
|
|
3481
|
+
return value ? "true" : "false";
|
|
3482
|
+
}
|
|
3483
|
+
if (typeof value === "number") {
|
|
3484
|
+
if (Number.isNaN(value)) return "null";
|
|
3485
|
+
if (!Number.isFinite(value)) return "null";
|
|
3486
|
+
return Object.is(value, -0) ? "-0" : String(value);
|
|
3487
|
+
}
|
|
3488
|
+
if (typeof value === "bigint") {
|
|
3489
|
+
return `${value}n`;
|
|
3490
|
+
}
|
|
3491
|
+
if (typeof value === "string") {
|
|
3492
|
+
return this.encodeString(value);
|
|
3493
|
+
}
|
|
3494
|
+
if (value instanceof Uint8Array) {
|
|
3495
|
+
return this.encodeBinary(value);
|
|
3496
|
+
}
|
|
3497
|
+
if (Array.isArray(value)) {
|
|
3498
|
+
return this.encodeArray(value);
|
|
3499
|
+
}
|
|
3500
|
+
if (typeof value === "object") {
|
|
3501
|
+
return this.encodeObject(value);
|
|
3502
|
+
}
|
|
3503
|
+
return "null";
|
|
3504
|
+
}
|
|
3505
|
+
encodeString(value) {
|
|
3506
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t");
|
|
3507
|
+
return `"${escaped}"`;
|
|
3508
|
+
}
|
|
3509
|
+
encodeBinary(value) {
|
|
3510
|
+
const base64 = this.uint8ArrayToBase64(value);
|
|
3511
|
+
return `<binary:${base64}>`;
|
|
3512
|
+
}
|
|
3513
|
+
uint8ArrayToBase64(bytes) {
|
|
3514
|
+
if (typeof btoa === "function") {
|
|
3515
|
+
return btoa(String.fromCharCode(...bytes));
|
|
3516
|
+
}
|
|
3517
|
+
return Buffer.from(bytes).toString("base64");
|
|
3518
|
+
}
|
|
3519
|
+
encodeArray(value) {
|
|
3520
|
+
if (value.length === 0) {
|
|
3521
|
+
return "[]";
|
|
3522
|
+
}
|
|
3523
|
+
const allPrimitive = value.every(
|
|
3524
|
+
(item) => item === null || typeof item === "boolean" || typeof item === "number" || typeof item === "string" || typeof item === "bigint"
|
|
3525
|
+
);
|
|
3526
|
+
if (allPrimitive && value.length <= 5 && this.options.compact) {
|
|
3527
|
+
const items2 = value.map((item) => this.encodeValue(item)).join(" ");
|
|
3528
|
+
return `[${items2}]`;
|
|
3529
|
+
}
|
|
3530
|
+
this.indent++;
|
|
3531
|
+
const items = value.map((item) => `${this.currentIndent}${this.encodeValue(item)}`);
|
|
3532
|
+
this.indent--;
|
|
3533
|
+
return `[${this.newline}${items.join(this.newline)}${this.newline}${this.currentIndent}]`;
|
|
3534
|
+
}
|
|
3535
|
+
encodeObject(value) {
|
|
3536
|
+
const entries = Object.entries(value);
|
|
3537
|
+
if (entries.length === 0) {
|
|
3538
|
+
return "{}";
|
|
3539
|
+
}
|
|
3540
|
+
this.indent++;
|
|
3541
|
+
const pairs = entries.map(([key, val]) => {
|
|
3542
|
+
const encodedKey = /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key) ? key : this.encodeString(key);
|
|
3543
|
+
return `${this.currentIndent}${encodedKey}: ${this.encodeValue(val)}`;
|
|
3544
|
+
});
|
|
3545
|
+
this.indent--;
|
|
3546
|
+
return `{${this.newline}${pairs.join(this.newline)}${this.newline}${this.currentIndent}}`;
|
|
3547
|
+
}
|
|
3548
|
+
};
|
|
3549
|
+
var BoomTextDecoder = class {
|
|
3550
|
+
input = "";
|
|
3551
|
+
pos = 0;
|
|
3552
|
+
options;
|
|
3553
|
+
depth = 0;
|
|
3554
|
+
constructor(options = {}) {
|
|
3555
|
+
this.options = mergeOptions(DEFAULT_OPTIONS, options);
|
|
3556
|
+
}
|
|
3557
|
+
decode(input) {
|
|
3558
|
+
this.input = input;
|
|
3559
|
+
this.pos = 0;
|
|
3560
|
+
this.depth = 0;
|
|
3561
|
+
this.skipWhitespaceAndComments();
|
|
3562
|
+
const value = this.parseValue();
|
|
3563
|
+
this.skipWhitespaceAndComments();
|
|
3564
|
+
if (this.pos < this.input.length) {
|
|
3565
|
+
throw new BoomError(`Unexpected character at position ${this.pos}: ${this.input[this.pos]}`);
|
|
3566
|
+
}
|
|
3567
|
+
return value;
|
|
3568
|
+
}
|
|
3569
|
+
get current() {
|
|
3570
|
+
return this.pos < this.input.length ? this.input[this.pos] : "";
|
|
3571
|
+
}
|
|
3572
|
+
// @ts-expect-error - peek is reserved for future use
|
|
3573
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3574
|
+
peek(offset = 0) {
|
|
3575
|
+
const idx = this.pos + offset;
|
|
3576
|
+
return idx < this.input.length ? this.input[idx] : "";
|
|
3577
|
+
}
|
|
3578
|
+
advance() {
|
|
3579
|
+
if (this.pos >= this.input.length) return "";
|
|
3580
|
+
const ch = this.input[this.pos];
|
|
3581
|
+
this.pos++;
|
|
3582
|
+
return ch;
|
|
3583
|
+
}
|
|
3584
|
+
skipWhitespaceAndComments() {
|
|
3585
|
+
while (this.pos < this.input.length) {
|
|
3586
|
+
const ch = this.current;
|
|
3587
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r") {
|
|
3588
|
+
this.pos++;
|
|
3589
|
+
} else if (ch === "#") {
|
|
3590
|
+
while (this.pos < this.input.length && this.current !== "\n") {
|
|
3591
|
+
this.pos++;
|
|
3592
|
+
}
|
|
3593
|
+
} else {
|
|
3594
|
+
break;
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
parseValue() {
|
|
3599
|
+
this.skipWhitespaceAndComments();
|
|
3600
|
+
const ch = this.current;
|
|
3601
|
+
if (ch === '"') {
|
|
3602
|
+
return this.parseString();
|
|
3603
|
+
}
|
|
3604
|
+
if (ch === "[") {
|
|
3605
|
+
return this.parseArray();
|
|
3606
|
+
}
|
|
3607
|
+
if (ch === "{") {
|
|
3608
|
+
return this.parseObject();
|
|
3609
|
+
}
|
|
3610
|
+
if (ch === "<") {
|
|
3611
|
+
return this.parseBinary();
|
|
3612
|
+
}
|
|
3613
|
+
if (ch === "-" || ch === "+" || ch >= "0" && ch <= "9") {
|
|
3614
|
+
return this.parseNumber();
|
|
3615
|
+
}
|
|
3616
|
+
if (this.matchKeyword("null")) {
|
|
3617
|
+
return null;
|
|
3618
|
+
}
|
|
3619
|
+
if (this.matchKeyword("true")) {
|
|
3620
|
+
return true;
|
|
3621
|
+
}
|
|
3622
|
+
if (this.matchKeyword("false")) {
|
|
3623
|
+
return false;
|
|
3624
|
+
}
|
|
3625
|
+
throw new BoomError(`Unexpected character at position ${this.pos}: ${ch}`);
|
|
3626
|
+
}
|
|
3627
|
+
matchKeyword(keyword) {
|
|
3628
|
+
if (this.input.slice(this.pos, this.pos + keyword.length) === keyword) {
|
|
3629
|
+
const nextChar = this.input[this.pos + keyword.length] ?? "";
|
|
3630
|
+
if (!/[a-zA-Z0-9_]/.test(nextChar)) {
|
|
3631
|
+
this.pos += keyword.length;
|
|
3632
|
+
return true;
|
|
3633
|
+
}
|
|
3634
|
+
}
|
|
3635
|
+
return false;
|
|
3636
|
+
}
|
|
3637
|
+
parseString() {
|
|
3638
|
+
this.advance();
|
|
3639
|
+
let result = "";
|
|
3640
|
+
while (this.pos < this.input.length) {
|
|
3641
|
+
const ch = this.advance();
|
|
3642
|
+
if (ch === '"') {
|
|
3643
|
+
return result;
|
|
3644
|
+
}
|
|
3645
|
+
if (ch === "\\") {
|
|
3646
|
+
const escaped = this.advance();
|
|
3647
|
+
switch (escaped) {
|
|
3648
|
+
case "n":
|
|
3649
|
+
result += "\n";
|
|
3650
|
+
break;
|
|
3651
|
+
case "r":
|
|
3652
|
+
result += "\r";
|
|
3653
|
+
break;
|
|
3654
|
+
case "t":
|
|
3655
|
+
result += " ";
|
|
3656
|
+
break;
|
|
3657
|
+
case '"':
|
|
3658
|
+
result += '"';
|
|
3659
|
+
break;
|
|
3660
|
+
case "\\":
|
|
3661
|
+
result += "\\";
|
|
3662
|
+
break;
|
|
3663
|
+
case "u": {
|
|
3664
|
+
const hex = this.input.slice(this.pos, this.pos + 4);
|
|
3665
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
3666
|
+
throw new BoomError(`Invalid unicode escape at position ${this.pos}`);
|
|
3667
|
+
}
|
|
3668
|
+
result += String.fromCharCode(parseInt(hex, 16));
|
|
3669
|
+
this.pos += 4;
|
|
3670
|
+
break;
|
|
3671
|
+
}
|
|
3672
|
+
default:
|
|
3673
|
+
result += escaped;
|
|
3674
|
+
}
|
|
3675
|
+
} else {
|
|
3676
|
+
result += ch;
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
throw new BoomError("Unterminated string");
|
|
3680
|
+
}
|
|
3681
|
+
parseNumber() {
|
|
3682
|
+
const start = this.pos;
|
|
3683
|
+
const firstChar = this.current;
|
|
3684
|
+
if (firstChar === "-" || firstChar === "+") {
|
|
3685
|
+
this.pos++;
|
|
3686
|
+
}
|
|
3687
|
+
while (this.current >= "0" && this.current <= "9") {
|
|
3688
|
+
this.pos++;
|
|
3689
|
+
}
|
|
3690
|
+
let isFloat = false;
|
|
3691
|
+
if (this.current === ".") {
|
|
3692
|
+
isFloat = true;
|
|
3693
|
+
this.pos++;
|
|
3694
|
+
while (this.current >= "0" && this.current <= "9") {
|
|
3695
|
+
this.pos++;
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
const expChar = this.current;
|
|
3699
|
+
if (expChar === "e" || expChar === "E") {
|
|
3700
|
+
isFloat = true;
|
|
3701
|
+
this.pos++;
|
|
3702
|
+
const signChar = this.current;
|
|
3703
|
+
if (signChar === "-" || signChar === "+") {
|
|
3704
|
+
this.pos++;
|
|
3705
|
+
}
|
|
3706
|
+
while (this.current >= "0" && this.current <= "9") {
|
|
3707
|
+
this.pos++;
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
if (this.current === "n") {
|
|
3711
|
+
this.pos++;
|
|
3712
|
+
const numStr2 = this.input.slice(start, this.pos - 1);
|
|
3713
|
+
return BigInt(numStr2);
|
|
3714
|
+
}
|
|
3715
|
+
const numStr = this.input.slice(start, this.pos);
|
|
3716
|
+
return isFloat ? parseFloat(numStr) : parseInt(numStr, 10);
|
|
3717
|
+
}
|
|
3718
|
+
parseArray() {
|
|
3719
|
+
this.advance();
|
|
3720
|
+
this.depth++;
|
|
3721
|
+
if (this.depth > this.options.maxDepth) {
|
|
3722
|
+
throw new BoomError(`Maximum nesting depth of ${this.options.maxDepth} exceeded`);
|
|
3723
|
+
}
|
|
3724
|
+
const arr = [];
|
|
3725
|
+
this.skipWhitespaceAndComments();
|
|
3726
|
+
if (this.current === "]") {
|
|
3727
|
+
this.advance();
|
|
3728
|
+
this.depth--;
|
|
3729
|
+
return arr;
|
|
3730
|
+
}
|
|
3731
|
+
while (true) {
|
|
3732
|
+
this.skipWhitespaceAndComments();
|
|
3733
|
+
arr.push(this.parseValue());
|
|
3734
|
+
this.skipWhitespaceAndComments();
|
|
3735
|
+
if (this.current === "]") {
|
|
3736
|
+
this.advance();
|
|
3737
|
+
break;
|
|
3738
|
+
}
|
|
3739
|
+
if (this.current === ",") {
|
|
3740
|
+
this.advance();
|
|
3741
|
+
}
|
|
3742
|
+
}
|
|
3743
|
+
this.depth--;
|
|
3744
|
+
return arr;
|
|
3745
|
+
}
|
|
3746
|
+
parseObject() {
|
|
3747
|
+
this.advance();
|
|
3748
|
+
this.depth++;
|
|
3749
|
+
if (this.depth > this.options.maxDepth) {
|
|
3750
|
+
throw new BoomError(`Maximum nesting depth of ${this.options.maxDepth} exceeded`);
|
|
3751
|
+
}
|
|
3752
|
+
const obj = {};
|
|
3753
|
+
this.skipWhitespaceAndComments();
|
|
3754
|
+
if (this.current === "}") {
|
|
3755
|
+
this.advance();
|
|
3756
|
+
this.depth--;
|
|
3757
|
+
return obj;
|
|
3758
|
+
}
|
|
3759
|
+
while (true) {
|
|
3760
|
+
this.skipWhitespaceAndComments();
|
|
3761
|
+
let key;
|
|
3762
|
+
const keyStart = this.current;
|
|
3763
|
+
if (keyStart === '"') {
|
|
3764
|
+
key = this.parseString();
|
|
3765
|
+
} else {
|
|
3766
|
+
const start = this.pos;
|
|
3767
|
+
while (/[a-zA-Z0-9_]/.test(this.current)) {
|
|
3768
|
+
this.pos++;
|
|
3769
|
+
}
|
|
3770
|
+
key = this.input.slice(start, this.pos);
|
|
3771
|
+
if (!key) {
|
|
3772
|
+
throw new BoomError(`Expected key at position ${this.pos}`);
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
this.skipWhitespaceAndComments();
|
|
3776
|
+
const colonChar = this.current;
|
|
3777
|
+
if (colonChar !== ":") {
|
|
3778
|
+
throw new BoomError(`Expected ':' after key at position ${this.pos}`);
|
|
3779
|
+
}
|
|
3780
|
+
this.advance();
|
|
3781
|
+
this.skipWhitespaceAndComments();
|
|
3782
|
+
obj[key] = this.parseValue();
|
|
3783
|
+
this.skipWhitespaceAndComments();
|
|
3784
|
+
const endChar = this.current;
|
|
3785
|
+
if (endChar === "}") {
|
|
3786
|
+
this.advance();
|
|
3787
|
+
break;
|
|
3788
|
+
}
|
|
3789
|
+
if (endChar === ",") {
|
|
3790
|
+
this.advance();
|
|
3791
|
+
}
|
|
3792
|
+
}
|
|
3793
|
+
this.depth--;
|
|
3794
|
+
return obj;
|
|
3795
|
+
}
|
|
3796
|
+
parseBinary() {
|
|
3797
|
+
if (!this.input.slice(this.pos).startsWith("<binary:")) {
|
|
3798
|
+
throw new BoomError(`Expected binary literal at position ${this.pos}`);
|
|
3799
|
+
}
|
|
3800
|
+
this.pos += 8;
|
|
3801
|
+
const endPos = this.input.indexOf(">", this.pos);
|
|
3802
|
+
if (endPos === -1) {
|
|
3803
|
+
throw new BoomError("Unterminated binary literal");
|
|
3804
|
+
}
|
|
3805
|
+
const base64 = this.input.slice(this.pos, endPos);
|
|
3806
|
+
this.pos = endPos + 1;
|
|
3807
|
+
return this.base64ToUint8Array(base64);
|
|
3808
|
+
}
|
|
3809
|
+
base64ToUint8Array(base64) {
|
|
3810
|
+
if (typeof atob === "function") {
|
|
3811
|
+
const binary = atob(base64);
|
|
3812
|
+
const bytes = new Uint8Array(binary.length);
|
|
3813
|
+
for (let i = 0; i < binary.length; i++) {
|
|
3814
|
+
bytes[i] = binary.charCodeAt(i);
|
|
3815
|
+
}
|
|
3816
|
+
return bytes;
|
|
3817
|
+
}
|
|
3818
|
+
return new Uint8Array(Buffer.from(base64, "base64"));
|
|
3819
|
+
}
|
|
3820
|
+
};
|
|
3821
|
+
function isUniformObjectArray(arr) {
|
|
3822
|
+
if (arr.length < 2) return false;
|
|
3823
|
+
const first = arr[0];
|
|
3824
|
+
if (typeof first !== "object" || first === null || Array.isArray(first)) return false;
|
|
3825
|
+
const firstKeys = Object.keys(first).sort().join(",");
|
|
3826
|
+
for (let i = 1; i < Math.min(arr.length, 3); i++) {
|
|
3827
|
+
const item = arr[i];
|
|
3828
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) return false;
|
|
3829
|
+
const itemKeys = Object.keys(item).sort().join(",");
|
|
3830
|
+
if (itemKeys !== firstKeys) return false;
|
|
3831
|
+
}
|
|
3832
|
+
return true;
|
|
3833
|
+
}
|
|
3834
|
+
function encode(value, options) {
|
|
3835
|
+
if (options?.forCompression) {
|
|
3836
|
+
options = { ...options, enableInterning: false, skipHeader: true };
|
|
3837
|
+
}
|
|
3838
|
+
if (!options || options.enableInterning !== false && !options.skipHeader && (!options.maxDepth || options.maxDepth === 64)) {
|
|
3839
|
+
if (Array.isArray(value) && isUniformObjectArray(value)) {
|
|
3840
|
+
return new BoomBinaryEncoder(options || {}).encode(value);
|
|
3841
|
+
}
|
|
3842
|
+
return fastEncode(value);
|
|
3843
|
+
}
|
|
3844
|
+
const result = new BoomBinaryEncoder(options).encode(value);
|
|
3845
|
+
if (options.skipHeader) {
|
|
3846
|
+
return result.slice(6);
|
|
3847
|
+
}
|
|
3848
|
+
return result;
|
|
3849
|
+
}
|
|
3850
|
+
function decode(buffer, options) {
|
|
3851
|
+
if (options?.strictBinaryMode) {
|
|
3852
|
+
if (buffer.length < 6 || buffer[0] !== 66 || buffer[1] !== 79 || buffer[2] !== 79 || buffer[3] !== 77) {
|
|
3853
|
+
throw new BoomError(
|
|
3854
|
+
'Strict binary mode: input must be BOOM binary format (starts with "BOOM" magic bytes). JSON and BOOM text formats are not allowed in production mode.'
|
|
3855
|
+
);
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
let actualBuffer = buffer;
|
|
3859
|
+
if (options?.skipHeader || options?.forCompression) {
|
|
3860
|
+
const withHeader = new Uint8Array(buffer.length + 6);
|
|
3861
|
+
withHeader[0] = 66;
|
|
3862
|
+
withHeader[1] = 79;
|
|
3863
|
+
withHeader[2] = 79;
|
|
3864
|
+
withHeader[3] = 77;
|
|
3865
|
+
withHeader[4] = 1;
|
|
3866
|
+
withHeader[5] = 0;
|
|
3867
|
+
withHeader.set(buffer, 6);
|
|
3868
|
+
actualBuffer = withHeader;
|
|
3869
|
+
}
|
|
3870
|
+
if (!options || (!options.maxDepth || options.maxDepth === 64)) {
|
|
3871
|
+
return fastDecode(actualBuffer);
|
|
3872
|
+
}
|
|
3873
|
+
return new BoomBinaryDecoder(options).decode(actualBuffer);
|
|
3874
|
+
}
|
|
3875
|
+
function stringify(value, options) {
|
|
3876
|
+
return new BoomTextEncoder(options).encode(value);
|
|
3877
|
+
}
|
|
3878
|
+
function parseText(input, options) {
|
|
3879
|
+
return new BoomTextDecoder(options).decode(input);
|
|
3880
|
+
}
|
|
3881
|
+
var DEFAULT_THRESHOLDS = {
|
|
3882
|
+
/** Below this, use JSON (default: 1KB) */
|
|
3883
|
+
minSize: 1024,
|
|
3884
|
+
/** Above this, prefer BOOM (default: 10KB) */
|
|
3885
|
+
preferSize: 10240,
|
|
3886
|
+
/** Above this, always use BOOM (default: 100KB) */
|
|
3887
|
+
forceSize: 102400
|
|
3888
|
+
};
|
|
3889
|
+
var globalThresholdConfig = {
|
|
3890
|
+
minSize: DEFAULT_THRESHOLDS.minSize,
|
|
3891
|
+
preferSize: DEFAULT_THRESHOLDS.preferSize,
|
|
3892
|
+
forceSize: DEFAULT_THRESHOLDS.forceSize,
|
|
3893
|
+
autoDetect: true,
|
|
3894
|
+
respectClientHint: true
|
|
3895
|
+
};
|
|
3896
|
+
|
|
3897
|
+
// src/http/fetch.ts
|
|
3898
|
+
var encodeFn;
|
|
3899
|
+
var decodeFn;
|
|
3900
|
+
var stringifyFn;
|
|
3901
|
+
var parseTextFn;
|
|
3902
|
+
function setCodecs(encode2, decode2, stringify2, parseText2) {
|
|
3903
|
+
encodeFn = encode2;
|
|
3904
|
+
decodeFn = decode2;
|
|
3905
|
+
stringifyFn = stringify2;
|
|
3906
|
+
parseTextFn = parseText2;
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3909
|
+
// src/browser.ts
|
|
3910
|
+
var parseTextFn2 = null;
|
|
3911
|
+
function setParseText(fn) {
|
|
3912
|
+
parseTextFn2 = fn;
|
|
3913
|
+
}
|
|
3914
|
+
|
|
3915
|
+
// src/constants.ts
|
|
3916
|
+
var MAGIC = new Uint8Array([66, 79, 79, 77]);
|
|
3917
|
+
var DEFAULT_OPTIONS2 = {
|
|
3918
|
+
maxDepth: 64,
|
|
3919
|
+
maxStringLength: 16 * 1024 * 1024,
|
|
3920
|
+
maxArrayLength: 1e6,
|
|
3921
|
+
enableInterning: true,
|
|
3922
|
+
skipHeader: false,
|
|
3923
|
+
forCompression: false
|
|
3924
|
+
};
|
|
3925
|
+
|
|
3926
|
+
// src/index.ts
|
|
3927
|
+
setParseText(parseText);
|
|
3928
|
+
setCodecs(encode, decode, stringify, parseText);
|
|
3929
|
+
|
|
3930
|
+
// src/cli.ts
|
|
3931
|
+
var VERSION3 = "1.0.0";
|
|
3932
|
+
var BOOM_MAGIC = [66, 79, 79, 77];
|
|
3933
|
+
function printHelp() {
|
|
3934
|
+
console.log(`
|
|
3935
|
+
BOOM CLI v${VERSION3} - Binary Object Optimised Markup
|
|
3936
|
+
|
|
3937
|
+
Usage:
|
|
3938
|
+
boom encode <input.json> [output] Encode JSON to BOOM format
|
|
3939
|
+
boom decode <input.boom> [output.json] Decode BOOM to JSON
|
|
3940
|
+
boom info <input.boom> Show info about a BOOM file
|
|
3941
|
+
boom <input.json> Shorthand for encode
|
|
3942
|
+
|
|
3943
|
+
Output Formats:
|
|
3944
|
+
--binary, -b Output BOOM binary format (default)
|
|
3945
|
+
--text, -t Output BOOM text format (.boom.txt)
|
|
3946
|
+
--json, -j Output JSON format (for decode)
|
|
3947
|
+
|
|
3948
|
+
Options:
|
|
3949
|
+
--help, -h Show this help message
|
|
3950
|
+
--version, -v Show version
|
|
3951
|
+
--pretty, -p Pretty-print output (JSON and text)
|
|
3952
|
+
--dict, -d Use shared dictionary (default: true)
|
|
3953
|
+
--no-dict Disable shared dictionary
|
|
3954
|
+
|
|
3955
|
+
Examples:
|
|
3956
|
+
boom encode data.json # Output: data.boom (binary)
|
|
3957
|
+
boom encode data.json --text # Output: data.boom.txt (text)
|
|
3958
|
+
boom encode data.json output.boom # Custom output file
|
|
3959
|
+
boom decode data.boom # Output: data.json
|
|
3960
|
+
boom decode data.boom --pretty # Pretty-printed JSON
|
|
3961
|
+
boom decode data.boom.txt # Decode BOOM text
|
|
3962
|
+
boom info data.boom # Show file info
|
|
3963
|
+
cat data.json | boom encode - > out.boom # Stdin/stdout
|
|
3964
|
+
cat data.boom | boom decode - # Decode from stdin
|
|
3965
|
+
|
|
3966
|
+
File Extensions:
|
|
3967
|
+
.boom BOOM binary format
|
|
3968
|
+
.boom.txt BOOM text format (human-readable)
|
|
3969
|
+
.json JSON format
|
|
3970
|
+
`);
|
|
3971
|
+
}
|
|
3972
|
+
function printVersion() {
|
|
3973
|
+
console.log(`boom v${VERSION3}`);
|
|
3974
|
+
}
|
|
3975
|
+
function parseArgs(args) {
|
|
3976
|
+
const options = {
|
|
3977
|
+
command: "help",
|
|
3978
|
+
input: null,
|
|
3979
|
+
output: null,
|
|
3980
|
+
pretty: false,
|
|
3981
|
+
useDict: true,
|
|
3982
|
+
format: "binary"
|
|
3983
|
+
};
|
|
3984
|
+
const positional = [];
|
|
3985
|
+
for (let i = 0; i < args.length; i++) {
|
|
3986
|
+
const arg = args[i];
|
|
3987
|
+
if (arg === void 0) continue;
|
|
3988
|
+
if (arg === "--help" || arg === "-h") {
|
|
3989
|
+
options.command = "help";
|
|
3990
|
+
return options;
|
|
3991
|
+
}
|
|
3992
|
+
if (arg === "--version" || arg === "-v") {
|
|
3993
|
+
options.command = "version";
|
|
3994
|
+
return options;
|
|
3995
|
+
}
|
|
3996
|
+
if (arg === "--pretty" || arg === "-p") {
|
|
3997
|
+
options.pretty = true;
|
|
3998
|
+
continue;
|
|
3999
|
+
}
|
|
4000
|
+
if (arg === "--dict" || arg === "-d") {
|
|
4001
|
+
options.useDict = true;
|
|
4002
|
+
continue;
|
|
4003
|
+
}
|
|
4004
|
+
if (arg === "--no-dict") {
|
|
4005
|
+
options.useDict = false;
|
|
4006
|
+
continue;
|
|
4007
|
+
}
|
|
4008
|
+
if (arg === "--binary" || arg === "-b") {
|
|
4009
|
+
options.format = "binary";
|
|
4010
|
+
continue;
|
|
4011
|
+
}
|
|
4012
|
+
if (arg === "--text" || arg === "-t") {
|
|
4013
|
+
options.format = "text";
|
|
4014
|
+
continue;
|
|
4015
|
+
}
|
|
4016
|
+
if (arg === "--json" || arg === "-j") {
|
|
4017
|
+
options.format = "json";
|
|
4018
|
+
continue;
|
|
4019
|
+
}
|
|
4020
|
+
if (arg === "-") {
|
|
4021
|
+
positional.push(arg);
|
|
4022
|
+
} else if (arg.startsWith("-")) {
|
|
4023
|
+
console.error(`Unknown option: ${arg}`);
|
|
4024
|
+
process.exit(1);
|
|
4025
|
+
} else {
|
|
4026
|
+
positional.push(arg);
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
if (positional.length === 0) {
|
|
4030
|
+
options.command = "help";
|
|
4031
|
+
return options;
|
|
4032
|
+
}
|
|
4033
|
+
const cmd = positional[0];
|
|
4034
|
+
if (!cmd) {
|
|
4035
|
+
options.command = "help";
|
|
4036
|
+
return options;
|
|
4037
|
+
}
|
|
4038
|
+
const cmdLower = cmd.toLowerCase();
|
|
4039
|
+
if (cmdLower === "encode") {
|
|
4040
|
+
options.command = "encode";
|
|
4041
|
+
options.input = positional[1] ?? null;
|
|
4042
|
+
options.output = positional[2] ?? null;
|
|
4043
|
+
} else if (cmdLower === "decode") {
|
|
4044
|
+
options.command = "decode";
|
|
4045
|
+
options.input = positional[1] ?? null;
|
|
4046
|
+
options.output = positional[2] ?? null;
|
|
4047
|
+
} else if (cmdLower === "info") {
|
|
4048
|
+
options.command = "info";
|
|
4049
|
+
options.input = positional[1] ?? null;
|
|
4050
|
+
} else if (cmdLower === "help") {
|
|
4051
|
+
options.command = "help";
|
|
4052
|
+
} else if (cmdLower === "version") {
|
|
4053
|
+
options.command = "version";
|
|
4054
|
+
} else {
|
|
4055
|
+
const inputFile = positional[0];
|
|
4056
|
+
if (inputFile) {
|
|
4057
|
+
options.input = inputFile;
|
|
4058
|
+
options.output = positional[1] ?? null;
|
|
4059
|
+
if (inputFile.endsWith(".boom") || inputFile.endsWith(".boom.txt")) {
|
|
4060
|
+
options.command = "decode";
|
|
4061
|
+
} else {
|
|
4062
|
+
options.command = "encode";
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
return options;
|
|
4067
|
+
}
|
|
4068
|
+
function readInput(inputPath) {
|
|
4069
|
+
if (inputPath === "-") {
|
|
4070
|
+
return fs.readFileSync(0);
|
|
4071
|
+
}
|
|
4072
|
+
return fs.readFileSync(inputPath);
|
|
4073
|
+
}
|
|
4074
|
+
function getOutputPath(inputPath, command, format) {
|
|
4075
|
+
if (inputPath === "-") {
|
|
4076
|
+
return "-";
|
|
4077
|
+
}
|
|
4078
|
+
let base;
|
|
4079
|
+
const dir = path.dirname(inputPath);
|
|
4080
|
+
if (inputPath.endsWith(".boom.txt")) {
|
|
4081
|
+
base = path.basename(inputPath, ".boom.txt");
|
|
4082
|
+
} else {
|
|
4083
|
+
const ext = path.extname(inputPath);
|
|
4084
|
+
base = path.basename(inputPath, ext);
|
|
4085
|
+
}
|
|
4086
|
+
if (command === "encode") {
|
|
4087
|
+
if (format === "text") {
|
|
4088
|
+
return path.join(dir, base + ".boom.txt");
|
|
4089
|
+
}
|
|
4090
|
+
return path.join(dir, base + ".boom");
|
|
4091
|
+
} else {
|
|
4092
|
+
return path.join(dir, base + ".json");
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
function writeOutput(outputPath, data) {
|
|
4096
|
+
if (outputPath === "-") {
|
|
4097
|
+
if (typeof data === "string") {
|
|
4098
|
+
process.stdout.write(data);
|
|
4099
|
+
} else {
|
|
4100
|
+
process.stdout.write(data);
|
|
4101
|
+
}
|
|
4102
|
+
} else {
|
|
4103
|
+
fs.writeFileSync(outputPath, data);
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
function formatBytes(bytes) {
|
|
4107
|
+
if (bytes < 1024) return bytes + " B";
|
|
4108
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + " KB";
|
|
4109
|
+
return (bytes / (1024 * 1024)).toFixed(2) + " MB";
|
|
4110
|
+
}
|
|
4111
|
+
async function runEncode(options) {
|
|
4112
|
+
if (!options.input) {
|
|
4113
|
+
console.error("Error: No input file specified");
|
|
4114
|
+
process.exit(1);
|
|
4115
|
+
}
|
|
4116
|
+
const inputData = readInput(options.input);
|
|
4117
|
+
const jsonData = JSON.parse(inputData.toString("utf-8"));
|
|
4118
|
+
const outputPath = options.output || getOutputPath(options.input, "encode", options.format);
|
|
4119
|
+
if (options.format === "text") {
|
|
4120
|
+
const textData = stringify(jsonData, { compact: !options.pretty });
|
|
4121
|
+
writeOutput(outputPath, textData + "\n");
|
|
4122
|
+
if (outputPath !== "-") {
|
|
4123
|
+
const savings = ((1 - textData.length / inputData.length) * 100).toFixed(1);
|
|
4124
|
+
console.log(`Encoded: ${options.input} -> ${outputPath}`);
|
|
4125
|
+
console.log(` JSON: ${formatBytes(inputData.length)}`);
|
|
4126
|
+
console.log(` BOOM text: ${formatBytes(textData.length)} (${savings}% smaller)`);
|
|
4127
|
+
}
|
|
4128
|
+
} else {
|
|
4129
|
+
const boomData = encode(jsonData, { enableInterning: options.useDict });
|
|
4130
|
+
writeOutput(outputPath, Buffer.from(boomData));
|
|
4131
|
+
if (outputPath !== "-") {
|
|
4132
|
+
const savings = ((1 - boomData.length / inputData.length) * 100).toFixed(1);
|
|
4133
|
+
console.log(`Encoded: ${options.input} -> ${outputPath}`);
|
|
4134
|
+
console.log(` JSON: ${formatBytes(inputData.length)}`);
|
|
4135
|
+
console.log(` BOOM binary: ${formatBytes(boomData.length)} (${savings}% smaller)`);
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
async function runDecode(options) {
|
|
4140
|
+
if (!options.input) {
|
|
4141
|
+
console.error("Error: No input file specified");
|
|
4142
|
+
process.exit(1);
|
|
4143
|
+
}
|
|
4144
|
+
const inputData = readInput(options.input);
|
|
4145
|
+
const isTextFormat = options.input.endsWith(".boom.txt") || options.input.endsWith(".txt") || !isBinaryFormat(inputData);
|
|
4146
|
+
let jsonData;
|
|
4147
|
+
let inputFormat;
|
|
4148
|
+
if (isTextFormat) {
|
|
4149
|
+
const textContent = inputData.toString("utf-8");
|
|
4150
|
+
jsonData = parseText(textContent);
|
|
4151
|
+
inputFormat = "BOOM text";
|
|
4152
|
+
} else {
|
|
4153
|
+
const boomArray = new Uint8Array(inputData);
|
|
4154
|
+
if (boomArray.length < 6 || boomArray[0] !== BOOM_MAGIC[0] || boomArray[1] !== BOOM_MAGIC[1] || boomArray[2] !== BOOM_MAGIC[2] || boomArray[3] !== BOOM_MAGIC[3]) {
|
|
4155
|
+
console.error("Error: Not a valid BOOM file (invalid magic header)");
|
|
4156
|
+
process.exit(1);
|
|
4157
|
+
}
|
|
4158
|
+
jsonData = decode(boomArray);
|
|
4159
|
+
inputFormat = "BOOM binary";
|
|
4160
|
+
}
|
|
4161
|
+
const jsonString = options.pretty ? JSON.stringify(jsonData, null, 2) : JSON.stringify(jsonData);
|
|
4162
|
+
const outputPath = options.output || getOutputPath(options.input, "decode", options.format);
|
|
4163
|
+
writeOutput(outputPath, jsonString + "\n");
|
|
4164
|
+
if (outputPath !== "-") {
|
|
4165
|
+
console.log(`Decoded: ${options.input} -> ${outputPath}`);
|
|
4166
|
+
console.log(` ${inputFormat}: ${formatBytes(inputData.length)}`);
|
|
4167
|
+
console.log(` JSON: ${formatBytes(jsonString.length)}`);
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
function isBinaryFormat(data) {
|
|
4171
|
+
return data.length >= 4 && data[0] === BOOM_MAGIC[0] && data[1] === BOOM_MAGIC[1] && data[2] === BOOM_MAGIC[2] && data[3] === BOOM_MAGIC[3];
|
|
4172
|
+
}
|
|
4173
|
+
async function runInfo(options) {
|
|
4174
|
+
if (!options.input) {
|
|
4175
|
+
console.error("Error: No input file specified");
|
|
4176
|
+
process.exit(1);
|
|
4177
|
+
}
|
|
4178
|
+
const inputData = readInput(options.input);
|
|
4179
|
+
const boomArray = new Uint8Array(inputData);
|
|
4180
|
+
if (boomArray.length < 6 || boomArray[0] !== BOOM_MAGIC[0] || boomArray[1] !== BOOM_MAGIC[1] || boomArray[2] !== BOOM_MAGIC[2] || boomArray[3] !== BOOM_MAGIC[3]) {
|
|
4181
|
+
console.error("Error: Not a valid BOOM file (invalid magic header)");
|
|
4182
|
+
process.exit(1);
|
|
4183
|
+
}
|
|
4184
|
+
const version = boomArray[4];
|
|
4185
|
+
const flags = boomArray[5];
|
|
4186
|
+
const usesDict = flags !== void 0 ? (flags & 1) !== 0 : false;
|
|
4187
|
+
const jsonData = decode(boomArray);
|
|
4188
|
+
const jsonString = JSON.stringify(jsonData);
|
|
4189
|
+
const prettyJson = JSON.stringify(jsonData, null, 2);
|
|
4190
|
+
const savings = ((1 - boomArray.length / jsonString.length) * 100).toFixed(1);
|
|
4191
|
+
console.log(`BOOM File Info: ${options.input}`);
|
|
4192
|
+
console.log(`${"\u2500".repeat(50)}`);
|
|
4193
|
+
console.log(` Format version: ${version}`);
|
|
4194
|
+
console.log(` Uses dictionary: ${usesDict ? "yes" : "no"}`);
|
|
4195
|
+
console.log(` BOOM size: ${formatBytes(boomArray.length)}`);
|
|
4196
|
+
console.log(` JSON size: ${formatBytes(jsonString.length)}`);
|
|
4197
|
+
console.log(` Size reduction: ${savings}%`);
|
|
4198
|
+
console.log(`${"\u2500".repeat(50)}`);
|
|
4199
|
+
console.log(`Preview (first 500 chars):`);
|
|
4200
|
+
console.log(prettyJson.slice(0, 500) + (prettyJson.length > 500 ? "..." : ""));
|
|
4201
|
+
}
|
|
4202
|
+
async function main() {
|
|
4203
|
+
const args = process.argv.slice(2);
|
|
4204
|
+
const options = parseArgs(args);
|
|
4205
|
+
try {
|
|
4206
|
+
switch (options.command) {
|
|
4207
|
+
case "help":
|
|
4208
|
+
printHelp();
|
|
4209
|
+
break;
|
|
4210
|
+
case "version":
|
|
4211
|
+
printVersion();
|
|
4212
|
+
break;
|
|
4213
|
+
case "encode":
|
|
4214
|
+
await runEncode(options);
|
|
4215
|
+
break;
|
|
4216
|
+
case "decode":
|
|
4217
|
+
await runDecode(options);
|
|
4218
|
+
break;
|
|
4219
|
+
case "info":
|
|
4220
|
+
await runInfo(options);
|
|
4221
|
+
break;
|
|
4222
|
+
}
|
|
4223
|
+
} catch (error) {
|
|
4224
|
+
if (error instanceof Error) {
|
|
4225
|
+
console.error(`Error: ${error.message}`);
|
|
4226
|
+
} else {
|
|
4227
|
+
console.error("An unknown error occurred");
|
|
4228
|
+
}
|
|
4229
|
+
process.exit(1);
|
|
4230
|
+
}
|
|
4231
|
+
}
|
|
4232
|
+
main();
|
|
4233
|
+
})();
|
|
4234
|
+
/**
|
|
4235
|
+
* BOOM - Binary Object Optimised Markup
|
|
4236
|
+
* A compact binary serialisation format with readable debug mode
|
|
4237
|
+
*
|
|
4238
|
+
* @module boom-format
|
|
4239
|
+
* @version 1.0.0
|
|
4240
|
+
* @license MIT
|
|
4241
|
+
*/
|
|
4242
|
+
/**
|
|
4243
|
+
* BOOM - Binary Object Optimised Markup
|
|
4244
|
+
* A compact binary serialization format with readable debug mode
|
|
4245
|
+
*
|
|
4246
|
+
* @module boom-format
|
|
4247
|
+
* @version 1.0.0
|
|
4248
|
+
* @license MIT
|
|
4249
|
+
*/
|