quico 0.1.3 → 0.2.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/libs/utils.js DELETED
@@ -1,404 +0,0 @@
1
-
2
- function writeVarInt(value) {
3
- if (value < 0x40) {
4
- // 1 byte, prefix 00
5
- return new Uint8Array([value]); // אין צורך ב־& 0x3f
6
- }
7
-
8
- if (value < 0x4000) {
9
- // 2 bytes, prefix 01
10
- return new Uint8Array([
11
- 0x40 | (value >> 8),
12
- value & 0xff
13
- ]);
14
- }
15
-
16
- if (value < 0x40000000) {
17
- // 4 bytes, prefix 10
18
- return new Uint8Array([
19
- 0x80 | (value >> 24),
20
- (value >> 16) & 0xff,
21
- (value >> 8) & 0xff,
22
- value & 0xff
23
- ]);
24
- }
25
-
26
- if (value <= Number.MAX_SAFE_INTEGER) {
27
- var hi = Math.floor(value / 2 ** 32);
28
- var lo = value >>> 0;
29
- return new Uint8Array([
30
- 0xC0 | (hi >> 24),
31
- (hi >> 16) & 0xff,
32
- (hi >> 8) & 0xff,
33
- hi & 0xff,
34
- (lo >> 24) & 0xff,
35
- (lo >> 16) & 0xff,
36
- (lo >> 8) & 0xff,
37
- lo & 0xff
38
- ]);
39
- }
40
-
41
- throw new Error("Value too large for QUIC VarInt");
42
- }
43
-
44
-
45
- function writeVarInt2(value) {
46
- if (value < 0x40) {
47
- // 1 byte
48
- return new Uint8Array([value & 0x3f]);
49
- }
50
-
51
- if (value < 0x4000) {
52
- // 2 bytes
53
- return new Uint8Array([
54
- 0x40 | ((value >> 8) & 0x3f),
55
- value & 0xff
56
- ]);
57
- }
58
-
59
- if (value < 0x40000000) {
60
- // 4 bytes
61
- return new Uint8Array([
62
- 0x80 | ((value >> 24) & 0x3f),
63
- (value >> 16) & 0xff,
64
- (value >> 8) & 0xff,
65
- value & 0xff
66
- ]);
67
- }
68
-
69
- if (value <= Number.MAX_SAFE_INTEGER) {
70
- var hi = Math.floor(value / 2 ** 32);
71
- var lo = value >>> 0;
72
- return new Uint8Array([
73
- 0xC0 | ((hi >> 24) & 0x3f),
74
- (hi >> 16) & 0xff,
75
- (hi >> 8) & 0xff,
76
- hi & 0xff,
77
- (lo >> 24) & 0xff,
78
- (lo >> 16) & 0xff,
79
- (lo >> 8) & 0xff,
80
- lo & 0xff
81
- ]);
82
- }
83
-
84
- throw new Error("Value too large for QUIC VarInt");
85
- }
86
-
87
-
88
-
89
- function readVarInt(array, offset) {
90
- if (offset >= array.length) return null;
91
-
92
- var first = array[offset];
93
- var prefix = first >> 6;
94
-
95
- if (prefix === 0b00) {
96
- return {
97
- value: first & 0x3f,
98
- byteLength: 1
99
- };
100
- }
101
-
102
- if (prefix === 0b01) {
103
- if (offset + 1 >= array.length) return null;
104
- var value = ((first & 0x3f) << 8) | array[offset + 1];
105
- return {
106
- value,
107
- byteLength: 2
108
- };
109
- }
110
-
111
- if (prefix === 0b10) {
112
- if (offset + 3 >= array.length) return null;
113
- var value = (
114
- ((first & 0x3F) << 24) |
115
- (array[offset + 1] << 16) |
116
- (array[offset + 2] << 8) |
117
- array[offset + 3]
118
- ) >>> 0;
119
- return {
120
- value,
121
- byteLength: 4
122
- };
123
- }
124
-
125
- if (prefix === 0b11) {
126
- if (offset + 7 >= array.length) return null;
127
-
128
- var hi = (
129
- ((first & 0x3F) << 24) |
130
- (array[offset + 1] << 16) |
131
- (array[offset + 2] << 8) |
132
- array[offset + 3]
133
- ) >>> 0;
134
-
135
- var lo = (
136
- (array[offset + 4] << 24) |
137
- (array[offset + 5] << 16) |
138
- (array[offset + 6] << 8) |
139
- array[offset + 7]
140
- ) >>> 0;
141
-
142
- var full = BigInt(hi) * 4294967296n + BigInt(lo); // 2^32
143
-
144
- if (full <= BigInt(Number.MAX_SAFE_INTEGER)) {
145
- return {
146
- value: Number(full),
147
- byteLength: 8
148
- };
149
- } else {
150
- return {
151
- value: full,
152
- byteLength: 8
153
- };
154
- }
155
- }
156
-
157
- return null;
158
- }
159
-
160
-
161
-
162
- function concatUint8Arrays(arrays) {
163
- var totalLength = 0;
164
- for (var i = 0; i < arrays.length; i++) {
165
- totalLength += arrays[i].length;
166
- }
167
-
168
- var result = new Uint8Array(totalLength);
169
- var offset = 0;
170
-
171
- for (var i = 0; i < arrays.length; i++) {
172
- result.set(arrays[i], offset);
173
- offset += arrays[i].length;
174
- }
175
-
176
- return result;
177
- }
178
-
179
- function arraybufferEqual(buf1, buf2) {
180
- //if (buf1 === buf2) {
181
- //return true;
182
- //}
183
-
184
- if (buf1.byteLength !== buf2.byteLength) {
185
- return false;
186
- }
187
-
188
- var view1 = new DataView(buf1);
189
- var view2 = new DataView(buf2);
190
-
191
- for (var i = 0; i < buf1.byteLength; i++) {
192
- if (view1.getUint8(i) !== view2.getUint8(i)) {
193
- return false;
194
- }
195
- }
196
-
197
- return true;
198
- }
199
-
200
-
201
-
202
- function buildAckFrameFromPackets(packets, ecnStats, ackDelay) {
203
- if (!packets || packets.length === 0) return null;
204
-
205
- var sorted = packets.slice().sort((a, b) => b - a);
206
-
207
- var ranges = [];
208
- var rangeStart = sorted[0];
209
- var rangeEnd = rangeStart;
210
- var lastPn = rangeStart;
211
-
212
- for (var i = 1; i < sorted.length; i++) {
213
- var pn = sorted[i];
214
- if (pn === lastPn - 1) {
215
- lastPn = pn;
216
- } else {
217
- ranges.push({ start: lastPn, end: rangeEnd });
218
- rangeEnd = pn;
219
- lastPn = pn;
220
- }
221
- }
222
- ranges.push({ start: lastPn, end: rangeEnd });
223
-
224
- var firstRange = ranges[0].end - ranges[0].start;
225
- var ackRanges = [];
226
-
227
- for (var i = 1; i < ranges.length; i++) {
228
- var gap = ranges[i - 1].start - ranges[i].end - 1;
229
- var length = ranges[i].end - ranges[i].start;
230
- ackRanges.push({ gap: gap, length: length });
231
- }
232
-
233
- var frame = {
234
- type: 'ack',
235
- largest: sorted[0],
236
- delay: ackDelay || 0, // ← כאן מכניסים את ה־delay שחושב
237
- firstRange: firstRange,
238
- ranges: ackRanges
239
- };
240
-
241
- if (ecnStats) {
242
- frame.ecn = {
243
- ect0: ecnStats.ect0 || 0,
244
- ect1: ecnStats.ect1 || 0,
245
- ce: ecnStats.ce || 0
246
- };
247
- }
248
-
249
- return frame;
250
- }
251
-
252
- function build_ack_info_from_ranges(flatRanges, ecnStats, ackDelay) {
253
- if (!flatRanges || flatRanges.length === 0) return null;
254
- if (flatRanges.length % 2 !== 0) throw new Error("flatRanges must be in [from, to, ...] pairs");
255
-
256
- var ranges = [];
257
- for (var i = 0; i < flatRanges.length; i += 2) {
258
- var from = flatRanges[i];
259
- var to = flatRanges[i + 1];
260
- if (to < from) throw new Error("Range end must be >= start");
261
- ranges.push({ start: from, end: to });
262
- }
263
-
264
- // Sort ranges from highest to lowest end
265
- ranges.sort((a, b) => b.end - a.end);
266
-
267
- // Merge overlapping or adjacent ranges
268
- var merged = [ranges[0]];
269
- for (var i = 1; i < ranges.length; i++) {
270
- var last = merged[merged.length - 1];
271
- var curr = ranges[i];
272
- if (curr.end >= last.start - 1) {
273
- // Merge them
274
- last.start = Math.min(last.start, curr.start);
275
- } else {
276
- merged.push(curr);
277
- }
278
- }
279
-
280
- var largest = merged[0].end;
281
- var firstRange = largest - merged[0].start;
282
- var ackRanges = [];
283
-
284
- for (var i = 1; i < merged.length; i++) {
285
- var gap = merged[i - 1].start - merged[i].end - 1;
286
- var length = merged[i].end - merged[i].start;
287
- ackRanges.push({ gap: gap, length: length });
288
- }
289
-
290
- return {
291
- type: 'ack',
292
- largest: largest,
293
- delay: ackDelay || 0,
294
- firstRange: firstRange,
295
- ranges: ackRanges,
296
- ecn: ecnStats ? {
297
- ect0: ecnStats.ect0 || 0,
298
- ect1: ecnStats.ect1 || 0,
299
- ce: ecnStats.ce || 0
300
- } : null
301
- };
302
- }
303
-
304
-
305
- function build_ack_info_from_ranges2(flatRanges, ecnStats, ackDelay) {
306
- if (!flatRanges || flatRanges.length === 0) return null;
307
- if (flatRanges.length % 2 !== 0) throw new Error("flatRanges must be in [from, to, ...] pairs");
308
-
309
- // בניית טווחים מלאים
310
- var ranges = [];
311
- for (var i = 0; i < flatRanges.length; i += 2) {
312
- var from = flatRanges[i];
313
- var to = flatRanges[i + 1];
314
- if (to < from) throw new Error("Range end must be >= start");
315
- ranges.push({ start: from, end: to });
316
- }
317
-
318
- // ממיינים מהגדול לקטן לפי end
319
- ranges.sort(function (a, b) { return b.end - a.end; });
320
-
321
- // הסרת טווחים חופפים או לא חוקיים
322
- for (var i = 1; i < ranges.length; i++) {
323
- if (ranges[i].end >= ranges[i - 1].start) {
324
- throw new Error("Overlapping ranges are not allowed");
325
- }
326
- }
327
-
328
- // התחלת ack מהטווח הגבוה ביותר
329
- var largest = ranges[0].end;
330
- var firstRange = largest - ranges[0].start;
331
-
332
- var ackRanges = [];
333
- var runningEnd = ranges[0].start - 1;
334
-
335
- for (var i = 1; i < ranges.length; i++) {
336
- var gap = runningEnd - ranges[i].end - 1;
337
- var length = ranges[i].end - ranges[i].start;
338
-
339
- // בדיקה אם הבלוק הבא יגלוש מתחת ל־0
340
- var nextEnd = runningEnd - (gap + 1 + length);
341
- if (nextEnd < 0) {
342
- console.warn("Skipped range due to underflow risk:", ranges[i]);
343
- continue; // לא מוסיפים את הטווח הזה
344
- }
345
-
346
- ackRanges.push({ gap: gap, length: length });
347
- runningEnd = ranges[i].start - 1;
348
- }
349
-
350
- var frame = {
351
- type: 'ack',
352
- largest: largest,
353
- delay: ackDelay || 0,
354
- firstRange: firstRange,
355
- ranges: ackRanges,
356
- ecn: ecnStats ? {
357
- ect0: ecnStats.ect0 || 0,
358
- ect1: ecnStats.ect1 || 0,
359
- ce: ecnStats.ce || 0
360
- } : null
361
- };
362
-
363
- return frame;
364
- }
365
-
366
-
367
-
368
- function quic_acked_info_to_ranges(ackFrame) {
369
- var flatRanges = [];
370
-
371
- if (!ackFrame || ackFrame.type !== 'ack') return flatRanges;
372
-
373
- var largest = ackFrame.largest;
374
- var firstRange = ackFrame.firstRange;
375
-
376
- // טווח ראשון: [largest - firstRange, largest]
377
- var rangeEnd = largest;
378
- var rangeStart = rangeEnd - firstRange;
379
- flatRanges.push(rangeStart, rangeEnd);
380
-
381
- // נתחיל לבנות את שאר הטווחים לפי gap+length
382
- var ranges = ackFrame.ranges || [];
383
- for (var i = 0; i < ranges.length; i++) {
384
- var { gap, length } = ranges[i];
385
-
386
- // מעבר אחורה לפי gap
387
- rangeEnd = rangeStart - 1 - gap;
388
- rangeStart = rangeEnd - length;
389
-
390
- flatRanges.push(rangeStart, rangeEnd);
391
- }
392
-
393
- return flatRanges;
394
- }
395
-
396
-
397
- export {
398
- concatUint8Arrays,
399
- arraybufferEqual,
400
- readVarInt,
401
- writeVarInt,
402
- quic_acked_info_to_ranges,
403
- build_ack_info_from_ranges
404
- };