edinburgh 0.1.2
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 +15 -0
- package/README.md +804 -0
- package/build/src/bytes.d.ts +155 -0
- package/build/src/bytes.js +455 -0
- package/build/src/bytes.js.map +1 -0
- package/build/src/edinburgh.d.ts +47 -0
- package/build/src/edinburgh.js +93 -0
- package/build/src/edinburgh.js.map +1 -0
- package/build/src/indexes.d.ts +348 -0
- package/build/src/indexes.js +632 -0
- package/build/src/indexes.js.map +1 -0
- package/build/src/models.d.ts +192 -0
- package/build/src/models.js +457 -0
- package/build/src/models.js.map +1 -0
- package/build/src/types.d.ts +301 -0
- package/build/src/types.js +522 -0
- package/build/src/types.js.map +1 -0
- package/build/src/utils.d.ts +26 -0
- package/build/src/utils.js +32 -0
- package/build/src/utils.js.map +1 -0
- package/package.json +56 -0
- package/src/bytes.ts +500 -0
- package/src/edinburgh.ts +119 -0
- package/src/indexes.ts +810 -0
- package/src/models.ts +519 -0
- package/src/types.ts +635 -0
- package/src/utils.ts +39 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A byte buffer for efficient reading and writing of primitive values and bit sequences.
|
|
3
|
+
*
|
|
4
|
+
* The Bytes class provides methods for serializing and deserializing various data types
|
|
5
|
+
* including numbers, strings, bit sequences, and other primitive values to/from byte buffers.
|
|
6
|
+
* It supports both reading and writing operations with automatic buffer management.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Bytes {
|
|
9
|
+
buffer: Uint8Array;
|
|
10
|
+
readByte: number;
|
|
11
|
+
readBit: number;
|
|
12
|
+
writeByte: number;
|
|
13
|
+
writeBit: number;
|
|
14
|
+
static BASE64_CHARS: string;
|
|
15
|
+
static BASE64_LOOKUP: Uint8Array<ArrayBuffer>;
|
|
16
|
+
/**
|
|
17
|
+
* Create a new Bytes instance.
|
|
18
|
+
* @param data - Optional initial data as Uint8Array or buffer size as number.
|
|
19
|
+
*/
|
|
20
|
+
constructor(data?: Uint8Array | number | undefined);
|
|
21
|
+
/**
|
|
22
|
+
* Reset read position to the beginning of the buffer.
|
|
23
|
+
* @returns This Bytes instance for chaining.
|
|
24
|
+
*/
|
|
25
|
+
reset(): this;
|
|
26
|
+
/**
|
|
27
|
+
* Get the number of bytes written to the buffer.
|
|
28
|
+
* @returns The byte count.
|
|
29
|
+
*/
|
|
30
|
+
byteCount(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Get the number of bits written to the buffer.
|
|
33
|
+
* @returns The bit count.
|
|
34
|
+
*/
|
|
35
|
+
bitCount(): number;
|
|
36
|
+
/**
|
|
37
|
+
* Check if there are more bytes available for reading.
|
|
38
|
+
* @returns true if more bytes can be read.
|
|
39
|
+
*/
|
|
40
|
+
readAvailable(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Read a specific number of bits from the buffer (safe up to 30 bits).
|
|
43
|
+
* @param bits - Number of bits to read (0-30).
|
|
44
|
+
* @param flip - Whether to flip the bit order.
|
|
45
|
+
* @returns The read value as a number.
|
|
46
|
+
*/
|
|
47
|
+
readBits(bits: number, flip?: boolean): number;
|
|
48
|
+
/**
|
|
49
|
+
* Write a specific number of bits to the buffer (safe up to 30 bits).
|
|
50
|
+
* @param value - The value to write.
|
|
51
|
+
* @param bits - Number of bits to write (0-30).
|
|
52
|
+
* @param flip - Whether to flip the bit order.
|
|
53
|
+
* @returns This Bytes instance for chaining.
|
|
54
|
+
*/
|
|
55
|
+
writeBits(value: number, bits: number, flip?: boolean): Bytes;
|
|
56
|
+
/**
|
|
57
|
+
* Write an unsigned integer using only the minimum required bits.
|
|
58
|
+
* @param value - The value to write (must be 0 <= value <= maxValue).
|
|
59
|
+
* @param maxValue - The maximum possible value.
|
|
60
|
+
* @returns This Bytes instance for chaining.
|
|
61
|
+
*/
|
|
62
|
+
writeUIntN(value: number, maxValue: number): Bytes;
|
|
63
|
+
/**
|
|
64
|
+
* Read an unsigned integer that was written with writeUIntN.
|
|
65
|
+
* @param maxValue - The maximum possible value (same as used in writeUIntN).
|
|
66
|
+
* @returns The read value.
|
|
67
|
+
*/
|
|
68
|
+
readUIntN(maxValue: number): number;
|
|
69
|
+
/**
|
|
70
|
+
* Read a Base64-encoded string of specified character count.
|
|
71
|
+
* @param charCount - Number of characters to read.
|
|
72
|
+
* @returns The decoded string.
|
|
73
|
+
*/
|
|
74
|
+
readBase64(charCount: number): string;
|
|
75
|
+
/**
|
|
76
|
+
* Write a Base64-encoded string to the buffer.
|
|
77
|
+
* @param value - The Base64 string to write.
|
|
78
|
+
* @returns This Bytes instance for chaining.
|
|
79
|
+
*/
|
|
80
|
+
writeBase64(value: string): this;
|
|
81
|
+
/**
|
|
82
|
+
* Pad read position to byte boundary.
|
|
83
|
+
*
|
|
84
|
+
* If currently reading in the middle of a byte, advance to the next byte boundary.
|
|
85
|
+
*/
|
|
86
|
+
padReadBits(): void;
|
|
87
|
+
/**
|
|
88
|
+
* Pad write position to byte boundary.
|
|
89
|
+
*
|
|
90
|
+
* If currently writing in the middle of a byte, advance to the next byte boundary.
|
|
91
|
+
*/
|
|
92
|
+
padWriteBits(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Ensure the buffer has capacity for additional bytes.
|
|
95
|
+
* @param additionalBytes - Number of additional bytes needed.
|
|
96
|
+
*/
|
|
97
|
+
ensureCapacity(additionalBytes: number): void;
|
|
98
|
+
/**
|
|
99
|
+
* Write a number to the buffer using efficient encoding.
|
|
100
|
+
*
|
|
101
|
+
* Integers are encoded using variable-length encoding based on their magnitude.
|
|
102
|
+
* Large numbers and floating-point numbers use standard IEEE 754 representation.
|
|
103
|
+
*
|
|
104
|
+
* @param value - The number to write.
|
|
105
|
+
* @returns This Bytes instance for chaining.
|
|
106
|
+
*/
|
|
107
|
+
writeNumber(value: number): Bytes;
|
|
108
|
+
/**
|
|
109
|
+
* Read a number from the buffer.
|
|
110
|
+
*
|
|
111
|
+
* Reads numbers that were written using the writeNumber method,
|
|
112
|
+
* automatically detecting the encoding format.
|
|
113
|
+
*
|
|
114
|
+
* @returns The read number.
|
|
115
|
+
*/
|
|
116
|
+
readNumber(): number;
|
|
117
|
+
/**
|
|
118
|
+
* Write a UTF-8 string to the buffer with null termination.
|
|
119
|
+
* @param value - The string to write.
|
|
120
|
+
* @returns This Bytes instance for chaining.
|
|
121
|
+
*/
|
|
122
|
+
writeString(value: string): Bytes;
|
|
123
|
+
/**
|
|
124
|
+
* Write another Bytes instance to this buffer.
|
|
125
|
+
* @param value - The Bytes instance to write.
|
|
126
|
+
* @returns This Bytes instance for chaining.
|
|
127
|
+
*/
|
|
128
|
+
writeBytes(value: Bytes): Bytes;
|
|
129
|
+
/**
|
|
130
|
+
* Read a Bytes instance from the buffer.
|
|
131
|
+
* @returns A new Bytes instance containing the read data.
|
|
132
|
+
*/
|
|
133
|
+
readBytes(): Bytes;
|
|
134
|
+
/**
|
|
135
|
+
* Read a null-terminated UTF-8 string from the buffer.
|
|
136
|
+
* @returns The decoded string.
|
|
137
|
+
*/
|
|
138
|
+
readString(): string;
|
|
139
|
+
/**
|
|
140
|
+
* Get the current buffer contents as a Uint8Array.
|
|
141
|
+
* @returns A new Uint8Array containing the written data.
|
|
142
|
+
*/
|
|
143
|
+
getBuffer(): Uint8Array;
|
|
144
|
+
/**
|
|
145
|
+
* Create a copy of this Bytes instance.
|
|
146
|
+
* @returns A new Bytes instance with the same content.
|
|
147
|
+
*/
|
|
148
|
+
copy(): Bytes;
|
|
149
|
+
/**
|
|
150
|
+
* Increment the last bit of the buffer. If it was already 1 set it to 0 and
|
|
151
|
+
* increment the previous bit, and so on. If all bits were 1, return undefined.
|
|
152
|
+
*/
|
|
153
|
+
increment(): Bytes | undefined;
|
|
154
|
+
toString(): string;
|
|
155
|
+
}
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
const encoder = new TextEncoder();
|
|
2
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
3
|
+
const BIT_COUNTS = [19, 35, 53]; // Bit counts for large integers
|
|
4
|
+
/**
|
|
5
|
+
* A byte buffer for efficient reading and writing of primitive values and bit sequences.
|
|
6
|
+
*
|
|
7
|
+
* The Bytes class provides methods for serializing and deserializing various data types
|
|
8
|
+
* including numbers, strings, bit sequences, and other primitive values to/from byte buffers.
|
|
9
|
+
* It supports both reading and writing operations with automatic buffer management.
|
|
10
|
+
*/
|
|
11
|
+
export class Bytes {
|
|
12
|
+
buffer;
|
|
13
|
+
readByte = 0;
|
|
14
|
+
readBit = 8;
|
|
15
|
+
writeByte = 0;
|
|
16
|
+
writeBit = 8;
|
|
17
|
+
static BASE64_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$';
|
|
18
|
+
static BASE64_LOOKUP = (() => {
|
|
19
|
+
const arr = new Uint8Array(128); // all ASCII
|
|
20
|
+
for (let i = 0; i < this.BASE64_CHARS.length; ++i)
|
|
21
|
+
arr[this.BASE64_CHARS.charCodeAt(i)] = i;
|
|
22
|
+
return arr;
|
|
23
|
+
})();
|
|
24
|
+
/**
|
|
25
|
+
* Create a new Bytes instance.
|
|
26
|
+
* @param data - Optional initial data as Uint8Array or buffer size as number.
|
|
27
|
+
*/
|
|
28
|
+
constructor(data = undefined) {
|
|
29
|
+
if (data instanceof Uint8Array) {
|
|
30
|
+
this.buffer = data;
|
|
31
|
+
this.writeByte = data.length;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.buffer = new Uint8Array(data ?? 64);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reset read position to the beginning of the buffer.
|
|
39
|
+
* @returns This Bytes instance for chaining.
|
|
40
|
+
*/
|
|
41
|
+
reset() {
|
|
42
|
+
this.readByte = 0;
|
|
43
|
+
this.readBit = 8;
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Get the number of bytes written to the buffer.
|
|
48
|
+
* @returns The byte count.
|
|
49
|
+
*/
|
|
50
|
+
byteCount() {
|
|
51
|
+
return this.writeByte + (this.writeBit < 8 ? 1 : 0);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the number of bits written to the buffer.
|
|
55
|
+
* @returns The bit count.
|
|
56
|
+
*/
|
|
57
|
+
bitCount() {
|
|
58
|
+
return (this.writeByte * 8) + (8 - this.writeBit);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Check if there are more bytes available for reading.
|
|
62
|
+
* @returns true if more bytes can be read.
|
|
63
|
+
*/
|
|
64
|
+
readAvailable() {
|
|
65
|
+
return this.readByte < this.buffer.length;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Read a specific number of bits from the buffer (safe up to 30 bits).
|
|
69
|
+
* @param bits - Number of bits to read (0-30).
|
|
70
|
+
* @param flip - Whether to flip the bit order.
|
|
71
|
+
* @returns The read value as a number.
|
|
72
|
+
*/
|
|
73
|
+
readBits(bits, flip = false) {
|
|
74
|
+
if (bits < 0 || bits > 30) {
|
|
75
|
+
throw new Error('Invalid bit count');
|
|
76
|
+
}
|
|
77
|
+
// Single bounds check upfront
|
|
78
|
+
const totalBitsRemaining = (this.buffer.length - this.readByte) * 8 - (8 - this.readBit);
|
|
79
|
+
if (bits > totalBitsRemaining) {
|
|
80
|
+
throw new Error('Not enough bits available');
|
|
81
|
+
}
|
|
82
|
+
let result = 0;
|
|
83
|
+
let bitsLeft = bits;
|
|
84
|
+
// Process bits while we need them
|
|
85
|
+
while (bitsLeft > 0) {
|
|
86
|
+
const take = Math.min(bitsLeft, this.readBit);
|
|
87
|
+
bitsLeft -= take;
|
|
88
|
+
if (take === 8) { // Fast path for full byte
|
|
89
|
+
result = (result << 8) | this.buffer[this.readByte++];
|
|
90
|
+
// bitPos remains 8, bytePos is incremented
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Extract bits: shift right to get our bits at the bottom, then mask
|
|
94
|
+
const extracted = (this.buffer[this.readByte] >>> (this.readBit - take)) & ((1 << take) - 1);
|
|
95
|
+
// The >>> 0 ensures we treat the result as an unsigned integer
|
|
96
|
+
result = ((result << take) >>> 0) | extracted;
|
|
97
|
+
this.readBit -= take;
|
|
98
|
+
// Move to next byte if current is exhausted
|
|
99
|
+
if (this.readBit == 0) {
|
|
100
|
+
this.readByte++;
|
|
101
|
+
this.readBit = 8;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return flip ? ((1 << bits) - 1) ^ result : result;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Write a specific number of bits to the buffer (safe up to 30 bits).
|
|
109
|
+
* @param value - The value to write.
|
|
110
|
+
* @param bits - Number of bits to write (0-30).
|
|
111
|
+
* @param flip - Whether to flip the bit order.
|
|
112
|
+
* @returns This Bytes instance for chaining.
|
|
113
|
+
*/
|
|
114
|
+
writeBits(value, bits, flip = false) {
|
|
115
|
+
if (bits < 0 || bits > 30) {
|
|
116
|
+
throw new Error('Invalid bit count');
|
|
117
|
+
}
|
|
118
|
+
value = flip ? ((1 << bits) - 1) ^ value : value;
|
|
119
|
+
this.ensureCapacity(1 + (bits >>> 3));
|
|
120
|
+
while (bits > 0) {
|
|
121
|
+
const bitsToWriteNow = Math.min(bits, this.writeBit);
|
|
122
|
+
bits -= bitsToWriteNow;
|
|
123
|
+
if (bitsToWriteNow === 8) { // Fast path for full bytes
|
|
124
|
+
this.buffer[this.writeByte++] = (value >>> bits) & 0xff;
|
|
125
|
+
// bitPos remains 8, bytePos is incremented
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const extracted = (value >>> bits) & ((1 << bitsToWriteNow) - 1);
|
|
129
|
+
this.buffer[this.writeByte] |= extracted << (this.writeBit - bitsToWriteNow);
|
|
130
|
+
this.writeBit -= bitsToWriteNow;
|
|
131
|
+
// Advance to next byte if current byte is full
|
|
132
|
+
if (this.writeBit === 0) {
|
|
133
|
+
this.writeByte++;
|
|
134
|
+
this.writeBit = 8;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Write an unsigned integer using only the minimum required bits.
|
|
142
|
+
* @param value - The value to write (must be 0 <= value <= maxValue).
|
|
143
|
+
* @param maxValue - The maximum possible value.
|
|
144
|
+
* @returns This Bytes instance for chaining.
|
|
145
|
+
*/
|
|
146
|
+
writeUIntN(value, maxValue) {
|
|
147
|
+
if (!Number.isInteger(value) || value < 0 || value > maxValue) {
|
|
148
|
+
throw new Error(`Value out of range: ${value} (max: ${maxValue})`);
|
|
149
|
+
}
|
|
150
|
+
const bitsNeeded = Math.ceil(Math.log2(maxValue + 1));
|
|
151
|
+
this.writeBits(value, bitsNeeded);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Read an unsigned integer that was written with writeUIntN.
|
|
156
|
+
* @param maxValue - The maximum possible value (same as used in writeUIntN).
|
|
157
|
+
* @returns The read value.
|
|
158
|
+
*/
|
|
159
|
+
readUIntN(maxValue) {
|
|
160
|
+
if (maxValue < 0) {
|
|
161
|
+
throw new Error(`Invalid max value: ${maxValue}`);
|
|
162
|
+
}
|
|
163
|
+
const bitsNeeded = Math.ceil(Math.log2(maxValue + 1));
|
|
164
|
+
return this.readBits(bitsNeeded);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Read a Base64-encoded string of specified character count.
|
|
168
|
+
* @param charCount - Number of characters to read.
|
|
169
|
+
* @returns The decoded string.
|
|
170
|
+
*/
|
|
171
|
+
readBase64(charCount) {
|
|
172
|
+
let result = '';
|
|
173
|
+
for (let i = 0; i < charCount; i++) {
|
|
174
|
+
result += Bytes.BASE64_CHARS[this.readBits(6)];
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Write a Base64-encoded string to the buffer.
|
|
180
|
+
* @param value - The Base64 string to write.
|
|
181
|
+
* @returns This Bytes instance for chaining.
|
|
182
|
+
*/
|
|
183
|
+
writeBase64(value) {
|
|
184
|
+
this.ensureCapacity(Math.ceil(value.length * 6 / 8));
|
|
185
|
+
for (let i = 0; i < value.length; i++) {
|
|
186
|
+
const v = Bytes.BASE64_LOOKUP[value.charCodeAt(i)];
|
|
187
|
+
if (v == undefined)
|
|
188
|
+
throw new Error(`Invalid Base64 character: ${value[i]}`);
|
|
189
|
+
this.writeBits(v, 6);
|
|
190
|
+
}
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Pad read position to byte boundary.
|
|
195
|
+
*
|
|
196
|
+
* If currently reading in the middle of a byte, advance to the next byte boundary.
|
|
197
|
+
*/
|
|
198
|
+
padReadBits() {
|
|
199
|
+
// If we have any bits left in the current byte, pad them to 8
|
|
200
|
+
if (this.readBit < 8) {
|
|
201
|
+
this.readByte++;
|
|
202
|
+
this.readBit = 8;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Pad write position to byte boundary.
|
|
207
|
+
*
|
|
208
|
+
* If currently writing in the middle of a byte, advance to the next byte boundary.
|
|
209
|
+
*/
|
|
210
|
+
padWriteBits() {
|
|
211
|
+
// If we have any bits left in the current byte, pad them to 8
|
|
212
|
+
if (this.writeBit < 8) {
|
|
213
|
+
this.writeByte++;
|
|
214
|
+
this.writeBit = 8;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Ensure the buffer has capacity for additional bytes.
|
|
219
|
+
* @param additionalBytes - Number of additional bytes needed.
|
|
220
|
+
*/
|
|
221
|
+
ensureCapacity(additionalBytes) {
|
|
222
|
+
const needed = this.writeByte + additionalBytes + 1;
|
|
223
|
+
if (needed <= this.buffer.length)
|
|
224
|
+
return;
|
|
225
|
+
// Grow by 1.5x or the needed amount, whichever is larger
|
|
226
|
+
const newCapacity = Math.max(needed, Math.floor(this.buffer.length * 1.5));
|
|
227
|
+
const newBuffer = new Uint8Array(newCapacity);
|
|
228
|
+
newBuffer.set(this.buffer.subarray(0, this.byteCount()));
|
|
229
|
+
this.buffer = newBuffer;
|
|
230
|
+
}
|
|
231
|
+
/*
|
|
232
|
+
* 5 bit header
|
|
233
|
+
*
|
|
234
|
+
* 0-2: negative integer with 53, 35 or 19 bits
|
|
235
|
+
* 3-14: negative integer with 12..1 bits (the first bit is always 1, and thus left unwritten)
|
|
236
|
+
* 15: literal 0
|
|
237
|
+
* 16-27: positive integer with 1..12 bits (the first bit is always 1, and thus left unwritten)
|
|
238
|
+
* 28-30: positive integer with 19, 35 or 53 bits
|
|
239
|
+
* 31: float64 number (follows after bit padding)
|
|
240
|
+
*
|
|
241
|
+
* Some examples:
|
|
242
|
+
* 3 bits (incl sign) fit in 6 bits
|
|
243
|
+
* 5 bits (incl sign) fit in 8 bits (1 byte)
|
|
244
|
+
* 6 bits (incl sign) fit in 9 bits
|
|
245
|
+
* 20 bits (incl sign) fit in 24 bits (3 bytes)
|
|
246
|
+
* 36 bits (incl sign) fit in 40 bits (5 bytes)
|
|
247
|
+
* 54 bits (incl sign) fit in 58 bits
|
|
248
|
+
*/
|
|
249
|
+
/**
|
|
250
|
+
* Write a number to the buffer using efficient encoding.
|
|
251
|
+
*
|
|
252
|
+
* Integers are encoded using variable-length encoding based on their magnitude.
|
|
253
|
+
* Large numbers and floating-point numbers use standard IEEE 754 representation.
|
|
254
|
+
*
|
|
255
|
+
* @param value - The number to write.
|
|
256
|
+
* @returns This Bytes instance for chaining.
|
|
257
|
+
*/
|
|
258
|
+
writeNumber(value) {
|
|
259
|
+
if (Number.isInteger(value) && value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER) {
|
|
260
|
+
// 33 bit integer (incl sign)
|
|
261
|
+
let num = Math.abs(value);
|
|
262
|
+
let bitCount = Math.ceil(Math.log2(num + 1)); // 0 (for literal 0) til 32 (inclusive)
|
|
263
|
+
const isNegative = value < 0;
|
|
264
|
+
if (bitCount < 13) {
|
|
265
|
+
this.writeBits(isNegative ? 15 - bitCount : 15 + bitCount, 5); // header
|
|
266
|
+
// Don't write the leading 1 bit
|
|
267
|
+
if (bitCount > 1)
|
|
268
|
+
this.writeBits(0 | num, bitCount - 1, isNegative); // value
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
const sizeOption = bitCount <= 19 ? 0 : (bitCount <= 35 ? 1 : 2);
|
|
272
|
+
bitCount = BIT_COUNTS[sizeOption];
|
|
273
|
+
this.writeBits(isNegative ? 2 - sizeOption : 28 + sizeOption, 5); // header
|
|
274
|
+
if (bitCount <= 30) {
|
|
275
|
+
this.writeBits(0 | num, bitCount, isNegative); // data
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.writeBits(0 | (num / 0x40000000), bitCount - 30, isNegative); // most significant bits
|
|
279
|
+
this.writeBits(num & 0x3fffffff, 30, isNegative); // least significant bits
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
// Float or large integer
|
|
285
|
+
this.writeBits(31, 5); // header for float
|
|
286
|
+
this.padWriteBits(); // Ensure we are byte-aligned
|
|
287
|
+
this.ensureCapacity(8); // float64 takes 8 bytes
|
|
288
|
+
const float64Array = new Float64Array(1);
|
|
289
|
+
float64Array[0] = value;
|
|
290
|
+
const bytes = new Uint8Array(float64Array.buffer);
|
|
291
|
+
this.buffer.set(bytes, this.writeByte);
|
|
292
|
+
this.writeByte += 8;
|
|
293
|
+
}
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Read a number from the buffer.
|
|
298
|
+
*
|
|
299
|
+
* Reads numbers that were written using the writeNumber method,
|
|
300
|
+
* automatically detecting the encoding format.
|
|
301
|
+
*
|
|
302
|
+
* @returns The read number.
|
|
303
|
+
*/
|
|
304
|
+
readNumber() {
|
|
305
|
+
const header = this.readBits(5);
|
|
306
|
+
if (header === 15) {
|
|
307
|
+
// Literal 0
|
|
308
|
+
return 0;
|
|
309
|
+
}
|
|
310
|
+
if (header === 31) {
|
|
311
|
+
// Float64
|
|
312
|
+
this.padReadBits();
|
|
313
|
+
const bytes = new Uint8Array(8);
|
|
314
|
+
for (let i = 0; i < 8; i++) {
|
|
315
|
+
bytes[i] = this.readBits(8);
|
|
316
|
+
}
|
|
317
|
+
return new Float64Array(bytes.buffer)[0];
|
|
318
|
+
}
|
|
319
|
+
// Integer handling - determine if positive/negative and get size
|
|
320
|
+
const isNegative = header < 15;
|
|
321
|
+
let value, bitCount;
|
|
322
|
+
if (header < 3 || header > 27) {
|
|
323
|
+
// Large integers
|
|
324
|
+
const sizeOption = isNegative ? 2 - header : header - 28;
|
|
325
|
+
bitCount = BIT_COUNTS[sizeOption];
|
|
326
|
+
if (bitCount <= 30) {
|
|
327
|
+
value = this.readBits(bitCount, isNegative);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
// Read the two parts of the large integer
|
|
331
|
+
value = this.readBits(bitCount - 30, isNegative) * 1073741824 + this.readBits(30, isNegative);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
// Small integers: reconstruct bits with implicit leading 1
|
|
336
|
+
bitCount = isNegative ? 15 - header : header - 15;
|
|
337
|
+
// Read bits and add implicit leading 1
|
|
338
|
+
value = this.readBits(bitCount - 1, isNegative) | (1 << (bitCount - 1));
|
|
339
|
+
}
|
|
340
|
+
return isNegative ? -value : value;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Write a UTF-8 string to the buffer with null termination.
|
|
344
|
+
* @param value - The string to write.
|
|
345
|
+
* @returns This Bytes instance for chaining.
|
|
346
|
+
*/
|
|
347
|
+
writeString(value) {
|
|
348
|
+
// Escape 0 characters and escape characters
|
|
349
|
+
value = value.replace(/[\u0001\u0000]/g, (match) => match === '\u0001' ? '\u0001e' : '\u0001z');
|
|
350
|
+
const encoded = encoder.encode(value);
|
|
351
|
+
this.padWriteBits();
|
|
352
|
+
this.ensureCapacity(encoded.length + 1); // +1 for null terminator
|
|
353
|
+
this.buffer.set(encoded, this.writeByte);
|
|
354
|
+
this.writeByte += encoded.length;
|
|
355
|
+
this.buffer[this.writeByte++] = 0; // Null terminator
|
|
356
|
+
return this;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Write another Bytes instance to this buffer.
|
|
360
|
+
* @param value - The Bytes instance to write.
|
|
361
|
+
* @returns This Bytes instance for chaining.
|
|
362
|
+
*/
|
|
363
|
+
writeBytes(value) {
|
|
364
|
+
let size = value.byteCount();
|
|
365
|
+
this.writeNumber(size);
|
|
366
|
+
this.padWriteBits();
|
|
367
|
+
this.ensureCapacity(size);
|
|
368
|
+
this.buffer.set(value.buffer, this.writeByte);
|
|
369
|
+
this.writeByte += size;
|
|
370
|
+
return this;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Read a Bytes instance from the buffer.
|
|
374
|
+
* @returns A new Bytes instance containing the read data.
|
|
375
|
+
*/
|
|
376
|
+
readBytes() {
|
|
377
|
+
const size = this.readNumber();
|
|
378
|
+
if (size < 0 || size > this.buffer.length - this.readByte) {
|
|
379
|
+
throw new Error('Invalid byte size read');
|
|
380
|
+
}
|
|
381
|
+
const bytes = new Bytes(this.buffer.subarray(this.readByte, this.readByte + size));
|
|
382
|
+
this.readByte += size;
|
|
383
|
+
return bytes;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Read a null-terminated UTF-8 string from the buffer.
|
|
387
|
+
* @returns The decoded string.
|
|
388
|
+
*/
|
|
389
|
+
readString() {
|
|
390
|
+
this.padReadBits();
|
|
391
|
+
const start = this.readByte;
|
|
392
|
+
const end = this.buffer.indexOf(0, start);
|
|
393
|
+
if (end < 0) {
|
|
394
|
+
throw new Error('String not null-terminated');
|
|
395
|
+
}
|
|
396
|
+
const encoded = this.buffer.subarray(start, end);
|
|
397
|
+
this.readByte = end + 1; // Skip null terminator
|
|
398
|
+
// Decode and unescape
|
|
399
|
+
let value = decoder.decode(encoded);
|
|
400
|
+
value = value.replace(/\u0001[ez]/g, (m) => m === '\u0001e' ? '\u0001' : '\u0000');
|
|
401
|
+
return value;
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get the current buffer contents as a Uint8Array.
|
|
405
|
+
* @returns A new Uint8Array containing the written data.
|
|
406
|
+
*/
|
|
407
|
+
getBuffer() {
|
|
408
|
+
return this.buffer.subarray(0, this.byteCount());
|
|
409
|
+
}
|
|
410
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
411
|
+
return Array.from(this.getBuffer())
|
|
412
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
413
|
+
.join(' ') + ` (${this.byteCount()} bytes)`;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Create a copy of this Bytes instance.
|
|
417
|
+
* @returns A new Bytes instance with the same content.
|
|
418
|
+
*/
|
|
419
|
+
copy() {
|
|
420
|
+
const result = new Bytes(this.buffer.slice(0));
|
|
421
|
+
result.writeByte = this.writeByte;
|
|
422
|
+
result.writeBit = this.writeBit;
|
|
423
|
+
return result;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Increment the last bit of the buffer. If it was already 1 set it to 0 and
|
|
427
|
+
* increment the previous bit, and so on. If all bits were 1, return undefined.
|
|
428
|
+
*/
|
|
429
|
+
increment() {
|
|
430
|
+
let startBit = this.writeBit;
|
|
431
|
+
for (let byte = this.writeByte; byte >= 0; byte--) {
|
|
432
|
+
for (let bit = startBit; bit < 8; bit++) {
|
|
433
|
+
const shift = 1 << bit;
|
|
434
|
+
if (this.buffer[byte] & shift) {
|
|
435
|
+
// Bit was 1, set to 0 and continue
|
|
436
|
+
this.buffer[byte] &= ~shift;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
// Bit was 0, set to 1 and return
|
|
440
|
+
this.buffer[byte] |= shift;
|
|
441
|
+
return this;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
startBit = 0;
|
|
445
|
+
}
|
|
446
|
+
return undefined; // All bits were 1 (and are now 0)
|
|
447
|
+
}
|
|
448
|
+
toString() {
|
|
449
|
+
// Convert this.getBuffer() as utf8 to a string, escaping non-printable characters:
|
|
450
|
+
return Array.from(this.getBuffer())
|
|
451
|
+
.map(b => b < 32 || b > 126 ? `\\x${b.toString(16).padStart(2, '0')}` : String.fromCharCode(b))
|
|
452
|
+
.join('');
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
//# sourceMappingURL=bytes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../src/bytes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export { Model, registerModel, field, setOnSaveCallback } from "./models.js";
|
|
2
|
+
export { string, number, boolean, identifier, undef, opt, or, array, literal, link, } from "./types.js";
|
|
3
|
+
export { index, primary, unique, dump, } from "./indexes.js";
|
|
4
|
+
export { BaseIndex, UniqueIndex, PrimaryIndex } from './indexes.js';
|
|
5
|
+
export { init, onCommit, onRevert, getTransactionData, setTransactionData, DatabaseError } from "olmdb";
|
|
6
|
+
/**
|
|
7
|
+
* Executes a function within a database transaction context.
|
|
8
|
+
*
|
|
9
|
+
* Loading models (also through links in other models) and changing models can only be done from
|
|
10
|
+
* within a transaction.
|
|
11
|
+
*
|
|
12
|
+
* Transactions have a consistent view of the database, and changes made within a transaction are
|
|
13
|
+
* isolated from other transactions until they are committed. In case a commit clashes with changes
|
|
14
|
+
* made by another transaction, the transaction function will automatically be re-executed up to 10
|
|
15
|
+
* times.
|
|
16
|
+
*
|
|
17
|
+
* @template T - The return type of the transaction function.
|
|
18
|
+
* @param fn - The function to execute within the transaction context.
|
|
19
|
+
* @returns A promise that resolves with the function's return value.
|
|
20
|
+
* @throws {TypeError} If nested transactions are attempted.
|
|
21
|
+
* @throws {DatabaseError} With code "RACING_TRANSACTION" if the transaction fails after retries due to conflicts.
|
|
22
|
+
* @throws {DatabaseError} With code "TRANSACTION_FAILED" if the transaction fails for other reasons.
|
|
23
|
+
* @throws {DatabaseError} With code "TXN_LIMIT" if maximum number of transactions is reached.
|
|
24
|
+
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const paid = await E.transact(() => {
|
|
29
|
+
* const user = User.load("john_doe");
|
|
30
|
+
* // This is concurrency-safe - the function will rerun if it is raced by another transaction
|
|
31
|
+
* if (user.credits > 0) {
|
|
32
|
+
* user.credits--;
|
|
33
|
+
* return true;
|
|
34
|
+
* }
|
|
35
|
+
* return false;
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
* ```typescript
|
|
39
|
+
* // Transaction with automatic retry on conflicts
|
|
40
|
+
* await E.transact(() => {
|
|
41
|
+
* const counter = Counter.load("global") || new Counter({id: "global", value: 0});
|
|
42
|
+
* counter.value++;
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function transact<T>(fn: () => T): Promise<T>;
|
|
47
|
+
export declare function deleteEverything(): Promise<void>;
|