sqlmath 2026.4.30 → 2026.6.30

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/package.json CHANGED
@@ -32,5 +32,5 @@
32
32
  },
33
33
  "shCiArtifactUpload": 1,
34
34
  "shCiPublishNpm": 1,
35
- "version": "2026.4.30"
35
+ "version": "2026.6.30"
36
36
  }
package/sqlmath.mjs CHANGED
@@ -20,6 +20,11 @@
20
20
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  // SOFTWARE.
22
22
 
23
+ /*
24
+ sh one-liner:
25
+ sh jslint_ci.sh shCiBuildWasm
26
+ sh jslint_ci.sh shSqlmathUpdate
27
+ */
23
28
 
24
29
  /*jslint beta, bitwise, name, node*/
25
30
  /*global FinalizationRegistry*/
@@ -100,14 +105,14 @@ let debugInline = (function () {
100
105
  let __consoleError = function () {
101
106
  return;
102
107
  };
103
- function debug(...argv) {
108
+ function debug(...argList) {
104
109
 
105
- // This function will print <argv> to stderr and then return <argv>[0].
110
+ // This function will print <argList> to stderr and then return <argList>[0].
106
111
 
107
112
  __consoleError("\n\ndebugInline");
108
- __consoleError(...argv);
113
+ __consoleError(...argList);
109
114
  __consoleError("\n");
110
- return argv[0];
115
+ return argList[0];
111
116
  }
112
117
  debug(); // Coverage-hack.
113
118
  __consoleError = console.error; //jslint-ignore-line
@@ -128,7 +133,7 @@ let {
128
133
  let sqlMessageDict = {}; // dict of web-worker-callbacks
129
134
  let sqlMessageId = 0;
130
135
  let sqlWorker;
131
- let version = "v2026.4.30";
136
+ let version = "v2026.6.30";
132
137
 
133
138
  async function assertErrorThrownAsync(asyncFunc, regexp) {
134
139
 
@@ -487,6 +492,197 @@ SQLMATH_CFLAG_WNO_LIST=" \\
487
492
  );
488
493
  }
489
494
 
495
+ function csvFromListofList({
496
+ colList,
497
+ rowList
498
+ }) {
499
+ // this function will convert json <rowList> to csv with given <colList>
500
+ let data = JSON.stringify([[colList], rowList].flat(), undefined, 1);
501
+ // convert data to csv
502
+ data = data.replace((
503
+ /\n /g
504
+ ), "");
505
+ data = data.replace((
506
+ /\n \[/g
507
+ ), "");
508
+ data = data.replace((
509
+ /\n \],?/g
510
+ ), "\r\n");
511
+ data = data.slice(1, -2);
512
+ // sqlite-strings are c-strings which should never contain null-char
513
+ data = data.replace((
514
+ /\u0000/g
515
+ ), "");
516
+ // hide double-backslash `\\\\` as null-char
517
+ data = data.replace((
518
+ /\\\\/g
519
+ ), "\u0000");
520
+ // escape double-quote `\\"` to `""`
521
+ data = data.replace((
522
+ /\\"/g
523
+ ), "\"\"");
524
+ // replace newline with space
525
+ data = data.replace((
526
+ /\\r\\n|\\r|\\n/g
527
+ ), " ");
528
+ // restore double-backslash `\\\\` from null-char
529
+ data = data.replace((
530
+ /\u0000/g
531
+ ), "\\\\");
532
+ return data;
533
+ }
534
+
535
+ function csvToListofList({
536
+ csv
537
+ }) {
538
+ // This function will convert <csv>-text to json list-of-list.
539
+ //
540
+ // https://tools.ietf.org/html/rfc4180#section-2
541
+ // Definition of the CSV Format
542
+ // While there are various specifications and implementations for the
543
+ // CSV format (for ex. [4], [5], [6] and [7]), there is no formal
544
+ // specification in existence, which allows for a wide variety of
545
+ // interpretations of CSV files. This section documents the format that
546
+ // seems to be followed by most implementations:
547
+ //
548
+ // 1. Each record is located on a separate line, delimited by a line
549
+ // break (CRLF). For example:
550
+ // aaa,bbb,ccc CRLF
551
+ // zzz,yyy,xxx CRLF
552
+ //
553
+ // 2. The last record in the file may or may not have an ending line
554
+ // break. For example:
555
+ // aaa,bbb,ccc CRLF
556
+ // zzz,yyy,xxx
557
+ //
558
+ // 3. There maybe an optional header line appearing as the first line
559
+ // of the file with the same format as normal record lines. This
560
+ // header will contain names corresponding to the fields in the file
561
+ // and should contain the same number of fields as the records in
562
+ // the rest of the file (the presence or absence of the header line
563
+ // should be indicated via the optional "header" parameter of this
564
+ // MIME type). For example:
565
+ // field_name,field_name,field_name CRLF
566
+ // aaa,bbb,ccc CRLF
567
+ // zzz,yyy,xxx CRLF
568
+ //
569
+ // 4. Within the header and each record, there may be one or more
570
+ // fields, separated by commas. Each line should contain the same
571
+ // number of fields throughout the file. Spaces are considered part
572
+ // of a field and should not be ignored. The last field in the
573
+ // record must not be followed by a comma. For example:
574
+ // aaa,bbb,ccc
575
+ //
576
+ // 5. Each field may or may not be enclosed in double quotes (however
577
+ // some programs, such as Microsoft Excel, do not use double quotes
578
+ // at all). If fields are not enclosed with double quotes, then
579
+ // double quotes may not appear inside the fields. For example:
580
+ // "aaa","bbb","ccc" CRLF
581
+ // zzz,yyy,xxx
582
+ //
583
+ // 6. Fields containing line breaks (CRLF), double quotes, and commas
584
+ // should be enclosed in double-quotes. For example:
585
+ // "aaa","b CRLF
586
+ // bb","ccc" CRLF
587
+ // zzz,yyy,xxx
588
+ //
589
+ // 7. If double-quotes are used to enclose fields, then a double-quote
590
+ // appearing inside a field must be escaped by preceding it with
591
+ // another double quote. For example:
592
+ // "aaa","b""bb","ccc"
593
+ let match;
594
+ let quote;
595
+ let rgx;
596
+ let row;
597
+ let rowList;
598
+ let val;
599
+ // normalize "\r\n" to "\n"
600
+ csv = csv.trimEnd().replace((
601
+ /\r\n?/gu
602
+ ), "\n") + "\n";
603
+ rgx = (
604
+ /(.*?)(""|"|,|\n)/gu
605
+ );
606
+ rowList = [];
607
+ // reset row
608
+ row = [];
609
+ val = "";
610
+ while (true) {
611
+ match = rgx.exec(csv);
612
+ if (!match) {
613
+ // 2. The last record in the file may or may not have an ending line
614
+ // break. For example:
615
+ // aaa,bbb,ccc CRLF
616
+ // zzz,yyy,xxx
617
+ if (!row.length) {
618
+ break;
619
+ }
620
+ // // if eof missing crlf, then mock it
621
+ // rgx.lastIndex = csv.length;
622
+ // match = [
623
+ // "\n", "", "\n"
624
+ // ];
625
+ }
626
+ // build val
627
+ val += match[1];
628
+ if (match[2] === "\"") {
629
+ // 5. Each field may or may not be enclosed in double quotes (however
630
+ // some programs, such as Microsoft Excel, do not use double quotes
631
+ // at all). If fields are not enclosed with double quotes, then
632
+ // double quotes may not appear inside the fields. For example:
633
+ // "aaa","bbb","ccc" CRLF
634
+ // zzz,yyy,xxx
635
+ quote = !quote;
636
+ } else if (quote) {
637
+ // 7. If double-quotes are used to enclose fields, then a double-quote
638
+ // appearing inside a field must be escaped by preceding it with
639
+ // another double quote. For example:
640
+ // "aaa","b""bb","ccc"
641
+ if (match[2] === "\"\"") {
642
+ val += "\"";
643
+ // 6. Fields containing line breaks (CRLF), double quotes, and commas
644
+ // should be enclosed in double-quotes. For example:
645
+ // "aaa","b CRLF
646
+ // bb","ccc" CRLF
647
+ // zzz,yyy,xxx
648
+ } else {
649
+ val += match[2];
650
+ }
651
+ } else if (match[2] === ",") {
652
+ // 4. Within the header and each record, there may be one or more
653
+ // fields, separated by commas. Each line should contain the same
654
+ // number of fields throughout the file. Spaces are considered part
655
+ // of a field and should not be ignored. The last field in the
656
+ // record must not be followed by a comma. For example:
657
+ // aaa,bbb,ccc
658
+ // delimit val
659
+ row.push(val);
660
+ val = "";
661
+ } else if (match[2] === "\n") {
662
+ // 1. Each record is located on a separate line, delimited by a line
663
+ // break (CRLF). For example:
664
+ // aaa,bbb,ccc CRLF
665
+ // zzz,yyy,xxx CRLF
666
+ // delimit val
667
+ row.push(val);
668
+ val = "";
669
+ // append row
670
+ rowList.push(row);
671
+ // reset row
672
+ row = [];
673
+ }
674
+ }
675
+ // // append val
676
+ // if (val) {
677
+ // row.push(val);
678
+ // }
679
+ // // append row
680
+ // if (row.length) {
681
+ // rowList.push(row);
682
+ // }
683
+ return rowList;
684
+ }
685
+
490
686
  async function dbCallAsync(baton, argList, mode, db) {
491
687
 
492
688
  // This function will call c-function dbXxx() with given <funcname>
@@ -517,7 +713,7 @@ async function dbCallAsync(baton, argList, mode, db) {
517
713
  profileStart = Date.now();
518
714
  sql = String(argList[1]);
519
715
  // sql-hash - remove comment
520
- sql = sql.replace((/(?:^|\s+?)--.*/gm), "");
716
+ sql = sql.replace((/\s*?--.*?$/gm), "");
521
717
  // sql-hash - remove vowel
522
718
  sql = sql.replace((/[aeiou]\b/gi), "\u0000$&");
523
719
  sql = sql.replace((/([bcdfghjklmnpqrstvwxyz])[aeiou]+/gi), "$1");
@@ -1093,7 +1289,7 @@ async function dbTableImportAsync({
1093
1289
  }
1094
1290
  switch (mode) {
1095
1291
  case "csv":
1096
- rowList = jsonRowListFromCsv({
1292
+ rowList = csvToListofList({
1097
1293
  csv: textData
1098
1294
  });
1099
1295
  break;
@@ -1215,7 +1411,7 @@ async function fsExistsUnlessTest(file, mode) {
1215
1411
  return false;
1216
1412
  }
1217
1413
  try {
1218
- await moduleFs.promises.access(file);
1414
+ await moduleFs.promises.access(file, moduleFs.promises.constants.F_OK);
1219
1415
  return true;
1220
1416
  } catch (ignore) {
1221
1417
  return false;
@@ -1521,157 +1717,6 @@ function jsonParseArraybuffer(buf) {
1521
1717
  );
1522
1718
  }
1523
1719
 
1524
- function jsonRowListFromCsv({
1525
- csv
1526
- }) {
1527
- // This function will convert <csv>-text to json list-of-list.
1528
- //
1529
- // https://tools.ietf.org/html/rfc4180#section-2
1530
- // Definition of the CSV Format
1531
- // While there are various specifications and implementations for the
1532
- // CSV format (for ex. [4], [5], [6] and [7]), there is no formal
1533
- // specification in existence, which allows for a wide variety of
1534
- // interpretations of CSV files. This section documents the format that
1535
- // seems to be followed by most implementations:
1536
- //
1537
- // 1. Each record is located on a separate line, delimited by a line
1538
- // break (CRLF). For example:
1539
- // aaa,bbb,ccc CRLF
1540
- // zzz,yyy,xxx CRLF
1541
- //
1542
- // 2. The last record in the file may or may not have an ending line
1543
- // break. For example:
1544
- // aaa,bbb,ccc CRLF
1545
- // zzz,yyy,xxx
1546
- //
1547
- // 3. There maybe an optional header line appearing as the first line
1548
- // of the file with the same format as normal record lines. This
1549
- // header will contain names corresponding to the fields in the file
1550
- // and should contain the same number of fields as the records in
1551
- // the rest of the file (the presence or absence of the header line
1552
- // should be indicated via the optional "header" parameter of this
1553
- // MIME type). For example:
1554
- // field_name,field_name,field_name CRLF
1555
- // aaa,bbb,ccc CRLF
1556
- // zzz,yyy,xxx CRLF
1557
- //
1558
- // 4. Within the header and each record, there may be one or more
1559
- // fields, separated by commas. Each line should contain the same
1560
- // number of fields throughout the file. Spaces are considered part
1561
- // of a field and should not be ignored. The last field in the
1562
- // record must not be followed by a comma. For example:
1563
- // aaa,bbb,ccc
1564
- //
1565
- // 5. Each field may or may not be enclosed in double quotes (however
1566
- // some programs, such as Microsoft Excel, do not use double quotes
1567
- // at all). If fields are not enclosed with double quotes, then
1568
- // double quotes may not appear inside the fields. For example:
1569
- // "aaa","bbb","ccc" CRLF
1570
- // zzz,yyy,xxx
1571
- //
1572
- // 6. Fields containing line breaks (CRLF), double quotes, and commas
1573
- // should be enclosed in double-quotes. For example:
1574
- // "aaa","b CRLF
1575
- // bb","ccc" CRLF
1576
- // zzz,yyy,xxx
1577
- //
1578
- // 7. If double-quotes are used to enclose fields, then a double-quote
1579
- // appearing inside a field must be escaped by preceding it with
1580
- // another double quote. For example:
1581
- // "aaa","b""bb","ccc"
1582
- let match;
1583
- let quote;
1584
- let rgx;
1585
- let row;
1586
- let rowList;
1587
- let val;
1588
- // normalize "\r\n" to "\n"
1589
- csv = csv.trimEnd().replace((
1590
- /\r\n?/gu
1591
- ), "\n") + "\n";
1592
- rgx = (
1593
- /(.*?)(""|"|,|\n)/gu
1594
- );
1595
- rowList = [];
1596
- // reset row
1597
- row = [];
1598
- val = "";
1599
- while (true) {
1600
- match = rgx.exec(csv);
1601
- if (!match) {
1602
- // 2. The last record in the file may or may not have an ending line
1603
- // break. For example:
1604
- // aaa,bbb,ccc CRLF
1605
- // zzz,yyy,xxx
1606
- if (!row.length) {
1607
- break;
1608
- }
1609
- // // if eof missing crlf, then mock it
1610
- // rgx.lastIndex = csv.length;
1611
- // match = [
1612
- // "\n", "", "\n"
1613
- // ];
1614
- }
1615
- // build val
1616
- val += match[1];
1617
- if (match[2] === "\"") {
1618
- // 5. Each field may or may not be enclosed in double quotes (however
1619
- // some programs, such as Microsoft Excel, do not use double quotes
1620
- // at all). If fields are not enclosed with double quotes, then
1621
- // double quotes may not appear inside the fields. For example:
1622
- // "aaa","bbb","ccc" CRLF
1623
- // zzz,yyy,xxx
1624
- quote = !quote;
1625
- } else if (quote) {
1626
- // 7. If double-quotes are used to enclose fields, then a double-quote
1627
- // appearing inside a field must be escaped by preceding it with
1628
- // another double quote. For example:
1629
- // "aaa","b""bb","ccc"
1630
- if (match[2] === "\"\"") {
1631
- val += "\"";
1632
- // 6. Fields containing line breaks (CRLF), double quotes, and commas
1633
- // should be enclosed in double-quotes. For example:
1634
- // "aaa","b CRLF
1635
- // bb","ccc" CRLF
1636
- // zzz,yyy,xxx
1637
- } else {
1638
- val += match[2];
1639
- }
1640
- } else if (match[2] === ",") {
1641
- // 4. Within the header and each record, there may be one or more
1642
- // fields, separated by commas. Each line should contain the same
1643
- // number of fields throughout the file. Spaces are considered part
1644
- // of a field and should not be ignored. The last field in the
1645
- // record must not be followed by a comma. For example:
1646
- // aaa,bbb,ccc
1647
- // delimit val
1648
- row.push(val);
1649
- val = "";
1650
- } else if (match[2] === "\n") {
1651
- // 1. Each record is located on a separate line, delimited by a line
1652
- // break (CRLF). For example:
1653
- // aaa,bbb,ccc CRLF
1654
- // zzz,yyy,xxx CRLF
1655
- // delimit val
1656
- row.push(val);
1657
- val = "";
1658
- // append row
1659
- rowList.push(row);
1660
- // reset row
1661
- row = [];
1662
- }
1663
- }
1664
- // // append val
1665
- // if (val) {
1666
- // row.push(val);
1667
- // }
1668
- // // append row
1669
- // if (row.length) {
1670
- // rowList.push(row);
1671
- // }
1672
- return rowList;
1673
- }
1674
-
1675
1720
  function libPlatformArchExt() {
1676
1721
  let libArch = process.arch;
1677
1722
  let libExt = process.platform;
@@ -1904,6 +1949,43 @@ function sqlmathWebworkerInit({
1904
1949
  }
1905
1950
  }
1906
1951
 
1952
+ async function uvthreadpoolsizeGet() {
1953
+
1954
+ // This function will guess how many logical-processors on current-host.
1955
+
1956
+ let uvthreadpoolsize;
1957
+ await new Promise(function (resolve) {
1958
+ let child;
1959
+ child = moduleChildProcess.spawn(
1960
+ "sh",
1961
+ ["-c", (`
1962
+ case "$(uname)" in
1963
+ Darwin)
1964
+ sysctl -n hw.logicalcpu
1965
+ ;;
1966
+ Linux)
1967
+ nproc
1968
+ ;;
1969
+ *NT*)
1970
+ wmic cpu get NumberOfLogicalProcessors | \
1971
+ grep -v "NumberOfLogicalProcessors"
1972
+ ;;
1973
+ esac
1974
+ `)],
1975
+ {stdio: ["ignore", "pipe", "ignore"]}
1976
+ );
1977
+ child.stdout.setEncoding("utf8");
1978
+ child.stdout.on("data", function (chunk) {
1979
+ uvthreadpoolsize = Number(chunk);
1980
+ });
1981
+ child.on("exit", resolve);
1982
+ });
1983
+ if (npm_config_mode_test) {
1984
+ uvthreadpoolsize = undefined;
1985
+ }
1986
+ return uvthreadpoolsize || 4;
1987
+ }
1988
+
1907
1989
  function waitAsync(timeout) {
1908
1990
 
1909
1991
  // This function will wait <timeout> ms.
@@ -1966,6 +2048,8 @@ export {
1966
2048
  assertOrThrow,
1967
2049
  childProcessSpawn2,
1968
2050
  ciBuildExt,
2051
+ csvFromListofList,
2052
+ csvToListofList,
1969
2053
  dbCloseAsync,
1970
2054
  dbExecAndReturnLastBlob,
1971
2055
  dbExecAndReturnLastRow,
@@ -1990,6 +2074,7 @@ export {
1990
2074
  noop,
1991
2075
  objectDeepCopyWithKeysSorted,
1992
2076
  sqlmathWebworkerInit,
2077
+ uvthreadpoolsizeGet,
1993
2078
  version,
1994
2079
  waitAsync
1995
2080
  };
@@ -1,6 +1,7 @@
1
1
  /*jslint beta, bitwise, browser, devel, nomen*/
2
2
  import {
3
3
  assertOrThrow,
4
+ csvFromListofList,
4
5
  dbCloseAsync,
5
6
  dbExecAsync,
6
7
  dbFileSaveAsync,
@@ -337,22 +338,11 @@ INSERT INTO tradebot_tech_intra_day
337
338
  *
338
339
  FROM (
339
340
  SELECT
340
- tname,
341
- datemkt0_beg AS xdate,
342
- datemkt0_beg AS xdate2,
343
- stk_beg0 AS tval
344
- FROM tradebot_state
345
- JOIN (
346
- SELECT '1a_stk_pct' AS tname
347
- --
348
- UNION ALL
349
- --
350
- SELECT '1b_stk_lmt' AS tname
351
- )
352
- --
353
- UNION ALL
354
- --
355
- SELECT '1a_stk_pct', xdate, xdate2, stk_pct FROM tradebot_tech_intra
341
+ '1a_stk_pct' AS tname,
342
+ xdate,
343
+ xdate2,
344
+ stk_pct AS tval
345
+ FROM tradebot_tech_intra
356
346
  --
357
347
  UNION ALL
358
348
  --
@@ -984,7 +974,7 @@ INSERT INTO chart._{{ii}}_tradebot_buysell_history (
984
974
  ? "unixepochToTimeutc"
985
975
  : "juliandayToDate"
986
976
  ),
987
- yaxisTitle: "percent holding",
977
+ yaxisTitle: "percent gain",
988
978
  yvalueSuffix: " %"
989
979
  };
990
980
  return (`
@@ -1574,7 +1564,8 @@ async function onDbAction(evt) {
1574
1564
  case "dbtableRename":
1575
1565
  title = target.textContent.trim().replace(/\s+/g, " ");
1576
1566
  UI_CRUD.querySelector(".modalTitle").innerHTML = (
1577
- `${stringHtmlSafe(baton.dbtableFullname)}<br>${title}`
1567
+ `${stringHtmlSafe(baton.dbtableFullname)}<br>` +
1568
+ `${stringHtmlSafe(title)}`
1578
1569
  );
1579
1570
  UI_CRUD.querySelector("tbody").innerHTML = (
1580
1571
  (`
@@ -1839,7 +1830,7 @@ DELETE FROM ${baton.dbtableName} WHERE rowid = ${baton.rowid};
1839
1830
  });
1840
1831
  data = data[0] || [];
1841
1832
  data.shift();
1842
- data = rowListToCsv({
1833
+ data = csvFromListofList({
1843
1834
  colList: baton.colList,
1844
1835
  rowList: data
1845
1836
  });
@@ -2101,46 +2092,6 @@ function onResize() {
2101
2092
  uitableInitWithinView({});
2102
2093
  }
2103
2094
 
2104
- function rowListToCsv({
2105
- colList,
2106
- rowList
2107
- }) {
2108
- // this function will convert json <rowList> to csv with given <colList>
2109
- let data = JSON.stringify([[colList], rowList].flat(), undefined, 1);
2110
- // convert data to csv
2111
- data = data.replace((
2112
- /\n /g
2113
- ), "");
2114
- data = data.replace((
2115
- /\n \[/g
2116
- ), "");
2117
- data = data.replace((
2118
- /\n \],?/g
2119
- ), "\r\n");
2120
- data = data.slice(1, -2);
2121
- // sqlite-strings are c-strings which should never contain null-char
2122
- data = data.replace((
2123
- /\u0000/g
2124
- ), "");
2125
- // hide double-backslash `\\\\` as null-char
2126
- data = data.replace((
2127
- /\\\\/g
2128
- ), "\u0000");
2129
- // escape double-quote `\\"` to `""`
2130
- data = data.replace((
2131
- /\\"/g
2132
- ), "\"\"");
2133
- // replace newline with space
2134
- data = data.replace((
2135
- /\\r\\n|\\r|\\n/g
2136
- ), " ");
2137
- // restore double-backslash `\\\\` from null-char
2138
- data = data.replace((
2139
- /\u0000/g
2140
- ), "\\\\");
2141
- return data;
2142
- }
2143
-
2144
2095
  function stringHtmlSafe(str) {
2145
2096
  // this function will make <str> html-safe
2146
2097
  // https://stackoverflow.com/questions/7381974
package/sqlmath_wasm.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /*jslint-disable*/
2
2
  // Copyright (c) 2021 Kai Zhu
3
3
  // SPDX-License-Identifier: MIT
4
- // 2026-05-02T20:50:59+0000
4
+ // 2026-07-01T23:02:00+0000
5
5
  (function () {
6
6
  "use strict";
7
7
 
8
- var g;g||(g=typeof Module !== 'undefined' ? Module : {});var aa=Object.assign;(function(){function a(){}function b(...c){a("\n\ndebugInline");a(...c);a("\n");return c[0]}b();a=console.error;return b})();function ba(a){return a&&a.constructor===ArrayBuffer}
8
+ var g;g||(g=typeof Module !== 'undefined' ? Module : {});var aa=Object.assign;function ba(a){return a&&a.constructor===ArrayBuffer}
9
9
  (async function(){let a=h("dbFileLoadOrSave","number",["number","string","number"]),b=h("jsbatonGetErrmsg","string",["number"]),c=h("jsbatonGetString","string",["number","number"]),d=h("sqlite3_errmsg","string",["number"]),e;globalThis.onmessage=async function({data:f}){await e;f.batonPtr=0;try{a:{let G=f.FILENAME_DBTMP;var k=f.JSBATON_OFFSET_ALL;let Rb=f.JSBATON_OFFSET_BUFV,P=f.argList,Q=new Uint8Array(f.baton.buffer),C=0,A=P[4],Sb=0,ea="",W=f.funcname,Va=P[2];switch(W){case "_dbClose":case "_dbExec":case "_dbFileLoad":case "_dbNoop":case "_dbOpen":C=
10
10
  ca(Q.byteLength);f.batonPtr=C;l.set(Q,C);switch(W){case "_dbClose":console.error(`_dbClose("${c(C,1)}")`);break;case "_dbFileLoad":Va||da(G,new Uint8Array(A));break;case "_dbOpen":console.error(`_dbOpen("${c(C,0)}")`)}fa(C);ea=b(C);Q.set(l.subarray(C,C+k));switch(!ea&&W){case "_dbExec":A=new BigInt64Array(Q.buffer,Rb);P[0]=l.slice(Number(A[0]),Number(A[0]+A[1])).buffer;ha(Number(A[0]));break;case "_dbFileLoad":if(Va){k=G;var m=m||0;var p=p||"binary";if("utf8"!==p&&"binary"!==p)throw Error('Invalid encoding type "'+
11
11
  p+'"');var q,t=n(k,m),v=r(k).size,H=new Uint8Array(v);ia(t,H,0,v,0);"utf8"===p?q=u(H,0):"binary"===p&&(q=H);ja(t);P[0]=q.buffer;ka(G)}break;case "_dbOpen":A&&(da(G,new Uint8Array(A)),A=Number(la(C,0)),(Sb=a(A,G,0))&&(ea=d(A)),ka(G))}postMessage({argList:P,baton:new DataView(Q.buffer),errmsg:ea,funcname:W,id:f.id},[Q.buffer,...P.filter(ba)]);var Tb=void 0;break a}throw Error(`invalid funcname "${W}"`);}await Tb}catch(G){postMessage({errmsg:G.stack,id:f.id})}finally{ha(f.batonPtr)}};e=new Promise(function(f){g.postRun=
package/test.mjs CHANGED
@@ -39,6 +39,7 @@ import {
39
39
  assertOrThrow,
40
40
  childProcessSpawn2,
41
41
  ciBuildExt,
42
+ csvFromListofList,
42
43
  dbCloseAsync,
43
44
  dbExecAndReturnLastBlob,
44
45
  dbExecAndReturnLastRow,
@@ -61,6 +62,7 @@ import {
61
62
  listOrEmptyList,
62
63
  noop,
63
64
  sqlmathWebworkerInit,
65
+ uvthreadpoolsizeGet,
64
66
  version,
65
67
  waitAsync
66
68
  } from "./sqlmath.mjs";
@@ -168,7 +170,8 @@ SELECT
168
170
  );
169
171
  result = result.stdout.trim();
170
172
  assertJsonEqual(result, "abcd1234|abcd1234");
171
- }())
173
+ }()),
174
+ uvthreadpoolsizeGet()
172
175
  ]);
173
176
  });
174
177
  });
@@ -3927,10 +3930,17 @@ SELECT
3927
3930
  ) USING (ii);
3928
3931
  `)
3929
3932
  });
3930
- valActual = (
3931
- "date saa sww spp"
3932
- + " ii linear_residual predict_sine\n"
3933
- + valActual.map(function (elem) {
3933
+ valActual = csvFromListofList({
3934
+ colList: [
3935
+ "date",
3936
+ "saa",
3937
+ "sww",
3938
+ "spp",
3939
+ "ii",
3940
+ "linear_residual",
3941
+ "predict_sine"
3942
+ ],
3943
+ rowList: valActual.map(function (elem) {
3934
3944
  return [
3935
3945
  elem.date,
3936
3946
  elem.saa,
@@ -3945,13 +3955,13 @@ SELECT
3945
3955
  ? num.toFixed(4)
3946
3956
  : num
3947
3957
  );
3948
- }).join(" ");
3949
- }).join("\n")
3950
- );
3951
- valActual = valActual.replace((/ /g), " null ");
3952
- valActual = valActual.replace((/ \n/g), "\n");
3953
- valActual = valActual.replace((/ /g), "\t");
3954
- valActual = valActual.trim() + "\n";
3958
+ });
3959
+ })
3960
+ });
3961
+ valActual = valActual.replace((/"/g), "");
3962
+ valActual = valActual.replace((/,,/g), ",null,");
3963
+ valActual = valActual.replace((/\r\n/g), "\n");
3964
+ valActual = valActual.replace((/,/g), "\t");
3955
3965
  await fsWriteFileUnlessTest(
3956
3966
  "test_data_sinefit.csv",
3957
3967
  valActual,