jsql-neo 3.4.6 → 3.4.7

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.
@@ -7,57 +7,69 @@ function safeJsonParse(str) {
7
7
 
8
8
  const textEncoder = new TextEncoder();
9
9
 
10
+ function utf8Len(s) {
11
+ let len = 0;
12
+ for (let i = 0; i < s.length; i++) {
13
+ const c = s.charCodeAt(i);
14
+ if (c < 0x80) len++;
15
+ else if (c < 0x800) len += 2;
16
+ else if (c < 0xD800 || c > 0xDFFF) len += 3;
17
+ else { len += 4; i++; }
18
+ }
19
+ return len;
20
+ }
21
+
22
+ function writeUtf8(buf, off, s) {
23
+ for (let i = 0; i < s.length; i++) {
24
+ const c = s.charCodeAt(i);
25
+ if (c < 0x80) { buf[off++] = c; }
26
+ else if (c < 0x800) { buf[off++] = 0xC0 | (c >> 6); buf[off++] = 0x80 | (c & 0x3F); }
27
+ else if (c < 0xD800 || c > 0xDFFF) { buf[off++] = 0xE0 | (c >> 12); buf[off++] = 0x80 | ((c >> 6) & 0x3F); buf[off++] = 0x80 | (c & 0x3F); }
28
+ else { const cp = 0x10000 + ((c & 0x3FF) << 10) + (s.charCodeAt(++i) & 0x3FF); buf[off++] = 0xF0 | (cp >> 18); buf[off++] = 0x80 | ((cp >> 12) & 0x3F); buf[off++] = 0x80 | ((cp >> 6) & 0x3F); buf[off++] = 0x80 | (cp & 0x3F); }
29
+ }
30
+ return off;
31
+ }
32
+
10
33
  function encodeBatch(rows) {
11
34
  if (rows.length === 0) return new Uint8Array(0);
12
35
  const fieldNames = Object.keys(rows[0]);
13
36
  const nFields = fieldNames.length;
14
37
 
15
- const nameBytes = fieldNames.map(n => textEncoder.encode(n));
38
+ // First pass: compute exact size, no allocations
16
39
  let size = 1;
17
- for (const nb of nameBytes) size += 1 + nb.length;
40
+ for (let fi = 0; fi < nFields; fi++) size += 1 + utf8Len(fieldNames[fi]);
18
41
  size += 4;
19
42
 
20
- const strBufs = [];
21
43
  for (let ri = 0; ri < rows.length; ri++) {
22
44
  const row = rows[ri];
23
45
  for (let fi = 0; fi < nFields; fi++) {
24
46
  const val = row[fieldNames[fi]];
25
- if (val === null || val === undefined) {
26
- size += 1;
27
- strBufs.push(null);
28
- } else if (typeof val === 'number') {
29
- size += 9;
30
- strBufs.push(null);
31
- } else if (typeof val === 'string') {
32
- const b = textEncoder.encode(val);
33
- strBufs.push(b);
34
- size += 1 + 4 + b.length;
35
- } else {
36
- size += 2;
37
- strBufs.push(val ? 1 : 0);
38
- }
47
+ if (val === null || val === undefined) size += 1;
48
+ else if (typeof val === 'number') size += 9;
49
+ else if (typeof val === 'string') size += 1 + 4 + utf8Len(val);
50
+ else size += 2;
39
51
  }
40
52
  }
41
53
 
54
+ // Second pass: write directly to pre-allocated buffer
42
55
  const buf = new Uint8Array(size);
43
56
  const dv = new DataView(buf.buffer, 0, size);
44
57
  let off = 0;
45
58
 
46
59
  buf[off++] = nFields;
47
- for (const nb of nameBytes) {
48
- buf[off++] = nb.length;
49
- buf.set(nb, off);
50
- off += nb.length;
60
+ for (let fi = 0; fi < nFields; fi++) {
61
+ const s = fieldNames[fi];
62
+ buf[off++] = utf8Len(s);
63
+ off = writeUtf8(buf, off, s);
51
64
  }
52
65
 
53
66
  dv.setUint32(off, rows.length, true);
54
67
  off += 4;
55
68
 
56
- let si = 0;
57
- for (const row of rows) {
69
+ for (let ri = 0; ri < rows.length; ri++) {
70
+ const row = rows[ri];
58
71
  for (let fi = 0; fi < nFields; fi++) {
59
72
  const val = row[fieldNames[fi]];
60
- const item = strBufs[si++];
61
73
  if (val === null || val === undefined) {
62
74
  buf[off++] = 0;
63
75
  } else if (typeof val === 'number') {
@@ -72,13 +84,13 @@ function encodeBatch(rows) {
72
84
  }
73
85
  } else if (typeof val === 'string') {
74
86
  buf[off++] = 3;
75
- dv.setUint32(off, item.length, true);
87
+ const strLen = utf8Len(val);
88
+ dv.setUint32(off, strLen, true);
76
89
  off += 4;
77
- buf.set(item, off);
78
- off += item.length;
90
+ off = writeUtf8(buf, off, val);
79
91
  } else {
80
92
  buf[off++] = 4;
81
- buf[off++] = item;
93
+ buf[off++] = val ? 1 : 0;
82
94
  }
83
95
  }
84
96
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsql-neo",
3
- "version": "3.4.6",
3
+ "version": "3.4.7",
4
4
  "description": "JSQL-NEO — Rust-powered embedded database with WASM, REST API, B-Tree indexes, WAL, crash recovery",
5
5
  "main": "index.js",
6
6
  "files": [
Binary file