@naeemo/capnp 0.9.1 → 0.9.3
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/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/{cli-bench-bkR1vGK8.js → cli-bench-BRKmxDEn.js} +672 -15
- package/dist/cli-bench-BRKmxDEn.js.map +1 -0
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +917 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +908 -28
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/dist/cli-bench-bkR1vGK8.js.map +0 -1
|
@@ -67,6 +67,432 @@ function checkEnvVar() {
|
|
|
67
67
|
}
|
|
68
68
|
if (checkEnvVar()) debugState.enabled = true;
|
|
69
69
|
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region node_modules/.pnpm/lz4js@0.2.0/node_modules/lz4js/util.js
|
|
72
|
+
var require_util = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
73
|
+
exports.hashU32 = function hashU32(a) {
|
|
74
|
+
a = a | 0;
|
|
75
|
+
a = a + 2127912214 + (a << 12) | 0;
|
|
76
|
+
a = a ^ -949894596 ^ a >>> 19;
|
|
77
|
+
a = a + 374761393 + (a << 5) | 0;
|
|
78
|
+
a = a + -744332180 ^ a << 9;
|
|
79
|
+
a = a + -42973499 + (a << 3) | 0;
|
|
80
|
+
return a ^ -1252372727 ^ a >>> 16 | 0;
|
|
81
|
+
};
|
|
82
|
+
exports.readU64 = function readU64(b, n) {
|
|
83
|
+
var x = 0;
|
|
84
|
+
x |= b[n++] << 0;
|
|
85
|
+
x |= b[n++] << 8;
|
|
86
|
+
x |= b[n++] << 16;
|
|
87
|
+
x |= b[n++] << 24;
|
|
88
|
+
x |= b[n++] << 32;
|
|
89
|
+
x |= b[n++] << 40;
|
|
90
|
+
x |= b[n++] << 48;
|
|
91
|
+
x |= b[n++] << 56;
|
|
92
|
+
return x;
|
|
93
|
+
};
|
|
94
|
+
exports.readU32 = function readU32(b, n) {
|
|
95
|
+
var x = 0;
|
|
96
|
+
x |= b[n++] << 0;
|
|
97
|
+
x |= b[n++] << 8;
|
|
98
|
+
x |= b[n++] << 16;
|
|
99
|
+
x |= b[n++] << 24;
|
|
100
|
+
return x;
|
|
101
|
+
};
|
|
102
|
+
exports.writeU32 = function writeU32(b, n, x) {
|
|
103
|
+
b[n++] = x >> 0 & 255;
|
|
104
|
+
b[n++] = x >> 8 & 255;
|
|
105
|
+
b[n++] = x >> 16 & 255;
|
|
106
|
+
b[n++] = x >> 24 & 255;
|
|
107
|
+
};
|
|
108
|
+
exports.imul = function imul(a, b) {
|
|
109
|
+
var ah = a >>> 16;
|
|
110
|
+
var al = a & 65535;
|
|
111
|
+
var bh = b >>> 16;
|
|
112
|
+
var bl = b & 65535;
|
|
113
|
+
return al * bl + (ah * bl + al * bh << 16) | 0;
|
|
114
|
+
};
|
|
115
|
+
}));
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region node_modules/.pnpm/lz4js@0.2.0/node_modules/lz4js/xxh32.js
|
|
119
|
+
var require_xxh32 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
120
|
+
var util = require_util();
|
|
121
|
+
var prime1 = 2654435761;
|
|
122
|
+
var prime2 = 2246822519;
|
|
123
|
+
var prime3 = 3266489917;
|
|
124
|
+
var prime4 = 668265263;
|
|
125
|
+
var prime5 = 374761393;
|
|
126
|
+
function rotl32(x, r) {
|
|
127
|
+
x = x | 0;
|
|
128
|
+
r = r | 0;
|
|
129
|
+
return x >>> (32 - r | 0) | x << r | 0;
|
|
130
|
+
}
|
|
131
|
+
function rotmul32(h, r, m) {
|
|
132
|
+
h = h | 0;
|
|
133
|
+
r = r | 0;
|
|
134
|
+
m = m | 0;
|
|
135
|
+
return util.imul(h >>> (32 - r | 0) | h << r, m) | 0;
|
|
136
|
+
}
|
|
137
|
+
function shiftxor32(h, s) {
|
|
138
|
+
h = h | 0;
|
|
139
|
+
s = s | 0;
|
|
140
|
+
return h >>> s ^ h | 0;
|
|
141
|
+
}
|
|
142
|
+
function xxhapply(h, src, m0, s, m1) {
|
|
143
|
+
return rotmul32(util.imul(src, m0) + h, s, m1);
|
|
144
|
+
}
|
|
145
|
+
function xxh1(h, src, index) {
|
|
146
|
+
return rotmul32(h + util.imul(src[index], prime5), 11, prime1);
|
|
147
|
+
}
|
|
148
|
+
function xxh4(h, src, index) {
|
|
149
|
+
return xxhapply(h, util.readU32(src, index), prime3, 17, prime4);
|
|
150
|
+
}
|
|
151
|
+
function xxh16(h, src, index) {
|
|
152
|
+
return [
|
|
153
|
+
xxhapply(h[0], util.readU32(src, index + 0), prime2, 13, prime1),
|
|
154
|
+
xxhapply(h[1], util.readU32(src, index + 4), prime2, 13, prime1),
|
|
155
|
+
xxhapply(h[2], util.readU32(src, index + 8), prime2, 13, prime1),
|
|
156
|
+
xxhapply(h[3], util.readU32(src, index + 12), prime2, 13, prime1)
|
|
157
|
+
];
|
|
158
|
+
}
|
|
159
|
+
function xxh32(seed, src, index, len) {
|
|
160
|
+
var h, l = len;
|
|
161
|
+
if (len >= 16) {
|
|
162
|
+
h = [
|
|
163
|
+
seed + prime1 + prime2,
|
|
164
|
+
seed + prime2,
|
|
165
|
+
seed,
|
|
166
|
+
seed - prime1
|
|
167
|
+
];
|
|
168
|
+
while (len >= 16) {
|
|
169
|
+
h = xxh16(h, src, index);
|
|
170
|
+
index += 16;
|
|
171
|
+
len -= 16;
|
|
172
|
+
}
|
|
173
|
+
h = rotl32(h[0], 1) + rotl32(h[1], 7) + rotl32(h[2], 12) + rotl32(h[3], 18) + l;
|
|
174
|
+
} else h = seed + prime5 + len >>> 0;
|
|
175
|
+
while (len >= 4) {
|
|
176
|
+
h = xxh4(h, src, index);
|
|
177
|
+
index += 4;
|
|
178
|
+
len -= 4;
|
|
179
|
+
}
|
|
180
|
+
while (len > 0) {
|
|
181
|
+
h = xxh1(h, src, index);
|
|
182
|
+
index++;
|
|
183
|
+
len--;
|
|
184
|
+
}
|
|
185
|
+
h = shiftxor32(util.imul(shiftxor32(util.imul(shiftxor32(h, 15), prime2), 13), prime3), 16);
|
|
186
|
+
return h >>> 0;
|
|
187
|
+
}
|
|
188
|
+
exports.hash = xxh32;
|
|
189
|
+
}));
|
|
190
|
+
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region node_modules/.pnpm/lz4js@0.2.0/node_modules/lz4js/lz4.js
|
|
193
|
+
var require_lz4 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
194
|
+
var xxhash = require_xxh32();
|
|
195
|
+
var util = require_util();
|
|
196
|
+
var minMatch = 4;
|
|
197
|
+
var minLength = 13;
|
|
198
|
+
var searchLimit = 5;
|
|
199
|
+
var skipTrigger = 6;
|
|
200
|
+
var hashSize = 65536;
|
|
201
|
+
var mlBits = 4;
|
|
202
|
+
var mlMask = (1 << mlBits) - 1;
|
|
203
|
+
var runMask = 15;
|
|
204
|
+
var blockBuf = makeBuffer(5 << 20);
|
|
205
|
+
var hashTable = makeHashTable();
|
|
206
|
+
var magicNum = 407708164;
|
|
207
|
+
var fdContentChksum = 4;
|
|
208
|
+
var fdContentSize = 8;
|
|
209
|
+
var fdBlockChksum = 16;
|
|
210
|
+
var fdVersion = 64;
|
|
211
|
+
var fdVersionMask = 192;
|
|
212
|
+
var bsUncompressed = 2147483648;
|
|
213
|
+
var bsDefault = 7;
|
|
214
|
+
var bsShift = 4;
|
|
215
|
+
var bsMask = 7;
|
|
216
|
+
var bsMap = {
|
|
217
|
+
4: 65536,
|
|
218
|
+
5: 262144,
|
|
219
|
+
6: 1048576,
|
|
220
|
+
7: 4194304
|
|
221
|
+
};
|
|
222
|
+
function makeHashTable() {
|
|
223
|
+
try {
|
|
224
|
+
return new Uint32Array(hashSize);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
var hashTable = new Array(hashSize);
|
|
227
|
+
for (var i = 0; i < hashSize; i++) hashTable[i] = 0;
|
|
228
|
+
return hashTable;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function clearHashTable(table) {
|
|
232
|
+
for (var i = 0; i < hashSize; i++) hashTable[i] = 0;
|
|
233
|
+
}
|
|
234
|
+
function makeBuffer(size) {
|
|
235
|
+
try {
|
|
236
|
+
return new Uint8Array(size);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
var buf = new Array(size);
|
|
239
|
+
for (var i = 0; i < size; i++) buf[i] = 0;
|
|
240
|
+
return buf;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function sliceArray(array, start, end) {
|
|
244
|
+
if (Uint8Array.prototype.slice) return array.slice(start, end);
|
|
245
|
+
else {
|
|
246
|
+
var len = array.length;
|
|
247
|
+
start = start | 0;
|
|
248
|
+
start = start < 0 ? Math.max(len + start, 0) : Math.min(start, len);
|
|
249
|
+
end = end === void 0 ? len : end | 0;
|
|
250
|
+
end = end < 0 ? Math.max(len + end, 0) : Math.min(end, len);
|
|
251
|
+
var arraySlice = new Uint8Array(end - start);
|
|
252
|
+
for (var i = start, n = 0; i < end;) arraySlice[n++] = array[i++];
|
|
253
|
+
return arraySlice;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.compressBound = function compressBound(n) {
|
|
257
|
+
return n + n / 255 + 16 | 0;
|
|
258
|
+
};
|
|
259
|
+
exports.decompressBound = function decompressBound(src) {
|
|
260
|
+
var sIndex = 0;
|
|
261
|
+
if (util.readU32(src, sIndex) !== magicNum) throw new Error("invalid magic number");
|
|
262
|
+
sIndex += 4;
|
|
263
|
+
var descriptor = src[sIndex++];
|
|
264
|
+
if ((descriptor & fdVersionMask) !== fdVersion) throw new Error("incompatible descriptor version " + (descriptor & fdVersionMask));
|
|
265
|
+
var useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
266
|
+
var useContentSize = (descriptor & fdContentSize) !== 0;
|
|
267
|
+
var bsIdx = src[sIndex++] >> bsShift & bsMask;
|
|
268
|
+
if (bsMap[bsIdx] === void 0) throw new Error("invalid block size " + bsIdx);
|
|
269
|
+
var maxBlockSize = bsMap[bsIdx];
|
|
270
|
+
if (useContentSize) return util.readU64(src, sIndex);
|
|
271
|
+
sIndex++;
|
|
272
|
+
var maxSize = 0;
|
|
273
|
+
while (true) {
|
|
274
|
+
var blockSize = util.readU32(src, sIndex);
|
|
275
|
+
sIndex += 4;
|
|
276
|
+
if (blockSize & bsUncompressed) {
|
|
277
|
+
blockSize &= ~bsUncompressed;
|
|
278
|
+
maxSize += blockSize;
|
|
279
|
+
} else maxSize += maxBlockSize;
|
|
280
|
+
if (blockSize === 0) return maxSize;
|
|
281
|
+
if (useBlockSum) sIndex += 4;
|
|
282
|
+
sIndex += blockSize;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
exports.makeBuffer = makeBuffer;
|
|
286
|
+
exports.decompressBlock = function decompressBlock(src, dst, sIndex, sLength, dIndex) {
|
|
287
|
+
var mLength, mOffset, sEnd = sIndex + sLength, n, i;
|
|
288
|
+
while (sIndex < sEnd) {
|
|
289
|
+
var token = src[sIndex++];
|
|
290
|
+
var literalCount = token >> 4;
|
|
291
|
+
if (literalCount > 0) {
|
|
292
|
+
if (literalCount === 15) while (true) {
|
|
293
|
+
literalCount += src[sIndex];
|
|
294
|
+
if (src[sIndex++] !== 255) break;
|
|
295
|
+
}
|
|
296
|
+
for (n = sIndex + literalCount; sIndex < n;) dst[dIndex++] = src[sIndex++];
|
|
297
|
+
}
|
|
298
|
+
if (sIndex >= sEnd) break;
|
|
299
|
+
mLength = token & 15;
|
|
300
|
+
mOffset = src[sIndex++] | src[sIndex++] << 8;
|
|
301
|
+
if (mLength === 15) while (true) {
|
|
302
|
+
mLength += src[sIndex];
|
|
303
|
+
if (src[sIndex++] !== 255) break;
|
|
304
|
+
}
|
|
305
|
+
mLength += minMatch;
|
|
306
|
+
for (i = dIndex - mOffset, n = i + mLength; i < n;) dst[dIndex++] = dst[i++] | 0;
|
|
307
|
+
}
|
|
308
|
+
return dIndex;
|
|
309
|
+
};
|
|
310
|
+
exports.compressBlock = function compressBlock(src, dst, sIndex, sLength, hashTable) {
|
|
311
|
+
var mIndex, mAnchor, mLength, mOffset, mStep;
|
|
312
|
+
var literalCount, dIndex = 0, sEnd = sLength + sIndex, n;
|
|
313
|
+
mAnchor = sIndex;
|
|
314
|
+
if (sLength >= minLength) {
|
|
315
|
+
var searchMatchCount = (1 << skipTrigger) + 3;
|
|
316
|
+
while (sIndex + minMatch < sEnd - searchLimit) {
|
|
317
|
+
var seq = util.readU32(src, sIndex);
|
|
318
|
+
var hash = util.hashU32(seq) >>> 0;
|
|
319
|
+
hash = (hash >> 16 ^ hash) >>> 0 & 65535;
|
|
320
|
+
mIndex = hashTable[hash] - 1;
|
|
321
|
+
hashTable[hash] = sIndex + 1;
|
|
322
|
+
if (mIndex < 0 || sIndex - mIndex >>> 16 > 0 || util.readU32(src, mIndex) !== seq) {
|
|
323
|
+
mStep = searchMatchCount++ >> skipTrigger;
|
|
324
|
+
sIndex += mStep;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
searchMatchCount = (1 << skipTrigger) + 3;
|
|
328
|
+
literalCount = sIndex - mAnchor;
|
|
329
|
+
mOffset = sIndex - mIndex;
|
|
330
|
+
sIndex += minMatch;
|
|
331
|
+
mIndex += minMatch;
|
|
332
|
+
mLength = sIndex;
|
|
333
|
+
while (sIndex < sEnd - searchLimit && src[sIndex] === src[mIndex]) {
|
|
334
|
+
sIndex++;
|
|
335
|
+
mIndex++;
|
|
336
|
+
}
|
|
337
|
+
mLength = sIndex - mLength;
|
|
338
|
+
var token = mLength < mlMask ? mLength : mlMask;
|
|
339
|
+
if (literalCount >= runMask) {
|
|
340
|
+
dst[dIndex++] = (runMask << mlBits) + token;
|
|
341
|
+
for (n = literalCount - runMask; n >= 255; n -= 255) dst[dIndex++] = 255;
|
|
342
|
+
dst[dIndex++] = n;
|
|
343
|
+
} else dst[dIndex++] = (literalCount << mlBits) + token;
|
|
344
|
+
for (var i = 0; i < literalCount; i++) dst[dIndex++] = src[mAnchor + i];
|
|
345
|
+
dst[dIndex++] = mOffset;
|
|
346
|
+
dst[dIndex++] = mOffset >> 8;
|
|
347
|
+
if (mLength >= mlMask) {
|
|
348
|
+
for (n = mLength - mlMask; n >= 255; n -= 255) dst[dIndex++] = 255;
|
|
349
|
+
dst[dIndex++] = n;
|
|
350
|
+
}
|
|
351
|
+
mAnchor = sIndex;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
if (mAnchor === 0) return 0;
|
|
355
|
+
literalCount = sEnd - mAnchor;
|
|
356
|
+
if (literalCount >= runMask) {
|
|
357
|
+
dst[dIndex++] = runMask << mlBits;
|
|
358
|
+
for (n = literalCount - runMask; n >= 255; n -= 255) dst[dIndex++] = 255;
|
|
359
|
+
dst[dIndex++] = n;
|
|
360
|
+
} else dst[dIndex++] = literalCount << mlBits;
|
|
361
|
+
sIndex = mAnchor;
|
|
362
|
+
while (sIndex < sEnd) dst[dIndex++] = src[sIndex++];
|
|
363
|
+
return dIndex;
|
|
364
|
+
};
|
|
365
|
+
exports.decompressFrame = function decompressFrame(src, dst) {
|
|
366
|
+
var useBlockSum, useContentSum, useContentSize, descriptor;
|
|
367
|
+
var sIndex = 0;
|
|
368
|
+
var dIndex = 0;
|
|
369
|
+
if (util.readU32(src, sIndex) !== magicNum) throw new Error("invalid magic number");
|
|
370
|
+
sIndex += 4;
|
|
371
|
+
descriptor = src[sIndex++];
|
|
372
|
+
if ((descriptor & fdVersionMask) !== fdVersion) throw new Error("incompatible descriptor version");
|
|
373
|
+
useBlockSum = (descriptor & fdBlockChksum) !== 0;
|
|
374
|
+
useContentSum = (descriptor & fdContentChksum) !== 0;
|
|
375
|
+
useContentSize = (descriptor & fdContentSize) !== 0;
|
|
376
|
+
if (bsMap[src[sIndex++] >> bsShift & bsMask] === void 0) throw new Error("invalid block size");
|
|
377
|
+
if (useContentSize) sIndex += 8;
|
|
378
|
+
sIndex++;
|
|
379
|
+
while (true) {
|
|
380
|
+
var compSize = util.readU32(src, sIndex);
|
|
381
|
+
sIndex += 4;
|
|
382
|
+
if (compSize === 0) break;
|
|
383
|
+
if (useBlockSum) sIndex += 4;
|
|
384
|
+
if ((compSize & bsUncompressed) !== 0) {
|
|
385
|
+
compSize &= ~bsUncompressed;
|
|
386
|
+
for (var j = 0; j < compSize; j++) dst[dIndex++] = src[sIndex++];
|
|
387
|
+
} else {
|
|
388
|
+
dIndex = exports.decompressBlock(src, dst, sIndex, compSize, dIndex);
|
|
389
|
+
sIndex += compSize;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (useContentSum) sIndex += 4;
|
|
393
|
+
return dIndex;
|
|
394
|
+
};
|
|
395
|
+
exports.compressFrame = function compressFrame(src, dst) {
|
|
396
|
+
var dIndex = 0;
|
|
397
|
+
util.writeU32(dst, dIndex, magicNum);
|
|
398
|
+
dIndex += 4;
|
|
399
|
+
dst[dIndex++] = fdVersion;
|
|
400
|
+
dst[dIndex++] = bsDefault << bsShift;
|
|
401
|
+
dst[dIndex] = xxhash.hash(0, dst, 4, dIndex - 4) >> 8;
|
|
402
|
+
dIndex++;
|
|
403
|
+
var maxBlockSize = bsMap[bsDefault];
|
|
404
|
+
var remaining = src.length;
|
|
405
|
+
var sIndex = 0;
|
|
406
|
+
clearHashTable(hashTable);
|
|
407
|
+
while (remaining > 0) {
|
|
408
|
+
var compSize = 0;
|
|
409
|
+
var blockSize = remaining > maxBlockSize ? maxBlockSize : remaining;
|
|
410
|
+
compSize = exports.compressBlock(src, blockBuf, sIndex, blockSize, hashTable);
|
|
411
|
+
if (compSize > blockSize || compSize === 0) {
|
|
412
|
+
util.writeU32(dst, dIndex, 2147483648 | blockSize);
|
|
413
|
+
dIndex += 4;
|
|
414
|
+
for (var z = sIndex + blockSize; sIndex < z;) dst[dIndex++] = src[sIndex++];
|
|
415
|
+
remaining -= blockSize;
|
|
416
|
+
} else {
|
|
417
|
+
util.writeU32(dst, dIndex, compSize);
|
|
418
|
+
dIndex += 4;
|
|
419
|
+
for (var j = 0; j < compSize;) dst[dIndex++] = blockBuf[j++];
|
|
420
|
+
sIndex += blockSize;
|
|
421
|
+
remaining -= blockSize;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
util.writeU32(dst, dIndex, 0);
|
|
425
|
+
dIndex += 4;
|
|
426
|
+
return dIndex;
|
|
427
|
+
};
|
|
428
|
+
exports.decompress = function decompress(src, maxSize) {
|
|
429
|
+
var dst, size;
|
|
430
|
+
if (maxSize === void 0) maxSize = exports.decompressBound(src);
|
|
431
|
+
dst = exports.makeBuffer(maxSize);
|
|
432
|
+
size = exports.decompressFrame(src, dst);
|
|
433
|
+
if (size !== maxSize) dst = sliceArray(dst, 0, size);
|
|
434
|
+
return dst;
|
|
435
|
+
};
|
|
436
|
+
exports.compress = function compress(src, maxSize) {
|
|
437
|
+
var dst, size;
|
|
438
|
+
if (maxSize === void 0) maxSize = exports.compressBound(src.length);
|
|
439
|
+
dst = exports.makeBuffer(maxSize);
|
|
440
|
+
size = exports.compressFrame(src, dst);
|
|
441
|
+
if (size !== maxSize) dst = sliceArray(dst, 0, size);
|
|
442
|
+
return dst;
|
|
443
|
+
};
|
|
444
|
+
}));
|
|
445
|
+
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region src/compression/lz4.ts
|
|
448
|
+
var import_lz4 = require_lz4();
|
|
449
|
+
/**
|
|
450
|
+
* Default compression options
|
|
451
|
+
*/
|
|
452
|
+
const DEFAULT_COMPRESSION_OPTIONS = {
|
|
453
|
+
threshold: 1024,
|
|
454
|
+
acceleration: 1,
|
|
455
|
+
level: 0
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* Compress data using LZ4
|
|
459
|
+
* @param data - Data to compress
|
|
460
|
+
* @param options - Compression options
|
|
461
|
+
* @returns Compressed data, or null if compression failed or not beneficial
|
|
462
|
+
*/
|
|
463
|
+
function compress(data, options = {}) {
|
|
464
|
+
const opts = {
|
|
465
|
+
...DEFAULT_COMPRESSION_OPTIONS,
|
|
466
|
+
...options
|
|
467
|
+
};
|
|
468
|
+
if (data.length < opts.threshold) return null;
|
|
469
|
+
try {
|
|
470
|
+
const compressed = (0, import_lz4.compress)(Array.from(data));
|
|
471
|
+
if (compressed.length >= data.length) return null;
|
|
472
|
+
return new Uint8Array(compressed);
|
|
473
|
+
} catch (_error) {
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Decompress LZ4 compressed data
|
|
479
|
+
* @param data - Compressed data
|
|
480
|
+
* @param originalSize - Original uncompressed size
|
|
481
|
+
* @returns Decompressed data, or null if decompression failed
|
|
482
|
+
*/
|
|
483
|
+
function decompress(data, originalSize) {
|
|
484
|
+
try {
|
|
485
|
+
const decompressed = (0, import_lz4.decompress)(Array.from(data), originalSize);
|
|
486
|
+
return new Uint8Array(decompressed);
|
|
487
|
+
} catch (_error) {
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Alias for decompress - same function, different name for API compatibility
|
|
493
|
+
*/
|
|
494
|
+
const uncompress = decompress;
|
|
495
|
+
|
|
70
496
|
//#endregion
|
|
71
497
|
//#region src/debug/index.ts
|
|
72
498
|
/**
|
|
@@ -3870,6 +4296,115 @@ var import_sender = /* @__PURE__ */ __toESM(require_sender(), 1);
|
|
|
3870
4296
|
var import_websocket = /* @__PURE__ */ __toESM(require_websocket(), 1);
|
|
3871
4297
|
var import_websocket_server = /* @__PURE__ */ __toESM(require_websocket_server(), 1);
|
|
3872
4298
|
|
|
4299
|
+
//#endregion
|
|
4300
|
+
//#region src/compression/frame.ts
|
|
4301
|
+
/**
|
|
4302
|
+
* LZ4 Frame Format Module
|
|
4303
|
+
*
|
|
4304
|
+
* Frame format: Magic(4) + Flags(1) + Length(4) + Payload
|
|
4305
|
+
* - Magic: 0x4C5A3401 (LZ4\0\x01)
|
|
4306
|
+
* - Flags: compression options and metadata
|
|
4307
|
+
* - Length: uncompressed data length (4 bytes, little-endian)
|
|
4308
|
+
* - Payload: compressed or uncompressed data
|
|
4309
|
+
*/
|
|
4310
|
+
/**
|
|
4311
|
+
* Frame format constants
|
|
4312
|
+
*/
|
|
4313
|
+
const LZ4_FRAME_MAGIC = 1280979969;
|
|
4314
|
+
const LZ4_FRAME_HEADER_SIZE = 9;
|
|
4315
|
+
/**
|
|
4316
|
+
* Frame flags
|
|
4317
|
+
*/
|
|
4318
|
+
let FrameFlags = /* @__PURE__ */ function(FrameFlags) {
|
|
4319
|
+
/** Data is compressed */
|
|
4320
|
+
FrameFlags[FrameFlags["COMPRESSED"] = 1] = "COMPRESSED";
|
|
4321
|
+
/** Reserved for future use */
|
|
4322
|
+
FrameFlags[FrameFlags["RESERVED_1"] = 2] = "RESERVED_1";
|
|
4323
|
+
/** Reserved for future use */
|
|
4324
|
+
FrameFlags[FrameFlags["RESERVED_2"] = 4] = "RESERVED_2";
|
|
4325
|
+
/** Reserved for future use */
|
|
4326
|
+
FrameFlags[FrameFlags["RESERVED_3"] = 8] = "RESERVED_3";
|
|
4327
|
+
/** Reserved for future use */
|
|
4328
|
+
FrameFlags[FrameFlags["RESERVED_4"] = 16] = "RESERVED_4";
|
|
4329
|
+
/** Reserved for future use */
|
|
4330
|
+
FrameFlags[FrameFlags["RESERVED_5"] = 32] = "RESERVED_5";
|
|
4331
|
+
/** Reserved for future use */
|
|
4332
|
+
FrameFlags[FrameFlags["RESERVED_6"] = 64] = "RESERVED_6";
|
|
4333
|
+
/** Reserved for future use */
|
|
4334
|
+
FrameFlags[FrameFlags["RESERVED_7"] = 128] = "RESERVED_7";
|
|
4335
|
+
return FrameFlags;
|
|
4336
|
+
}({});
|
|
4337
|
+
/**
|
|
4338
|
+
* Check if data has LZ4 frame magic header
|
|
4339
|
+
*/
|
|
4340
|
+
function hasFrameMagic(data) {
|
|
4341
|
+
if (data.length < 4) return false;
|
|
4342
|
+
return new DataView(data.buffer, data.byteOffset, data.byteLength).getUint32(0, true) === LZ4_FRAME_MAGIC;
|
|
4343
|
+
}
|
|
4344
|
+
/**
|
|
4345
|
+
* Parse frame header from data
|
|
4346
|
+
* @returns FrameHeader if valid, null otherwise
|
|
4347
|
+
*/
|
|
4348
|
+
function parseFrameHeader(data) {
|
|
4349
|
+
if (data.length < LZ4_FRAME_HEADER_SIZE) return null;
|
|
4350
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
4351
|
+
const magic = view.getUint32(0, true);
|
|
4352
|
+
if (magic !== LZ4_FRAME_MAGIC) return null;
|
|
4353
|
+
return {
|
|
4354
|
+
magic,
|
|
4355
|
+
flags: view.getUint8(4),
|
|
4356
|
+
length: view.getUint32(5, true)
|
|
4357
|
+
};
|
|
4358
|
+
}
|
|
4359
|
+
/**
|
|
4360
|
+
* Decompress framed data
|
|
4361
|
+
* @param data - Framed data (with or without frame header)
|
|
4362
|
+
* @param decompressFn - Decompression function for compressed payloads
|
|
4363
|
+
* @returns Decompressed data, or null if invalid
|
|
4364
|
+
*/
|
|
4365
|
+
function decompressFrame(data, decompressFn) {
|
|
4366
|
+
const header = parseFrameHeader(data);
|
|
4367
|
+
if (!header) return data;
|
|
4368
|
+
const payloadOffset = LZ4_FRAME_HEADER_SIZE;
|
|
4369
|
+
if (data.length - payloadOffset < 0) return null;
|
|
4370
|
+
const payload = data.subarray(payloadOffset);
|
|
4371
|
+
if (header.flags & FrameFlags.COMPRESSED) return decompressFn(payload, header.length);
|
|
4372
|
+
return payload;
|
|
4373
|
+
}
|
|
4374
|
+
|
|
4375
|
+
//#endregion
|
|
4376
|
+
//#region src/compression/index.ts
|
|
4377
|
+
/**
|
|
4378
|
+
* Create default compression config
|
|
4379
|
+
*/
|
|
4380
|
+
function createCompressionConfig(config) {
|
|
4381
|
+
return {
|
|
4382
|
+
enabled: false,
|
|
4383
|
+
algorithm: "lz4",
|
|
4384
|
+
threshold: 1024,
|
|
4385
|
+
level: 0,
|
|
4386
|
+
highCompression: false,
|
|
4387
|
+
...config
|
|
4388
|
+
};
|
|
4389
|
+
}
|
|
4390
|
+
/**
|
|
4391
|
+
* Create empty compression stats
|
|
4392
|
+
*/
|
|
4393
|
+
function createCompressionStats() {
|
|
4394
|
+
return {
|
|
4395
|
+
messagesCompressed: 0,
|
|
4396
|
+
messagesDecompressed: 0,
|
|
4397
|
+
bytesOriginal: 0,
|
|
4398
|
+
bytesCompressed: 0,
|
|
4399
|
+
compressionRatio: 1,
|
|
4400
|
+
savingsPercent: 0
|
|
4401
|
+
};
|
|
4402
|
+
}
|
|
4403
|
+
/**
|
|
4404
|
+
* Default compression configuration
|
|
4405
|
+
*/
|
|
4406
|
+
const DEFAULT_COMPRESSION_CONFIG = createCompressionConfig();
|
|
4407
|
+
|
|
3873
4408
|
//#endregion
|
|
3874
4409
|
//#region src/proxy/websocket-proxy.ts
|
|
3875
4410
|
/**
|
|
@@ -3878,6 +4413,27 @@ var import_websocket_server = /* @__PURE__ */ __toESM(require_websocket_server()
|
|
|
3878
4413
|
* Allows browsers to connect to native Cap'n Proto services (C++, etc.)
|
|
3879
4414
|
* via WebSocket. Handles the protocol bridging between WebSocket (browser)
|
|
3880
4415
|
* and raw TCP (Cap'n Proto services).
|
|
4416
|
+
*
|
|
4417
|
+
* Features:
|
|
4418
|
+
* - Independent compression configuration for WebSocket and TCP sides
|
|
4419
|
+
* - Automatic compression/decompression bridging
|
|
4420
|
+
* - Support for different compression settings on each side
|
|
4421
|
+
* - Backward compatibility with non-compressed peers
|
|
4422
|
+
*/
|
|
4423
|
+
/**
|
|
4424
|
+
* Convert Buffer to Uint8Array without copying if possible
|
|
4425
|
+
*/
|
|
4426
|
+
function bufferToUint8Array(buffer) {
|
|
4427
|
+
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
4428
|
+
}
|
|
4429
|
+
/**
|
|
4430
|
+
* Convert Uint8Array to Buffer without copying if possible
|
|
4431
|
+
*/
|
|
4432
|
+
function uint8ArrayToBuffer(arr) {
|
|
4433
|
+
return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
4434
|
+
}
|
|
4435
|
+
/**
|
|
4436
|
+
* Represents a single proxy connection between WebSocket client and TCP server
|
|
3881
4437
|
*/
|
|
3882
4438
|
var ProxyConnection = class extends EventEmitter {
|
|
3883
4439
|
ws;
|
|
@@ -3885,16 +4441,22 @@ var ProxyConnection = class extends EventEmitter {
|
|
|
3885
4441
|
stats;
|
|
3886
4442
|
options;
|
|
3887
4443
|
closed = false;
|
|
4444
|
+
wsCompressionConfig;
|
|
4445
|
+
tcpCompressionConfig;
|
|
3888
4446
|
constructor(ws, options) {
|
|
3889
4447
|
super();
|
|
3890
4448
|
this.ws = ws;
|
|
3891
4449
|
this.options = options;
|
|
4450
|
+
this.wsCompressionConfig = createCompressionConfig(options.compression?.ws);
|
|
4451
|
+
this.tcpCompressionConfig = createCompressionConfig(options.compression?.tcp);
|
|
3892
4452
|
this.stats = {
|
|
3893
4453
|
wsMessagesIn: 0,
|
|
3894
4454
|
wsMessagesOut: 0,
|
|
3895
4455
|
tcpBytesIn: 0,
|
|
3896
4456
|
tcpBytesOut: 0,
|
|
3897
|
-
connectedAt: /* @__PURE__ */ new Date()
|
|
4457
|
+
connectedAt: /* @__PURE__ */ new Date(),
|
|
4458
|
+
wsCompression: createCompressionStats(),
|
|
4459
|
+
tcpCompression: createCompressionStats()
|
|
3898
4460
|
};
|
|
3899
4461
|
this.setupWebSocket();
|
|
3900
4462
|
}
|
|
@@ -3922,6 +4484,7 @@ var ProxyConnection = class extends EventEmitter {
|
|
|
3922
4484
|
});
|
|
3923
4485
|
this.tcpSocket.on("connect", () => {
|
|
3924
4486
|
this.log("Connected to target TCP service");
|
|
4487
|
+
this.log(`Compression - WS: ${this.wsCompressionConfig.enabled ? "enabled" : "disabled"}, TCP: ${this.tcpCompressionConfig.enabled ? "enabled" : "disabled"}`);
|
|
3925
4488
|
this.emit("connected");
|
|
3926
4489
|
});
|
|
3927
4490
|
this.tcpSocket.on("data", (data) => {
|
|
@@ -3941,29 +4504,78 @@ var ProxyConnection = class extends EventEmitter {
|
|
|
3941
4504
|
this.close();
|
|
3942
4505
|
});
|
|
3943
4506
|
}
|
|
4507
|
+
/**
|
|
4508
|
+
* Handle incoming message from WebSocket client
|
|
4509
|
+
* - Decompress if compressed (from browser)
|
|
4510
|
+
* - Re-compress for TCP side if TCP compression is enabled
|
|
4511
|
+
* - Forward to TCP server
|
|
4512
|
+
*/
|
|
3944
4513
|
handleWebSocketMessage(data) {
|
|
3945
4514
|
if (this.closed) return;
|
|
3946
4515
|
const buffer = Buffer.isBuffer(data) ? data : Array.isArray(data) ? Buffer.concat(data) : Buffer.from(data);
|
|
3947
4516
|
const maxSize = this.options.maxMessageSize ?? 16 * 1024 * 1024;
|
|
3948
|
-
|
|
3949
|
-
|
|
4517
|
+
const uint8Data = bufferToUint8Array(buffer);
|
|
4518
|
+
const frameInfo = parseFrameHeader(uint8Data);
|
|
4519
|
+
const uncompressedSize = frameInfo ? frameInfo.length : buffer.length;
|
|
4520
|
+
if (uncompressedSize > maxSize) {
|
|
4521
|
+
this.log(`Message too large: ${uncompressedSize} bytes (max: ${maxSize})`);
|
|
3950
4522
|
this.close();
|
|
3951
4523
|
return;
|
|
3952
4524
|
}
|
|
3953
4525
|
this.stats.wsMessagesIn++;
|
|
3954
|
-
|
|
4526
|
+
let decompressedData;
|
|
4527
|
+
if (hasFrameMagic(uint8Data)) {
|
|
4528
|
+
const decompressed = decompressFrame(uint8Data, uncompress);
|
|
4529
|
+
if (decompressed !== null) {
|
|
4530
|
+
decompressedData = decompressed;
|
|
4531
|
+
this.log(`Decompressed WS message: ${buffer.length} -> ${decompressedData.length} bytes`);
|
|
4532
|
+
} else decompressedData = uint8Data;
|
|
4533
|
+
} else decompressedData = uint8Data;
|
|
4534
|
+
let dataToSend = decompressedData;
|
|
4535
|
+
if (this.tcpCompressionConfig.enabled) {
|
|
4536
|
+
const compressed = compress(decompressedData, { threshold: this.tcpCompressionConfig.threshold });
|
|
4537
|
+
if (compressed !== null) {
|
|
4538
|
+
dataToSend = compressed;
|
|
4539
|
+
this.log(`Compressed for TCP: ${decompressedData.length} -> ${dataToSend.length} bytes`);
|
|
4540
|
+
}
|
|
4541
|
+
}
|
|
4542
|
+
this.stats.tcpBytesOut += uint8ArrayToBuffer(dataToSend).length;
|
|
3955
4543
|
if (this.tcpSocket?.writable) {
|
|
3956
|
-
|
|
3957
|
-
this.
|
|
4544
|
+
const bufferToSend = uint8ArrayToBuffer(dataToSend);
|
|
4545
|
+
this.tcpSocket.write(bufferToSend);
|
|
4546
|
+
this.log(`Forwarded ${dataToSend.length} bytes to TCP (original: ${decompressedData.length})`);
|
|
3958
4547
|
}
|
|
3959
4548
|
}
|
|
4549
|
+
/**
|
|
4550
|
+
* Handle incoming data from TCP server
|
|
4551
|
+
* - Decompress if compressed (from native Cap'n Proto service)
|
|
4552
|
+
* - Re-compress for WebSocket side if WS compression is enabled
|
|
4553
|
+
* - Forward to WebSocket client
|
|
4554
|
+
*/
|
|
3960
4555
|
handleTcpData(data) {
|
|
3961
4556
|
if (this.closed) return;
|
|
3962
4557
|
this.stats.tcpBytesIn += data.length;
|
|
4558
|
+
const uint8Data = bufferToUint8Array(data);
|
|
4559
|
+
let decompressedData;
|
|
4560
|
+
if (hasFrameMagic(uint8Data)) {
|
|
4561
|
+
const decompressed = decompressFrame(uint8Data, uncompress);
|
|
4562
|
+
if (decompressed !== null) {
|
|
4563
|
+
decompressedData = decompressed;
|
|
4564
|
+
this.log(`Decompressed TCP message: ${data.length} -> ${decompressedData.length} bytes`);
|
|
4565
|
+
} else decompressedData = uint8Data;
|
|
4566
|
+
} else decompressedData = uint8Data;
|
|
4567
|
+
let dataToSend = decompressedData;
|
|
4568
|
+
if (this.wsCompressionConfig.enabled) {
|
|
4569
|
+
const compressed = compress(decompressedData, { threshold: this.wsCompressionConfig.threshold });
|
|
4570
|
+
if (compressed !== null) {
|
|
4571
|
+
dataToSend = compressed;
|
|
4572
|
+
this.log(`Compressed for WS: ${decompressedData.length} -> ${dataToSend.length} bytes`);
|
|
4573
|
+
}
|
|
4574
|
+
}
|
|
3963
4575
|
this.stats.wsMessagesOut++;
|
|
3964
4576
|
if (this.ws.readyState === import_websocket.default.OPEN) {
|
|
3965
|
-
this.ws.send(
|
|
3966
|
-
this.log(`Forwarded ${
|
|
4577
|
+
this.ws.send(dataToSend);
|
|
4578
|
+
this.log(`Forwarded ${dataToSend.length} bytes to WebSocket (original: ${decompressedData.length})`);
|
|
3967
4579
|
}
|
|
3968
4580
|
}
|
|
3969
4581
|
log(...args) {
|
|
@@ -3980,6 +4592,10 @@ var ProxyConnection = class extends EventEmitter {
|
|
|
3980
4592
|
this.emit("closed");
|
|
3981
4593
|
}
|
|
3982
4594
|
};
|
|
4595
|
+
/**
|
|
4596
|
+
* WebSocket-to-TCP Proxy server
|
|
4597
|
+
* Manages multiple proxy connections
|
|
4598
|
+
*/
|
|
3983
4599
|
var CapnpWebSocketProxy = class extends EventEmitter {
|
|
3984
4600
|
wss;
|
|
3985
4601
|
connections = /* @__PURE__ */ new Map();
|
|
@@ -4037,6 +4653,9 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
4037
4653
|
let targetHost = "localhost";
|
|
4038
4654
|
let targetPort = 8081;
|
|
4039
4655
|
let debug = false;
|
|
4656
|
+
let wsCompression = false;
|
|
4657
|
+
let tcpCompression = false;
|
|
4658
|
+
let compressionThreshold = 1024;
|
|
4040
4659
|
for (let i = 0; i < args.length; i++) switch (args[i]) {
|
|
4041
4660
|
case "--ws-port":
|
|
4042
4661
|
case "-p":
|
|
@@ -4053,6 +4672,17 @@ if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
4053
4672
|
case "-d":
|
|
4054
4673
|
debug = true;
|
|
4055
4674
|
break;
|
|
4675
|
+
case "--ws-compression":
|
|
4676
|
+
case "-w":
|
|
4677
|
+
wsCompression = true;
|
|
4678
|
+
break;
|
|
4679
|
+
case "--tcp-compression":
|
|
4680
|
+
case "-c":
|
|
4681
|
+
tcpCompression = true;
|
|
4682
|
+
break;
|
|
4683
|
+
case "--compression-threshold":
|
|
4684
|
+
compressionThreshold = Number.parseInt(args[++i], 10);
|
|
4685
|
+
break;
|
|
4056
4686
|
case "--help":
|
|
4057
4687
|
case "-h":
|
|
4058
4688
|
console.log(`
|
|
@@ -4061,13 +4691,25 @@ Cap'n Proto WebSocket-to-TCP Proxy
|
|
|
4061
4691
|
Usage: npx @naeemo/capnp proxy [options]
|
|
4062
4692
|
|
|
4063
4693
|
Options:
|
|
4064
|
-
-p, --ws-port <port>
|
|
4065
|
-
-t, --target <host:port>
|
|
4066
|
-
-d, --debug
|
|
4067
|
-
-
|
|
4694
|
+
-p, --ws-port <port> WebSocket server port (default: 8080)
|
|
4695
|
+
-t, --target <host:port> Target TCP service (default: localhost:8081)
|
|
4696
|
+
-d, --debug Enable debug logging
|
|
4697
|
+
-w, --ws-compression Enable WebSocket side compression
|
|
4698
|
+
-c, --tcp-compression Enable TCP side compression
|
|
4699
|
+
--compression-threshold <n> Minimum size to compress (default: 1024)
|
|
4700
|
+
-h, --help Show this help
|
|
4068
4701
|
|
|
4069
|
-
|
|
4702
|
+
Examples:
|
|
4070
4703
|
npx @naeemo/capnp proxy -p 9000 -t 192.168.1.100:7000
|
|
4704
|
+
|
|
4705
|
+
# Enable compression on WebSocket side only (for browser clients)
|
|
4706
|
+
npx @naeemo/capnp proxy -p 9000 -t localhost:7000 -w
|
|
4707
|
+
|
|
4708
|
+
# Enable compression on both sides
|
|
4709
|
+
npx @naeemo/capnp proxy -p 9000 -t localhost:7000 -w -c
|
|
4710
|
+
|
|
4711
|
+
# Enable compression with lower threshold
|
|
4712
|
+
npx @naeemo/capnp proxy -p 9000 -t localhost:7000 -w --compression-threshold 512
|
|
4071
4713
|
`);
|
|
4072
4714
|
process.exit(0);
|
|
4073
4715
|
}
|
|
@@ -4075,11 +4717,26 @@ Example:
|
|
|
4075
4717
|
wsPort,
|
|
4076
4718
|
targetHost,
|
|
4077
4719
|
targetPort,
|
|
4078
|
-
debug
|
|
4720
|
+
debug,
|
|
4721
|
+
compression: {
|
|
4722
|
+
ws: {
|
|
4723
|
+
enabled: wsCompression,
|
|
4724
|
+
threshold: compressionThreshold
|
|
4725
|
+
},
|
|
4726
|
+
tcp: {
|
|
4727
|
+
enabled: tcpCompression,
|
|
4728
|
+
threshold: compressionThreshold
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4079
4731
|
});
|
|
4080
4732
|
console.log("WebSocket-to-TCP Proxy started");
|
|
4081
4733
|
console.log(` WebSocket: ws://localhost:${wsPort}`);
|
|
4082
4734
|
console.log(` Target: ${targetHost}:${targetPort}`);
|
|
4735
|
+
if (wsCompression || tcpCompression) {
|
|
4736
|
+
console.log(" Compression:");
|
|
4737
|
+
console.log(` WebSocket: ${wsCompression ? "enabled" : "disabled"} (threshold: ${compressionThreshold})`);
|
|
4738
|
+
console.log(` TCP: ${tcpCompression ? "enabled" : "disabled"} (threshold: ${compressionThreshold})`);
|
|
4739
|
+
}
|
|
4083
4740
|
proxy.on("connection", () => {
|
|
4084
4741
|
console.log(`Active connections: ${proxy.getConnectionCount()}`);
|
|
4085
4742
|
});
|
|
@@ -4525,4 +5182,4 @@ async function run(args) {
|
|
|
4525
5182
|
|
|
4526
5183
|
//#endregion
|
|
4527
5184
|
export { run };
|
|
4528
|
-
//# sourceMappingURL=cli-bench-
|
|
5185
|
+
//# sourceMappingURL=cli-bench-BRKmxDEn.js.map
|