index.cjs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. /*
  4. control character types:
  5. 1 - metadata
  6. 2 - symbols
  7. 6 - false
  8. 7 - true
  9. 8- 16 - negative doubles
  10. 16-24 positive doubles
  11. 27 - String starts with a character 27 or less or is an empty string
  12. 0 - multipart separator
  13. > 27 normal string characters
  14. */
  15. /*
  16. * Convert arbitrary scalar values to buffer bytes with type preservation and type-appropriate ordering
  17. */
  18. const float64Array = new Float64Array(2);
  19. const int32Array = new Int32Array(float64Array.buffer, 0, 4);
  20. let nullTerminate = false;
  21. let textEncoder;
  22. try {
  23. textEncoder = new TextEncoder();
  24. } catch (error) {}
  25. /*
  26. * Convert arbitrary scalar values to buffer bytes with type preservation and type-appropriate ordering
  27. */
  28. function writeKey(key, target, position, inSequence) {
  29. let targetView = target.dataView;
  30. if (!targetView)
  31. targetView = target.dataView = new DataView(target.buffer, target.byteOffset, ((target.byteLength + 3) >> 2) << 2);
  32. switch (typeof key) {
  33. case 'string':
  34. let strLength = key.length;
  35. let c1 = key.charCodeAt(0);
  36. if (!(c1 >= 28)) // escape character
  37. target[position++] = 27;
  38. if (strLength < 0x40) {
  39. let i, c2;
  40. for (i = 0; i < strLength; i++) {
  41. c1 = key.charCodeAt(i);
  42. if (c1 <= 4) {
  43. target[position++] = 4;
  44. target[position++] = c1;
  45. } else if (c1 < 0x80) {
  46. target[position++] = c1;
  47. } else if (c1 < 0x800) {
  48. target[position++] = c1 >> 6 | 0xc0;
  49. target[position++] = c1 & 0x3f | 0x80;
  50. } else if (
  51. (c1 & 0xfc00) === 0xd800 &&
  52. ((c2 = key.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
  53. ) {
  54. c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
  55. i++;
  56. target[position++] = c1 >> 18 | 0xf0;
  57. target[position++] = c1 >> 12 & 0x3f | 0x80;
  58. target[position++] = c1 >> 6 & 0x3f | 0x80;
  59. target[position++] = c1 & 0x3f | 0x80;
  60. } else {
  61. target[position++] = c1 >> 12 | 0xe0;
  62. target[position++] = c1 >> 6 & 0x3f | 0x80;
  63. target[position++] = c1 & 0x3f | 0x80;
  64. }
  65. }
  66. } else {
  67. if (target.utf8Write)
  68. position += target.utf8Write(key, position, target.byteLength - position);
  69. else
  70. position += textEncoder.encodeInto(key, target.subarray(position)).written;
  71. if (position > target.length - 4)
  72. throw new RangeError('String does not fit in target buffer')
  73. }
  74. break
  75. case 'number':
  76. float64Array[0] = key;
  77. let lowInt = int32Array[0];
  78. let highInt = int32Array[1];
  79. let length;
  80. if (key < 0) {
  81. targetView.setInt32(position + 4, ~((lowInt >>> 4) | (highInt << 28)));
  82. targetView.setInt32(position + 0, (highInt ^ 0x7fffffff) >>> 4);
  83. targetView.setInt32(position + 8, ((lowInt & 0xf) ^ 0xf) << 4, true); // just always do the null termination here
  84. return position + 9
  85. } else if ((lowInt & 0xf) || inSequence) {
  86. length = 9;
  87. } else if (lowInt & 0xfffff)
  88. length = 8;
  89. else if (lowInt || (highInt & 0xf))
  90. length = 6;
  91. else
  92. length = 4;
  93. // switching order to go to little endian
  94. targetView.setInt32(position + 0, (highInt >>> 4) | 0x10000000);
  95. targetView.setInt32(position + 4, (lowInt >>> 4) | (highInt << 28));
  96. // if (length == 9 || nullTerminate)
  97. targetView.setInt32(position + 8, (lowInt & 0xf) << 4, true);
  98. return position + length;
  99. case 'object':
  100. if (key) {
  101. if (Array.isArray(key)) {
  102. for (let i = 0, l = key.length; i < l; i++) {
  103. if (i > 0)
  104. target[position++] = 0;
  105. position = writeKey(key[i], target, position, true);
  106. }
  107. break
  108. } else if (key instanceof Uint8Array) {
  109. target.set(key, position);
  110. position += key.length;
  111. break
  112. } else {
  113. throw new Error('Unable to serialize object as a key: ' + JSON.stringify(key))
  114. }
  115. } else // null
  116. target[position++] = 0;
  117. break
  118. case 'boolean':
  119. targetView.setUint32(position++, key ? 7 : 6, true);
  120. return position
  121. case 'bigint':
  122. let asFloat = Number(key);
  123. if (BigInt(asFloat) > key) {
  124. float64Array[0] = asFloat;
  125. if (asFloat > 0) {
  126. if (int32Array[0])
  127. int32Array[0]--;
  128. else {
  129. int32Array[1]--;
  130. int32Array[0] = 0xffffffff;
  131. }
  132. } else {
  133. if (int32Array[0] < 0xffffffff)
  134. int32Array[0]++;
  135. else {
  136. int32Array[1]++;
  137. int32Array[0] = 0;
  138. }
  139. }
  140. asFloat = float64Array[0];
  141. }
  142. let difference = key - BigInt(asFloat);
  143. if (difference === 0n)
  144. return writeKey(asFloat, target, position, inSequence)
  145. writeKey(asFloat, target, position, inSequence);
  146. position += 9; // always increment by 9 if we are adding fractional bits
  147. let exponent = BigInt((int32Array[1] >> 20 & 0x7ff) - 1079);
  148. let nextByte = difference >> exponent;
  149. target[position - 1] |= Number(nextByte);
  150. difference -= nextByte << exponent;
  151. let first = true;
  152. while (difference || first) {
  153. first = false;
  154. exponent -= 7n;
  155. let nextByte = difference >> exponent;
  156. target[position++] = Number(nextByte) | 0x80;
  157. difference -= nextByte << exponent;
  158. }
  159. return position;
  160. case 'undefined':
  161. return position
  162. // undefined is interpreted as the absence of a key, signified by zero length
  163. case 'symbol':
  164. target[position++] = 2;
  165. return writeKey(key.description, target, position, inSequence)
  166. default:
  167. throw new Error('Can not serialize key of type ' + typeof key)
  168. }
  169. if (nullTerminate && !inSequence)
  170. targetView.setUint32(position, 0);
  171. return position
  172. }
  173. let position;
  174. function readKey(buffer, start, end, inSequence) {
  175. position = start;
  176. let controlByte = buffer[position];
  177. let value;
  178. if (controlByte < 24) {
  179. if (controlByte < 8) {
  180. position++;
  181. if (controlByte == 6) {
  182. value = false;
  183. } else if (controlByte == 7) {
  184. value = true;
  185. } else if (controlByte == 0) {
  186. value = null;
  187. } else if (controlByte == 2) {
  188. value = Symbol.for(readStringSafely(buffer, end));
  189. } else
  190. return Uint8Array.prototype.slice.call(buffer, start, end)
  191. } else {
  192. let dataView;
  193. try {
  194. dataView = buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, ((buffer.byteLength + 3) >> 2) << 2));
  195. } catch(error) {
  196. // if it is write at the end of the ArrayBuffer, we may need to retry with the exact remaining bytes
  197. dataView = buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.buffer.byteLength - buffer.byteOffset));
  198. }
  199. let highInt = dataView.getInt32(position) << 4;
  200. let size = end - position;
  201. let lowInt;
  202. if (size > 4) {
  203. lowInt = dataView.getInt32(position + 4);
  204. highInt |= lowInt >>> 28;
  205. if (size <= 6) { // clear the last bits
  206. lowInt &= -0x10000;
  207. }
  208. lowInt = lowInt << 4;
  209. if (size > 8) {
  210. lowInt = lowInt | buffer[position + 8] >> 4;
  211. }
  212. } else
  213. lowInt = 0;
  214. if (controlByte < 16) {
  215. // negative gets negated
  216. highInt = highInt ^ 0x7fffffff;
  217. lowInt = ~lowInt;
  218. }
  219. int32Array[1] = highInt;
  220. int32Array[0] = lowInt;
  221. value = float64Array[0];
  222. position += 9;
  223. if (size > 9 && buffer[position] > 0) {
  224. // convert the float to bigint, and then we will add precision as we enumerate through the
  225. // extra bytes
  226. value = BigInt(value);
  227. let exponent = highInt >> 20 & 0x7ff;
  228. let next_byte = buffer[position - 1] & 0xf;
  229. value += BigInt(next_byte) << BigInt(exponent - 1079);
  230. while ((next_byte = buffer[position]) > 0 && position++ < end) {
  231. value += BigInt(next_byte & 0x7f) << BigInt((start - position) * 7 + exponent - 1016);
  232. }
  233. }
  234. }
  235. } else {
  236. if (controlByte == 27) {
  237. position++;
  238. }
  239. value = readStringSafely(buffer, end);
  240. }
  241. while (position < end) {
  242. if (buffer[position] === 0)
  243. position++;
  244. if (inSequence) {
  245. encoder.position = position;
  246. return value
  247. }
  248. let nextValue = readKey(buffer, position, end, true);
  249. if (value instanceof Array) {
  250. value.push(nextValue);
  251. } else
  252. value = [ value, nextValue ];
  253. }
  254. return value
  255. }
  256. const enableNullTermination = () => nullTerminate = true;
  257. const encoder = {
  258. writeKey,
  259. readKey,
  260. enableNullTermination,
  261. };
  262. let targetBuffer = [];
  263. let targetPosition = 0;
  264. const hasNodeBuffer = typeof Buffer !== 'undefined';
  265. const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
  266. const toBufferKey = (key) => {
  267. let newBuffer;
  268. if (targetPosition + 100 > targetBuffer.length) {
  269. targetBuffer = new ByteArrayAllocate(8192);
  270. targetPosition = 0;
  271. newBuffer = true;
  272. }
  273. try {
  274. let result = targetBuffer.slice(targetPosition, targetPosition = writeKey(key, targetBuffer, targetPosition));
  275. if (targetPosition > targetBuffer.length) {
  276. if (newBuffer)
  277. throw new Error('Key is too large')
  278. return toBufferKey(key)
  279. }
  280. return result
  281. } catch(error) {
  282. if (newBuffer)
  283. throw error
  284. targetPosition = targetBuffer.length;
  285. return toBufferKey(key)
  286. }
  287. };
  288. const fromBufferKey = (sourceBuffer) => {
  289. return readKey(sourceBuffer, 0, sourceBuffer.length)
  290. };
  291. const fromCharCode = String.fromCharCode;
  292. function makeStringBuilder() {
  293. let stringBuildCode = '(source) => {';
  294. let previous = [];
  295. for (let i = 0; i < 0x30; i++) {
  296. let v = fromCharCode((i & 0xf) + 97) + fromCharCode((i >> 4) + 97);
  297. stringBuildCode += `
  298. let ${v} = source[position++]
  299. if (${v} > 4) {
  300. if (${v} >= 0x80) ${v} = finishUtf8(${v}, source)
  301. } else {
  302. if (${v} === 4)
  303. ${v} = source[position++]
  304. else
  305. return fromCharCode(${previous})
  306. }
  307. `;
  308. previous.push(v);
  309. if (i == 1000000) // this just exists to prevent rollup from doing dead code elimination on finishUtf8
  310. finishUtf8();
  311. }
  312. stringBuildCode += `return fromCharCode(${previous}) + readString(source)}`;
  313. return stringBuildCode
  314. }
  315. let pendingSurrogate;
  316. function finishUtf8(byte1, src) {
  317. if ((byte1 & 0xe0) === 0xc0) {
  318. // 2 bytes
  319. const byte2 = src[position++] & 0x3f;
  320. return ((byte1 & 0x1f) << 6) | byte2
  321. } else if ((byte1 & 0xf0) === 0xe0) {
  322. // 3 bytes
  323. const byte2 = src[position++] & 0x3f;
  324. const byte3 = src[position++] & 0x3f;
  325. return ((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3
  326. } else if ((byte1 & 0xf8) === 0xf0) {
  327. // 4 bytes
  328. if (pendingSurrogate) {
  329. byte1 = pendingSurrogate;
  330. pendingSurrogate = null;
  331. position += 3;
  332. return byte1
  333. }
  334. const byte2 = src[position++] & 0x3f;
  335. const byte3 = src[position++] & 0x3f;
  336. const byte4 = src[position++] & 0x3f;
  337. let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
  338. if (unit > 0xffff) {
  339. pendingSurrogate = 0xdc00 | (unit & 0x3ff);
  340. unit = (((unit - 0x10000) >>> 10) & 0x3ff) | 0xd800;
  341. position -= 4; // reset so we can return the next part of the surrogate pair
  342. }
  343. return unit
  344. } else {
  345. return byte1
  346. }
  347. }
  348. const readString =
  349. typeof process !== 'undefined' && process.isBun ? // the eval in bun doesn't properly closure on position, so we
  350. // have to manually update it
  351. (function(reading) {
  352. let { setPosition, getPosition, readString } = reading;
  353. return (source) => {
  354. setPosition(position);
  355. let value = readString(source);
  356. position = getPosition();
  357. return value;
  358. };
  359. })((new Function('fromCharCode', 'let position; let readString = ' + makeStringBuilder() +
  360. ';return {' +
  361. 'setPosition(p) { position = p },' +
  362. 'getPosition() { return position },' +
  363. 'readString }'))(fromCharCode)) :
  364. eval(makeStringBuilder());
  365. function readStringSafely(source, end) {
  366. if (source[end] > 0) {
  367. let previous = source[end];
  368. try {
  369. // read string expects a null terminator, that is a 0 or undefined from reading past the end of the buffer, so we
  370. // have to ensure that, but do so safely, restoring the buffer to its original state
  371. source[end] = 0;
  372. return readString(source)
  373. } finally {
  374. source[end] = previous;
  375. }
  376. } else return readString(source);
  377. }
  378. function compareKeys(a, b) {
  379. // compare with type consistency that matches binary comparison
  380. if (typeof a == 'object') {
  381. if (!a) {
  382. return b == null ? 0 : -1
  383. }
  384. if (a.compare) {
  385. if (b == null) {
  386. return 1
  387. } else if (b.compare) {
  388. return a.compare(b)
  389. } else {
  390. return -1
  391. }
  392. }
  393. let arrayComparison;
  394. if (b instanceof Array) {
  395. let i = 0;
  396. while((arrayComparison = compareKeys(a[i], b[i])) == 0 && i <= a.length) {
  397. i++;
  398. }
  399. return arrayComparison
  400. }
  401. arrayComparison = compareKeys(a[0], b);
  402. if (arrayComparison == 0 && a.length > 1)
  403. return 1
  404. return arrayComparison
  405. } else if (typeof a == typeof b) {
  406. if (typeof a === 'symbol') {
  407. a = Symbol.keyFor(a);
  408. b = Symbol.keyFor(b);
  409. }
  410. return a < b ? -1 : a === b ? 0 : 1
  411. }
  412. else if (typeof b == 'object') {
  413. if (b instanceof Array)
  414. return -compareKeys(b, a)
  415. return 1
  416. } else {
  417. return typeOrder[typeof a] < typeOrder[typeof b] ? -1 : 1
  418. }
  419. }
  420. const typeOrder = {
  421. symbol: 0,
  422. undefined: 1,
  423. boolean: 2,
  424. number: 3,
  425. string: 4
  426. };
  427. const MINIMUM_KEY = null;
  428. const MAXIMUM_KEY = new Uint8Array([0xff]);
  429. exports.MAXIMUM_KEY = MAXIMUM_KEY;
  430. exports.MINIMUM_KEY = MINIMUM_KEY;
  431. exports.compareKeys = compareKeys;
  432. exports.enableNullTermination = enableNullTermination;
  433. exports.encoder = encoder;
  434. exports.fromBufferKey = fromBufferKey;
  435. exports.readKey = readKey;
  436. exports.toBufferKey = toBufferKey;
  437. exports.writeKey = writeKey;