ordered-binary 1.1.3 → 1.2.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 CHANGED
@@ -1,8 +1,34 @@
1
+ [![npm version](https://img.shields.io/npm/dw/ordered-binary)](https://www.npmjs.org/package/ordered-binary)
2
+ [![npm version](https://img.shields.io/npm/v/ordered-binary.svg?style=flat-square)](https://www.npmjs.org/package/ordered-binary)
3
+ [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
1
4
  <a href="https://dev.doctorevidence.com/"><img src="./assets/powers-dre.png" width="203" /></a>
2
5
 
3
- The ordered-binary provides a representation of JavaScript primitives as NodeJS Buffers, such that there binary values are naturally ordered such that it matches primitive ordering. For example, since -2.0321 > -2.04, then `toBufferKey(-2.0321)` will be greater than `toBufferKey(-2.04)` as a binary representation, in left-to-right evaluation. This is particular useful for storing keys as binaries with something like LevelDB, to avoid any custom sorting.
6
+ The ordered-binary package provides a representation of JavaScript primitives, serialized into binary format (NodeJS Buffers or Uint8Arrays), such that the binary values are naturally ordered such that it matches the natural ordering or values. For example, since -2.0321 > -2.04, then `toBufferKey(-2.0321)` will be greater than `toBufferKey(-2.04)` as a binary representation, in left-to-right evaluation. This is particular useful for storing keys as binaries with something like LMDB or LevelDB, to avoid any custom sorting.
4
7
 
5
- The main module exports two functions:
8
+ The ordered-binary package supports strings, numbers, booleans, symbols, null, as well as an array of primitives. Here is an example of ordering of primitive values:
9
+ ```
10
+ Buffer.from([0]) // buffers are left unchanged, and this is the minimum value
11
+ Symbol.for('even symbols')
12
+ -10 // negative supported
13
+ -1.1 // decimals supported
14
+ 400
15
+ 3E10
16
+ 'Hello'
17
+ ['Hello', 'World']
18
+ 'World'
19
+ 'hello'
20
+ ['hello', 1, 'world']
21
+ ['hello', 'world']
22
+ Buffer.from([0xff])
23
+ ```
24
+
25
+
26
+ The main module exports these functions:
27
+
28
+ `writeKey(key: string | number | boolean | null | Array, target: Buffer, position: integer, inSequence?: boolean)` - Writes the provide key to the target buffer
29
+
30
+ `readKey(buffer, start, end, inSequence)` - Reads the key from the buffer, given the provided start and end, as a primitive value
6
31
 
7
32
  `toBufferKey(jsPrimitive)` - This accepts a string, number, or boolean as the argument, and returns a `Buffer`.
33
+
8
34
  `fromBufferKey(bufferKey, multiple)` - This accepts a Buffer and returns a JavaScript primitive value. This can also parse buffers that hold multiple values delimited by a byte `30`, by setting the second argument to true (in which case it will return an array).
package/dist/index.cjs CHANGED
@@ -20,7 +20,14 @@ control character types:
20
20
 
21
21
  const float64Array = new Float64Array(2);
22
22
  const int32Array = new Int32Array(float64Array.buffer, 0, 4);
23
+ new Uint8Array(float64Array.buffer, 2, 6);
24
+ new Uint8Array(float64Array.buffer, 0, 8);
23
25
  let nullTerminate = false;
26
+ let textEncoder;
27
+ try {
28
+ textEncoder = new TextEncoder();
29
+ } catch (error) {}
30
+
24
31
  /*
25
32
  * Convert arbitrary scalar values to buffer bytes with type preservation and type-appropriate ordering
26
33
  */
@@ -32,9 +39,9 @@ function writeKey(key, target, position, inSequence) {
32
39
  case 'string':
33
40
  let strLength = key.length;
34
41
  let c1 = key.charCodeAt(0);
35
- if (c1 < 28) // escape character
42
+ if (!(c1 >= 28)) // escape character
36
43
  target[position++] = 27;
37
- if (strLength < 0x20) {
44
+ if (strLength < 0x40) {
38
45
  let i, c2;
39
46
  for (i = 0; i < strLength; i++) {
40
47
  c1 = key.charCodeAt(i);
@@ -60,7 +67,12 @@ function writeKey(key, target, position, inSequence) {
60
67
  }
61
68
  }
62
69
  } else {
63
- position += target.utf8Write(key, position, 2000);
70
+ if (target.utf8Write)
71
+ position += target.utf8Write(key, position);
72
+ else
73
+ position += textEncoder.encodeInto(key, target.subarray(position)).written;
74
+ if (position > target.length - 4)
75
+ throw new RangeError('String does not fit in target buffer')
64
76
  }
65
77
  break
66
78
  case 'number':
@@ -200,9 +212,12 @@ function readKey(buffer, start, end, inSequence) {
200
212
  }
201
213
  return value
202
214
  }
215
+ const enableNullTermination = () => nullTerminate = true;
216
+
203
217
  const encoder = {
204
218
  writeKey,
205
219
  readKey,
220
+ enableNullTermination,
206
221
  };
207
222
  const toBufferKey = (key) => {
208
223
  let buffer = Buffer.alloc(2048);
@@ -267,12 +282,10 @@ function finishUtf8(byte1, src) {
267
282
  }
268
283
  }
269
284
 
270
- const enableNullTermination = () => nullTerminate = true;
271
-
272
285
  const readString = eval(makeStringBuilder());
273
286
 
274
287
  function compareKeys(a, b) {
275
- // compare with type consistency that matches ordered-binary
288
+ // compare with type consistency that matches binary comparison
276
289
  if (typeof a == 'object') {
277
290
  if (!a) {
278
291
  return b == null ? 0 : -1
@@ -319,8 +332,12 @@ const typeOrder = {
319
332
  boolean: 2,
320
333
  number: 3,
321
334
  string: 4
322
- };
335
+ };
336
+ const MINIMUM_KEY = null;
337
+ const MAXIMUM_KEY = new Uint8Array([0xff]);
323
338
 
339
+ exports.MAXIMUM_KEY = MAXIMUM_KEY;
340
+ exports.MINIMUM_KEY = MINIMUM_KEY;
324
341
  exports.compareKeys = compareKeys;
325
342
  exports.enableNullTermination = enableNullTermination;
326
343
  exports.encoder = encoder;
package/index.js CHANGED
@@ -19,6 +19,11 @@ const int32Array = new Int32Array(float64Array.buffer, 0, 4)
19
19
  const uint8Array6 = new Uint8Array(float64Array.buffer, 2, 6)
20
20
  const uint8Array8 = new Uint8Array(float64Array.buffer, 0, 8)
21
21
  let nullTerminate = false
22
+ let textEncoder
23
+ try {
24
+ textEncoder = new TextEncoder()
25
+ } catch (error) {}
26
+
22
27
  /*
23
28
  * Convert arbitrary scalar values to buffer bytes with type preservation and type-appropriate ordering
24
29
  */
@@ -30,9 +35,9 @@ export function writeKey(key, target, position, inSequence) {
30
35
  case 'string':
31
36
  let strLength = key.length
32
37
  let c1 = key.charCodeAt(0)
33
- if (c1 < 28) // escape character
38
+ if (!(c1 >= 28)) // escape character
34
39
  target[position++] = 27
35
- if (strLength < 0x20) {
40
+ if (strLength < 0x40) {
36
41
  let i, c2
37
42
  for (i = 0; i < strLength; i++) {
38
43
  c1 = key.charCodeAt(i)
@@ -58,7 +63,12 @@ export function writeKey(key, target, position, inSequence) {
58
63
  }
59
64
  }
60
65
  } else {
61
- position += target.utf8Write(key, position, 2000)
66
+ if (target.utf8Write)
67
+ position += target.utf8Write(key, position)
68
+ else
69
+ position += textEncoder.encodeInto(key, target.subarray(position)).written
70
+ if (position > target.length - 4)
71
+ throw new RangeError('String does not fit in target buffer')
62
72
  }
63
73
  break
64
74
  case 'number':
@@ -198,9 +208,12 @@ export function readKey(buffer, start, end, inSequence) {
198
208
  }
199
209
  return value
200
210
  }
211
+ export const enableNullTermination = () => nullTerminate = true
212
+
201
213
  export const encoder = {
202
214
  writeKey,
203
215
  readKey,
216
+ enableNullTermination,
204
217
  }
205
218
  export const toBufferKey = (key) => {
206
219
  let buffer = Buffer.alloc(2048)
@@ -265,12 +278,10 @@ function finishUtf8(byte1, src) {
265
278
  }
266
279
  }
267
280
 
268
- export const enableNullTermination = () => nullTerminate = true
269
-
270
281
  const readString = eval(makeStringBuilder())
271
282
 
272
283
  export function compareKeys(a, b) {
273
- // compare with type consistency that matches ordered-binary
284
+ // compare with type consistency that matches binary comparison
274
285
  if (typeof a == 'object') {
275
286
  if (!a) {
276
287
  return b == null ? 0 : -1
@@ -318,3 +329,5 @@ const typeOrder = {
318
329
  number: 3,
319
330
  string: 4
320
331
  }
332
+ export const MINIMUM_KEY = null
333
+ export const MAXIMUM_KEY = new Uint8Array([0xff])
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ordered-binary",
3
3
  "author": "Kris Zyp",
4
- "version": "1.1.3",
4
+ "version": "1.2.3",
5
5
  "description": "Conversion of JavaScript primitives to and from Buffer with binary order matching natural primitive order",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -14,6 +14,7 @@
14
14
  "test": "mocha tests -u tdd"
15
15
  },
16
16
  "type": "module",
17
+ "main": "dist/index.cjs",
17
18
  "module": "index.js",
18
19
  "exports": {
19
20
  ".": {
@@ -30,7 +31,7 @@
30
31
  "devDependencies": {
31
32
  "@types/node": "latest",
32
33
  "chai": "^4",
33
- "mocha": "^8.1.3",
34
- "rollup": "^1.20.3"
34
+ "mocha": "^9.1.3",
35
+ "rollup": "^2.61.1"
35
36
  }
36
37
  }
package/tests/test.js CHANGED
@@ -43,6 +43,7 @@ suite('key buffers', () => {
43
43
  test('string equivalence', () => {
44
44
  assert.strictEqual(fromBufferKey(toBufferKey('4')), '4')
45
45
  assert.strictEqual(fromBufferKey(toBufferKey('hello')), 'hello')
46
+ assert.strictEqual(fromBufferKey(toBufferKey('')), '')
46
47
  })
47
48
  test('string comparison', () => {
48
49
  assertBufferComparison(toBufferKey('4'), toBufferKey('5'))