@nshiab/simple-data-analysis-core 2.0.5 → 2.0.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.
Files changed (244) 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 +271 -288
  9. package/esm/class/SimpleTable.d.ts.map +1 -1
  10. package/esm/class/SimpleTable.js +269 -340
  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/addColumn.d.ts +1 -1
  75. package/esm/methods/addColumn.d.ts.map +1 -1
  76. package/esm/methods/bins.d.ts +1 -1
  77. package/esm/methods/bins.d.ts.map +1 -1
  78. package/esm/methods/bins.js +45 -29
  79. package/esm/methods/bm25.d.ts.map +1 -1
  80. package/esm/methods/bm25.js +1 -2
  81. package/esm/methods/cache.d.ts.map +1 -1
  82. package/esm/methods/cache.js +4 -6
  83. package/esm/methods/convert.d.ts +2 -2
  84. package/esm/methods/convert.d.ts.map +1 -1
  85. package/esm/methods/convert.js +5 -0
  86. package/esm/methods/getBottom.d.ts +1 -1
  87. package/esm/methods/getBottom.d.ts.map +1 -1
  88. package/esm/methods/getBottom.js +2 -2
  89. package/esm/methods/getData.d.ts +1 -1
  90. package/esm/methods/getData.d.ts.map +1 -1
  91. package/esm/methods/getData.js +2 -2
  92. package/esm/methods/join.d.ts.map +1 -1
  93. package/esm/methods/join.js +8 -16
  94. package/esm/methods/joinGeo.d.ts.map +1 -1
  95. package/esm/methods/joinGeo.js +10 -19
  96. package/esm/methods/loadArray.d.ts +1 -1
  97. package/esm/methods/loadArray.d.ts.map +1 -1
  98. package/esm/methods/loadArray.js +74 -19
  99. package/esm/methods/loadData.js +3 -0
  100. package/esm/methods/log.d.ts +7 -0
  101. package/esm/methods/log.d.ts.map +1 -0
  102. package/esm/methods/log.js +63 -0
  103. package/esm/methods/logBottom.d.ts +5 -0
  104. package/esm/methods/logBottom.d.ts.map +1 -0
  105. package/esm/methods/logBottom.js +9 -0
  106. package/esm/methods/removeTable.d.ts.map +1 -1
  107. package/esm/methods/removeTable.js +2 -0
  108. package/esm/methods/removeTables.d.ts.map +1 -1
  109. package/esm/methods/removeTables.js +7 -0
  110. package/esm/methods/renameTable.d.ts.map +1 -1
  111. package/esm/methods/renameTable.js +4 -0
  112. package/esm/methods/rowToText.js +2 -2
  113. package/esm/methods/selectTables.d.ts.map +1 -1
  114. package/esm/methods/selectTables.js +6 -0
  115. package/esm/methods/setTypes.d.ts +1 -1
  116. package/esm/methods/setTypes.d.ts.map +1 -1
  117. package/esm/methods/stream.d.ts.map +1 -1
  118. package/esm/methods/stream.js +2 -1
  119. package/esm/methods/updateWithJS.d.ts +1 -3
  120. package/esm/methods/updateWithJS.d.ts.map +1 -1
  121. package/esm/methods/updateWithJS.js +123 -37
  122. package/llm.md +365 -461
  123. package/llms.txt +1 -1
  124. package/package.json +1 -1
  125. package/script/class/Simple.d.ts +8 -2
  126. package/script/class/Simple.d.ts.map +1 -1
  127. package/script/class/Simple.js +9 -3
  128. package/script/class/SimpleDB.d.ts +72 -1
  129. package/script/class/SimpleDB.d.ts.map +1 -1
  130. package/script/class/SimpleDB.js +81 -1
  131. package/script/class/SimpleTable.d.ts +271 -288
  132. package/script/class/SimpleTable.d.ts.map +1 -1
  133. package/script/class/SimpleTable.js +269 -340
  134. package/script/helpers/LogValue.d.ts +8 -0
  135. package/script/helpers/LogValue.d.ts.map +1 -0
  136. package/script/helpers/LogValue.js +26 -0
  137. package/script/helpers/cacheTableDependencies.d.ts +9 -0
  138. package/script/helpers/cacheTableDependencies.d.ts.map +1 -1
  139. package/script/helpers/cacheTableDependencies.js +170 -20
  140. package/script/helpers/cleanSQL.d.ts +1 -1
  141. package/script/helpers/cleanSQL.d.ts.map +1 -1
  142. package/script/helpers/cleanSQL.js +271 -23
  143. package/script/helpers/flushAllTables.d.ts.map +1 -1
  144. package/script/helpers/flushAllTables.js +24 -29
  145. package/script/helpers/foldIdentifier.d.ts +3 -0
  146. package/script/helpers/foldIdentifier.d.ts.map +1 -0
  147. package/script/helpers/foldIdentifier.js +7 -0
  148. package/script/helpers/geometryFromJSON.d.ts +3 -0
  149. package/script/helpers/geometryFromJSON.d.ts.map +1 -0
  150. package/script/helpers/geometryFromJSON.js +7 -0
  151. package/script/helpers/index.d.ts +1 -0
  152. package/script/helpers/index.d.ts.map +1 -1
  153. package/script/helpers/index.js +3 -1
  154. package/script/helpers/logData.d.ts.map +1 -1
  155. package/script/helpers/logData.js +45 -44
  156. package/script/helpers/makeLogConverter.d.ts +5 -0
  157. package/script/helpers/makeLogConverter.d.ts.map +1 -0
  158. package/script/helpers/makeLogConverter.js +70 -0
  159. package/script/helpers/osmFiles.d.ts.map +1 -1
  160. package/script/helpers/parseTypes.d.ts +1 -1
  161. package/script/helpers/parseTypes.d.ts.map +1 -1
  162. package/script/helpers/parseTypes.js +4 -0
  163. package/script/helpers/pendingOps.d.ts +4 -2
  164. package/script/helpers/pendingOps.d.ts.map +1 -1
  165. package/script/helpers/prepareGeometry.d.ts +3 -0
  166. package/script/helpers/prepareGeometry.d.ts.map +1 -0
  167. package/script/helpers/prepareGeometry.js +102 -0
  168. package/script/helpers/prepareJSON.d.ts +3 -0
  169. package/script/helpers/prepareJSON.d.ts.map +1 -0
  170. package/script/helpers/prepareJSON.js +53 -0
  171. package/script/helpers/printTable.d.ts +5 -4
  172. package/script/helpers/printTable.d.ts.map +1 -1
  173. package/script/helpers/printTable.js +32 -36
  174. package/script/helpers/queryDB.js +1 -1
  175. package/script/helpers/queueAsyncBarrier.d.ts +4 -0
  176. package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
  177. package/script/helpers/queueAsyncBarrier.js +4 -0
  178. package/script/helpers/queueOp.d.ts.map +1 -1
  179. package/script/helpers/queueOp.js +4 -2
  180. package/script/helpers/readMutationRows.d.ts +9 -0
  181. package/script/helpers/readMutationRows.d.ts.map +1 -0
  182. package/script/helpers/readMutationRows.js +97 -0
  183. package/script/helpers/referencedTables.d.ts +9 -0
  184. package/script/helpers/referencedTables.d.ts.map +1 -0
  185. package/script/helpers/referencedTables.js +28 -0
  186. package/script/helpers/runQuery.d.ts.map +1 -1
  187. package/script/helpers/runQuery.js +11 -13
  188. package/script/helpers/scanSQL.d.ts +7 -0
  189. package/script/helpers/scanSQL.d.ts.map +1 -0
  190. package/script/helpers/scanSQL.js +74 -0
  191. package/script/helpers/tableRegistry.d.ts +2 -0
  192. package/script/helpers/tableRegistry.d.ts.map +1 -1
  193. package/script/helpers/tableRegistry.js +16 -4
  194. package/script/helpers/updateColumnsWithJS.d.ts +52 -0
  195. package/script/helpers/updateColumnsWithJS.d.ts.map +1 -0
  196. package/script/helpers/updateColumnsWithJS.js +145 -0
  197. package/script/methods/addColumn.d.ts +1 -1
  198. package/script/methods/addColumn.d.ts.map +1 -1
  199. package/script/methods/bins.d.ts +1 -1
  200. package/script/methods/bins.d.ts.map +1 -1
  201. package/script/methods/bins.js +45 -29
  202. package/script/methods/bm25.d.ts.map +1 -1
  203. package/script/methods/bm25.js +1 -2
  204. package/script/methods/cache.d.ts.map +1 -1
  205. package/script/methods/cache.js +3 -5
  206. package/script/methods/convert.d.ts +2 -2
  207. package/script/methods/convert.d.ts.map +1 -1
  208. package/script/methods/convert.js +5 -0
  209. package/script/methods/getBottom.d.ts +1 -1
  210. package/script/methods/getBottom.d.ts.map +1 -1
  211. package/script/methods/getBottom.js +2 -2
  212. package/script/methods/getData.d.ts +1 -1
  213. package/script/methods/getData.d.ts.map +1 -1
  214. package/script/methods/getData.js +2 -2
  215. package/script/methods/join.d.ts.map +1 -1
  216. package/script/methods/join.js +8 -16
  217. package/script/methods/joinGeo.d.ts.map +1 -1
  218. package/script/methods/joinGeo.js +10 -19
  219. package/script/methods/loadArray.d.ts +1 -1
  220. package/script/methods/loadArray.d.ts.map +1 -1
  221. package/script/methods/loadArray.js +74 -19
  222. package/script/methods/loadData.js +3 -0
  223. package/script/methods/log.d.ts +7 -0
  224. package/script/methods/log.d.ts.map +1 -0
  225. package/script/methods/log.js +69 -0
  226. package/script/methods/logBottom.d.ts +5 -0
  227. package/script/methods/logBottom.d.ts.map +1 -0
  228. package/script/methods/logBottom.js +15 -0
  229. package/script/methods/removeTable.d.ts.map +1 -1
  230. package/script/methods/removeTable.js +2 -0
  231. package/script/methods/removeTables.d.ts.map +1 -1
  232. package/script/methods/removeTables.js +7 -0
  233. package/script/methods/renameTable.d.ts.map +1 -1
  234. package/script/methods/renameTable.js +4 -0
  235. package/script/methods/rowToText.js +2 -2
  236. package/script/methods/selectTables.d.ts.map +1 -1
  237. package/script/methods/selectTables.js +6 -0
  238. package/script/methods/setTypes.d.ts +1 -1
  239. package/script/methods/setTypes.d.ts.map +1 -1
  240. package/script/methods/stream.d.ts.map +1 -1
  241. package/script/methods/stream.js +2 -1
  242. package/script/methods/updateWithJS.d.ts +1 -3
  243. package/script/methods/updateWithJS.d.ts.map +1 -1
  244. package/script/methods/updateWithJS.js +122 -36
@@ -1,5 +1,6 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
2
  import cleanSQL from "./cleanSQL.js";
3
+ import referencedTables from "./referencedTables.js";
3
4
  import ensureSpatial from "./ensureSpatial.js";
4
5
  import extractTypes from "./extractTypes.js";
5
6
  import mergeOptions from "./mergeOptions.js";
@@ -141,7 +142,7 @@ async function replayEntries(sdb, pendingEntries) {
141
142
  const reads = op.rawSQL === undefined
142
143
  ? []
143
144
  : referencedTables(op.rawSQL, sdb);
144
- if (reads.includes(table)) {
145
+ if (op.kind === "fusable" && reads.includes(table)) {
145
146
  // User-supplied SQL referencing the operation's own table must read
146
147
  // the state produced by the previous steps, which a fused chain
147
148
  // can't provide (the name would resolve to the pre-chain table). So
@@ -177,7 +178,8 @@ async function replayEntries(sdb, pendingEntries) {
177
178
  if (op.kind === "source") {
178
179
  // A source replaces the target table from an external relation. It
179
180
  // starts a new segment rather than consuming any segment already open
180
- // on the same table.
181
+ // on the same table. A source may read that materialized table itself
182
+ // (for example, an in-place join) and still fuse with downstream steps.
181
183
  await runOpenSegment();
182
184
  open = { table, ops: [op] };
183
185
  current = null;
@@ -256,23 +258,6 @@ async function drainAsyncOperationFrame(frame) {
256
258
  }
257
259
  }
258
260
  }
259
- /**
260
- * Returns the tables of the database whose names appear in the given SQL
261
- * fragments. Matching is conservative (a column sharing a table's name
262
- * counts as a reference): a false positive only costs fusion, never
263
- * correctness.
264
- */
265
- function referencedTables(rawSQL, sdb) {
266
- const referenced = [];
267
- for (const table of getRegisteredTables(sdb)) {
268
- const escaped = table.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
269
- const pattern = new RegExp(`(?<![\\w"])"?${escaped}"?(?![\\w"])`, "i");
270
- if (rawSQL.some((sql) => pattern.test(sql))) {
271
- referenced.push(table);
272
- }
273
- }
274
- return referenced;
275
- }
276
261
  async function runSegment(table, ops) {
277
262
  if (ops.length === 1) {
278
263
  await runStepwise(table, ops[0]);
@@ -281,8 +266,7 @@ async function runSegment(table, ops) {
281
266
  if (ops.some(needsSpatial)) {
282
267
  await ensureSpatial(table);
283
268
  }
284
- // Each fragment is cleaned individually: cleanSQL's WHERE handling must not
285
- // cross fragment boundaries once they are composed into one statement.
269
+ // Normalize each fragment once using the database syntax before composition.
286
270
  const ctes = [];
287
271
  // The schema of the next fragment's input, reused while operations declare
288
272
  // they preserve it, so a run of same-shape steps costs at most one
@@ -309,11 +293,21 @@ async function runSegment(table, ops) {
309
293
  await executeFused(table, ops, ctes);
310
294
  }
311
295
  async function compileOp(table, op, ctes, schema) {
296
+ // Source relations can read tables named s1, s2, etc. A generated CTE must
297
+ // not shadow those physical inputs, including in later chain fragments.
298
+ const usedNames = new Set([
299
+ ...getRegisteredTables(table.sdb).map((input) => input.name.toLowerCase()),
300
+ ...ctes.map((cte) => cte.alias),
301
+ ]);
302
+ let aliasIndex = ctes.length + 1;
303
+ while (usedNames.has(`s${aliasIndex}`))
304
+ aliasIndex++;
305
+ const alias = `s${aliasIndex}`;
312
306
  if (op.kind === "source") {
313
307
  return {
314
308
  cte: {
315
- alias: `s${ctes.length + 1}`,
316
- select: cleanSQL(op.buildSelect()),
309
+ alias,
310
+ select: cleanSQL(await op.buildSelect(), table.sdb.expressionSyntax),
317
311
  values: [],
318
312
  },
319
313
  schema: op.schema ?? null,
@@ -335,15 +329,16 @@ async function compileOp(table, op, ctes, schema) {
335
329
  : null;
336
330
  return {
337
331
  cte: {
338
- alias: `s${ctes.length + 1}`,
339
- select: cleanSQL(op.buildSelect(input, buildSchema)),
332
+ alias,
333
+ select: cleanSQL(op.buildSelect(input, buildSchema), table.sdb.expressionSyntax),
340
334
  values: resolveValues(op, buildSchema),
341
335
  },
342
336
  schema: outputSchema,
343
337
  };
344
338
  }
345
339
  async function executeFused(table, ops, ctes) {
346
- const query = `CREATE OR REPLACE TABLE ${quoteIdentifier(table.name)} AS WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select})`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
340
+ // A trailing line comment must end before the generated CTE delimiter.
341
+ const query = `CREATE OR REPLACE TABLE ${quoteIdentifier(table.name)} AS WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select}\n)`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
347
342
  try {
348
343
  await queryDB(table, query, mergeOptions(table, {
349
344
  table: table.name,
@@ -381,7 +376,7 @@ async function runStepwise(table, op) {
381
376
  }));
382
377
  }
383
378
  function needsSpatial(op) {
384
- return op.kind === "fusable" && op.needsSpatial === true;
379
+ return op.needsSpatial === true;
385
380
  }
386
381
  function resolveValues(op, schema) {
387
382
  return typeof op.values === "function" ? op.values(schema) : op.values ?? [];
@@ -394,7 +389,7 @@ function resolveValues(op, schema) {
394
389
  async function describeChain(table, ctes) {
395
390
  const select = ctes.length === 0
396
391
  ? `SELECT * FROM ${quoteIdentifier(table.name)}`
397
- : `WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select})`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
392
+ : `WITH ${ctes.map((c) => `${quoteIdentifier(c.alias)} AS (${c.select}\n)`).join(", ")} SELECT * FROM ${quoteIdentifier(ctes[ctes.length - 1].alias)}`;
398
393
  const query = ctes.length === 0
399
394
  ? `DESCRIBE ${quoteIdentifier(table.name)}`
400
395
  : `DESCRIBE ${select}`;
@@ -0,0 +1,3 @@
1
+ /** Matches DuckDB's ASCII case folding for quoted and unquoted identifiers. */
2
+ export default function foldIdentifier(identifier: string): string;
3
+ //# sourceMappingURL=foldIdentifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foldIdentifier.d.ts","sourceRoot":"","sources":["../../src/helpers/foldIdentifier.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEjE"}
@@ -0,0 +1,4 @@
1
+ /** Matches DuckDB's ASCII case folding for quoted and unquoted identifiers. */
2
+ export default function foldIdentifier(identifier) {
3
+ return identifier.replace(/[A-Z]/g, (letter) => letter.toLowerCase());
4
+ }
@@ -0,0 +1,3 @@
1
+ /** Converts validated GeoJSON SQL text to an explicitly typed WGS84 geometry. */
2
+ export default function geometryFromJSON(expression: string): string;
3
+ //# sourceMappingURL=geometryFromJSON.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometryFromJSON.d.ts","sourceRoot":"","sources":["../../src/helpers/geometryFromJSON.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEnE"}
@@ -0,0 +1,4 @@
1
+ /** Converts validated GeoJSON SQL text to an explicitly typed WGS84 geometry. */
2
+ export default function geometryFromJSON(expression) {
3
+ return `ST_GeomFromGeoJSON(${expression})::GEOMETRY('EPSG:4326')`;
4
+ }
@@ -20,4 +20,5 @@ export { default as queryDB } from "./queryDB.js";
20
20
  export { default as queueAsyncBarrier } from "./queueAsyncBarrier.js";
21
21
  export { default as quoteIdentifier } from "./quoteIdentifier.js";
22
22
  export { default as stringToArray } from "./stringToArray.js";
23
+ export { default as updateColumnsWithJS } from "./updateColumnsWithJS.js";
23
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -20,3 +20,4 @@ export { default as queryDB } from "./queryDB.js";
20
20
  export { default as queueAsyncBarrier } from "./queueAsyncBarrier.js";
21
21
  export { default as quoteIdentifier } from "./quoteIdentifier.js";
22
22
  export { default as stringToArray } from "./stringToArray.js";
23
+ export { default as updateColumnsWithJS } from "./updateColumnsWithJS.js";
@@ -1 +1 @@
1
- {"version":3,"file":"logData.d.ts","sourceRoot":"","sources":["../../src/helpers/logData.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,IAAI,EACvC,IAAI,EACA;IACA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,EAAE,GACD,IAAI,EACR,UAAU,CAAC,EAAE,MAAM,QA4DpB"}
1
+ {"version":3,"file":"logData.d.ts","sourceRoot":"","sources":["../../src/helpers/logData.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,IAAI,EACvC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,GAAG,IAAI,EACzC,UAAU,CAAC,EAAE,MAAM,QAkEpB"}
@@ -1,53 +1,54 @@
1
+ import LogValue from "./LogValue.js";
1
2
  import printTable from "./printTable.js";
2
3
  export default function logData(types, data, charsToLog) {
3
4
  if (data === null) {
4
5
  console.log("Data is null");
6
+ return;
5
7
  }
6
- else {
7
- if (data.length === 0) {
8
- console.log(data);
8
+ if (data.length === 0) {
9
+ console.log(data);
10
+ return;
11
+ }
12
+ const formatted = data.map((row) => Object.fromEntries(Object.entries(row).map(([key, value]) => {
13
+ const nested = value !== null && typeof value === "object" &&
14
+ !(value instanceof Date) && !(value instanceof LogValue);
15
+ let text = value instanceof LogValue
16
+ ? value.text
17
+ : nested
18
+ ? JSON.stringify(value)
19
+ : value;
20
+ const truncatable = !(value instanceof LogValue) ||
21
+ value.category === "string";
22
+ if (truncatable && typeof text === "string" &&
23
+ typeof charsToLog === "number" && text.length > charsToLog) {
24
+ const limit = Math.max(0, Math.floor(charsToLog));
25
+ text = text.slice(0, Math.max(0, limit - 3)) + "...".slice(0, limit);
9
26
  }
10
- else {
11
- const dataToBeLogged = [];
12
- const keys = Object.keys(data[0]);
13
- for (let i = 0; i < data.length; i++) {
14
- const newItem = {};
15
- for (const key of keys) {
16
- if (typeof charsToLog === "number" &&
17
- typeof data[i][key] === "string" &&
18
- data[i][key].length > charsToLog) {
19
- newItem[key] = data[i][key].slice(0, charsToLog) + "...";
20
- }
21
- else {
22
- newItem[key] = data[i][key];
23
- }
24
- }
25
- dataToBeLogged.push(newItem);
26
- }
27
- let hasTypesRow = false;
28
- if (types !== null) {
29
- const columns = Object.keys(types);
30
- if (columns.length > 0) {
31
- for (const col of columns) {
32
- if (data[0][col] === "<Geometry>") {
33
- continue;
34
- }
35
- else {
36
- types[col] = types[col] + "/" +
37
- (data[0][col] === null ? null : typeof data[0][col]);
38
- }
39
- }
40
- // Add types as the first row
41
- dataToBeLogged.unshift(types);
42
- hasTypesRow = true;
27
+ return [
28
+ key,
29
+ value instanceof LogValue
30
+ ? new LogValue(String(text), value.jsType, value.category)
31
+ : text,
32
+ ];
33
+ })));
34
+ const hasTypes = types !== null && Object.keys(types).length > 0;
35
+ if (hasTypes) {
36
+ formatted.unshift(Object.fromEntries(Object.entries(types).map(([key, sqlType]) => {
37
+ const representations = new Set(data.flatMap((row) => {
38
+ const value = row[key];
39
+ if (value instanceof LogValue) {
40
+ return value.category === "null" ? [] : [value.jsType];
43
41
  }
44
- }
45
- printTable(dataToBeLogged, {
46
- ...(typeof charsToLog === "number"
47
- ? { maxColumnWidth: charsToLog }
48
- : {}),
49
- ...(hasTypesRow ? { typesRowIndex: 0 } : {}),
50
- });
51
- }
42
+ return value === null || value === undefined ? [] : [typeof value];
43
+ }));
44
+ const first = data[0][key];
45
+ const representation = representations.size > 0
46
+ ? [...representations].join("|")
47
+ : first instanceof LogValue
48
+ ? first.jsType
49
+ : "null";
50
+ return [key, `${sqlType}/${representation}`];
51
+ })));
52
52
  }
53
+ printTable(formatted, hasTypes ? { typesRowIndex: 0 } : undefined);
53
54
  }
@@ -0,0 +1,5 @@
1
+ import { type DuckDBType, type DuckDBValue } from "@duckdb/node-api";
2
+ import LogValue from "./LogValue.js";
3
+ /** Formats native temporal values before extraction can discard precision. */
4
+ export default function makeLogConverter(type: DuckDBType, convert: (value: DuckDBValue) => unknown): (value: DuckDBValue) => LogValue;
5
+ //# sourceMappingURL=makeLogConverter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"makeLogConverter.d.ts","sourceRoot":"","sources":["../../src/helpers/makeLogConverter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,8EAA8E;AAC9E,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,GACvC,CAAC,KAAK,EAAE,WAAW,KAAK,QAAQ,CA8DlC"}
@@ -0,0 +1,64 @@
1
+ import { DuckDBTypeId, } from "@duckdb/node-api";
2
+ import LogValue from "./LogValue.js";
3
+ /** Formats native temporal values before extraction can discard precision. */
4
+ export default function makeLogConverter(type, convert) {
5
+ const sqlType = type.toString();
6
+ const floatArray = sqlType.includes("FLOAT[");
7
+ const placeholder = sqlType.toLowerCase().includes("geometry") ||
8
+ floatArray;
9
+ const temporal = [
10
+ DuckDBTypeId.DATE,
11
+ DuckDBTypeId.TIME,
12
+ DuckDBTypeId.TIME_TZ,
13
+ DuckDBTypeId.TIME_NS,
14
+ DuckDBTypeId.TIMESTAMP,
15
+ DuckDBTypeId.TIMESTAMP_TZ,
16
+ DuckDBTypeId.TIMESTAMP_S,
17
+ DuckDBTypeId.TIMESTAMP_MS,
18
+ DuckDBTypeId.TIMESTAMP_NS,
19
+ ].includes(type.typeId);
20
+ const numeric = !placeholder &&
21
+ /^(TINYINT|SMALLINT|INTEGER|BIGINT|HUGEINT|UTINYINT|USMALLINT|UINTEGER|UBIGINT|UHUGEINT|FLOAT|DOUBLE|DECIMAL|BIGNUM)(\(|$)/
22
+ .test(sqlType);
23
+ const jsType = placeholder ? "string" : type.typeId === DuckDBTypeId.DATE ||
24
+ type.typeId === DuckDBTypeId.TIMESTAMP
25
+ ? "object"
26
+ : temporal
27
+ ? "string"
28
+ : type.typeId === DuckDBTypeId.BOOLEAN
29
+ ? "boolean"
30
+ : numeric
31
+ ? (/^(DECIMAL|BIGNUM)/.test(sqlType) ? "string" : "number")
32
+ : [
33
+ DuckDBTypeId.LIST,
34
+ DuckDBTypeId.ARRAY,
35
+ DuckDBTypeId.STRUCT,
36
+ DuckDBTypeId.MAP,
37
+ DuckDBTypeId.UNION,
38
+ DuckDBTypeId.INTERVAL,
39
+ ].includes(type.typeId)
40
+ ? "object"
41
+ : "string";
42
+ return (value) => {
43
+ if (value === null)
44
+ return new LogValue("null", jsType, "null");
45
+ // TIMESTAMPTZ uses the existing UTC converter, independent of process timezone.
46
+ const converted = floatArray
47
+ ? `<${sqlType}>`
48
+ : temporal && type.typeId !== DuckDBTypeId.TIMESTAMP_TZ
49
+ ? String(value)
50
+ : convert(value);
51
+ const text = typeof converted === "object" && converted !== null
52
+ ? JSON.stringify(converted)
53
+ : String(converted);
54
+ return new LogValue(text,
55
+ // NaN and infinities are strings in the public JSON conversion.
56
+ temporal ? jsType : typeof converted, temporal
57
+ ? "date"
58
+ : numeric
59
+ ? "number"
60
+ : jsType === "boolean"
61
+ ? "boolean"
62
+ : "string");
63
+ };
64
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"osmFiles.d.ts","sourceRoot":"","sources":["../../src/helpers/osmFiles.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAShD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMnE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBrD;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IACP,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,GACA,OAAO,CAAC,MAAM,CAAC,CAmHjB;AAgMD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD"}
1
+ {"version":3,"file":"osmFiles.d.ts","sourceRoot":"","sources":["../../src/helpers/osmFiles.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAShD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMnE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBrD;AAED,wBAAsB,0BAA0B,CAC9C,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IACP,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD,GACA,OAAO,CAAC,MAAM,CAAC,CAqHjB;AAgMD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWjD"}
@@ -1,2 +1,2 @@
1
- export default function parseType(type: "integer" | "float" | "number" | "string" | "date" | "time" | "datetime" | "datetimeTz" | "bigint" | "double" | "varchar" | "timestamp" | "timestamp with time zone" | "boolean" | `geometry('${string}')` | `GEOMETRY('${string}')`): string;
1
+ export default function parseType(type: "integer" | "float" | "number" | "string" | "date" | "time" | "datetime" | "datetimeTz" | "bigint" | "double" | "varchar" | "timestamp" | "timestamp with time zone" | "boolean" | "json" | "JSON" | `float[${number}]` | `FLOAT[${number}]` | `geometry('${string}')` | `GEOMETRY('${string}')`): string;
2
2
  //# sourceMappingURL=parseTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parseTypes.d.ts","sourceRoot":"","sources":["../../src/helpers/parseTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,IAAI,EACA,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,0BAA0B,GAC1B,SAAS,GACT,aAAa,MAAM,IAAI,GACvB,aAAa,MAAM,IAAI,UAgC5B"}
1
+ {"version":3,"file":"parseTypes.d.ts","sourceRoot":"","sources":["../../src/helpers/parseTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,IAAI,EACA,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,0BAA0B,GAC1B,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,MAAM,GAAG,GAClB,SAAS,MAAM,GAAG,GAClB,aAAa,MAAM,IAAI,GACvB,aAAa,MAAM,IAAI,UAmC5B"}
@@ -25,9 +25,13 @@ export default function parseType(type) {
25
25
  "timestamp",
26
26
  "timestamp with time zone",
27
27
  "boolean",
28
+ "json",
28
29
  ].includes(typeLowerCase)) {
29
30
  return type.toUpperCase();
30
31
  }
32
+ else if (/^float\[[1-9]\d*\]$/.test(typeLowerCase)) {
33
+ return type.toUpperCase();
34
+ }
31
35
  else if (typeLowerCase.includes("geometry")) {
32
36
  return type.toUpperCase();
33
37
  }
@@ -94,8 +94,10 @@ export type SourceOp = {
94
94
  rawSQL?: string[];
95
95
  /** A schema known from explicit source options, when inference is unnecessary. */
96
96
  schema?: TableSchema;
97
- /** Returns the source as a single composable SELECT statement. */
98
- buildSelect: () => string;
97
+ /** Whether the source uses spatial functions. */
98
+ needsSpatial?: boolean;
99
+ /** Returns a composable SELECT, optionally inspecting materialized inputs. */
100
+ buildSelect: () => string | Promise<string>;
99
101
  };
100
102
  /** A relational operation that can participate in a fused segment. */
101
103
  export type RelationalOp = SourceOp | FusableOp;
@@ -1 +1 @@
1
- {"version":3,"file":"pendingOps.d.ts","sourceRoot":"","sources":["../../src/helpers/pendingOps.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pendingOps.d.ts","sourceRoot":"","sources":["../../src/helpers/pendingOps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Validates and snapshots a two-dimensional WGS84 GeoJSON geometry cell. */
2
+ export default function prepareGeometry(value: unknown, column: string, row: number): string | null;
3
+ //# sourceMappingURL=prepareGeometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepareGeometry.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareGeometry.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CA+Gf"}
@@ -0,0 +1,99 @@
1
+ /** Validates and snapshots a two-dimensional WGS84 GeoJSON geometry cell. */
2
+ export default function prepareGeometry(value, column, row) {
3
+ if (value === null)
4
+ return null;
5
+ const fail = (message) => {
6
+ throw new Error(`Column ${JSON.stringify(column)}, row ${row}: ${message}`);
7
+ };
8
+ const active = new Set();
9
+ let hasSignedZero = false;
10
+ function position(value) {
11
+ if (!Array.isArray(value) || value.length !== 2 ||
12
+ !Array.from(value).every((n) => typeof n === "number" && Number.isFinite(n))) {
13
+ fail("Expected a finite two-dimensional [longitude, latitude] position; Z/M coordinates are unsupported.");
14
+ }
15
+ const point = value;
16
+ if (Math.abs(point[0]) > 180 || Math.abs(point[1]) > 90) {
17
+ fail("Expected WGS84 longitude [-180, 180] and latitude [-90, 90]; reproject the input first.");
18
+ }
19
+ hasSignedZero ||= Object.is(point[0], -0) || Object.is(point[1], -0);
20
+ return [...point];
21
+ }
22
+ function list(value, convert) {
23
+ if (!Array.isArray(value))
24
+ fail("Expected a coordinate array.");
25
+ return Array.from(value, convert);
26
+ }
27
+ function line(value) {
28
+ const points = list(value, position);
29
+ if (points.length < 2) {
30
+ fail("A LineString must contain at least two positions.");
31
+ }
32
+ return points;
33
+ }
34
+ function ring(value) {
35
+ const points = list(value, position);
36
+ if (points.length < 4 || points[0][0] !== points.at(-1)[0] ||
37
+ points[0][1] !== points.at(-1)[1]) {
38
+ fail("A polygon ring must contain at least four positions and be closed.");
39
+ }
40
+ return points;
41
+ }
42
+ function geometry(value) {
43
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
44
+ fail("Expected a GeoJSON geometry object or null.");
45
+ }
46
+ const object = value;
47
+ if (active.has(object))
48
+ fail("Cyclic GeometryCollections are unsupported.");
49
+ if (active.size >= 100) {
50
+ fail("GeometryCollections may nest at most 100 levels.");
51
+ }
52
+ active.add(object);
53
+ try {
54
+ const type = object.type;
55
+ if (type === "Feature" || type === "FeatureCollection") {
56
+ fail("Expected a GeoJSON geometry object, not a Feature or FeatureCollection; extract each feature's geometry first.");
57
+ }
58
+ if ("crs" in object) {
59
+ fail("Geometry crs members are unsupported; supply WGS84 coordinates and declare GEOMETRY('EPSG:4326').");
60
+ }
61
+ let coordinates;
62
+ switch (type) {
63
+ case "Point":
64
+ coordinates = position(object.coordinates);
65
+ break;
66
+ case "MultiPoint":
67
+ coordinates = list(object.coordinates, position);
68
+ break;
69
+ case "LineString":
70
+ coordinates = line(object.coordinates);
71
+ break;
72
+ case "MultiLineString":
73
+ coordinates = list(object.coordinates, line);
74
+ break;
75
+ case "Polygon":
76
+ coordinates = list(object.coordinates, ring);
77
+ break;
78
+ case "MultiPolygon":
79
+ coordinates = list(object.coordinates, (v) => list(v, ring));
80
+ break;
81
+ case "GeometryCollection":
82
+ return { type, geometries: list(object.geometries, geometry) };
83
+ default:
84
+ fail("Expected a supported GeoJSON geometry type.");
85
+ }
86
+ return { type, coordinates };
87
+ }
88
+ finally {
89
+ active.delete(object);
90
+ }
91
+ }
92
+ const prepared = geometry(value);
93
+ if (!hasSignedZero)
94
+ return JSON.stringify(prepared);
95
+ // JSON.stringify normalizes -0. Only supported geometry type names survive
96
+ // validation as strings, so the "-0" marker cannot collide with input text.
97
+ // Emit a decimal literal so DuckDB also preserves its sign when parsing JSON.
98
+ return JSON.stringify(prepared, (_key, cell) => Object.is(cell, -0) ? "-0" : cell).replaceAll('"-0"', "-0.0");
99
+ }
@@ -0,0 +1,3 @@
1
+ /** Validates and snapshots a JavaScript JSON value without dropping information. */
2
+ export default function prepareJSON(value: unknown, column: string, row: number): string | null;
3
+ //# sourceMappingURL=prepareJSON.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepareJSON.d.ts","sourceRoot":"","sources":["../../src/helpers/prepareJSON.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAmEf"}
@@ -0,0 +1,50 @@
1
+ /** Validates and snapshots a JavaScript JSON value without dropping information. */
2
+ export default function prepareJSON(value, column, row) {
3
+ if (value === null || value === undefined)
4
+ return null;
5
+ const active = new Set();
6
+ const fail = (path, message) => {
7
+ throw new Error(`Column ${JSON.stringify(column)}, row ${row}, ${path}: ${message}`);
8
+ };
9
+ function serialize(value, path) {
10
+ if (value === null)
11
+ return "null";
12
+ if (typeof value === "string" || typeof value === "boolean") {
13
+ return JSON.stringify(value);
14
+ }
15
+ if (typeof value === "number" && Number.isFinite(value)) {
16
+ return Object.is(value, -0) ? "-0.0" : JSON.stringify(value);
17
+ }
18
+ if (typeof value !== "object") {
19
+ return fail(path, "Expected a JSON value: finite numbers, strings, booleans, null, arrays, or plain objects.");
20
+ }
21
+ if (active.has(value)) {
22
+ return fail(path, "Cyclic JSON values are unsupported.");
23
+ }
24
+ if (active.size >= 100) {
25
+ return fail(path, "JSON values may nest at most 100 levels.");
26
+ }
27
+ const array = Array.isArray(value);
28
+ if (!array && Object.getPrototypeOf(value) !== Object.prototype &&
29
+ Object.getPrototypeOf(value) !== null) {
30
+ return fail(path, "Expected a plain JSON object; convert class instances to JSON values first.");
31
+ }
32
+ if (Object.getOwnPropertySymbols(value).length) {
33
+ return fail(path, "JSON cannot represent symbol keys.");
34
+ }
35
+ active.add(value);
36
+ try {
37
+ if (array) {
38
+ if (Object.keys(value).length !== value.length) {
39
+ return fail(path, "JSON arrays must be dense and have no extra properties.");
40
+ }
41
+ return `[${Array.from(value, (item, i) => serialize(item, `${path}[${i}]`)).join(",")}]`;
42
+ }
43
+ return `{${Object.entries(value).map(([key, item]) => `${JSON.stringify(key)}:${serialize(item, `${path}[${JSON.stringify(key)}]`)}`).join(",")}}`;
44
+ }
45
+ finally {
46
+ active.delete(value);
47
+ }
48
+ }
49
+ return serialize(value, "$");
50
+ }
@@ -1,14 +1,15 @@
1
1
  /**
2
2
  * Prints a formatted table to the console with support for word wrapping
3
- * within cells. Unlike `console.table()`, this function properly handles
4
- * multi-line content within cells, making it ideal for displaying data with
5
- * long text values.
3
+ * within headers and cells. Unlike `console.table()`, this function properly
4
+ * handles multi-line content, making it ideal for displaying data with long
5
+ * column names and text values.
6
6
  *
7
7
  * @param data - An array of objects representing the rows of the table. Each
8
8
  * object should have string keys.
9
9
  * @param options - Optional configuration for table rendering.
10
10
  * @param options.maxColumnWidth - The maximum width for any column (default:
11
- * `75`). Values exceeding this width will be wrapped at word boundaries.
11
+ * `75`). Headers and values exceeding this width will be wrapped at word
12
+ * boundaries.
12
13
  * @param options.minColumnWidth - The minimum width for any column (default:
13
14
  * `3`).
14
15
  * @param options.typesRowIndex - The index of a row that contains type
@@ -1 +1 @@
1
- {"version":3,"file":"printTable.d.ts","sourceRoot":"","sources":["../../src/helpers/printTable.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,EAClC,OAAO,CAAC,EAAE;IACR,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,IAAI,CAuNN"}
1
+ {"version":3,"file":"printTable.d.ts","sourceRoot":"","sources":["../../src/helpers/printTable.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,EAClC,OAAO,CAAC,EAAE;IACR,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,IAAI,CAgNN"}