ordered-binary 1.6.0 → 1.6.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/.claude/worktrees/bun-finishutf8/LICENSE +21 -0
- package/.claude/worktrees/bun-finishutf8/README.md +38 -0
- package/.claude/worktrees/bun-finishutf8/assets/powers-dre.png +0 -0
- package/.claude/worktrees/bun-finishutf8/dist/index.cjs +464 -0
- package/.claude/worktrees/bun-finishutf8/index.d.ts +23 -0
- package/.claude/worktrees/bun-finishutf8/index.js +450 -0
- package/.claude/worktrees/bun-finishutf8/package-lock.json +1163 -0
- package/.claude/worktrees/bun-finishutf8/package.json +37 -0
- package/.claude/worktrees/bun-finishutf8/rollup.config.js +11 -0
- package/.claude/worktrees/bun-finishutf8/tests/test.js +181 -0
- package/dist/index.cjs +12 -2
- package/index.js +12 -2
- package/package.json +1 -1
- package/tests/test.js +2 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ordered-binary",
|
|
3
|
+
"author": "Kris Zyp",
|
|
4
|
+
"version": "1.6.1",
|
|
5
|
+
"description": "Conversion of JavaScript primitives to and from Buffer with binary order matching natural primitive order",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "http://github.com/kriszyp/ordered-binary"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "rollup -c",
|
|
13
|
+
"prepare": "rollup -c",
|
|
14
|
+
"test": "mocha tests -u tdd"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "dist/index.cjs",
|
|
18
|
+
"module": "index.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"require": "./dist/index.cjs",
|
|
22
|
+
"import": "./index.js"
|
|
23
|
+
},
|
|
24
|
+
"./index.js": {
|
|
25
|
+
"require": "./dist/index.cjs",
|
|
26
|
+
"import": "./index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"typings": "./index.d.ts",
|
|
30
|
+
"optionalDependencies": {},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "latest",
|
|
33
|
+
"chai": "^4",
|
|
34
|
+
"mocha": "^9.2.0",
|
|
35
|
+
"rollup": "^2.61.1"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { assert } from 'chai'
|
|
2
|
+
|
|
3
|
+
import { toBufferKey, fromBufferKey, readKey, writeKey } from '../index.js'
|
|
4
|
+
|
|
5
|
+
function assertBufferComparison(lesser, greater) {
|
|
6
|
+
for (let i = 0; i < lesser.length; i++) {
|
|
7
|
+
if (lesser[i] < greater[i]) {
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
if (lesser[i] > (greater[i] || 0)) {
|
|
11
|
+
assert.fail('Byte ' + i + 'should not be ' + lesser[i] + '>' + greater[i])
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//var inspector = require('inspector'); inspector.open(9330, null, true); debugger
|
|
16
|
+
let seed = 0;
|
|
17
|
+
export function random() {
|
|
18
|
+
seed++;
|
|
19
|
+
let a = seed * 15485863;
|
|
20
|
+
return ((a * a * a) % 2038074743) / 2038074743;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
suite('key buffers', () => {
|
|
24
|
+
|
|
25
|
+
test('numbers equivalence', () => {
|
|
26
|
+
assert.strictEqual(fromBufferKey(toBufferKey(4)), 4)
|
|
27
|
+
assert.strictEqual(fromBufferKey(toBufferKey(-4)), -4)
|
|
28
|
+
assert.strictEqual(fromBufferKey(toBufferKey(3.4)), 3.4)
|
|
29
|
+
assert.strictEqual(fromBufferKey(toBufferKey(Math.PI)), Math.PI)
|
|
30
|
+
assert.strictEqual(fromBufferKey(toBufferKey(2002225)), 2002225)
|
|
31
|
+
// check to make sure it works with a limited ArrayBuffer
|
|
32
|
+
assert.strictEqual(fromBufferKey(new Uint8Array(toBufferKey(2002225))), 2002225)
|
|
33
|
+
assert.strictEqual(fromBufferKey(toBufferKey(9377288)), 9377288)
|
|
34
|
+
assert.strictEqual(fromBufferKey(toBufferKey(1503579323825)), 1503579323825)
|
|
35
|
+
assert.strictEqual(fromBufferKey(toBufferKey(1503579323825.3523532)), 1503579323825.3523532)
|
|
36
|
+
assert.strictEqual(fromBufferKey(toBufferKey(-1503579323825)), -1503579323825)
|
|
37
|
+
assert.strictEqual(fromBufferKey(toBufferKey(0.00005032)), 0.00005032)
|
|
38
|
+
assert.strictEqual(fromBufferKey(toBufferKey(-0.00005032)), -0.00005032)
|
|
39
|
+
assert.strictEqual(fromBufferKey(toBufferKey(0.00000000000000000000000005431)), 0.00000000000000000000000005431)
|
|
40
|
+
})
|
|
41
|
+
test('within buffer equivalence', () => {
|
|
42
|
+
let buffer = Buffer.alloc(1024, 0xff);
|
|
43
|
+
let length = writeKey(2002225, buffer, 0);
|
|
44
|
+
let position = length;
|
|
45
|
+
buffer[position++] = 0xff;
|
|
46
|
+
buffer[position++] = 0xff;
|
|
47
|
+
assert.strictEqual(readKey(buffer, 0, length), 2002225);
|
|
48
|
+
length = writeKey('hello, world', buffer, 0);
|
|
49
|
+
assert.strictEqual(readKey(buffer, 0, length), 'hello, world');
|
|
50
|
+
// ensure that reading the string didn't modify the buffer after the string (or is restored at least)
|
|
51
|
+
assert.strictEqual(buffer[length], 0xff);
|
|
52
|
+
});
|
|
53
|
+
test('number comparison', () => {
|
|
54
|
+
assertBufferComparison(toBufferKey(4), toBufferKey(5))
|
|
55
|
+
assertBufferComparison(toBufferKey(1503579323824), toBufferKey(1503579323825))
|
|
56
|
+
assertBufferComparison(toBufferKey(1.4), toBufferKey(2))
|
|
57
|
+
assertBufferComparison(toBufferKey(0.000000001), toBufferKey(0.00000001))
|
|
58
|
+
assertBufferComparison(toBufferKey(-4), toBufferKey(3))
|
|
59
|
+
assertBufferComparison(toBufferKey(0), toBufferKey(1))
|
|
60
|
+
assertBufferComparison(toBufferKey(-0.001), toBufferKey(0))
|
|
61
|
+
assertBufferComparison(toBufferKey(-0.001), toBufferKey(-0.000001))
|
|
62
|
+
assertBufferComparison(toBufferKey(-5236532532532), toBufferKey(-5236532532531))
|
|
63
|
+
})
|
|
64
|
+
test('bigint equivalence', () => {
|
|
65
|
+
assert.strictEqual(fromBufferKey(toBufferKey(-35913040084491349n)), -35913040084491349n)
|
|
66
|
+
assert.strictEqual(fromBufferKey(toBufferKey(6135421331404949076605986n)), 6135421331404949076605986n)
|
|
67
|
+
assert.strictEqual(fromBufferKey(toBufferKey(0xfffffffffffffffffffffn)), 0xfffffffffffffffffffffn)
|
|
68
|
+
assert.strictEqual(fromBufferKey(toBufferKey(12345678901234567890n)), 12345678901234567890n)
|
|
69
|
+
assert.deepEqual(fromBufferKey(toBufferKey([12345678901234567890n, 44])), [12345678901234567890n, 44])
|
|
70
|
+
assert.deepEqual(fromBufferKey(toBufferKey(['hi', 12345678901234567890n])), ['hi', 12345678901234567890n])
|
|
71
|
+
assert.deepEqual(fromBufferKey(toBufferKey([6135421331404949076605986n, 'after'])), [6135421331404949076605986n, 'after'])
|
|
72
|
+
assert.strictEqual(fromBufferKey(toBufferKey(132923456789012345678903533235253252353211125n)), 132923456789012345678903533235253252353211125n)
|
|
73
|
+
assert.strictEqual(fromBufferKey(toBufferKey(352n)), 352)
|
|
74
|
+
let num = 5325n
|
|
75
|
+
for (let i = 0; i < 1100; i++) {
|
|
76
|
+
num *= BigInt(Math.floor(random() * 3 + 1));
|
|
77
|
+
num -= BigInt(Math.floor(random() * 1000));
|
|
78
|
+
assert.strictEqual(BigInt(fromBufferKey(toBufferKey(num))), num)
|
|
79
|
+
assert.strictEqual(BigInt(fromBufferKey(toBufferKey(-num))), -num)
|
|
80
|
+
}
|
|
81
|
+
assert.strictEqual(fromBufferKey(toBufferKey(-352n)), -352)
|
|
82
|
+
})
|
|
83
|
+
test('bigint comparison', () => {
|
|
84
|
+
assertBufferComparison(toBufferKey(0xfffffffffffffffffffffn), toBufferKey(0x100fffffffffffffffffffn))
|
|
85
|
+
assertBufferComparison(toBufferKey(12345678901234567890), toBufferKey(12345678901234567890n))
|
|
86
|
+
assertBufferComparison(toBufferKey(6135421331404949076605986n), toBufferKey(6135421331404949076605987n))
|
|
87
|
+
assertBufferComparison(toBufferKey(-6135421331404949076605986n), toBufferKey(-6135421331404949076605985n))
|
|
88
|
+
assertBufferComparison(toBufferKey(-35913040084491349n), toBufferKey(-35913040084491348n))
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
test('string equivalence', () => {
|
|
92
|
+
assert.strictEqual(fromBufferKey(toBufferKey('4')), '4')
|
|
93
|
+
assert.strictEqual(fromBufferKey(toBufferKey('hello')), 'hello')
|
|
94
|
+
assert.strictEqual(fromBufferKey(toBufferKey('')), '')
|
|
95
|
+
assert.strictEqual(fromBufferKey(toBufferKey('\x00')), '\x00')
|
|
96
|
+
assert.strictEqual(fromBufferKey(toBufferKey('\x03test\x01\x00')), '\x03test\x01\x00')
|
|
97
|
+
assert.strictEqual(fromBufferKey(toBufferKey('prance 🧚🏻♀️🩷')), 'prance 🧚🏻♀️🩷')
|
|
98
|
+
})
|
|
99
|
+
test('string comparison', () => {
|
|
100
|
+
assertBufferComparison(toBufferKey('4'), toBufferKey('5'))
|
|
101
|
+
assertBufferComparison(toBufferKey('and'), toBufferKey('bad'))
|
|
102
|
+
assertBufferComparison(toBufferKey('hello'), toBufferKey('hello2'))
|
|
103
|
+
let buffer = Buffer.alloc(1024)
|
|
104
|
+
let end = writeKey(['this is a test', 5.25], buffer, 0)
|
|
105
|
+
})
|
|
106
|
+
test('boolean equivalence', () => {
|
|
107
|
+
assert.strictEqual(fromBufferKey(toBufferKey(true)), true)
|
|
108
|
+
assert.strictEqual(fromBufferKey(toBufferKey(false)), false)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('multipart equivalence', () => {
|
|
112
|
+
assert.deepEqual(fromBufferKey(toBufferKey([4, 5])),
|
|
113
|
+
[4, 5])
|
|
114
|
+
assert.deepEqual(fromBufferKey(toBufferKey(['hello', 5.25])),
|
|
115
|
+
['hello', 5.25])
|
|
116
|
+
assert.deepEqual(fromBufferKey(toBufferKey([5, 'hello', null, 5.25])),
|
|
117
|
+
[5, 'hello', null, 5.25])
|
|
118
|
+
assert.deepEqual(fromBufferKey(toBufferKey([true, 1503579323825])),
|
|
119
|
+
[true, 1503579323825])
|
|
120
|
+
assert.deepEqual(fromBufferKey(toBufferKey([-0.2525, 'sec\x00nd'])),
|
|
121
|
+
[-0.2525, 'sec\x00nd'])
|
|
122
|
+
assert.deepEqual(fromBufferKey(toBufferKey([-0.2525, '2nd', '3rd'])),
|
|
123
|
+
[-0.2525, '2nd', '3rd'])
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
test('multipart comparison', () => {
|
|
127
|
+
assertBufferComparison(
|
|
128
|
+
Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey(5)]),
|
|
129
|
+
Buffer.concat([toBufferKey(5), Buffer.from([30]), toBufferKey(5)]))
|
|
130
|
+
assertBufferComparison(
|
|
131
|
+
Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey(5)]),
|
|
132
|
+
Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey(6)]))
|
|
133
|
+
assertBufferComparison(
|
|
134
|
+
Buffer.concat([toBufferKey('and'), Buffer.from([30]), toBufferKey(5)]),
|
|
135
|
+
Buffer.concat([toBufferKey('and2'), Buffer.from([30]), toBufferKey(5)]))
|
|
136
|
+
assertBufferComparison(
|
|
137
|
+
Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey('and')]),
|
|
138
|
+
Buffer.concat([toBufferKey(4), Buffer.from([30]), toBufferKey('cat')]))
|
|
139
|
+
})
|
|
140
|
+
test('performance', () => {
|
|
141
|
+
let buffer = Buffer.alloc(1024)
|
|
142
|
+
let start = process.hrtime.bigint()
|
|
143
|
+
let end, value
|
|
144
|
+
for (let i = 0; i < 1000000; i++) {
|
|
145
|
+
end = writeKey('this is a test of a longer string to read and write', buffer, 0)
|
|
146
|
+
}
|
|
147
|
+
console.log('writeKey string time', nextTime(), end)
|
|
148
|
+
for (let i = 0; i < 1000000; i++) {
|
|
149
|
+
value = readKey(buffer, 0, end)
|
|
150
|
+
}
|
|
151
|
+
console.log('readKey string time', nextTime(), value)
|
|
152
|
+
|
|
153
|
+
for (let i = 0; i < 1000000; i++) {
|
|
154
|
+
end = writeKey(33456, buffer, 0)
|
|
155
|
+
}
|
|
156
|
+
console.log('writeKey number time', nextTime(), end)
|
|
157
|
+
|
|
158
|
+
for (let i = 0; i < 1000000; i++) {
|
|
159
|
+
value = readKey(buffer, 2, end)
|
|
160
|
+
}
|
|
161
|
+
console.log('readKey number time', nextTime(), value)
|
|
162
|
+
|
|
163
|
+
for (let i = 0; i < 1000000; i++) {
|
|
164
|
+
end = writeKey(['hello', 33456], buffer, 0)
|
|
165
|
+
}
|
|
166
|
+
console.log('writeKey array time', nextTime(), end, buffer.slice(0, end))
|
|
167
|
+
|
|
168
|
+
for (let i = 0; i < 1000000; i++) {
|
|
169
|
+
value = readKey(buffer, 0, end)
|
|
170
|
+
}
|
|
171
|
+
console.log('readKey array time', nextTime(), value)
|
|
172
|
+
|
|
173
|
+
function nextTime() {
|
|
174
|
+
let ns = process.hrtime.bigint()
|
|
175
|
+
let elapsed = ns - start
|
|
176
|
+
start = ns
|
|
177
|
+
return Number(elapsed) / 1000000 + 'ns'
|
|
178
|
+
}
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
})
|
package/dist/index.cjs
CHANGED
|
@@ -212,7 +212,12 @@ function readKey(buffer, start, end, inSequence) {
|
|
|
212
212
|
let size = end - position;
|
|
213
213
|
let lowInt;
|
|
214
214
|
if (size > 4) {
|
|
215
|
-
lowInt = dataView.getInt32(position + 4)
|
|
215
|
+
lowInt = position + 8 <= buffer.length ? dataView.getInt32(position + 4) : (
|
|
216
|
+
buffer[position + 4] << 24 |
|
|
217
|
+
buffer[position + 5] << 16 |
|
|
218
|
+
buffer[position + 6] << 8 |
|
|
219
|
+
buffer[position + 7]
|
|
220
|
+
);
|
|
216
221
|
highInt |= lowInt >>> 28;
|
|
217
222
|
if (size <= 6) { // clear the last bits
|
|
218
223
|
lowInt &= -0x10000;
|
|
@@ -372,7 +377,12 @@ const readString =
|
|
|
372
377
|
position = getPosition();
|
|
373
378
|
return value;
|
|
374
379
|
};
|
|
375
|
-
})((new Function('fromCharCode', 'let position; let
|
|
380
|
+
})((new Function('fromCharCode', 'let position; let pendingSurrogate; ' +
|
|
381
|
+
// finishUtf8 references `position`/`pendingSurrogate`, but new Function compiles
|
|
382
|
+
// in global scope and can't close over the module-level copies, so embed its
|
|
383
|
+
// source here to bind it to this function's local (synced) `position`.
|
|
384
|
+
'let finishUtf8 = ' + finishUtf8.toString() + '; ' +
|
|
385
|
+
'let readString = ' + makeStringBuilder() +
|
|
376
386
|
';return {' +
|
|
377
387
|
'setPosition(p) { position = p },' +
|
|
378
388
|
'getPosition() { return position },' +
|
package/index.js
CHANGED
|
@@ -208,7 +208,12 @@ export function readKey(buffer, start, end, inSequence) {
|
|
|
208
208
|
let size = end - position
|
|
209
209
|
let lowInt
|
|
210
210
|
if (size > 4) {
|
|
211
|
-
lowInt = dataView.getInt32(position + 4)
|
|
211
|
+
lowInt = position + 8 <= buffer.length ? dataView.getInt32(position + 4) : (
|
|
212
|
+
buffer[position + 4] << 24 |
|
|
213
|
+
buffer[position + 5] << 16 |
|
|
214
|
+
buffer[position + 6] << 8 |
|
|
215
|
+
buffer[position + 7]
|
|
216
|
+
)
|
|
212
217
|
highInt |= lowInt >>> 28
|
|
213
218
|
if (size <= 6) { // clear the last bits
|
|
214
219
|
lowInt &= -0x10000
|
|
@@ -368,7 +373,12 @@ const readString =
|
|
|
368
373
|
position = getPosition();
|
|
369
374
|
return value;
|
|
370
375
|
};
|
|
371
|
-
})((new Function('fromCharCode', 'let position; let
|
|
376
|
+
})((new Function('fromCharCode', 'let position; let pendingSurrogate; ' +
|
|
377
|
+
// finishUtf8 references `position`/`pendingSurrogate`, but new Function compiles
|
|
378
|
+
// in global scope and can't close over the module-level copies, so embed its
|
|
379
|
+
// source here to bind it to this function's local (synced) `position`.
|
|
380
|
+
'let finishUtf8 = ' + finishUtf8.toString() + '; ' +
|
|
381
|
+
'let readString = ' + makeStringBuilder() +
|
|
372
382
|
';return {' +
|
|
373
383
|
'setPosition(p) { position = p },' +
|
|
374
384
|
'getPosition() { return position },' +
|
package/package.json
CHANGED
package/tests/test.js
CHANGED
|
@@ -28,6 +28,8 @@ suite('key buffers', () => {
|
|
|
28
28
|
assert.strictEqual(fromBufferKey(toBufferKey(3.4)), 3.4)
|
|
29
29
|
assert.strictEqual(fromBufferKey(toBufferKey(Math.PI)), Math.PI)
|
|
30
30
|
assert.strictEqual(fromBufferKey(toBufferKey(2002225)), 2002225)
|
|
31
|
+
// check to make sure it works with a limited ArrayBuffer
|
|
32
|
+
assert.strictEqual(fromBufferKey(new Uint8Array(toBufferKey(2002225))), 2002225)
|
|
31
33
|
assert.strictEqual(fromBufferKey(toBufferKey(9377288)), 9377288)
|
|
32
34
|
assert.strictEqual(fromBufferKey(toBufferKey(1503579323825)), 1503579323825)
|
|
33
35
|
assert.strictEqual(fromBufferKey(toBufferKey(1503579323825.3523532)), 1503579323825.3523532)
|