@nshiab/simple-data-analysis-core 2.0.4 → 2.0.6

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.
Files changed (280) hide show
  1. package/README.md +118 -12
  2. package/esm/class/Simple.d.ts +8 -2
  3. package/esm/class/Simple.d.ts.map +1 -1
  4. package/esm/class/Simple.js +9 -3
  5. package/esm/class/SimpleDB.d.ts +72 -1
  6. package/esm/class/SimpleDB.d.ts.map +1 -1
  7. package/esm/class/SimpleDB.js +81 -1
  8. package/esm/class/SimpleTable.d.ts +434 -263
  9. package/esm/class/SimpleTable.d.ts.map +1 -1
  10. package/esm/class/SimpleTable.js +441 -316
  11. package/esm/helpers/LogValue.d.ts +8 -0
  12. package/esm/helpers/LogValue.d.ts.map +1 -0
  13. package/esm/helpers/LogValue.js +23 -0
  14. package/esm/helpers/cacheTableDependencies.d.ts +9 -0
  15. package/esm/helpers/cacheTableDependencies.d.ts.map +1 -1
  16. package/esm/helpers/cacheTableDependencies.js +131 -21
  17. package/esm/helpers/cleanSQL.d.ts +1 -1
  18. package/esm/helpers/cleanSQL.d.ts.map +1 -1
  19. package/esm/helpers/cleanSQL.js +268 -23
  20. package/esm/helpers/flushAllTables.d.ts.map +1 -1
  21. package/esm/helpers/flushAllTables.js +23 -28
  22. package/esm/helpers/foldIdentifier.d.ts +3 -0
  23. package/esm/helpers/foldIdentifier.d.ts.map +1 -0
  24. package/esm/helpers/foldIdentifier.js +4 -0
  25. package/esm/helpers/geometryFromJSON.d.ts +3 -0
  26. package/esm/helpers/geometryFromJSON.d.ts.map +1 -0
  27. package/esm/helpers/geometryFromJSON.js +4 -0
  28. package/esm/helpers/index.d.ts +1 -0
  29. package/esm/helpers/index.d.ts.map +1 -1
  30. package/esm/helpers/index.js +1 -0
  31. package/esm/helpers/logData.d.ts.map +1 -1
  32. package/esm/helpers/logData.js +45 -44
  33. package/esm/helpers/makeLogConverter.d.ts +5 -0
  34. package/esm/helpers/makeLogConverter.d.ts.map +1 -0
  35. package/esm/helpers/makeLogConverter.js +64 -0
  36. package/esm/helpers/osmFiles.d.ts.map +1 -1
  37. package/esm/helpers/parseTypes.d.ts +1 -1
  38. package/esm/helpers/parseTypes.d.ts.map +1 -1
  39. package/esm/helpers/parseTypes.js +4 -0
  40. package/esm/helpers/pendingOps.d.ts +4 -2
  41. package/esm/helpers/pendingOps.d.ts.map +1 -1
  42. package/esm/helpers/prepareGeometry.d.ts +3 -0
  43. package/esm/helpers/prepareGeometry.d.ts.map +1 -0
  44. package/esm/helpers/prepareGeometry.js +99 -0
  45. package/esm/helpers/prepareJSON.d.ts +3 -0
  46. package/esm/helpers/prepareJSON.d.ts.map +1 -0
  47. package/esm/helpers/prepareJSON.js +50 -0
  48. package/esm/helpers/printTable.d.ts +5 -4
  49. package/esm/helpers/printTable.d.ts.map +1 -1
  50. package/esm/helpers/printTable.js +32 -36
  51. package/esm/helpers/queryDB.js +1 -1
  52. package/esm/helpers/queueAsyncBarrier.d.ts +4 -0
  53. package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
  54. package/esm/helpers/queueAsyncBarrier.js +4 -0
  55. package/esm/helpers/queueOp.d.ts.map +1 -1
  56. package/esm/helpers/queueOp.js +5 -3
  57. package/esm/helpers/readMutationRows.d.ts +9 -0
  58. package/esm/helpers/readMutationRows.d.ts.map +1 -0
  59. package/esm/helpers/readMutationRows.js +94 -0
  60. package/esm/helpers/referencedTables.d.ts +9 -0
  61. package/esm/helpers/referencedTables.d.ts.map +1 -0
  62. package/esm/helpers/referencedTables.js +22 -0
  63. package/esm/helpers/runQuery.d.ts.map +1 -1
  64. package/esm/helpers/runQuery.js +11 -13
  65. package/esm/helpers/scanSQL.d.ts +7 -0
  66. package/esm/helpers/scanSQL.d.ts.map +1 -0
  67. package/esm/helpers/scanSQL.js +71 -0
  68. package/esm/helpers/tableRegistry.d.ts +2 -0
  69. package/esm/helpers/tableRegistry.d.ts.map +1 -1
  70. package/esm/helpers/tableRegistry.js +12 -4
  71. package/esm/helpers/updateColumnsWithJS.d.ts +52 -0
  72. package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -0
  73. package/esm/helpers/updateColumnsWithJS.js +139 -0
  74. package/esm/methods/addCharacterCount.d.ts +3 -0
  75. package/esm/methods/addCharacterCount.d.ts.map +1 -0
  76. package/esm/methods/addCharacterCount.js +15 -0
  77. package/esm/methods/addColumn.d.ts +1 -1
  78. package/esm/methods/addColumn.d.ts.map +1 -1
  79. package/esm/methods/addGeoNoise.d.ts +7 -0
  80. package/esm/methods/addGeoNoise.d.ts.map +1 -0
  81. package/esm/methods/addGeoNoise.js +135 -0
  82. package/esm/methods/addNoise.d.ts +5 -0
  83. package/esm/methods/addNoise.d.ts.map +1 -0
  84. package/esm/methods/addNoise.js +53 -0
  85. package/esm/methods/addWordCount.d.ts +3 -0
  86. package/esm/methods/addWordCount.d.ts.map +1 -0
  87. package/esm/methods/addWordCount.js +15 -0
  88. package/esm/methods/bm25.d.ts.map +1 -1
  89. package/esm/methods/bm25.js +1 -2
  90. package/esm/methods/cache.d.ts.map +1 -1
  91. package/esm/methods/cache.js +4 -6
  92. package/esm/methods/columnProportions.d.ts +1 -0
  93. package/esm/methods/columnProportions.d.ts.map +1 -1
  94. package/esm/methods/columnProportions.js +7 -2
  95. package/esm/methods/convert.d.ts +2 -2
  96. package/esm/methods/convert.d.ts.map +1 -1
  97. package/esm/methods/convert.js +5 -0
  98. package/esm/methods/getBottom.d.ts +1 -1
  99. package/esm/methods/getBottom.d.ts.map +1 -1
  100. package/esm/methods/getBottom.js +2 -2
  101. package/esm/methods/getData.d.ts +1 -1
  102. package/esm/methods/getData.d.ts.map +1 -1
  103. package/esm/methods/getData.js +2 -2
  104. package/esm/methods/join.d.ts.map +1 -1
  105. package/esm/methods/join.js +8 -16
  106. package/esm/methods/joinGeo.d.ts.map +1 -1
  107. package/esm/methods/joinGeo.js +10 -19
  108. package/esm/methods/loadArray.d.ts +4 -2
  109. package/esm/methods/loadArray.d.ts.map +1 -1
  110. package/esm/methods/loadArray.js +182 -18
  111. package/esm/methods/loadData.js +3 -0
  112. package/esm/methods/loadYahooFinanceData.d.ts +10 -0
  113. package/esm/methods/loadYahooFinanceData.d.ts.map +1 -0
  114. package/esm/methods/loadYahooFinanceData.js +133 -0
  115. package/esm/methods/log.d.ts +7 -0
  116. package/esm/methods/log.d.ts.map +1 -0
  117. package/esm/methods/log.js +58 -0
  118. package/esm/methods/logBottom.d.ts +5 -0
  119. package/esm/methods/logBottom.d.ts.map +1 -0
  120. package/esm/methods/logBottom.js +9 -0
  121. package/esm/methods/removeTable.d.ts.map +1 -1
  122. package/esm/methods/removeTable.js +2 -0
  123. package/esm/methods/removeTables.d.ts.map +1 -1
  124. package/esm/methods/removeTables.js +7 -0
  125. package/esm/methods/renameTable.d.ts.map +1 -1
  126. package/esm/methods/renameTable.js +4 -0
  127. package/esm/methods/rowProportions.d.ts +1 -0
  128. package/esm/methods/rowProportions.d.ts.map +1 -1
  129. package/esm/methods/rowProportions.js +5 -1
  130. package/esm/methods/rowToText.js +2 -2
  131. package/esm/methods/selectTables.d.ts.map +1 -1
  132. package/esm/methods/selectTables.js +6 -0
  133. package/esm/methods/setTypes.d.ts +1 -1
  134. package/esm/methods/setTypes.d.ts.map +1 -1
  135. package/esm/methods/stream.d.ts.map +1 -1
  136. package/esm/methods/stream.js +2 -1
  137. package/esm/methods/updateWithJS.d.ts +1 -3
  138. package/esm/methods/updateWithJS.d.ts.map +1 -1
  139. package/esm/methods/updateWithJS.js +123 -37
  140. package/llm.md +600 -430
  141. package/llms.txt +1 -1
  142. package/package.json +1 -1
  143. package/script/class/Simple.d.ts +8 -2
  144. package/script/class/Simple.d.ts.map +1 -1
  145. package/script/class/Simple.js +9 -3
  146. package/script/class/SimpleDB.d.ts +72 -1
  147. package/script/class/SimpleDB.d.ts.map +1 -1
  148. package/script/class/SimpleDB.js +81 -1
  149. package/script/class/SimpleTable.d.ts +434 -263
  150. package/script/class/SimpleTable.d.ts.map +1 -1
  151. package/script/class/SimpleTable.js +441 -316
  152. package/script/helpers/LogValue.d.ts +8 -0
  153. package/script/helpers/LogValue.d.ts.map +1 -0
  154. package/script/helpers/LogValue.js +26 -0
  155. package/script/helpers/cacheTableDependencies.d.ts +9 -0
  156. package/script/helpers/cacheTableDependencies.d.ts.map +1 -1
  157. package/script/helpers/cacheTableDependencies.js +170 -20
  158. package/script/helpers/cleanSQL.d.ts +1 -1
  159. package/script/helpers/cleanSQL.d.ts.map +1 -1
  160. package/script/helpers/cleanSQL.js +271 -23
  161. package/script/helpers/flushAllTables.d.ts.map +1 -1
  162. package/script/helpers/flushAllTables.js +24 -29
  163. package/script/helpers/foldIdentifier.d.ts +3 -0
  164. package/script/helpers/foldIdentifier.d.ts.map +1 -0
  165. package/script/helpers/foldIdentifier.js +7 -0
  166. package/script/helpers/geometryFromJSON.d.ts +3 -0
  167. package/script/helpers/geometryFromJSON.d.ts.map +1 -0
  168. package/script/helpers/geometryFromJSON.js +7 -0
  169. package/script/helpers/index.d.ts +1 -0
  170. package/script/helpers/index.d.ts.map +1 -1
  171. package/script/helpers/index.js +3 -1
  172. package/script/helpers/logData.d.ts.map +1 -1
  173. package/script/helpers/logData.js +45 -44
  174. package/script/helpers/makeLogConverter.d.ts +5 -0
  175. package/script/helpers/makeLogConverter.d.ts.map +1 -0
  176. package/script/helpers/makeLogConverter.js +70 -0
  177. package/script/helpers/osmFiles.d.ts.map +1 -1
  178. package/script/helpers/parseTypes.d.ts +1 -1
  179. package/script/helpers/parseTypes.d.ts.map +1 -1
  180. package/script/helpers/parseTypes.js +4 -0
  181. package/script/helpers/pendingOps.d.ts +4 -2
  182. package/script/helpers/pendingOps.d.ts.map +1 -1
  183. package/script/helpers/prepareGeometry.d.ts +3 -0
  184. package/script/helpers/prepareGeometry.d.ts.map +1 -0
  185. package/script/helpers/prepareGeometry.js +102 -0
  186. package/script/helpers/prepareJSON.d.ts +3 -0
  187. package/script/helpers/prepareJSON.d.ts.map +1 -0
  188. package/script/helpers/prepareJSON.js +53 -0
  189. package/script/helpers/printTable.d.ts +5 -4
  190. package/script/helpers/printTable.d.ts.map +1 -1
  191. package/script/helpers/printTable.js +32 -36
  192. package/script/helpers/queryDB.js +1 -1
  193. package/script/helpers/queueAsyncBarrier.d.ts +4 -0
  194. package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
  195. package/script/helpers/queueAsyncBarrier.js +4 -0
  196. package/script/helpers/queueOp.d.ts.map +1 -1
  197. package/script/helpers/queueOp.js +4 -2
  198. package/script/helpers/readMutationRows.d.ts +9 -0
  199. package/script/helpers/readMutationRows.d.ts.map +1 -0
  200. package/script/helpers/readMutationRows.js +97 -0
  201. package/script/helpers/referencedTables.d.ts +9 -0
  202. package/script/helpers/referencedTables.d.ts.map +1 -0
  203. package/script/helpers/referencedTables.js +28 -0
  204. package/script/helpers/runQuery.d.ts.map +1 -1
  205. package/script/helpers/runQuery.js +11 -13
  206. package/script/helpers/scanSQL.d.ts +7 -0
  207. package/script/helpers/scanSQL.d.ts.map +1 -0
  208. package/script/helpers/scanSQL.js +74 -0
  209. package/script/helpers/tableRegistry.d.ts +2 -0
  210. package/script/helpers/tableRegistry.d.ts.map +1 -1
  211. package/script/helpers/tableRegistry.js +16 -4
  212. package/script/helpers/updateColumnsWithJS.d.ts +52 -0
  213. package/script/helpers/updateColumnsWithJS.d.ts.map +1 -0
  214. package/script/helpers/updateColumnsWithJS.js +145 -0
  215. package/script/methods/addCharacterCount.d.ts +3 -0
  216. package/script/methods/addCharacterCount.d.ts.map +1 -0
  217. package/script/methods/addCharacterCount.js +21 -0
  218. package/script/methods/addColumn.d.ts +1 -1
  219. package/script/methods/addColumn.d.ts.map +1 -1
  220. package/script/methods/addGeoNoise.d.ts +7 -0
  221. package/script/methods/addGeoNoise.d.ts.map +1 -0
  222. package/script/methods/addGeoNoise.js +141 -0
  223. package/script/methods/addNoise.d.ts +5 -0
  224. package/script/methods/addNoise.d.ts.map +1 -0
  225. package/script/methods/addNoise.js +59 -0
  226. package/script/methods/addWordCount.d.ts +3 -0
  227. package/script/methods/addWordCount.d.ts.map +1 -0
  228. package/script/methods/addWordCount.js +21 -0
  229. package/script/methods/bm25.d.ts.map +1 -1
  230. package/script/methods/bm25.js +1 -2
  231. package/script/methods/cache.d.ts.map +1 -1
  232. package/script/methods/cache.js +3 -5
  233. package/script/methods/columnProportions.d.ts +1 -0
  234. package/script/methods/columnProportions.d.ts.map +1 -1
  235. package/script/methods/columnProportions.js +7 -2
  236. package/script/methods/convert.d.ts +2 -2
  237. package/script/methods/convert.d.ts.map +1 -1
  238. package/script/methods/convert.js +5 -0
  239. package/script/methods/getBottom.d.ts +1 -1
  240. package/script/methods/getBottom.d.ts.map +1 -1
  241. package/script/methods/getBottom.js +2 -2
  242. package/script/methods/getData.d.ts +1 -1
  243. package/script/methods/getData.d.ts.map +1 -1
  244. package/script/methods/getData.js +2 -2
  245. package/script/methods/join.d.ts.map +1 -1
  246. package/script/methods/join.js +8 -16
  247. package/script/methods/joinGeo.d.ts.map +1 -1
  248. package/script/methods/joinGeo.js +10 -19
  249. package/script/methods/loadArray.d.ts +4 -2
  250. package/script/methods/loadArray.d.ts.map +1 -1
  251. package/script/methods/loadArray.js +181 -17
  252. package/script/methods/loadData.js +3 -0
  253. package/script/methods/loadYahooFinanceData.d.ts +10 -0
  254. package/script/methods/loadYahooFinanceData.d.ts.map +1 -0
  255. package/script/methods/loadYahooFinanceData.js +139 -0
  256. package/script/methods/log.d.ts +7 -0
  257. package/script/methods/log.d.ts.map +1 -0
  258. package/script/methods/log.js +64 -0
  259. package/script/methods/logBottom.d.ts +5 -0
  260. package/script/methods/logBottom.d.ts.map +1 -0
  261. package/script/methods/logBottom.js +15 -0
  262. package/script/methods/removeTable.d.ts.map +1 -1
  263. package/script/methods/removeTable.js +2 -0
  264. package/script/methods/removeTables.d.ts.map +1 -1
  265. package/script/methods/removeTables.js +7 -0
  266. package/script/methods/renameTable.d.ts.map +1 -1
  267. package/script/methods/renameTable.js +4 -0
  268. package/script/methods/rowProportions.d.ts +1 -0
  269. package/script/methods/rowProportions.d.ts.map +1 -1
  270. package/script/methods/rowProportions.js +5 -1
  271. package/script/methods/rowToText.js +2 -2
  272. package/script/methods/selectTables.d.ts.map +1 -1
  273. package/script/methods/selectTables.js +6 -0
  274. package/script/methods/setTypes.d.ts +1 -1
  275. package/script/methods/setTypes.d.ts.map +1 -1
  276. package/script/methods/stream.d.ts.map +1 -1
  277. package/script/methods/stream.js +2 -1
  278. package/script/methods/updateWithJS.d.ts +1 -3
  279. package/script/methods/updateWithJS.d.ts.map +1 -1
  280. package/script/methods/updateWithJS.js +122 -36
package/README.md CHANGED
@@ -60,8 +60,28 @@ npx @nshiab/setup-data-project
60
60
  bunx @nshiab/setup-data-project
61
61
  ```
62
62
 
63
+ ## Running a data pipeline
64
+
65
+ Transformation methods are synchronous and chainable. SDA-core queues their work
66
+ and combines compatible operations into a single DuckDB statement. Async methods
67
+ such as `getData()`, `log()`, and `writeData()` execute pending work before
68
+ returning results, so only the final method in a chain needs to be awaited.
69
+
70
+ ```ts
71
+ await table
72
+ .filter("salary > 50000")
73
+ .selectColumns(["name", "salary"])
74
+ .log();
75
+ ```
76
+
77
+ Use `await table.run()` or `await sdb.run()` to execute pending work without
78
+ reading or exporting a result. Both execute queued operations across all tables
79
+ in the database, in the order the methods were called.
80
+
63
81
  ## Performance benchmarks
64
82
 
83
+ These are end-to-end workflow comparisons.
84
+
65
85
  These benchmarks compare SDA-core with raw DuckDB and popular Python and R
66
86
  libraries, measuring duration and peak memory.
67
87
 
@@ -69,6 +89,14 @@ They were run on a MacBook Pro with an Apple M4 Max and 64 GB of memory.
69
89
 
70
90
  <!-- benchmark-results:start -->
71
91
 
92
+ **Tabular versions:** @duckdb/node-api 1.5.5-r.4; DuckDB v1.5.5 (Deno 2.9.6);
93
+ SDA-core 2.0.5 (Deno 2.9.6); pandas 3.0.5 (Python 3.14.7); tidyverse 2.0.0 (R
94
+ 4.6.1).
95
+
96
+ **Spatial versions:** @duckdb/node-api 1.5.5-r.4; DuckDB v1.5.5 (Deno 2.9.6);
97
+ SDA-core 2.0.5 (Deno 2.9.6); GeoPandas 1.1.4 (Python 3.14.7); sf 1.1.2 (R
98
+ 4.6.1).
99
+
72
100
  ### Tabular workload
73
101
 
74
102
  Using 22,051,025 temperature records (`ahccd.csv`, 1.77 GB, in
@@ -76,12 +104,12 @@ Using 22,051,025 temperature records (`ahccd.csv`, 1.77 GB, in
76
104
  save the cleaned data, then calculate average temperatures by station and decade
77
105
  and export the sorted results.
78
106
 
79
- | Library version | Runtime | Mean duration | Duration difference | Mean peak memory | Memory difference |
80
- | ----------------------------------------- | ------------- | -------------: | ------------------: | ---------------: | ----------------: |
81
- | @duckdb/node-api 1.5.5-r.4; DuckDB v1.5.5 | Deno 2.9.6 | 1.14 ± 0.01 s | -8.2% | 2,372 MB | -7.1% |
82
- | SDA-core 2.0.0 | Deno 2.9.6 | 1.24 ± 0.03 s | baseline | 2,554 MB | baseline |
83
- | pandas 3.0.5 | Python 3.14.7 | 28.21 ± 0.01 s | +2168.6% | 4,699 MB | +84.0% |
84
- | tidyverse 2.0.0 | R 4.6.1 | 78.81 ± 0.17 s | +6236.7% | 8,178 MB | +220.2% |
107
+ | Library | Mean duration | Duration difference | Mean peak memory | Memory difference |
108
+ | --------- | -------------: | ------------------: | ---------------: | ----------------: |
109
+ | DuckDB | 1.30 ± 0.03 s | -9.7% | 2,457 MB | -2.7% |
110
+ | SDA-core | 1.44 ± 0.03 s | baseline | 2,524 MB | baseline |
111
+ | pandas | 30.08 ± 0.07 s | +1987.9% | 4,700 MB | +86.2% |
112
+ | tidyverse | 82.62 ± 0.22 s | +5634.4% | 8,178 MB | +224.0% |
85
113
 
86
114
  ### Spatial workload
87
115
 
@@ -91,15 +119,72 @@ in `benchmarks/data/`, we remove missing coordinates, create points, join trees
91
119
  to neighbourhoods, then count trees per neighbourhood and export the sorted
92
120
  results.
93
121
 
94
- | Library version | Runtime | Mean duration | Duration difference | Mean peak memory | Memory difference |
95
- | ----------------------------------------- | ------------- | ------------: | ------------------: | ---------------: | ----------------: |
96
- | @duckdb/node-api 1.5.5-r.4; DuckDB v1.5.5 | Deno 2.9.6 | 0.72 ± 0.01 s | -3.4% | 255 MB | -7.2% |
97
- | SDA-core 2.0.0 | Deno 2.9.6 | 0.75 ± 0.01 s | baseline | 275 MB | baseline |
98
- | GeoPandas 1.1.4 | Python 3.14.7 | 1.11 ± 0.00 s | +48.7% | 292 MB | +6.0% |
99
- | sf 1.1.2 | R 4.6.1 | 1.58 ± 0.00 s | +111.2% | 489 MB | +78.0% |
122
+ | Library | Mean duration | Duration difference | Mean peak memory | Memory difference |
123
+ | --------- | ------------: | ------------------: | ---------------: | ----------------: |
124
+ | DuckDB | 0.78 ± 0.00 s | -5.1% | 255 MB | -5.8% |
125
+ | SDA-core | 0.82 ± 0.01 s | baseline | 271 MB | baseline |
126
+ | GeoPandas | 1.25 ± 0.01 s | +51.4% | 294 MB | +8.5% |
127
+ | sf | 1.80 ± 0.01 s | +118.9% | 490 MB | +81.1% |
100
128
 
101
129
  <!-- benchmark-results:end -->
102
130
 
131
+ ### Focused operation benchmarks
132
+
133
+ These additional benchmarks compare Core and DuckDB on data transfer, joins,
134
+ aggregations, and JavaScript geometry updates to help track and improve
135
+ performance over time. Run `deno task benchmark-core` to regenerate these
136
+ tables. See the [benchmark methodology](benchmarks/operations/README.md) for
137
+ fixture sizes, validation, and measurement details. Peak process memory includes
138
+ setup, warm-up, the measured operation, and validation.
139
+
140
+ <!-- benchmark-operations:start -->
141
+
142
+ #### Join followed by aggregation
143
+
144
+ | Operation | Rows | Batch size | Implementation | Mean duration ± SD | Mean peak process memory |
145
+ | ---------------- | --------: | ---------: | -------------- | -----------------: | -----------------------: |
146
+ | Join → aggregate | 1,000,000 | — | Core | 12.11 ± 0.25 ms | 123.1 MiB |
147
+ | Join → aggregate | 1,000,000 | — | DuckDB | 11.29 ± 0.33 ms | 134.2 MiB |
148
+
149
+ #### JavaScript data transfer
150
+
151
+ `loadArray()` measures JavaScript → DuckDB; `getData()` measures DuckDB →
152
+ JavaScript. `updateWithJS()` measures the round trip with a simple numeric
153
+ increment, including Core's staging and table replacement.
154
+
155
+ | Operation | Rows | Batch size | Implementation | Mean duration ± SD | Mean peak process memory |
156
+ | -------------- | ------: | ---------: | -------------- | -----------------: | -----------------------: |
157
+ | loadArray() | 100,000 | — | Core | 9.40 ± 0.68 ms | 202.3 MiB |
158
+ | loadArray() | 100,000 | — | DuckDB | 19.80 ± 0.94 ms | 230.8 MiB |
159
+ | getData() | 100,000 | — | Core | 9.29 ± 0.26 ms | 191.2 MiB |
160
+ | getData() | 100,000 | — | DuckDB | 12.54 ± 0.27 ms | 209.0 MiB |
161
+ | updateWithJS() | 100,000 | 1000 | Core | 92.45 ± 3.19 ms | 208.2 MiB |
162
+ | updateWithJS() | 100,000 | 1000 | DuckDB | 65.89 ± 1.13 ms | 239.6 MiB |
163
+ | updateWithJS() | 100,000 | 10000 | Core | 42.93 ± 1.05 ms | 218.6 MiB |
164
+ | updateWithJS() | 100,000 | 10000 | DuckDB | 41.76 ± 0.81 ms | 233.5 MiB |
165
+
166
+ #### JavaScript geometry updates
167
+
168
+ Points have one position per geometry; polygons have one ring with 1,001
169
+ positions. Both implementations transfer GeoJSON through JavaScript and stage
170
+ writes. These updates add a label and shift every longitude by 0.01 degrees. A
171
+ batch size of — means all input rows at once. Attribute-only updates are also
172
+ measured and retained in the raw results; their similar timings are omitted here
173
+ to keep the table concise.
174
+
175
+ | Operation | Rows | Batch size | Implementation | Mean duration ± SD | Mean peak process memory |
176
+ | ------------------------- | ------: | ---------: | -------------- | -----------------: | -----------------------: |
177
+ | Points: geometry update | 100,000 | — | Core | 182.59 ± 1.02 ms | 402.4 MiB |
178
+ | Points: geometry update | 100,000 | — | DuckDB | 180.20 ± 1.98 ms | 402.2 MiB |
179
+ | Points: geometry update | 100,000 | 1000 | Core | 252.07 ± 6.59 ms | 267.9 MiB |
180
+ | Points: geometry update | 100,000 | 1000 | DuckDB | 217.69 ± 2.43 ms | 245.4 MiB |
181
+ | Polygons: geometry update | 1,000 | — | Core | 403.35 ± 1.92 ms | 938.3 MiB |
182
+ | Polygons: geometry update | 1,000 | — | DuckDB | 408.62 ± 2.57 ms | 1104.8 MiB |
183
+ | Polygons: geometry update | 1,000 | 100 | Core | 418.45 ± 2.45 ms | 747.0 MiB |
184
+ | Polygons: geometry update | 1,000 | 100 | DuckDB | 416.90 ± 2.54 ms | 714.6 MiB |
185
+
186
+ <!-- benchmark-operations:end -->
187
+
103
188
  ## Building extensions
104
189
 
105
190
  The full
@@ -115,6 +200,10 @@ chainable, define them on a `SimpleTable` subclass, give them a return type of
115
200
  create tables should always use `this.sdb.newTable()` so they also return your
116
201
  extended table type.
117
202
 
203
+ Builders return `this` synchronously; their queued work runs when an observer
204
+ such as `getData()`, `log()`, or `run()` is called. Observers execute pending
205
+ work across the database in program order.
206
+
118
207
  ```ts
119
208
  import {
120
209
  SimpleDB as CoreDB,
@@ -172,3 +261,20 @@ The callback must await all asynchronous work that can queue builders. If it
172
261
  rejects, captured builders that have not already run are discarded. Builders
173
262
  already drained by an observer inside the callback remain applied;
174
263
  `queueAsyncBarrier()` does not provide database rollback.
264
+
265
+ This differs from a failure while executing queued builders: during replay, the
266
+ failing table's remaining chain is aborted, but unexecuted work for other tables
267
+ is requeued for their next observation.
268
+
269
+ Other useful helpers, imported from `@nshiab/simple-data-analysis-core/helpers`:
270
+
271
+ - `updateColumnsWithJS()`: enrich selected columns asynchronously in bounded
272
+ batches inside `queueAsyncBarrier()`, preserving untouched columns, including
273
+ geometry. Return one result per input row, in the same order.
274
+ - `queryDB()` with `mergeOptions()`: execute SQL with the library's logging and
275
+ diagnostic settings. Queries flush queued work before running.
276
+ - `quoteIdentifier()`: quote table and column names safely when constructing
277
+ SQL.
278
+
279
+ See the [exported helpers](src/helpers/index.ts) for the complete list and links
280
+ to their documentation and examples. Helpers outside that list are internal.
@@ -18,9 +18,15 @@ export default class Simple {
18
18
  */
19
19
  typesToLog: boolean;
20
20
  /**
21
- * The maximum number of characters to display for text-based cells. If undefined, the entire text is shown.
21
+ * The maximum number of characters to display for text and stringified nested cells, including the truncation marker. This does not control column width. Set to Infinity to show the entire text.
22
22
  *
23
- * @defaultValue `undefined`
23
+ * @example
24
+ * ```ts
25
+ * const sdb = new SimpleDB({ charsToLog: 150 });
26
+ * await sdb.newTable().loadArray([{ text: "x".repeat(200) }]).log();
27
+ * ```
28
+ *
29
+ * @defaultValue `75`
24
30
  */
25
31
  charsToLog: number | undefined;
26
32
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Simple.d.ts","sourceRoot":"","sources":["../../src/class/Simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;OAEG;IACH,EAAE,EAAG,cAAc,CAAC;IACpB;;OAEG;IACH,UAAU,EAAG,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,EAAG,CACT,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,gBAAgB,EAC5B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,UAAU,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,GAAG,IAAI,CAAC;QAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;QACvB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;KACrB,KACE,OAAO,CACR;QACA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,EAAE,GACD,IAAI,CACP,CAAC;gBAGA,OAAO,GAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACjB;CAOT"}
1
+ {"version":3,"file":"Simple.d.ts","sourceRoot":"","sources":["../../src/class/Simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;OAEG;IACH,EAAE,EAAG,cAAc,CAAC;IACpB;;OAEG;IACH,UAAU,EAAG,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,EAAG,CACT,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,gBAAgB,EAC5B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,UAAU,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,GAAG,IAAI,CAAC;QAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;QACvB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;KACrB,KACE,OAAO,CACR;QACA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,EAAE,GACD,IAAI,CACP,CAAC;gBAGA,OAAO,GAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACjB;CAOT"}
@@ -28,9 +28,15 @@ export default class Simple {
28
28
  value: void 0
29
29
  });
30
30
  /**
31
- * The maximum number of characters to display for text-based cells. If undefined, the entire text is shown.
31
+ * The maximum number of characters to display for text and stringified nested cells, including the truncation marker. This does not control column width. Set to Infinity to show the entire text.
32
32
  *
33
- * @defaultValue `undefined`
33
+ * @example
34
+ * ```ts
35
+ * const sdb = new SimpleDB({ charsToLog: 150 });
36
+ * await sdb.newTable().loadArray([{ text: "x".repeat(200) }]).log();
37
+ * ```
38
+ *
39
+ * @defaultValue `75`
34
40
  */
35
41
  Object.defineProperty(this, "charsToLog", {
36
42
  enumerable: true,
@@ -100,7 +106,7 @@ export default class Simple {
100
106
  value: void 0
101
107
  });
102
108
  this.rowsToLog = options.rowsToLog ?? 10;
103
- this.charsToLog = options.charsToLog;
109
+ this.charsToLog = options.charsToLog ?? 75;
104
110
  this.typesToLog = options.typesToLog ?? false;
105
111
  this.defaultTableName = false;
106
112
  }
@@ -36,6 +36,73 @@ import Simple from "./Simple.js";
36
36
  */
37
37
  export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends Simple {
38
38
  #private;
39
+ /**
40
+ * The operator syntax used by expressions and custom queries in this database.
41
+ * `"js"` translates JavaScript-style operators (`&&`, `||`, `==`, `===`,
42
+ * `!==`) and null comparisons within SQL expressions. It does not evaluate
43
+ * arbitrary JavaScript. `||` remains concatenation when string literals, list
44
+ * literals, explicit text casts, or `concat()` results make that intent clear.
45
+ * Otherwise `||` becomes OR; column types are not inferred. Use `concat()`
46
+ * when concatenation would otherwise be ambiguous, such as `first || last`.
47
+ * `"sql"` passes SQL through unchanged, including `||` and null comparisons.
48
+ * Choose the syntax when constructing the database; it applies to all tables.
49
+ *
50
+ * @defaultValue `"js"`
51
+ * @category Properties
52
+ * @example
53
+ * ```ts
54
+ * const sdb = new SimpleDB({ expressionSyntax: "js" }); // The default mode
55
+ * // || becomes SQL OR: keep rows where at least one condition is true.
56
+ * await sdb.newTable().loadArray([{ active: true, admin: false }])
57
+ * .filter("active || admin").log();
58
+ * ```
59
+ * @example
60
+ * ```ts
61
+ * const sdb = new SimpleDB({ expressionSyntax: "js" });
62
+ * // && becomes SQL AND: both conditions must be true.
63
+ * // === becomes SQL =: compare the age with 18.
64
+ * await sdb.newTable().loadArray([{ active: true, age: 18 }])
65
+ * .filter("active && age === 18").log();
66
+ * ```
67
+ * @example
68
+ * ```ts
69
+ * const sdb = new SimpleDB({ expressionSyntax: "js" });
70
+ * // SQL AND and OR also work in JS mode; they pass through unchanged.
71
+ * // Keep active adults, or anyone who is an admin.
72
+ * await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
73
+ * .filter("(active AND age >= 18) OR admin").log();
74
+ * ```
75
+ * @example
76
+ * ```ts
77
+ * const sdb = new SimpleDB({ expressionSyntax: "js" });
78
+ * // Bare column names do not establish concatenation. Use concat() explicitly.
79
+ * await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
80
+ * .addColumn("name", "string", "concat(first, ' ', last)").log();
81
+ * ```
82
+ * @example
83
+ * ```ts
84
+ * const sdb = new SimpleDB(); // JS mode is the default
85
+ * // The string literal ' ' makes concatenation clear, so both || stay unchanged.
86
+ * await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
87
+ * .addColumn("name", "string", "first || ' ' || last").log();
88
+ * ```
89
+ * @example
90
+ * ```ts
91
+ * const sdb = new SimpleDB({ expressionSyntax: "sql" });
92
+ * // SQL mode preserves || as concatenation: the name becomes "Jane Doe".
93
+ * await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
94
+ * .addColumn("name", "string", "first || ' ' || last").log();
95
+ * ```
96
+ * @example
97
+ * ```ts
98
+ * const sdb = new SimpleDB({ expressionSyntax: "sql" });
99
+ * // Use SQL AND and OR for logical conditions; && and || are not translated.
100
+ * // Both active and adult must be true, unless admin is true.
101
+ * await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
102
+ * .filter("(active AND age >= 18) OR admin").log();
103
+ * ```
104
+ */
105
+ readonly expressionSyntax: "js" | "sql";
39
106
  /**
40
107
  * Whether to log each SQL statement immediately before execution.
41
108
  *
@@ -255,9 +322,10 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
255
322
  * @param options.readOnly - Opens an existing DuckDB file read-only. Defaults to false. Requires a file and cannot be combined with overwrite.
256
323
  * @param options.logDuration - A flag indicating whether to log the total execution duration.
257
324
  * @param options.rowsToLog - The number of rows to display when logging a table.
258
- * @param options.charsToLog - The maximum number of characters to display for text-based cells.
325
+ * @param options.charsToLog - The maximum characters to display for text and stringified nested cells, including truncation markers (default: 75). Independent of column width. Use Infinity for unlimited text.
259
326
  * @param options.typesToLog - A flag indicating whether to include data types when logging a table.
260
327
  * @param options.cacheVerbose - Whether to log cache hits and misses, code and input changes, TTL status, and cache read/write timing.
328
+ * @param options.expressionSyntax - Operator syntax for expressions and custom queries: `"js"` (default) translates JavaScript-style operators in SQL expressions; `"sql"` preserves SQL unchanged.
261
329
  * @param options.logSQL - A flag indicating whether to log SQL immediately before execution.
262
330
  * @param options.explainSQL - A flag indicating whether to log DuckDB query plans for supported statements.
263
331
  * @param options.duckDbCache - A flag indicating whether to use DuckDB's external file cache.
@@ -283,6 +351,7 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
283
351
  charsToLog?: number;
284
352
  typesToLog?: boolean;
285
353
  cacheVerbose?: boolean;
354
+ expressionSyntax?: "js" | "sql";
286
355
  logSQL?: boolean;
287
356
  explainSQL?: boolean;
288
357
  duckDbCache?: boolean | null;
@@ -300,6 +369,7 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
300
369
  start(): Promise<SimpleDB>;
301
370
  /**
302
371
  * Creates a new SimpleTable instance within the database.
372
+ * The name must be unique among registered tables, ignoring ASCII letter case.
303
373
  *
304
374
  * @param name - The name of the new table. If not provided, a default name is generated (e.g., "table1").
305
375
  * @returns A new table instance.
@@ -486,6 +556,7 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
486
556
  }[]>;
487
557
  /**
488
558
  * Executes a custom SQL query directly against the DuckDB instance.
559
+ * With the default `SimpleDB.expressionSyntax: "js"`, queries support JavaScript-style operators (`&&`, `||`, `===`, `!==`). Set `expressionSyntax: "sql"` for unchanged SQL.
489
560
  * Queries run in UTC. When data is returned, temporal values use the same
490
561
  * JavaScript representations as `SimpleTable.getData()`.
491
562
  *
@@ -1 +1 @@
1
- {"version":3,"file":"SimpleDB.d.ts","sourceRoot":"","sources":["../../src/class/SimpleDB.ts"],"names":[],"mappings":"AAGA,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAG3C,OAAO,MAAM,MAAM,aAAa,CAAC;AA6BjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW,CACnE,SAAQ,MAAM;;IACd;;;;;;;;;OASG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;;;;;OASG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;OAOG;IACH,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAInC;;;;OAIG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,UAAU,EAAE,KACV,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,QAAQ,EACb,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,KACE,KAAK,CAQC;IAEX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;gBAED,OAAO,GAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KACb;IAgCR;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC;IAqGhC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,QAAQ,CACN,IAAI,CAAC,EAAE,MAAM,GACZ,KAAK;IAuCR;;;;;;;;;;;;;OAaG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAiB5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;IACG,YAAY,CAChB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC;IAKhB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACG,YAAY,CAChB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC;IAKhB;;;;;;;;;;;;OAYG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxC;;;;;;;;;;;;OAYG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAYpC;;;;;;;;;;;;;;OAcG;IACH,SAAS,IAAI,SAAS,KAAK,EAAE;IAI7B;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMvD;;;;;;;;;;;;OAYG;IACG,aAAa,IAAI,OAAO,CAC5B;QACE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,EAAE,CACJ;IAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACG,WAAW,CACf,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KACX,GACL,OAAO,CACN;QACA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,EAAE,GACD,IAAI,CACP;IAaD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACG,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GACxD,OAAO,CAAC,IAAI,CAAC;IAKhB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACG,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;IAU9B;;;;;;;;;;;;;;;OAeG;IACG,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC;CAkGjC"}
1
+ {"version":3,"file":"SimpleDB.d.ts","sourceRoot":"","sources":["../../src/class/SimpleDB.ts"],"names":[],"mappings":"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"}
@@ -89,9 +89,10 @@ class SimpleDB extends Simple {
89
89
  * @param options.readOnly - Opens an existing DuckDB file read-only. Defaults to false. Requires a file and cannot be combined with overwrite.
90
90
  * @param options.logDuration - A flag indicating whether to log the total execution duration.
91
91
  * @param options.rowsToLog - The number of rows to display when logging a table.
92
- * @param options.charsToLog - The maximum number of characters to display for text-based cells.
92
+ * @param options.charsToLog - The maximum characters to display for text and stringified nested cells, including truncation markers (default: 75). Independent of column width. Use Infinity for unlimited text.
93
93
  * @param options.typesToLog - A flag indicating whether to include data types when logging a table.
94
94
  * @param options.cacheVerbose - Whether to log cache hits and misses, code and input changes, TTL status, and cache read/write timing.
95
+ * @param options.expressionSyntax - Operator syntax for expressions and custom queries: `"js"` (default) translates JavaScript-style operators in SQL expressions; `"sql"` preserves SQL unchanged.
95
96
  * @param options.logSQL - A flag indicating whether to log SQL immediately before execution.
96
97
  * @param options.explainSQL - A flag indicating whether to log DuckDB query plans for supported statements.
97
98
  * @param options.duckDbCache - A flag indicating whether to use DuckDB's external file cache.
@@ -111,6 +112,78 @@ class SimpleDB extends Simple {
111
112
  constructor(options = {}) {
112
113
  super(options);
113
114
  _SimpleDB_instances.add(this);
115
+ /**
116
+ * The operator syntax used by expressions and custom queries in this database.
117
+ * `"js"` translates JavaScript-style operators (`&&`, `||`, `==`, `===`,
118
+ * `!==`) and null comparisons within SQL expressions. It does not evaluate
119
+ * arbitrary JavaScript. `||` remains concatenation when string literals, list
120
+ * literals, explicit text casts, or `concat()` results make that intent clear.
121
+ * Otherwise `||` becomes OR; column types are not inferred. Use `concat()`
122
+ * when concatenation would otherwise be ambiguous, such as `first || last`.
123
+ * `"sql"` passes SQL through unchanged, including `||` and null comparisons.
124
+ * Choose the syntax when constructing the database; it applies to all tables.
125
+ *
126
+ * @defaultValue `"js"`
127
+ * @category Properties
128
+ * @example
129
+ * ```ts
130
+ * const sdb = new SimpleDB({ expressionSyntax: "js" }); // The default mode
131
+ * // || becomes SQL OR: keep rows where at least one condition is true.
132
+ * await sdb.newTable().loadArray([{ active: true, admin: false }])
133
+ * .filter("active || admin").log();
134
+ * ```
135
+ * @example
136
+ * ```ts
137
+ * const sdb = new SimpleDB({ expressionSyntax: "js" });
138
+ * // && becomes SQL AND: both conditions must be true.
139
+ * // === becomes SQL =: compare the age with 18.
140
+ * await sdb.newTable().loadArray([{ active: true, age: 18 }])
141
+ * .filter("active && age === 18").log();
142
+ * ```
143
+ * @example
144
+ * ```ts
145
+ * const sdb = new SimpleDB({ expressionSyntax: "js" });
146
+ * // SQL AND and OR also work in JS mode; they pass through unchanged.
147
+ * // Keep active adults, or anyone who is an admin.
148
+ * await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
149
+ * .filter("(active AND age >= 18) OR admin").log();
150
+ * ```
151
+ * @example
152
+ * ```ts
153
+ * const sdb = new SimpleDB({ expressionSyntax: "js" });
154
+ * // Bare column names do not establish concatenation. Use concat() explicitly.
155
+ * await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
156
+ * .addColumn("name", "string", "concat(first, ' ', last)").log();
157
+ * ```
158
+ * @example
159
+ * ```ts
160
+ * const sdb = new SimpleDB(); // JS mode is the default
161
+ * // The string literal ' ' makes concatenation clear, so both || stay unchanged.
162
+ * await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
163
+ * .addColumn("name", "string", "first || ' ' || last").log();
164
+ * ```
165
+ * @example
166
+ * ```ts
167
+ * const sdb = new SimpleDB({ expressionSyntax: "sql" });
168
+ * // SQL mode preserves || as concatenation: the name becomes "Jane Doe".
169
+ * await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
170
+ * .addColumn("name", "string", "first || ' ' || last").log();
171
+ * ```
172
+ * @example
173
+ * ```ts
174
+ * const sdb = new SimpleDB({ expressionSyntax: "sql" });
175
+ * // Use SQL AND and OR for logical conditions; && and || are not translated.
176
+ * // Both active and adult must be true, unless admin is true.
177
+ * await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
178
+ * .filter("(active AND age >= 18) OR admin").log();
179
+ * ```
180
+ */
181
+ Object.defineProperty(this, "expressionSyntax", {
182
+ enumerable: true,
183
+ configurable: true,
184
+ writable: true,
185
+ value: void 0
186
+ });
114
187
  /**
115
188
  * Whether to log each SQL statement immediately before execution.
116
189
  *
@@ -423,6 +496,11 @@ class SimpleDB extends Simple {
423
496
  writable: true,
424
497
  value: SimpleTable
425
498
  });
499
+ if (options.expressionSyntax !== undefined &&
500
+ !["js", "sql"].includes(options.expressionSyntax)) {
501
+ throw new Error('expressionSyntax must be "js" or "sql".');
502
+ }
503
+ this.expressionSyntax = options.expressionSyntax ?? "js";
426
504
  this.file = options.file ?? ":memory:";
427
505
  this.logSQL = options.logSQL ?? false;
428
506
  this.explainSQL = options.explainSQL ?? false;
@@ -475,6 +553,7 @@ class SimpleDB extends Simple {
475
553
  }
476
554
  /**
477
555
  * Creates a new SimpleTable instance within the database.
556
+ * The name must be unique among registered tables, ignoring ASCII letter case.
478
557
  *
479
558
  * @param name - The name of the new table. If not provided, a default name is generated (e.g., "table1").
480
559
  * @returns A new table instance.
@@ -728,6 +807,7 @@ class SimpleDB extends Simple {
728
807
  }
729
808
  /**
730
809
  * Executes a custom SQL query directly against the DuckDB instance.
810
+ * With the default `SimpleDB.expressionSyntax: "js"`, queries support JavaScript-style operators (`&&`, `||`, `===`, `!==`). Set `expressionSyntax: "sql"` for unchanged SQL.
731
811
  * Queries run in UTC. When data is returned, temporal values use the same
732
812
  * JavaScript representations as `SimpleTable.getData()`.
733
813
  *