@nshiab/simple-data-analysis-core 2.0.9 → 2.1.1

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 (459) hide show
  1. package/esm/class/SDAError.d.ts +6 -6
  2. package/esm/class/SDAError.js +6 -6
  3. package/esm/class/Simple.d.ts +9 -9
  4. package/esm/class/Simple.js +9 -9
  5. package/esm/class/SimpleDB.d.ts +80 -76
  6. package/esm/class/SimpleDB.d.ts.map +1 -1
  7. package/esm/class/SimpleDB.js +80 -76
  8. package/esm/class/SimpleTable.d.ts +2806 -1139
  9. package/esm/class/SimpleTable.d.ts.map +1 -1
  10. package/esm/class/SimpleTable.js +2792 -1149
  11. package/esm/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
  12. package/esm/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
  13. package/esm/helpers/buildApproximateMutualReachabilityMst.js +212 -0
  14. package/esm/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
  15. package/esm/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
  16. package/esm/helpers/buildChronologicalGraphComponentsSql.js +167 -0
  17. package/esm/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
  18. package/esm/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
  19. package/esm/helpers/buildExactMutualReachabilityMst.js +97 -0
  20. package/esm/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
  21. package/esm/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
  22. package/esm/helpers/buildGraphTemporalCostStateSql.js +86 -0
  23. package/esm/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
  24. package/esm/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
  25. package/esm/helpers/buildGraphTemporalReachabilitySql.js +70 -0
  26. package/esm/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
  27. package/esm/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
  28. package/esm/helpers/buildSparseMutualReachabilityMst.js +47 -0
  29. package/esm/helpers/buildUmapGraph.d.ts +2 -5
  30. package/esm/helpers/buildUmapGraph.d.ts.map +1 -1
  31. package/esm/helpers/buildUmapGraph.js +6 -100
  32. package/esm/helpers/buildVectorNeighbors.d.ts +45 -0
  33. package/esm/helpers/buildVectorNeighbors.d.ts.map +1 -0
  34. package/esm/helpers/buildVectorNeighbors.js +170 -0
  35. package/esm/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
  36. package/esm/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
  37. package/esm/helpers/buildWeakGraphComponentsSql.js +32 -0
  38. package/esm/helpers/camelCase.d.ts +7 -5
  39. package/esm/helpers/camelCase.d.ts.map +1 -1
  40. package/esm/helpers/camelCase.js +7 -5
  41. package/esm/helpers/capitalize.d.ts +6 -4
  42. package/esm/helpers/capitalize.d.ts.map +1 -1
  43. package/esm/helpers/capitalize.js +6 -4
  44. package/esm/helpers/clusterHdbscan.d.ts +18 -0
  45. package/esm/helpers/clusterHdbscan.d.ts.map +1 -0
  46. package/esm/helpers/clusterHdbscan.js +342 -0
  47. package/esm/helpers/computeCovariance.d.ts +16 -0
  48. package/esm/helpers/computeCovariance.d.ts.map +1 -0
  49. package/esm/helpers/computeCovariance.js +99 -0
  50. package/esm/helpers/computeMahalanobisDistances.d.ts +14 -0
  51. package/esm/helpers/computeMahalanobisDistances.d.ts.map +1 -0
  52. package/esm/helpers/computeMahalanobisDistances.js +87 -0
  53. package/esm/helpers/createDirectory.d.ts +4 -3
  54. package/esm/helpers/createDirectory.d.ts.map +1 -1
  55. package/esm/helpers/createDirectory.js +4 -3
  56. package/esm/helpers/dataToArrays.d.ts +6 -4
  57. package/esm/helpers/dataToArrays.d.ts.map +1 -1
  58. package/esm/helpers/dataToArrays.js +6 -4
  59. package/esm/helpers/extractTypes.d.ts +1 -1
  60. package/esm/helpers/extractTypes.js +4 -9
  61. package/esm/helpers/factorCovariance.d.ts +17 -0
  62. package/esm/helpers/factorCovariance.d.ts.map +1 -0
  63. package/esm/helpers/factorCovariance.js +189 -0
  64. package/esm/helpers/findGeoColumn.d.ts +6 -4
  65. package/esm/helpers/findGeoColumn.d.ts.map +1 -1
  66. package/esm/helpers/findGeoColumn.js +6 -4
  67. package/esm/helpers/findGeoColumnFromSchema.d.ts +8 -5
  68. package/esm/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
  69. package/esm/helpers/findGeoColumnFromSchema.js +8 -5
  70. package/esm/helpers/formatDate.d.ts +12 -6
  71. package/esm/helpers/formatDate.d.ts.map +1 -1
  72. package/esm/helpers/formatDate.js +12 -6
  73. package/esm/helpers/formatMissingTables.d.ts +8 -5
  74. package/esm/helpers/formatMissingTables.d.ts.map +1 -1
  75. package/esm/helpers/formatMissingTables.js +8 -5
  76. package/esm/helpers/formatNumber.d.ts +19 -10
  77. package/esm/helpers/formatNumber.d.ts.map +1 -1
  78. package/esm/helpers/formatNumber.js +32 -17
  79. package/esm/helpers/getGraphEdgeIdColumn.d.ts +9 -0
  80. package/esm/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
  81. package/esm/helpers/getGraphEdgeIdColumn.js +25 -0
  82. package/esm/helpers/getGraphEndpointColumns.d.ts +11 -0
  83. package/esm/helpers/getGraphEndpointColumns.d.ts.map +1 -0
  84. package/esm/helpers/getGraphEndpointColumns.js +160 -0
  85. package/esm/helpers/getGraphWeightColumn.d.ts +10 -0
  86. package/esm/helpers/getGraphWeightColumn.d.ts.map +1 -0
  87. package/esm/helpers/getGraphWeightColumn.js +40 -0
  88. package/esm/helpers/graphRouteResultSchema.d.ts +4 -0
  89. package/esm/helpers/graphRouteResultSchema.d.ts.map +1 -0
  90. package/esm/helpers/graphRouteResultSchema.js +12 -0
  91. package/esm/helpers/graphRouteResultSelect.d.ts +4 -0
  92. package/esm/helpers/graphRouteResultSelect.d.ts.map +1 -0
  93. package/esm/helpers/graphRouteResultSelect.js +22 -0
  94. package/esm/helpers/hasGeometryColumn.d.ts +4 -3
  95. package/esm/helpers/hasGeometryColumn.d.ts.map +1 -1
  96. package/esm/helpers/hasGeometryColumn.js +4 -3
  97. package/esm/helpers/inspectGraphConnectivity.d.ts +10 -0
  98. package/esm/helpers/inspectGraphConnectivity.d.ts.map +1 -0
  99. package/esm/helpers/inspectGraphConnectivity.js +55 -0
  100. package/esm/helpers/mergeOptions.d.ts +24 -13
  101. package/esm/helpers/mergeOptions.d.ts.map +1 -1
  102. package/esm/helpers/mergeOptions.js +24 -13
  103. package/esm/helpers/parseValue.d.ts +6 -4
  104. package/esm/helpers/parseValue.d.ts.map +1 -1
  105. package/esm/helpers/parseValue.js +6 -4
  106. package/esm/helpers/prepareGraphRouteSql.d.ts +31 -0
  107. package/esm/helpers/prepareGraphRouteSql.d.ts.map +1 -0
  108. package/esm/helpers/prepareGraphRouteSql.js +86 -0
  109. package/esm/helpers/prepareGraphStarts.d.ts +9 -0
  110. package/esm/helpers/prepareGraphStarts.d.ts.map +1 -0
  111. package/esm/helpers/prepareGraphStarts.js +68 -0
  112. package/esm/helpers/prepareGraphTemporalSql.d.ts +28 -0
  113. package/esm/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
  114. package/esm/helpers/prepareGraphTemporalSql.js +154 -0
  115. package/esm/helpers/prepareGraphTraversal.d.ts +19 -0
  116. package/esm/helpers/prepareGraphTraversal.d.ts.map +1 -0
  117. package/esm/helpers/prepareGraphTraversal.js +79 -0
  118. package/esm/helpers/prepareNumericFeatures.d.ts +41 -0
  119. package/esm/helpers/prepareNumericFeatures.d.ts.map +1 -0
  120. package/esm/helpers/prepareNumericFeatures.js +210 -0
  121. package/esm/helpers/prettyDuration.d.ts +14 -8
  122. package/esm/helpers/prettyDuration.d.ts.map +1 -1
  123. package/esm/helpers/prettyDuration.js +14 -8
  124. package/esm/helpers/printTable.d.ts +18 -13
  125. package/esm/helpers/printTable.d.ts.map +1 -1
  126. package/esm/helpers/printTable.js +18 -13
  127. package/esm/helpers/publishPreparedColumns.d.ts +37 -0
  128. package/esm/helpers/publishPreparedColumns.d.ts.map +1 -0
  129. package/esm/helpers/publishPreparedColumns.js +113 -0
  130. package/esm/helpers/queryDB.d.ts +24 -13
  131. package/esm/helpers/queryDB.d.ts.map +1 -1
  132. package/esm/helpers/queryDB.js +24 -13
  133. package/esm/helpers/queueAsyncBarrier.d.ts +12 -7
  134. package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
  135. package/esm/helpers/queueAsyncBarrier.js +12 -7
  136. package/esm/helpers/queueGraphResult.d.ts +18 -0
  137. package/esm/helpers/queueGraphResult.d.ts.map +1 -0
  138. package/esm/helpers/queueGraphResult.js +39 -0
  139. package/esm/helpers/quoteIdentifier.d.ts +4 -3
  140. package/esm/helpers/quoteIdentifier.d.ts.map +1 -1
  141. package/esm/helpers/quoteIdentifier.js +4 -3
  142. package/esm/helpers/quoteQualifiedIdentifier.d.ts +6 -4
  143. package/esm/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
  144. package/esm/helpers/quoteQualifiedIdentifier.js +6 -4
  145. package/esm/helpers/runQuery.d.ts.map +1 -1
  146. package/esm/helpers/runQuery.js +17 -3
  147. package/esm/helpers/selectFuzzyReplacements.d.ts +11 -0
  148. package/esm/helpers/selectFuzzyReplacements.d.ts.map +1 -0
  149. package/esm/helpers/selectFuzzyReplacements.js +124 -0
  150. package/esm/helpers/stabilizeCosineVectors.d.ts +14 -0
  151. package/esm/helpers/stabilizeCosineVectors.d.ts.map +1 -0
  152. package/esm/helpers/stabilizeCosineVectors.js +34 -0
  153. package/esm/helpers/stringToArray.d.ts +4 -3
  154. package/esm/helpers/stringToArray.d.ts.map +1 -1
  155. package/esm/helpers/stringToArray.js +4 -3
  156. package/esm/helpers/updateColumnsWithJS.d.ts +12 -6
  157. package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -1
  158. package/esm/helpers/updateColumnsWithJS.js +12 -6
  159. package/esm/helpers/validateGraphRouteResultSchema.d.ts +4 -0
  160. package/esm/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
  161. package/esm/helpers/validateGraphRouteResultSchema.js +13 -0
  162. package/esm/helpers/validateGraphTemporalEvents.d.ts +7 -0
  163. package/esm/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
  164. package/esm/helpers/validateGraphTemporalEvents.js +47 -0
  165. package/esm/helpers/validateNumericalAnalysis.d.ts +10 -6
  166. package/esm/helpers/validateNumericalAnalysis.d.ts.map +1 -1
  167. package/esm/helpers/validateNumericalAnalysis.js +10 -6
  168. package/esm/helpers/validateVectorRowIds.d.ts +4 -0
  169. package/esm/helpers/validateVectorRowIds.d.ts.map +1 -0
  170. package/esm/helpers/validateVectorRowIds.js +16 -0
  171. package/esm/helpers/vectorDistanceExpression.d.ts +6 -0
  172. package/esm/helpers/vectorDistanceExpression.d.ts.map +1 -0
  173. package/esm/helpers/vectorDistanceExpression.js +11 -0
  174. package/esm/helpers/wrapString.d.ts +10 -7
  175. package/esm/helpers/wrapString.d.ts.map +1 -1
  176. package/esm/helpers/wrapString.js +10 -7
  177. package/esm/methods/addId.d.ts +5 -0
  178. package/esm/methods/addId.d.ts.map +1 -0
  179. package/esm/methods/addId.js +38 -0
  180. package/esm/methods/commonNeighbors.d.ts +10 -0
  181. package/esm/methods/commonNeighbors.d.ts.map +1 -0
  182. package/esm/methods/commonNeighbors.js +101 -0
  183. package/esm/methods/connectedComponents.d.ts +9 -0
  184. package/esm/methods/connectedComponents.d.ts.map +1 -0
  185. package/esm/methods/connectedComponents.js +147 -0
  186. package/esm/methods/degree.d.ts +9 -0
  187. package/esm/methods/degree.d.ts.map +1 -0
  188. package/esm/methods/degree.js +135 -0
  189. package/esm/methods/distances.d.ts +12 -0
  190. package/esm/methods/distances.d.ts.map +1 -0
  191. package/esm/methods/distances.js +164 -0
  192. package/esm/methods/findCycles.d.ts +12 -0
  193. package/esm/methods/findCycles.d.ts.map +1 -0
  194. package/esm/methods/findCycles.js +330 -0
  195. package/esm/methods/fuzzyClean.d.ts.map +1 -1
  196. package/esm/methods/fuzzyClean.js +17 -136
  197. package/esm/methods/fuzzyJoin.js +70 -16
  198. package/esm/methods/getTypes.d.ts +1 -1
  199. package/esm/methods/hdbscan.d.ts +5 -0
  200. package/esm/methods/hdbscan.d.ts.map +1 -0
  201. package/esm/methods/hdbscan.js +208 -0
  202. package/esm/methods/mahalanobis.d.ts +5 -0
  203. package/esm/methods/mahalanobis.d.ts.map +1 -0
  204. package/esm/methods/mahalanobis.js +92 -0
  205. package/esm/methods/neighbors.d.ts +9 -0
  206. package/esm/methods/neighbors.d.ts.map +1 -0
  207. package/esm/methods/neighbors.js +81 -0
  208. package/esm/methods/normalizeVector.d.ts +5 -0
  209. package/esm/methods/normalizeVector.d.ts.map +1 -0
  210. package/esm/methods/normalizeVector.js +132 -0
  211. package/esm/methods/paths.d.ts +12 -0
  212. package/esm/methods/paths.d.ts.map +1 -0
  213. package/esm/methods/paths.js +287 -0
  214. package/esm/methods/reachable.d.ts +11 -0
  215. package/esm/methods/reachable.d.ts.map +1 -0
  216. package/esm/methods/reachable.js +131 -0
  217. package/esm/methods/rowToVector.d.ts +5 -0
  218. package/esm/methods/rowToVector.d.ts.map +1 -0
  219. package/esm/methods/rowToVector.js +77 -0
  220. package/esm/methods/shortestPath.d.ts +12 -0
  221. package/esm/methods/shortestPath.d.ts.map +1 -0
  222. package/esm/methods/shortestPath.js +337 -0
  223. package/esm/methods/topologicalSort.d.ts +7 -0
  224. package/esm/methods/topologicalSort.d.ts.map +1 -0
  225. package/esm/methods/topologicalSort.js +164 -0
  226. package/esm/methods/trim.d.ts +1 -1
  227. package/esm/methods/trim.d.ts.map +1 -1
  228. package/esm/methods/trim.js +17 -8
  229. package/llm.md +2146 -173
  230. package/llms.txt +1 -1
  231. package/package.json +1 -1
  232. package/script/class/SDAError.d.ts +6 -6
  233. package/script/class/SDAError.js +6 -6
  234. package/script/class/Simple.d.ts +9 -9
  235. package/script/class/Simple.js +9 -9
  236. package/script/class/SimpleDB.d.ts +80 -76
  237. package/script/class/SimpleDB.d.ts.map +1 -1
  238. package/script/class/SimpleDB.js +80 -76
  239. package/script/class/SimpleTable.d.ts +2806 -1139
  240. package/script/class/SimpleTable.d.ts.map +1 -1
  241. package/script/class/SimpleTable.js +2792 -1149
  242. package/script/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
  243. package/script/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
  244. package/script/helpers/buildApproximateMutualReachabilityMst.js +219 -0
  245. package/script/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
  246. package/script/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
  247. package/script/helpers/buildChronologicalGraphComponentsSql.js +174 -0
  248. package/script/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
  249. package/script/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
  250. package/script/helpers/buildExactMutualReachabilityMst.js +103 -0
  251. package/script/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
  252. package/script/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
  253. package/script/helpers/buildGraphTemporalCostStateSql.js +92 -0
  254. package/script/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
  255. package/script/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
  256. package/script/helpers/buildGraphTemporalReachabilitySql.js +76 -0
  257. package/script/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
  258. package/script/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
  259. package/script/helpers/buildSparseMutualReachabilityMst.js +50 -0
  260. package/script/helpers/buildUmapGraph.d.ts +2 -5
  261. package/script/helpers/buildUmapGraph.d.ts.map +1 -1
  262. package/script/helpers/buildUmapGraph.js +6 -100
  263. package/script/helpers/buildVectorNeighbors.d.ts +45 -0
  264. package/script/helpers/buildVectorNeighbors.d.ts.map +1 -0
  265. package/script/helpers/buildVectorNeighbors.js +176 -0
  266. package/script/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
  267. package/script/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
  268. package/script/helpers/buildWeakGraphComponentsSql.js +38 -0
  269. package/script/helpers/camelCase.d.ts +7 -5
  270. package/script/helpers/camelCase.d.ts.map +1 -1
  271. package/script/helpers/camelCase.js +7 -5
  272. package/script/helpers/capitalize.d.ts +6 -4
  273. package/script/helpers/capitalize.d.ts.map +1 -1
  274. package/script/helpers/capitalize.js +6 -4
  275. package/script/helpers/clusterHdbscan.d.ts +18 -0
  276. package/script/helpers/clusterHdbscan.d.ts.map +1 -0
  277. package/script/helpers/clusterHdbscan.js +346 -0
  278. package/script/helpers/computeCovariance.d.ts +16 -0
  279. package/script/helpers/computeCovariance.d.ts.map +1 -0
  280. package/script/helpers/computeCovariance.js +105 -0
  281. package/script/helpers/computeMahalanobisDistances.d.ts +14 -0
  282. package/script/helpers/computeMahalanobisDistances.d.ts.map +1 -0
  283. package/script/helpers/computeMahalanobisDistances.js +93 -0
  284. package/script/helpers/createDirectory.d.ts +4 -3
  285. package/script/helpers/createDirectory.d.ts.map +1 -1
  286. package/script/helpers/createDirectory.js +4 -3
  287. package/script/helpers/dataToArrays.d.ts +6 -4
  288. package/script/helpers/dataToArrays.d.ts.map +1 -1
  289. package/script/helpers/dataToArrays.js +6 -4
  290. package/script/helpers/extractTypes.d.ts +1 -1
  291. package/script/helpers/extractTypes.js +4 -9
  292. package/script/helpers/factorCovariance.d.ts +17 -0
  293. package/script/helpers/factorCovariance.d.ts.map +1 -0
  294. package/script/helpers/factorCovariance.js +194 -0
  295. package/script/helpers/findGeoColumn.d.ts +6 -4
  296. package/script/helpers/findGeoColumn.d.ts.map +1 -1
  297. package/script/helpers/findGeoColumn.js +6 -4
  298. package/script/helpers/findGeoColumnFromSchema.d.ts +8 -5
  299. package/script/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
  300. package/script/helpers/findGeoColumnFromSchema.js +8 -5
  301. package/script/helpers/formatDate.d.ts +12 -6
  302. package/script/helpers/formatDate.d.ts.map +1 -1
  303. package/script/helpers/formatDate.js +12 -6
  304. package/script/helpers/formatMissingTables.d.ts +8 -5
  305. package/script/helpers/formatMissingTables.d.ts.map +1 -1
  306. package/script/helpers/formatMissingTables.js +8 -5
  307. package/script/helpers/formatNumber.d.ts +19 -10
  308. package/script/helpers/formatNumber.d.ts.map +1 -1
  309. package/script/helpers/formatNumber.js +32 -17
  310. package/script/helpers/getGraphEdgeIdColumn.d.ts +9 -0
  311. package/script/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
  312. package/script/helpers/getGraphEdgeIdColumn.js +31 -0
  313. package/script/helpers/getGraphEndpointColumns.d.ts +11 -0
  314. package/script/helpers/getGraphEndpointColumns.d.ts.map +1 -0
  315. package/script/helpers/getGraphEndpointColumns.js +166 -0
  316. package/script/helpers/getGraphWeightColumn.d.ts +10 -0
  317. package/script/helpers/getGraphWeightColumn.d.ts.map +1 -0
  318. package/script/helpers/getGraphWeightColumn.js +46 -0
  319. package/script/helpers/graphRouteResultSchema.d.ts +4 -0
  320. package/script/helpers/graphRouteResultSchema.d.ts.map +1 -0
  321. package/script/helpers/graphRouteResultSchema.js +18 -0
  322. package/script/helpers/graphRouteResultSelect.d.ts +4 -0
  323. package/script/helpers/graphRouteResultSelect.d.ts.map +1 -0
  324. package/script/helpers/graphRouteResultSelect.js +28 -0
  325. package/script/helpers/hasGeometryColumn.d.ts +4 -3
  326. package/script/helpers/hasGeometryColumn.d.ts.map +1 -1
  327. package/script/helpers/hasGeometryColumn.js +4 -3
  328. package/script/helpers/inspectGraphConnectivity.d.ts +10 -0
  329. package/script/helpers/inspectGraphConnectivity.d.ts.map +1 -0
  330. package/script/helpers/inspectGraphConnectivity.js +58 -0
  331. package/script/helpers/mergeOptions.d.ts +24 -13
  332. package/script/helpers/mergeOptions.d.ts.map +1 -1
  333. package/script/helpers/mergeOptions.js +24 -13
  334. package/script/helpers/parseValue.d.ts +6 -4
  335. package/script/helpers/parseValue.d.ts.map +1 -1
  336. package/script/helpers/parseValue.js +6 -4
  337. package/script/helpers/prepareGraphRouteSql.d.ts +31 -0
  338. package/script/helpers/prepareGraphRouteSql.d.ts.map +1 -0
  339. package/script/helpers/prepareGraphRouteSql.js +127 -0
  340. package/script/helpers/prepareGraphStarts.d.ts +9 -0
  341. package/script/helpers/prepareGraphStarts.d.ts.map +1 -0
  342. package/script/helpers/prepareGraphStarts.js +71 -0
  343. package/script/helpers/prepareGraphTemporalSql.d.ts +28 -0
  344. package/script/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
  345. package/script/helpers/prepareGraphTemporalSql.js +161 -0
  346. package/script/helpers/prepareGraphTraversal.d.ts +19 -0
  347. package/script/helpers/prepareGraphTraversal.d.ts.map +1 -0
  348. package/script/helpers/prepareGraphTraversal.js +87 -0
  349. package/script/helpers/prepareNumericFeatures.d.ts +41 -0
  350. package/script/helpers/prepareNumericFeatures.d.ts.map +1 -0
  351. package/script/helpers/prepareNumericFeatures.js +217 -0
  352. package/script/helpers/prettyDuration.d.ts +14 -8
  353. package/script/helpers/prettyDuration.d.ts.map +1 -1
  354. package/script/helpers/prettyDuration.js +14 -8
  355. package/script/helpers/printTable.d.ts +18 -13
  356. package/script/helpers/printTable.d.ts.map +1 -1
  357. package/script/helpers/printTable.js +18 -13
  358. package/script/helpers/publishPreparedColumns.d.ts +37 -0
  359. package/script/helpers/publishPreparedColumns.d.ts.map +1 -0
  360. package/script/helpers/publishPreparedColumns.js +119 -0
  361. package/script/helpers/queryDB.d.ts +24 -13
  362. package/script/helpers/queryDB.d.ts.map +1 -1
  363. package/script/helpers/queryDB.js +24 -13
  364. package/script/helpers/queueAsyncBarrier.d.ts +12 -7
  365. package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
  366. package/script/helpers/queueAsyncBarrier.js +12 -7
  367. package/script/helpers/queueGraphResult.d.ts +18 -0
  368. package/script/helpers/queueGraphResult.d.ts.map +1 -0
  369. package/script/helpers/queueGraphResult.js +45 -0
  370. package/script/helpers/quoteIdentifier.d.ts +4 -3
  371. package/script/helpers/quoteIdentifier.d.ts.map +1 -1
  372. package/script/helpers/quoteIdentifier.js +4 -3
  373. package/script/helpers/quoteQualifiedIdentifier.d.ts +6 -4
  374. package/script/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
  375. package/script/helpers/quoteQualifiedIdentifier.js +6 -4
  376. package/script/helpers/runQuery.d.ts.map +1 -1
  377. package/script/helpers/runQuery.js +17 -3
  378. package/script/helpers/selectFuzzyReplacements.d.ts +11 -0
  379. package/script/helpers/selectFuzzyReplacements.d.ts.map +1 -0
  380. package/script/helpers/selectFuzzyReplacements.js +127 -0
  381. package/script/helpers/stabilizeCosineVectors.d.ts +14 -0
  382. package/script/helpers/stabilizeCosineVectors.d.ts.map +1 -0
  383. package/script/helpers/stabilizeCosineVectors.js +40 -0
  384. package/script/helpers/stringToArray.d.ts +4 -3
  385. package/script/helpers/stringToArray.d.ts.map +1 -1
  386. package/script/helpers/stringToArray.js +4 -3
  387. package/script/helpers/updateColumnsWithJS.d.ts +12 -6
  388. package/script/helpers/updateColumnsWithJS.d.ts.map +1 -1
  389. package/script/helpers/updateColumnsWithJS.js +12 -6
  390. package/script/helpers/validateGraphRouteResultSchema.d.ts +4 -0
  391. package/script/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
  392. package/script/helpers/validateGraphRouteResultSchema.js +19 -0
  393. package/script/helpers/validateGraphTemporalEvents.d.ts +7 -0
  394. package/script/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
  395. package/script/helpers/validateGraphTemporalEvents.js +53 -0
  396. package/script/helpers/validateNumericalAnalysis.d.ts +10 -6
  397. package/script/helpers/validateNumericalAnalysis.d.ts.map +1 -1
  398. package/script/helpers/validateNumericalAnalysis.js +10 -6
  399. package/script/helpers/validateVectorRowIds.d.ts +4 -0
  400. package/script/helpers/validateVectorRowIds.d.ts.map +1 -0
  401. package/script/helpers/validateVectorRowIds.js +19 -0
  402. package/script/helpers/vectorDistanceExpression.d.ts +6 -0
  403. package/script/helpers/vectorDistanceExpression.d.ts.map +1 -0
  404. package/script/helpers/vectorDistanceExpression.js +14 -0
  405. package/script/helpers/wrapString.d.ts +10 -7
  406. package/script/helpers/wrapString.d.ts.map +1 -1
  407. package/script/helpers/wrapString.js +10 -7
  408. package/script/methods/addId.d.ts +5 -0
  409. package/script/methods/addId.d.ts.map +1 -0
  410. package/script/methods/addId.js +44 -0
  411. package/script/methods/commonNeighbors.d.ts +10 -0
  412. package/script/methods/commonNeighbors.d.ts.map +1 -0
  413. package/script/methods/commonNeighbors.js +140 -0
  414. package/script/methods/connectedComponents.d.ts +9 -0
  415. package/script/methods/connectedComponents.d.ts.map +1 -0
  416. package/script/methods/connectedComponents.js +186 -0
  417. package/script/methods/degree.d.ts +9 -0
  418. package/script/methods/degree.d.ts.map +1 -0
  419. package/script/methods/degree.js +141 -0
  420. package/script/methods/distances.d.ts +12 -0
  421. package/script/methods/distances.d.ts.map +1 -0
  422. package/script/methods/distances.js +203 -0
  423. package/script/methods/findCycles.d.ts +12 -0
  424. package/script/methods/findCycles.d.ts.map +1 -0
  425. package/script/methods/findCycles.js +369 -0
  426. package/script/methods/fuzzyClean.d.ts.map +1 -1
  427. package/script/methods/fuzzyClean.js +17 -136
  428. package/script/methods/fuzzyJoin.js +70 -16
  429. package/script/methods/getTypes.d.ts +1 -1
  430. package/script/methods/hdbscan.d.ts +5 -0
  431. package/script/methods/hdbscan.d.ts.map +1 -0
  432. package/script/methods/hdbscan.js +214 -0
  433. package/script/methods/mahalanobis.d.ts +5 -0
  434. package/script/methods/mahalanobis.d.ts.map +1 -0
  435. package/script/methods/mahalanobis.js +98 -0
  436. package/script/methods/neighbors.d.ts +9 -0
  437. package/script/methods/neighbors.d.ts.map +1 -0
  438. package/script/methods/neighbors.js +120 -0
  439. package/script/methods/normalizeVector.d.ts +5 -0
  440. package/script/methods/normalizeVector.d.ts.map +1 -0
  441. package/script/methods/normalizeVector.js +138 -0
  442. package/script/methods/paths.d.ts +12 -0
  443. package/script/methods/paths.d.ts.map +1 -0
  444. package/script/methods/paths.js +326 -0
  445. package/script/methods/reachable.d.ts +11 -0
  446. package/script/methods/reachable.d.ts.map +1 -0
  447. package/script/methods/reachable.js +170 -0
  448. package/script/methods/rowToVector.d.ts +5 -0
  449. package/script/methods/rowToVector.d.ts.map +1 -0
  450. package/script/methods/rowToVector.js +83 -0
  451. package/script/methods/shortestPath.d.ts +12 -0
  452. package/script/methods/shortestPath.d.ts.map +1 -0
  453. package/script/methods/shortestPath.js +376 -0
  454. package/script/methods/topologicalSort.d.ts +7 -0
  455. package/script/methods/topologicalSort.d.ts.map +1 -0
  456. package/script/methods/topologicalSort.js +170 -0
  457. package/script/methods/trim.d.ts +1 -1
  458. package/script/methods/trim.d.ts.map +1 -1
  459. package/script/methods/trim.js +17 -8
@@ -5,14 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = fuzzyClean;
7
7
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
+ const node_api_1 = require("@duckdb/node-api");
8
9
  const mergeOptions_js_1 = __importDefault(require("../helpers/mergeOptions.js"));
9
10
  const queryDB_js_1 = __importDefault(require("../helpers/queryDB.js"));
10
11
  const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
11
12
  const buildFuzzyMatchSql_js_1 = __importDefault(require("../helpers/buildFuzzyMatchSql.js"));
13
+ const selectFuzzyReplacements_js_1 = __importDefault(require("../helpers/selectFuzzyReplacements.js"));
12
14
  function fuzzyClean(table, column, newColumn, threshold, options = {}) {
13
- // The clustering runs in JS over the fuzzy pairs read from the table, so
14
- // fuzzyClean can't be expressed as a single SELECT over its input: it
15
- // executes as a barrier.
15
+ // This implementation clusters fuzzy pairs in JS and writes the mapping
16
+ // back to DuckDB, so it executes as a barrier.
16
17
  options = structuredClone(options);
17
18
  (0, queueOp_js_1.default)(table, {
18
19
  kind: "barrier",
@@ -63,149 +64,29 @@ async function executeFuzzyClean(table, column, newColumn, threshold, options =
63
64
  }
64
65
  return;
65
66
  }
66
- // Build count map from the pairs — no separate query needed.
67
- const countMap = new Map();
68
- for (const { left_value, left_cnt, right_value, right_cnt } of pairs) {
69
- countMap.set(left_value, Number(left_cnt));
70
- countMap.set(right_value, Number(right_cnt));
71
- }
72
- // Union-Find — only over values that actually participate in a pair.
73
- const parent = new Map();
74
- const find = (x) => {
75
- if (!parent.has(x))
76
- parent.set(x, x);
77
- if (parent.get(x) !== x)
78
- parent.set(x, find(parent.get(x)));
79
- return parent.get(x);
80
- };
81
- const union = (a, b) => {
82
- const ra = find(a);
83
- const rb = find(b);
84
- if (ra !== rb)
85
- parent.set(ra, rb);
86
- };
87
- for (const v of countMap.keys())
88
- find(v);
89
- for (const { left_value, right_value } of pairs) {
90
- union(left_value, right_value);
91
- }
92
- // Group values by their cluster root.
93
- const clusters = new Map();
94
- for (const v of countMap.keys()) {
95
- const root = find(v);
96
- if (!clusters.has(root))
97
- clusters.set(root, []);
98
- clusters.get(root).push(v);
99
- }
100
- // Pick the canonical value for each cluster.
101
- const replacement = new Map();
102
- for (const members of clusters.values()) {
103
- if (members.length === 1)
104
- continue; // All pairs are already canonical — skip.
105
- // Score sums and per-member max scores are computed lazily — only when
106
- // actually needed as a primary criterion or tie-breaker.
107
- //
108
- // scoreSum: total similarity to all other cluster members (used by
109
- // "mostCentral" as primary, and as tie-breaker for all strategies).
110
- // scoreMax: highest single pairwise score (used by "maxScore" as primary).
111
- let scoreSum = null;
112
- const getScoreSum = () => {
113
- if (scoreSum === null) {
114
- scoreSum = new Map(members.map((m) => [m, 0]));
115
- for (const { left_value, right_value, score } of pairs) {
116
- if (scoreSum.has(left_value) && scoreSum.has(right_value)) {
117
- scoreSum.set(left_value, (scoreSum.get(left_value) ?? 0) + score);
118
- scoreSum.set(right_value, (scoreSum.get(right_value) ?? 0) + score);
119
- }
120
- }
121
- }
122
- return scoreSum;
123
- };
124
- let scoreMax = null;
125
- const getScoreMax = () => {
126
- if (scoreMax === null) {
127
- scoreMax = new Map(members.map((m) => [m, 0]));
128
- for (const { left_value, right_value, score } of pairs) {
129
- if (scoreMax.has(left_value) && scoreMax.has(right_value)) {
130
- scoreMax.set(left_value, Math.max(scoreMax.get(left_value) ?? 0, score));
131
- scoreMax.set(right_value, Math.max(scoreMax.get(right_value) ?? 0, score));
132
- }
133
- }
134
- }
135
- return scoreMax;
136
- };
137
- // Sum-based comparator: highest total similarity, then alphabetical.
138
- const byScore = (a, b) => {
139
- const sum = getScoreSum();
140
- const sa = sum.get(a) ?? 0;
141
- const sb = sum.get(b) ?? 0;
142
- if (sa !== sb)
143
- return sa > sb ? a : b;
144
- return a <= b ? a : b; // alphabetical tie-break
145
- };
146
- // Max-based comparator: highest single-pair score, then sum, then alphabetical.
147
- const byMaxScore = (a, b) => {
148
- const mx = getScoreMax();
149
- const ma = mx.get(a) ?? 0;
150
- const mb = mx.get(b) ?? 0;
151
- if (ma !== mb)
152
- return ma > mb ? a : b;
153
- return byScore(a, b); // sum then alphabetical tie-break
154
- };
155
- let canonical;
156
- if (strategy === "longestString") {
157
- canonical = members.reduce((a, b) => {
158
- if (a.length !== b.length)
159
- return a.length > b.length ? a : b;
160
- return byScore(a, b);
161
- });
162
- }
163
- else if (strategy === "shortestString") {
164
- canonical = members.reduce((a, b) => {
165
- if (a.length !== b.length)
166
- return a.length < b.length ? a : b;
167
- return byScore(a, b);
168
- });
169
- }
170
- else if (strategy === "mostCommon") {
171
- canonical = members.reduce((a, b) => {
172
- const ca = countMap.get(a) ?? 0;
173
- const cb = countMap.get(b) ?? 0;
174
- if (ca !== cb)
175
- return ca > cb ? a : b;
176
- return byScore(a, b);
177
- });
178
- }
179
- else if (strategy === "mostCentral") {
180
- // Most central string — highest total similarity to all other cluster members.
181
- canonical = members.reduce((a, b) => byScore(a, b));
182
- }
183
- else {
184
- // "maxScore": the string participating in the single highest-scoring pair.
185
- canonical = members.reduce((a, b) => byMaxScore(a, b));
186
- }
187
- for (const m of members) {
188
- if (m !== canonical)
189
- replacement.set(m, canonical);
190
- }
191
- }
67
+ const replacement = (0, selectFuzzyReplacements_js_1.default)(pairs, strategy);
192
68
  if (replacement.size === 0)
193
69
  return;
194
- // Use a VALUES-based CTE for the UPDATE so DuckDB can use a hash join
195
- // instead of evaluating a potentially huge CASE WHEN expression.
196
- const replacementEntries = [...replacement.entries()];
197
- const valuesList = replacementEntries.map(() => "(?, ?)").join(",\n ");
198
- const values = replacementEntries.flatMap(([from, to]) => [from, to]);
70
+ // Two bound lists keep the SQL and parameter count fixed as the mapping
71
+ // grows. Side-by-side UNNEST zips the equally sized lists into mapping rows,
72
+ // which DuckDB can hash-join to the original table.
73
+ const values = [
74
+ new node_api_1.DuckDBListValue([...replacement.keys()]),
75
+ new node_api_1.DuckDBListValue([...replacement.values()]),
76
+ ];
77
+ const mapping = `WITH mapping(original, canonical) AS (
78
+ SELECT UNNEST(?::VARCHAR[]), UNNEST(?::VARCHAR[])
79
+ )`;
199
80
  const query = newColumn !== column
200
81
  ? `ALTER TABLE ${(0, quoteIdentifier_js_1.default)(table.name)} ADD ${(0, quoteIdentifier_js_1.default)(newColumn)} VARCHAR;
201
82
  UPDATE ${(0, quoteIdentifier_js_1.default)(table.name)}
202
83
  SET ${(0, quoteIdentifier_js_1.default)(newColumn)} = ${(0, quoteIdentifier_js_1.default)(column)};
203
- WITH mapping(original, canonical) AS (VALUES ${valuesList})
84
+ ${mapping}
204
85
  UPDATE ${(0, quoteIdentifier_js_1.default)(table.name)}
205
86
  SET ${(0, quoteIdentifier_js_1.default)(newColumn)} = m.canonical
206
87
  FROM mapping m
207
88
  WHERE ${(0, quoteIdentifier_js_1.default)(table.name)}.${(0, quoteIdentifier_js_1.default)(newColumn)} = m.original`
208
- : `WITH mapping(original, canonical) AS (VALUES ${valuesList})
89
+ : `${mapping}
209
90
  UPDATE ${(0, quoteIdentifier_js_1.default)(table.name)}
210
91
  SET ${(0, quoteIdentifier_js_1.default)(column)} = m.canonical
211
92
  FROM mapping m
@@ -54,17 +54,7 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
54
54
  }
55
55
  const method = options.method ?? "ratio";
56
56
  const similarityColumn = options.similarityColumn;
57
- // The right table's copy of a column shared with the left table (only
58
- // rightColumn can be shared, checked above) is excluded from the SELECT
59
- // directly, instead of dropping its _1 duplicate with a rewrite after the
60
- // join.
61
- const rightSelect = rightCols
62
- .filter((d) => !leftCols.includes(d))
63
- .map((d) => `${(0, quoteIdentifier_js_1.default)(rightTable.name)}.${(0, quoteIdentifier_js_1.default)(d)}`)
64
- .join(", ");
65
- const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
66
- fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength);
67
- await (0, queryDB_js_1.default)(leftTable, sql, (0, mergeOptions_js_1.default)(leftTable, {
57
+ const queryOptions = (0, mergeOptions_js_1.default)(leftTable, {
68
58
  table: outputTable.name,
69
59
  method: "fuzzyJoin()",
70
60
  parameters: {
@@ -74,26 +64,90 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
74
64
  threshold,
75
65
  options,
76
66
  },
77
- }));
67
+ });
68
+ const deduplicate = await shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions);
69
+ // The right table's copy of a column shared with the left table (only
70
+ // rightColumn can be shared, checked above) is excluded from the SELECT
71
+ // directly, instead of dropping its _1 duplicate with a rewrite after the
72
+ // join.
73
+ const rightSelect = rightCols
74
+ .filter((d) => !leftCols.includes(d))
75
+ .map((d) => `${(0, quoteIdentifier_js_1.default)(rightTable.name)}.${(0, quoteIdentifier_js_1.default)(d)}`)
76
+ .join(", ");
77
+ const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
78
+ fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength, deduplicate);
79
+ await (0, queryDB_js_1.default)(leftTable, sql, queryOptions);
78
80
  }
79
- function fuzzyJoinQuery(leftTable, leftColumn, rightTable, rightColumn, method, threshold, outputTable, similarityColumn, rightSelect, prefilterPrefixLength) {
81
+ async function shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions) {
82
+ const left = (0, quoteIdentifier_js_1.default)(leftTable.name);
83
+ const right = (0, quoteIdentifier_js_1.default)(rightTable.name);
84
+ const counts = (await (0, queryDB_js_1.default)(leftTable, `SELECT (SELECT COUNT(*) FROM ${left}) AS left_count,
85
+ (SELECT COUNT(*) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
86
+ const leftCount = Number(counts.left_count);
87
+ const rightCount = Number(counts.right_count);
88
+ const comparisons = leftCount * rightCount;
89
+ // Avoid distinct scans for small joins and short lookup tables. For larger
90
+ // joins, require at least a twofold reduction to pay for grouping and rejoining.
91
+ if (comparisons < 100_000 || Math.min(leftCount, rightCount) < 32) {
92
+ return false;
93
+ }
94
+ const distinct = (await (0, queryDB_js_1.default)(leftTable, `SELECT
95
+ (SELECT COUNT(DISTINCT ENCODE(${(0, quoteIdentifier_js_1.default)(leftColumn)})) FROM ${left}) AS left_count,
96
+ (SELECT COUNT(DISTINCT ENCODE(${(0, quoteIdentifier_js_1.default)(rightColumn)})) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
97
+ return Number(distinct.left_count) * Number(distinct.right_count) <=
98
+ comparisons / 2;
99
+ }
100
+ function fuzzyJoinQuery(leftTable, leftColumn, rightTable, rightColumn, method, threshold, outputTable, similarityColumn, rightSelect, prefilterPrefixLength, deduplicate = false) {
80
101
  const leftExpression = `${(0, quoteIdentifier_js_1.default)(leftTable)}.${(0, quoteIdentifier_js_1.default)(leftColumn)}`;
81
102
  const rightExpression = `${(0, quoteIdentifier_js_1.default)(rightTable)}.${(0, quoteIdentifier_js_1.default)(rightColumn)}`;
82
103
  const { scoreExpression, condition } = (0, buildFuzzyMatchSql_js_1.default)(leftExpression, rightExpression, method, threshold, { decimals: 2, prefilterPrefixLength });
104
+ let cte = "";
105
+ let from = `FROM ${(0, quoteIdentifier_js_1.default)(leftTable)} LEFT JOIN ${(0, quoteIdentifier_js_1.default)(rightTable)} ON ${condition}`;
106
+ let score = scoreExpression;
107
+ if (deduplicate) {
108
+ const matches = (0, quoteIdentifier_js_1.default)(`__sda_fuzzy_matches_${crypto.randomUUID().replaceAll("-", "")}`);
109
+ const match = (0, buildFuzzyMatchSql_js_1.default)("l.value", "r.value", method, threshold, { decimals: 2, prefilterPrefixLength });
110
+ // Keep the original value's collation for prefix matching, but use byte
111
+ // keys for deduplication and expansion: fuzzy scores distinguish case even
112
+ // when an input column has a case-insensitive collation.
113
+ cte = `WITH ${matches} AS MATERIALIZED (
114
+ SELECT l.key AS left_key, r.key AS right_key,
115
+ ${match.scoreExpression} AS score
116
+ FROM (
117
+ SELECT DISTINCT ${(0, quoteIdentifier_js_1.default)(leftColumn)} AS value,
118
+ ENCODE(${(0, quoteIdentifier_js_1.default)(leftColumn)}) AS key
119
+ FROM ${(0, quoteIdentifier_js_1.default)(leftTable)}
120
+ WHERE ${(0, quoteIdentifier_js_1.default)(leftColumn)} IS NOT NULL
121
+ ) l
122
+ INNER JOIN (
123
+ SELECT DISTINCT ${(0, quoteIdentifier_js_1.default)(rightColumn)} AS value,
124
+ ENCODE(${(0, quoteIdentifier_js_1.default)(rightColumn)}) AS key
125
+ FROM ${(0, quoteIdentifier_js_1.default)(rightTable)}
126
+ WHERE ${(0, quoteIdentifier_js_1.default)(rightColumn)} IS NOT NULL
127
+ ) r ON ${match.condition}
128
+ )`;
129
+ from = `FROM ${(0, quoteIdentifier_js_1.default)(leftTable)}
130
+ LEFT JOIN ${matches} ON ENCODE(${leftExpression}) = ${matches}.left_key
131
+ LEFT JOIN ${(0, quoteIdentifier_js_1.default)(rightTable)}
132
+ ON ENCODE(${rightExpression}) = ${matches}.right_key`;
133
+ score = `${matches}.score`;
134
+ }
83
135
  if (similarityColumn) {
84
136
  return `CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(outputTable)} AS
137
+ ${cte}
85
138
  SELECT * EXCLUDE ("_sda_score"), "_sda_score" AS ${(0, quoteIdentifier_js_1.default)(similarityColumn)}
86
139
  FROM (
87
- SELECT ${(0, quoteIdentifier_js_1.default)(leftTable)}.*, ${rightSelect}, ${scoreExpression} AS "_sda_score"
88
- FROM ${(0, quoteIdentifier_js_1.default)(leftTable)} LEFT JOIN ${(0, quoteIdentifier_js_1.default)(rightTable)} ON ${condition}
140
+ SELECT ${(0, quoteIdentifier_js_1.default)(leftTable)}.*, ${rightSelect}, ${score} AS "_sda_score"
141
+ ${from}
89
142
  ) _sda
90
143
  ORDER BY ${(0, quoteIdentifier_js_1.default)(leftColumn)}, "_sda_score" DESC;\n`;
91
144
  }
92
145
  return `CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(outputTable)} AS
146
+ ${cte}
93
147
  SELECT *
94
148
  FROM (
95
149
  SELECT ${(0, quoteIdentifier_js_1.default)(leftTable)}.*, ${rightSelect}
96
- FROM ${(0, quoteIdentifier_js_1.default)(leftTable)} LEFT JOIN ${(0, quoteIdentifier_js_1.default)(rightTable)} ON ${condition}
150
+ ${from}
97
151
  ) _sda
98
152
  ORDER BY ${(0, quoteIdentifier_js_1.default)(leftColumn)}, ${(0, quoteIdentifier_js_1.default)(rightColumn)};\n`;
99
153
  }
@@ -1,5 +1,5 @@
1
1
  import type SimpleTable from "../class/SimpleTable.js";
2
2
  export default function getTypes(simpleTable: SimpleTable): Promise<{
3
- [key: string]: string;
3
+ [k: string]: string;
4
4
  }>;
5
5
  //# sourceMappingURL=getTypes.d.ts.map
@@ -0,0 +1,5 @@
1
+ import type SimpleTable from "../class/SimpleTable.js";
2
+ type Options = NonNullable<Parameters<SimpleTable["hdbscan"]>[2]>;
3
+ export default function hdbscan(table: SimpleTable, columns: string | string[], newColumn: string, options?: Options): void;
4
+ export {};
5
+ //# sourceMappingURL=hdbscan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hdbscan.d.ts","sourceRoot":"","sources":["../../src/methods/hdbscan.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAWvD,KAAK,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAElE,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,OAAY,GACpB,IAAI,CASN"}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = hdbscan;
7
+ const node_api_1 = require("@duckdb/node-api");
8
+ const appendColumnBatches_js_1 = __importDefault(require("../helpers/appendColumnBatches.js"));
9
+ const buildApproximateMutualReachabilityMst_js_1 = __importDefault(require("../helpers/buildApproximateMutualReachabilityMst.js"));
10
+ const buildExactMutualReachabilityMst_js_1 = __importDefault(require("../helpers/buildExactMutualReachabilityMst.js"));
11
+ const clusterHdbscan_js_1 = __importDefault(require("../helpers/clusterHdbscan.js"));
12
+ const foldIdentifier_js_1 = __importDefault(require("../helpers/foldIdentifier.js"));
13
+ const prepareNumericFeatures_js_1 = __importDefault(require("../helpers/prepareNumericFeatures.js"));
14
+ const publishPreparedColumns_js_1 = __importDefault(require("../helpers/publishPreparedColumns.js"));
15
+ const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
16
+ const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
17
+ function hdbscan(table, columns, newColumn, options = {}) {
18
+ const selected = typeof columns === "string" ? columns : [...columns];
19
+ const settings = structuredClone(options);
20
+ (0, queueOp_js_1.default)(table, {
21
+ kind: "barrier",
22
+ method: "hdbscan()",
23
+ parameters: { columns: selected, newColumn, options: settings },
24
+ execute: () => execute(table, selected, newColumn, settings),
25
+ });
26
+ }
27
+ async function execute(table, columns, newColumn, options) {
28
+ const { minClusterSize = 5, metric = "euclidean", allowSingleCluster = false, approximate = false, membershipScoreColumn, outlierScoreColumn, } = options;
29
+ const minSamples = options.minSamples ?? minClusterSize;
30
+ if (typeof newColumn !== "string") {
31
+ throw new Error("hdbscan() newColumn must be a string.");
32
+ }
33
+ if (!Number.isSafeInteger(minClusterSize) || minClusterSize < 2) {
34
+ throw new Error("hdbscan() minClusterSize must be a safe integer of at least 2.");
35
+ }
36
+ if (!Number.isSafeInteger(minSamples) || minSamples < 1) {
37
+ throw new Error("hdbscan() minSamples must be a safe integer of at least 1.");
38
+ }
39
+ if (!["euclidean", "cosine"].includes(metric)) {
40
+ throw new Error('hdbscan() metric must be "euclidean" or "cosine".');
41
+ }
42
+ if (typeof allowSingleCluster !== "boolean") {
43
+ throw new Error("hdbscan() allowSingleCluster must be a boolean.");
44
+ }
45
+ if (typeof approximate !== "boolean") {
46
+ throw new Error("hdbscan() approximate must be a boolean.");
47
+ }
48
+ if (membershipScoreColumn !== undefined &&
49
+ typeof membershipScoreColumn !== "string") {
50
+ throw new Error("hdbscan() membershipScoreColumn must be a string.");
51
+ }
52
+ if (outlierScoreColumn !== undefined &&
53
+ typeof outlierScoreColumn !== "string") {
54
+ throw new Error("hdbscan() outlierScoreColumn must be a string.");
55
+ }
56
+ const sourceColumns = Object.keys(await table.getTypes());
57
+ const outputNames = [newColumn, membershipScoreColumn, outlierScoreColumn]
58
+ .filter((name) => name !== undefined);
59
+ validateOutputNames(sourceColumns, outputNames);
60
+ const prepared = await (0, prepareNumericFeatures_js_1.default)(table, typeof columns === "string"
61
+ ? { kind: "vector", column: columns }
62
+ : { kind: "scalars", columns }, { method: "hdbscan()" });
63
+ const connection = table.connection;
64
+ const suffix = crypto.randomUUID().replaceAll("-", "");
65
+ const name = (part) => `__sda_hdbscan_${suffix}_${part}`;
66
+ const names = {
67
+ rows: name("rows"),
68
+ neighbors: name("neighbors"),
69
+ search: name("search"),
70
+ hnsw: name("hnsw"),
71
+ candidates: name("candidates"),
72
+ coreDistances: name("core_distances"),
73
+ frontier: name("frontier"),
74
+ edges: name("edges"),
75
+ components: name("components"),
76
+ representatives: name("representatives"),
77
+ componentPairs: name("component_pairs"),
78
+ bridgeCandidates: name("bridge_candidates"),
79
+ mst: name("mst"),
80
+ result: name("result"),
81
+ };
82
+ try {
83
+ if (prepared.rowCount < 2) {
84
+ throw new Error(`hdbscan() requires at least 2 rows, but the input has ${prepared.rowCount}.`);
85
+ }
86
+ if (prepared.rowCount > 0x40000000) {
87
+ throw new Error("hdbscan() supports at most 1073741824 rows because its 2*n-1 hierarchy nodes use signed INTEGER identifiers.");
88
+ }
89
+ if (minSamples >= prepared.rowCount) {
90
+ const defaulted = options.minSamples === undefined
91
+ ? " (defaulted from minClusterSize)"
92
+ : "";
93
+ throw new Error(`hdbscan() minSamples is ${minSamples}${defaulted}, but ${prepared.rowCount} rows provide at most ${prepared.rowCount - 1} other point${prepared.rowCount === 2 ? "" : "s"}. Set minSamples between 1 and ${prepared.rowCount - 1}, or provide at least ${minSamples + 1} rows.`);
94
+ }
95
+ if (minClusterSize > prepared.rowCount) {
96
+ throw new Error(`hdbscan() minClusterSize is ${minClusterSize}, but the input has ${prepared.rowCount} rows. Set minClusterSize between 2 and ${prepared.rowCount}, or provide more rows.`);
97
+ }
98
+ const q = quoteIdentifier_js_1.default;
99
+ await connection.run(`CREATE TEMP TABLE ${q(names.rows)} AS
100
+ SELECT ${q(prepared.rowIdColumn)}::INTEGER AS vertex,
101
+ ${q(prepared.vectorColumn)} AS vec
102
+ FROM ${q(prepared.relation)}
103
+ ORDER BY ${q(prepared.rowIdColumn)}`);
104
+ if (approximate) {
105
+ await (0, buildApproximateMutualReachabilityMst_js_1.default)(connection, {
106
+ count: prepared.rowCount,
107
+ dimensions: prepared.dimensions,
108
+ minSamples,
109
+ }, { metric }, {
110
+ rows: names.rows,
111
+ neighbors: names.neighbors,
112
+ search: names.search,
113
+ hnsw: names.hnsw,
114
+ candidates: names.candidates,
115
+ coreDistances: names.coreDistances,
116
+ edges: names.edges,
117
+ components: names.components,
118
+ representatives: names.representatives,
119
+ componentPairs: names.componentPairs,
120
+ bridgeCandidates: names.bridgeCandidates,
121
+ mst: names.mst,
122
+ });
123
+ }
124
+ else {
125
+ await (0, buildExactMutualReachabilityMst_js_1.default)(connection, { count: prepared.rowCount, minSamples }, { metric }, {
126
+ rows: q(names.rows),
127
+ coreDistances: q(names.coreDistances),
128
+ frontier: q(names.frontier),
129
+ mst: q(names.mst),
130
+ });
131
+ }
132
+ const result = await (0, clusterHdbscan_js_1.default)(connection, q(names.mst), {
133
+ count: prepared.rowCount,
134
+ minClusterSize,
135
+ allowSingleCluster,
136
+ });
137
+ const labelColumn = "label";
138
+ const membershipColumn = "membership";
139
+ const gloshColumn = "glosh";
140
+ const resultColumns = [
141
+ "row_id INTEGER",
142
+ `${labelColumn} VARCHAR`,
143
+ membershipScoreColumn === undefined
144
+ ? undefined
145
+ : `${membershipColumn} DOUBLE`,
146
+ outlierScoreColumn === undefined ? undefined : `${gloshColumn} DOUBLE`,
147
+ ].filter((definition) => definition !== undefined);
148
+ await connection.run(`CREATE TEMP TABLE ${q(names.result)} (${resultColumns.join(",")})`);
149
+ const outputTypes = [
150
+ node_api_1.INTEGER,
151
+ node_api_1.VARCHAR,
152
+ ...(membershipScoreColumn === undefined ? [] : [node_api_1.DOUBLE]),
153
+ ...(outlierScoreColumn === undefined ? [] : [node_api_1.DOUBLE]),
154
+ ];
155
+ await (0, appendColumnBatches_js_1.default)(connection, names.result, outputTypes, prepared.rowCount, (column, start, end) => {
156
+ if (column === 0) {
157
+ return Array.from({ length: end - start }, (_, offset) => start + offset);
158
+ }
159
+ if (column === 1) {
160
+ return Array.from(result.labels.subarray(start, end), (label) => label < 0 ? "noise" : `cluster-${label}`);
161
+ }
162
+ const membershipIndex = membershipScoreColumn === undefined ? -1 : 2;
163
+ return Array.from(column === membershipIndex
164
+ ? result.probabilities.subarray(start, end)
165
+ : result.outlierScores.subarray(start, end));
166
+ });
167
+ const publicationOutputs = [{
168
+ name: newColumn,
169
+ expression: `r.${q(labelColumn)}`,
170
+ }];
171
+ if (membershipScoreColumn !== undefined) {
172
+ publicationOutputs.push({
173
+ name: membershipScoreColumn,
174
+ expression: `r.${q(membershipColumn)}`,
175
+ });
176
+ }
177
+ if (outlierScoreColumn !== undefined) {
178
+ publicationOutputs.push({
179
+ name: outlierScoreColumn,
180
+ expression: `r.${q(gloshColumn)}`,
181
+ });
182
+ }
183
+ await (0, publishPreparedColumns_js_1.default)(table, prepared, {
184
+ method: "hdbscan()",
185
+ parameters: { columns, newColumn, options },
186
+ result: { relation: names.result, rowIdColumn: "row_id" },
187
+ outputs: publicationOutputs,
188
+ });
189
+ }
190
+ finally {
191
+ for (const relation of Object.entries(names).reverse().flatMap(([key, value]) => key === "hnsw" ? [] : [value])) {
192
+ await connection.run(`DROP TABLE IF EXISTS ${(0, quoteIdentifier_js_1.default)(relation)}`);
193
+ }
194
+ await prepared.cleanup();
195
+ }
196
+ }
197
+ function validateOutputNames(sourceColumns, outputNames) {
198
+ const seen = new Map();
199
+ for (const name of outputNames) {
200
+ if (name.length === 0 || name.includes("\0")) {
201
+ throw new Error("hdbscan() output column names must be non-empty strings without null characters.");
202
+ }
203
+ const folded = (0, foldIdentifier_js_1.default)(name);
204
+ const source = sourceColumns.find((column) => (0, foldIdentifier_js_1.default)(column) === folded);
205
+ if (source !== undefined) {
206
+ throw new Error(`hdbscan() cannot create ${(0, quoteIdentifier_js_1.default)(name)} because that source column already exists. Remove it first or choose different output names.`);
207
+ }
208
+ const duplicate = seen.get(folded);
209
+ if (duplicate !== undefined) {
210
+ throw new Error(`hdbscan() output columns ${(0, quoteIdentifier_js_1.default)(duplicate)} and ${(0, quoteIdentifier_js_1.default)(name)} refer to the same column. Choose distinct output names.`);
211
+ }
212
+ seen.set(folded, name);
213
+ }
214
+ }
@@ -0,0 +1,5 @@
1
+ import type SimpleTable from "../class/SimpleTable.js";
2
+ type Options = NonNullable<Parameters<SimpleTable["mahalanobis"]>[3]>;
3
+ export default function mahalanobis(table: SimpleTable, columns: string | string[], referencePoint: number[], newColumn: string, options?: Options): void;
4
+ export {};
5
+ //# sourceMappingURL=mahalanobis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mahalanobis.d.ts","sourceRoot":"","sources":["../../src/methods/mahalanobis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AASvD,KAAK,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtE,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,cAAc,EAAE,MAAM,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,OAAY,GACpB,IAAI,CAyBN"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = mahalanobis;
7
+ const computeCovariance_js_1 = __importDefault(require("../helpers/computeCovariance.js"));
8
+ const computeMahalanobisDistances_js_1 = __importDefault(require("../helpers/computeMahalanobisDistances.js"));
9
+ const foldIdentifier_js_1 = __importDefault(require("../helpers/foldIdentifier.js"));
10
+ const prepareNumericFeatures_js_1 = __importDefault(require("../helpers/prepareNumericFeatures.js"));
11
+ const publishPreparedColumns_js_1 = __importDefault(require("../helpers/publishPreparedColumns.js"));
12
+ const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
13
+ const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
14
+ function mahalanobis(table, columns, referencePoint, newColumn, options = {}) {
15
+ if (!Array.isArray(referencePoint) || referencePoint.length === 0 ||
16
+ Array.from(referencePoint).some((value) => typeof value !== "number" || !Number.isFinite(value))) {
17
+ throw new Error("mahalanobis() referencePoint must be a nonempty array of finite numbers in feature-dimension order.");
18
+ }
19
+ const selected = typeof columns === "string" ? columns : [...columns];
20
+ const reference = [...referencePoint];
21
+ const settings = { ...options };
22
+ (0, queueOp_js_1.default)(table, {
23
+ kind: "barrier",
24
+ method: "mahalanobis()",
25
+ parameters: {
26
+ columns: selected,
27
+ referencePoint: reference,
28
+ newColumn,
29
+ options: settings,
30
+ },
31
+ execute: () => execute(table, selected, reference, newColumn, settings),
32
+ });
33
+ }
34
+ async function execute(table, columns, referencePoint, newColumn, options) {
35
+ const sourceColumns = Object.keys(await table.getTypes());
36
+ const outputNames = options.similarityScoreColumn === undefined
37
+ ? [newColumn]
38
+ : [newColumn, options.similarityScoreColumn];
39
+ const seen = new Set();
40
+ for (const name of outputNames) {
41
+ if (typeof name !== "string" || name.length === 0 || name.includes("\0")) {
42
+ throw new Error("mahalanobis() output column names must be nonempty strings without null characters.");
43
+ }
44
+ const folded = (0, foldIdentifier_js_1.default)(name);
45
+ if (seen.has(folded)) {
46
+ throw new Error("mahalanobis() distance and similarity score columns must have different names (case-insensitive).");
47
+ }
48
+ seen.add(folded);
49
+ if (sourceColumns.some((column) => (0, foldIdentifier_js_1.default)(column) === folded)) {
50
+ throw new Error(`mahalanobis() cannot create ${(0, quoteIdentifier_js_1.default)(name)} because that column already exists. Remove it first or choose a different name.`);
51
+ }
52
+ }
53
+ const prepared = await (0, prepareNumericFeatures_js_1.default)(table, typeof columns === "string"
54
+ ? { kind: "vector", column: columns }
55
+ : { kind: "scalars", columns }, { method: "mahalanobis()" });
56
+ try {
57
+ if (referencePoint.length !== prepared.dimensions) {
58
+ throw new Error(`mahalanobis() referencePoint must contain ${prepared.dimensions} values in feature-dimension order; received ${referencePoint.length}.`);
59
+ }
60
+ const model = await (0, computeCovariance_js_1.default)(table.connection, {
61
+ relation: prepared.relation,
62
+ rowIdColumn: prepared.rowIdColumn,
63
+ vectorColumn: prepared.vectorColumn,
64
+ observations: prepared.rowCount,
65
+ dimensions: prepared.dimensions,
66
+ });
67
+ const distances = await (0, computeMahalanobisDistances_js_1.default)(table.connection, {
68
+ relation: prepared.relation,
69
+ rowIdColumn: prepared.rowIdColumn,
70
+ vectorColumn: prepared.vectorColumn,
71
+ }, model, referencePoint);
72
+ try {
73
+ const distance = `r.${(0, quoteIdentifier_js_1.default)(distances.distanceColumn)}`;
74
+ const outputs = [{ name: newColumn, expression: distance }];
75
+ if (options.similarityScoreColumn !== undefined) {
76
+ outputs.push({
77
+ name: options.similarityScoreColumn,
78
+ expression: `CASE WHEN max(${distance}) OVER () = 0 THEN 1::DOUBLE ELSE 1 - ${distance} / max(${distance}) OVER () END`,
79
+ });
80
+ }
81
+ await (0, publishPreparedColumns_js_1.default)(table, prepared, {
82
+ method: "mahalanobis()",
83
+ parameters: { columns, referencePoint, newColumn, options },
84
+ result: {
85
+ relation: distances.relation,
86
+ rowIdColumn: distances.rowIdColumn,
87
+ },
88
+ outputs,
89
+ });
90
+ }
91
+ finally {
92
+ await distances.cleanup();
93
+ }
94
+ }
95
+ finally {
96
+ await prepared.cleanup();
97
+ }
98
+ }
@@ -0,0 +1,9 @@
1
+ import { type GraphId } from "../helpers/prepareGraphStarts.js";
2
+ import type SimpleTable from "../class/SimpleTable.js";
3
+ type NeighborsOptions = {
4
+ direction?: "outgoing" | "incoming" | "both";
5
+ outputTable?: string | boolean;
6
+ };
7
+ export default function neighbors(simpleTable: SimpleTable, sourceColumn: string, targetColumn: string, startNodes: GraphId | GraphId[], options?: NeighborsOptions): SimpleTable;
8
+ export {};
9
+ //# sourceMappingURL=neighbors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"neighbors.d.ts","sourceRoot":"","sources":["../../src/methods/neighbors.ts"],"names":[],"mappings":"AAAA,OAA2B,EACzB,KAAK,OAAO,EAEb,MAAM,kCAAkC,CAAC;AAO1C,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,KAAK,gBAAgB,GAAG;IACtB,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,OAAO,GAAG,OAAO,EAAE,EAC/B,OAAO,GAAE,gBAAqB,GAC7B,WAAW,CAuEb"}