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

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 (453) 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 +2795 -1139
  9. package/esm/class/SimpleTable.d.ts.map +1 -1
  10. package/esm/class/SimpleTable.js +2781 -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/llm.md +2106 -143
  227. package/llms.txt +1 -1
  228. package/package.json +1 -1
  229. package/script/class/SDAError.d.ts +6 -6
  230. package/script/class/SDAError.js +6 -6
  231. package/script/class/Simple.d.ts +9 -9
  232. package/script/class/Simple.js +9 -9
  233. package/script/class/SimpleDB.d.ts +80 -76
  234. package/script/class/SimpleDB.d.ts.map +1 -1
  235. package/script/class/SimpleDB.js +80 -76
  236. package/script/class/SimpleTable.d.ts +2795 -1139
  237. package/script/class/SimpleTable.d.ts.map +1 -1
  238. package/script/class/SimpleTable.js +2781 -1149
  239. package/script/helpers/buildApproximateMutualReachabilityMst.d.ts +45 -0
  240. package/script/helpers/buildApproximateMutualReachabilityMst.d.ts.map +1 -0
  241. package/script/helpers/buildApproximateMutualReachabilityMst.js +219 -0
  242. package/script/helpers/buildChronologicalGraphComponentsSql.d.ts +14 -0
  243. package/script/helpers/buildChronologicalGraphComponentsSql.d.ts.map +1 -0
  244. package/script/helpers/buildChronologicalGraphComponentsSql.js +174 -0
  245. package/script/helpers/buildExactMutualReachabilityMst.d.ts +28 -0
  246. package/script/helpers/buildExactMutualReachabilityMst.d.ts.map +1 -0
  247. package/script/helpers/buildExactMutualReachabilityMst.js +103 -0
  248. package/script/helpers/buildGraphTemporalCostStateSql.d.ts +12 -0
  249. package/script/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -0
  250. package/script/helpers/buildGraphTemporalCostStateSql.js +92 -0
  251. package/script/helpers/buildGraphTemporalReachabilitySql.d.ts +13 -0
  252. package/script/helpers/buildGraphTemporalReachabilitySql.d.ts.map +1 -0
  253. package/script/helpers/buildGraphTemporalReachabilitySql.js +76 -0
  254. package/script/helpers/buildSparseMutualReachabilityMst.d.ts +10 -0
  255. package/script/helpers/buildSparseMutualReachabilityMst.d.ts.map +1 -0
  256. package/script/helpers/buildSparseMutualReachabilityMst.js +50 -0
  257. package/script/helpers/buildUmapGraph.d.ts +2 -5
  258. package/script/helpers/buildUmapGraph.d.ts.map +1 -1
  259. package/script/helpers/buildUmapGraph.js +6 -100
  260. package/script/helpers/buildVectorNeighbors.d.ts +45 -0
  261. package/script/helpers/buildVectorNeighbors.d.ts.map +1 -0
  262. package/script/helpers/buildVectorNeighbors.js +176 -0
  263. package/script/helpers/buildWeakGraphComponentsSql.d.ts +3 -0
  264. package/script/helpers/buildWeakGraphComponentsSql.d.ts.map +1 -0
  265. package/script/helpers/buildWeakGraphComponentsSql.js +38 -0
  266. package/script/helpers/camelCase.d.ts +7 -5
  267. package/script/helpers/camelCase.d.ts.map +1 -1
  268. package/script/helpers/camelCase.js +7 -5
  269. package/script/helpers/capitalize.d.ts +6 -4
  270. package/script/helpers/capitalize.d.ts.map +1 -1
  271. package/script/helpers/capitalize.js +6 -4
  272. package/script/helpers/clusterHdbscan.d.ts +18 -0
  273. package/script/helpers/clusterHdbscan.d.ts.map +1 -0
  274. package/script/helpers/clusterHdbscan.js +346 -0
  275. package/script/helpers/computeCovariance.d.ts +16 -0
  276. package/script/helpers/computeCovariance.d.ts.map +1 -0
  277. package/script/helpers/computeCovariance.js +105 -0
  278. package/script/helpers/computeMahalanobisDistances.d.ts +14 -0
  279. package/script/helpers/computeMahalanobisDistances.d.ts.map +1 -0
  280. package/script/helpers/computeMahalanobisDistances.js +93 -0
  281. package/script/helpers/createDirectory.d.ts +4 -3
  282. package/script/helpers/createDirectory.d.ts.map +1 -1
  283. package/script/helpers/createDirectory.js +4 -3
  284. package/script/helpers/dataToArrays.d.ts +6 -4
  285. package/script/helpers/dataToArrays.d.ts.map +1 -1
  286. package/script/helpers/dataToArrays.js +6 -4
  287. package/script/helpers/extractTypes.d.ts +1 -1
  288. package/script/helpers/extractTypes.js +4 -9
  289. package/script/helpers/factorCovariance.d.ts +17 -0
  290. package/script/helpers/factorCovariance.d.ts.map +1 -0
  291. package/script/helpers/factorCovariance.js +194 -0
  292. package/script/helpers/findGeoColumn.d.ts +6 -4
  293. package/script/helpers/findGeoColumn.d.ts.map +1 -1
  294. package/script/helpers/findGeoColumn.js +6 -4
  295. package/script/helpers/findGeoColumnFromSchema.d.ts +8 -5
  296. package/script/helpers/findGeoColumnFromSchema.d.ts.map +1 -1
  297. package/script/helpers/findGeoColumnFromSchema.js +8 -5
  298. package/script/helpers/formatDate.d.ts +12 -6
  299. package/script/helpers/formatDate.d.ts.map +1 -1
  300. package/script/helpers/formatDate.js +12 -6
  301. package/script/helpers/formatMissingTables.d.ts +8 -5
  302. package/script/helpers/formatMissingTables.d.ts.map +1 -1
  303. package/script/helpers/formatMissingTables.js +8 -5
  304. package/script/helpers/formatNumber.d.ts +19 -10
  305. package/script/helpers/formatNumber.d.ts.map +1 -1
  306. package/script/helpers/formatNumber.js +32 -17
  307. package/script/helpers/getGraphEdgeIdColumn.d.ts +9 -0
  308. package/script/helpers/getGraphEdgeIdColumn.d.ts.map +1 -0
  309. package/script/helpers/getGraphEdgeIdColumn.js +31 -0
  310. package/script/helpers/getGraphEndpointColumns.d.ts +11 -0
  311. package/script/helpers/getGraphEndpointColumns.d.ts.map +1 -0
  312. package/script/helpers/getGraphEndpointColumns.js +166 -0
  313. package/script/helpers/getGraphWeightColumn.d.ts +10 -0
  314. package/script/helpers/getGraphWeightColumn.d.ts.map +1 -0
  315. package/script/helpers/getGraphWeightColumn.js +46 -0
  316. package/script/helpers/graphRouteResultSchema.d.ts +4 -0
  317. package/script/helpers/graphRouteResultSchema.d.ts.map +1 -0
  318. package/script/helpers/graphRouteResultSchema.js +18 -0
  319. package/script/helpers/graphRouteResultSelect.d.ts +4 -0
  320. package/script/helpers/graphRouteResultSelect.d.ts.map +1 -0
  321. package/script/helpers/graphRouteResultSelect.js +28 -0
  322. package/script/helpers/hasGeometryColumn.d.ts +4 -3
  323. package/script/helpers/hasGeometryColumn.d.ts.map +1 -1
  324. package/script/helpers/hasGeometryColumn.js +4 -3
  325. package/script/helpers/inspectGraphConnectivity.d.ts +10 -0
  326. package/script/helpers/inspectGraphConnectivity.d.ts.map +1 -0
  327. package/script/helpers/inspectGraphConnectivity.js +58 -0
  328. package/script/helpers/mergeOptions.d.ts +24 -13
  329. package/script/helpers/mergeOptions.d.ts.map +1 -1
  330. package/script/helpers/mergeOptions.js +24 -13
  331. package/script/helpers/parseValue.d.ts +6 -4
  332. package/script/helpers/parseValue.d.ts.map +1 -1
  333. package/script/helpers/parseValue.js +6 -4
  334. package/script/helpers/prepareGraphRouteSql.d.ts +31 -0
  335. package/script/helpers/prepareGraphRouteSql.d.ts.map +1 -0
  336. package/script/helpers/prepareGraphRouteSql.js +127 -0
  337. package/script/helpers/prepareGraphStarts.d.ts +9 -0
  338. package/script/helpers/prepareGraphStarts.d.ts.map +1 -0
  339. package/script/helpers/prepareGraphStarts.js +71 -0
  340. package/script/helpers/prepareGraphTemporalSql.d.ts +28 -0
  341. package/script/helpers/prepareGraphTemporalSql.d.ts.map +1 -0
  342. package/script/helpers/prepareGraphTemporalSql.js +161 -0
  343. package/script/helpers/prepareGraphTraversal.d.ts +19 -0
  344. package/script/helpers/prepareGraphTraversal.d.ts.map +1 -0
  345. package/script/helpers/prepareGraphTraversal.js +87 -0
  346. package/script/helpers/prepareNumericFeatures.d.ts +41 -0
  347. package/script/helpers/prepareNumericFeatures.d.ts.map +1 -0
  348. package/script/helpers/prepareNumericFeatures.js +217 -0
  349. package/script/helpers/prettyDuration.d.ts +14 -8
  350. package/script/helpers/prettyDuration.d.ts.map +1 -1
  351. package/script/helpers/prettyDuration.js +14 -8
  352. package/script/helpers/printTable.d.ts +18 -13
  353. package/script/helpers/printTable.d.ts.map +1 -1
  354. package/script/helpers/printTable.js +18 -13
  355. package/script/helpers/publishPreparedColumns.d.ts +37 -0
  356. package/script/helpers/publishPreparedColumns.d.ts.map +1 -0
  357. package/script/helpers/publishPreparedColumns.js +119 -0
  358. package/script/helpers/queryDB.d.ts +24 -13
  359. package/script/helpers/queryDB.d.ts.map +1 -1
  360. package/script/helpers/queryDB.js +24 -13
  361. package/script/helpers/queueAsyncBarrier.d.ts +12 -7
  362. package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
  363. package/script/helpers/queueAsyncBarrier.js +12 -7
  364. package/script/helpers/queueGraphResult.d.ts +18 -0
  365. package/script/helpers/queueGraphResult.d.ts.map +1 -0
  366. package/script/helpers/queueGraphResult.js +45 -0
  367. package/script/helpers/quoteIdentifier.d.ts +4 -3
  368. package/script/helpers/quoteIdentifier.d.ts.map +1 -1
  369. package/script/helpers/quoteIdentifier.js +4 -3
  370. package/script/helpers/quoteQualifiedIdentifier.d.ts +6 -4
  371. package/script/helpers/quoteQualifiedIdentifier.d.ts.map +1 -1
  372. package/script/helpers/quoteQualifiedIdentifier.js +6 -4
  373. package/script/helpers/runQuery.d.ts.map +1 -1
  374. package/script/helpers/runQuery.js +17 -3
  375. package/script/helpers/selectFuzzyReplacements.d.ts +11 -0
  376. package/script/helpers/selectFuzzyReplacements.d.ts.map +1 -0
  377. package/script/helpers/selectFuzzyReplacements.js +127 -0
  378. package/script/helpers/stabilizeCosineVectors.d.ts +14 -0
  379. package/script/helpers/stabilizeCosineVectors.d.ts.map +1 -0
  380. package/script/helpers/stabilizeCosineVectors.js +40 -0
  381. package/script/helpers/stringToArray.d.ts +4 -3
  382. package/script/helpers/stringToArray.d.ts.map +1 -1
  383. package/script/helpers/stringToArray.js +4 -3
  384. package/script/helpers/updateColumnsWithJS.d.ts +12 -6
  385. package/script/helpers/updateColumnsWithJS.d.ts.map +1 -1
  386. package/script/helpers/updateColumnsWithJS.js +12 -6
  387. package/script/helpers/validateGraphRouteResultSchema.d.ts +4 -0
  388. package/script/helpers/validateGraphRouteResultSchema.d.ts.map +1 -0
  389. package/script/helpers/validateGraphRouteResultSchema.js +19 -0
  390. package/script/helpers/validateGraphTemporalEvents.d.ts +7 -0
  391. package/script/helpers/validateGraphTemporalEvents.d.ts.map +1 -0
  392. package/script/helpers/validateGraphTemporalEvents.js +53 -0
  393. package/script/helpers/validateNumericalAnalysis.d.ts +10 -6
  394. package/script/helpers/validateNumericalAnalysis.d.ts.map +1 -1
  395. package/script/helpers/validateNumericalAnalysis.js +10 -6
  396. package/script/helpers/validateVectorRowIds.d.ts +4 -0
  397. package/script/helpers/validateVectorRowIds.d.ts.map +1 -0
  398. package/script/helpers/validateVectorRowIds.js +19 -0
  399. package/script/helpers/vectorDistanceExpression.d.ts +6 -0
  400. package/script/helpers/vectorDistanceExpression.d.ts.map +1 -0
  401. package/script/helpers/vectorDistanceExpression.js +14 -0
  402. package/script/helpers/wrapString.d.ts +10 -7
  403. package/script/helpers/wrapString.d.ts.map +1 -1
  404. package/script/helpers/wrapString.js +10 -7
  405. package/script/methods/addId.d.ts +5 -0
  406. package/script/methods/addId.d.ts.map +1 -0
  407. package/script/methods/addId.js +44 -0
  408. package/script/methods/commonNeighbors.d.ts +10 -0
  409. package/script/methods/commonNeighbors.d.ts.map +1 -0
  410. package/script/methods/commonNeighbors.js +140 -0
  411. package/script/methods/connectedComponents.d.ts +9 -0
  412. package/script/methods/connectedComponents.d.ts.map +1 -0
  413. package/script/methods/connectedComponents.js +186 -0
  414. package/script/methods/degree.d.ts +9 -0
  415. package/script/methods/degree.d.ts.map +1 -0
  416. package/script/methods/degree.js +141 -0
  417. package/script/methods/distances.d.ts +12 -0
  418. package/script/methods/distances.d.ts.map +1 -0
  419. package/script/methods/distances.js +203 -0
  420. package/script/methods/findCycles.d.ts +12 -0
  421. package/script/methods/findCycles.d.ts.map +1 -0
  422. package/script/methods/findCycles.js +369 -0
  423. package/script/methods/fuzzyClean.d.ts.map +1 -1
  424. package/script/methods/fuzzyClean.js +17 -136
  425. package/script/methods/fuzzyJoin.js +70 -16
  426. package/script/methods/getTypes.d.ts +1 -1
  427. package/script/methods/hdbscan.d.ts +5 -0
  428. package/script/methods/hdbscan.d.ts.map +1 -0
  429. package/script/methods/hdbscan.js +214 -0
  430. package/script/methods/mahalanobis.d.ts +5 -0
  431. package/script/methods/mahalanobis.d.ts.map +1 -0
  432. package/script/methods/mahalanobis.js +98 -0
  433. package/script/methods/neighbors.d.ts +9 -0
  434. package/script/methods/neighbors.d.ts.map +1 -0
  435. package/script/methods/neighbors.js +120 -0
  436. package/script/methods/normalizeVector.d.ts +5 -0
  437. package/script/methods/normalizeVector.d.ts.map +1 -0
  438. package/script/methods/normalizeVector.js +138 -0
  439. package/script/methods/paths.d.ts +12 -0
  440. package/script/methods/paths.d.ts.map +1 -0
  441. package/script/methods/paths.js +326 -0
  442. package/script/methods/reachable.d.ts +11 -0
  443. package/script/methods/reachable.d.ts.map +1 -0
  444. package/script/methods/reachable.js +170 -0
  445. package/script/methods/rowToVector.d.ts +5 -0
  446. package/script/methods/rowToVector.d.ts.map +1 -0
  447. package/script/methods/rowToVector.js +83 -0
  448. package/script/methods/shortestPath.d.ts +12 -0
  449. package/script/methods/shortestPath.d.ts.map +1 -0
  450. package/script/methods/shortestPath.js +376 -0
  451. package/script/methods/topologicalSort.d.ts +7 -0
  452. package/script/methods/topologicalSort.d.ts.map +1 -0
  453. package/script/methods/topologicalSort.js +170 -0
@@ -0,0 +1,330 @@
1
+ import getGraphEdgeIdColumn from "../helpers/getGraphEdgeIdColumn.js";
2
+ import getGraphWeightColumn from "../helpers/getGraphWeightColumn.js";
3
+ import graphRouteResultSchema from "../helpers/graphRouteResultSchema.js";
4
+ import graphRouteResultSelect from "../helpers/graphRouteResultSelect.js";
5
+ import prepareGraphTemporalSql, { prepareGraphTemporalOptions, } from "../helpers/prepareGraphTemporalSql.js";
6
+ import prepareGraphStarts from "../helpers/prepareGraphStarts.js";
7
+ import prepareGraphTraversal, { validateGraphStarts, } from "../helpers/prepareGraphTraversal.js";
8
+ import queueGraphResult from "../helpers/queueGraphResult.js";
9
+ import quoteIdentifier from "../helpers/quoteIdentifier.js";
10
+ import validateGraphTemporalEvents from "../helpers/validateGraphTemporalEvents.js";
11
+ import validateGraphRouteResultSchema from "../helpers/validateGraphRouteResultSchema.js";
12
+ export default function findCycles(simpleTable, sourceColumn, targetColumn, edgeId, startNodes, options = {}) {
13
+ if (typeof sourceColumn !== "string") {
14
+ throw new TypeError("findCycles() sourceColumn must be a string.");
15
+ }
16
+ if (typeof targetColumn !== "string") {
17
+ throw new TypeError("findCycles() targetColumn must be a string.");
18
+ }
19
+ if (typeof edgeId !== "string") {
20
+ throw new TypeError("findCycles() edgeId must be a string.");
21
+ }
22
+ const preparedStarts = prepareGraphStarts(startNodes, "findCycles()", "startNodes");
23
+ if (options === null || typeof options !== "object" || Array.isArray(options)) {
24
+ throw new TypeError("findCycles() options must be an object.");
25
+ }
26
+ if (options.direction !== undefined &&
27
+ !["outgoing", "incoming", "both"].includes(options.direction)) {
28
+ throw new TypeError('findCycles() options.direction must be "outgoing", "incoming", or "both".');
29
+ }
30
+ if (options.weight !== undefined && typeof options.weight !== "string") {
31
+ throw new TypeError("findCycles() options.weight must be a string.");
32
+ }
33
+ if (options.outputTable !== undefined &&
34
+ typeof options.outputTable !== "string" &&
35
+ typeof options.outputTable !== "boolean") {
36
+ throw new TypeError("findCycles() options.outputTable must be a string or boolean.");
37
+ }
38
+ const direction = options.direction ?? "outgoing";
39
+ const temporalOptions = prepareGraphTemporalOptions(options, direction, "findCycles()");
40
+ options = structuredClone(options);
41
+ const parameters = {
42
+ sourceColumn,
43
+ targetColumn,
44
+ edgeId,
45
+ startNodes: structuredClone(startNodes),
46
+ options,
47
+ };
48
+ return queueGraphResult(simpleTable, {
49
+ method: "findCycles()",
50
+ parameters,
51
+ outputTable: options.outputTable,
52
+ preflight: temporalOptions === undefined
53
+ ? undefined
54
+ : (input) => validateGraphTemporalEvents(input, temporalOptions, "findCycles()", parameters),
55
+ values: (schema) => {
56
+ validateFindCyclesInputs(schema, sourceColumn, targetColumn, edgeId, preparedStarts, options.weight);
57
+ const temporal = temporalOptions === undefined
58
+ ? undefined
59
+ : prepareGraphTemporalSql(schema, temporalOptions, "findCycles()");
60
+ return temporal === undefined
61
+ ? preparedStarts.values
62
+ : [temporal.gapParameter, ...preparedStarts.values];
63
+ },
64
+ buildSelect: (input, schema) => findCyclesSelect(input, schema, sourceColumn, targetColumn, edgeId, preparedStarts, direction, options.weight, temporalOptions),
65
+ outputSchema: (schema) => {
66
+ const validated = validateFindCyclesInputs(schema, sourceColumn, targetColumn, edgeId, preparedStarts, options.weight);
67
+ if (temporalOptions !== undefined) {
68
+ prepareGraphTemporalSql(schema, temporalOptions, "findCycles()");
69
+ }
70
+ return {
71
+ start: validated.nodeIdType,
72
+ ...graphRouteResultSchema(schema, validated.distanceType, "findCycles()"),
73
+ };
74
+ },
75
+ });
76
+ }
77
+ function validateFindCyclesInputs(schema, source, target, edgeId, starts, weight) {
78
+ const endpoints = validateGraphStarts(schema, source, target, starts, "findCycles()", "startNodes");
79
+ const edgeIdColumn = getGraphEdgeIdColumn(schema, edgeId, "findCycles()");
80
+ const weightColumn = weight === undefined
81
+ ? undefined
82
+ : getGraphWeightColumn(schema, weight, "findCycles()");
83
+ validateGraphRouteResultSchema(schema, "findCycles()", ["start"]);
84
+ return {
85
+ distanceType: weightColumn?.distanceType ?? "BIGINT",
86
+ edgeIdType: edgeIdColumn.idType,
87
+ nodeIdType: endpoints.idType,
88
+ };
89
+ }
90
+ function findCyclesSelect(input, schema, source, target, edgeId, starts, direction, weight, temporalOptions) {
91
+ const prepared = prepareGraphTraversal(input, schema, source, target, starts, "findCycles()", "startNodes");
92
+ const edgeIdColumn = getGraphEdgeIdColumn(schema, edgeId, "findCycles()");
93
+ const weightColumn = weight === undefined
94
+ ? undefined
95
+ : getGraphWeightColumn(schema, weight, "findCycles()");
96
+ const distanceType = weightColumn?.distanceType ?? "BIGINT";
97
+ const q = quoteIdentifier;
98
+ const edgeIdReference = `${q("edges")}.${q(edgeIdColumn.column)}`;
99
+ const typedEdgeId = `CAST(${edgeIdReference} AS ${edgeIdColumn.idType})`;
100
+ const edgeKey = edgeIdColumn.family === "string"
101
+ ? `ENCODE(${typedEdgeId})`
102
+ : typedEdgeId;
103
+ const edgeWeight = weightColumn === undefined
104
+ ? `CAST(1 AS ${distanceType})`
105
+ : `CAST(${q("edges")}.${q(weightColumn.column)} AS ${distanceType})`;
106
+ const stepType = `STRUCT(${q("edgeId")} ${edgeIdColumn.idType}, ${q("source")} ${prepared.endpoints.idType}, ${q("target")} ${prepared.endpoints.idType}, ${q("weight")} ${distanceType}, ${q("distance")} ${distanceType})`;
107
+ if (temporalOptions !== undefined) {
108
+ const temporal = prepareGraphTemporalSql(schema, temporalOptions, "findCycles()");
109
+ return temporalFindCyclesSelect(prepared, direction, temporal, typedEdgeId, edgeKey, edgeWeight, distanceType, stepType, input, edgeIdColumn);
110
+ }
111
+ const relations = prepared.relationNames([
112
+ "graph_start_values",
113
+ "graph_starts",
114
+ "graph_edges",
115
+ "graph_cycle_walks",
116
+ "graph_complete_cycles",
117
+ "graph_ranked_cycles",
118
+ ]);
119
+ const startValuesRelation = relations.graph_start_values;
120
+ const startsRelation = relations.graph_starts;
121
+ const edgesRelation = relations.graph_edges;
122
+ const walksRelation = relations.graph_cycle_walks;
123
+ const completeRelation = relations.graph_complete_cycles;
124
+ const rankedRelation = relations.graph_ranked_cycles;
125
+ const edgeFrom = `${q("edges")}.${q("__from")}`;
126
+ const edgeTo = `${q("edges")}.${q("__to")}`;
127
+ const edgeFromKey = `${q("edges")}.${q("__from_key")}`;
128
+ const edgeToKey = `${q("edges")}.${q("__to_key")}`;
129
+ const edgeIdentity = `${q("edges")}.${q("__edge_id")}`;
130
+ const edgeIdentityKey = `${q("edges")}.${q("__edge_key")}`;
131
+ const edgeCost = `${q("edges")}.${q("__weight")}`;
132
+ const walkDistance = `${q("walks")}.${q("distance")}`;
133
+ const candidateDistance = `CAST(${walkDistance} + ${edgeCost} AS ${distanceType})`;
134
+ return `WITH RECURSIVE ${startValuesRelation}(${q("start")}) AS (
135
+ VALUES ${prepared.startValues}
136
+ ), ${startsRelation} AS (
137
+ SELECT ${q("start")},
138
+ ${prepared.key(q("start"))} AS ${q("__start_key")}
139
+ FROM ${startValuesRelation}
140
+ ), ${edgesRelation} AS (
141
+ ${prepared.edges(direction, [
142
+ `${typedEdgeId} AS ${q("__edge_id")}`,
143
+ `${edgeKey} AS ${q("__edge_key")}`,
144
+ `${edgeWeight} AS ${q("__weight")}`,
145
+ ])}
146
+ ), ${walksRelation}(
147
+ ${q("start")}, ${q("__start_key")}, ${q("node")},
148
+ ${q("__node_key")}, ${q("__visited")}, ${q("__edge_keys")},
149
+ ${q("steps")}, ${q("distance")}, ${q("closed")}
150
+ ) AS (
151
+ SELECT ${q("starts")}.${q("start")},
152
+ ${q("starts")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
153
+ CASE WHEN ${edgeFromKey} = ${edgeToKey}
154
+ THEN [${edgeFromKey}]
155
+ ELSE [${edgeFromKey}, ${edgeToKey}]
156
+ END,
157
+ [${edgeIdentityKey}],
158
+ [struct_pack(
159
+ ${q("edgeId")} := ${edgeIdentity},
160
+ ${q("source")} := ${edgeFrom},
161
+ ${q("target")} := ${edgeTo},
162
+ ${q("weight")} := ${edgeCost},
163
+ ${q("distance")} := ${edgeCost}
164
+ )]::${stepType}[],
165
+ ${edgeCost}, ${edgeFromKey} = ${edgeToKey}
166
+ FROM ${edgesRelation} AS ${q("edges")}
167
+ INNER JOIN ${startsRelation} AS ${q("starts")}
168
+ ON ${q("starts")}.${q("__start_key")} = ${edgeFromKey}
169
+ UNION ALL
170
+ SELECT ${q("walks")}.${q("start")},
171
+ ${q("walks")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
172
+ list_append(${q("walks")}.${q("__visited")}, ${edgeToKey}),
173
+ list_append(${q("walks")}.${q("__edge_keys")}, ${edgeIdentityKey}),
174
+ list_append(${q("walks")}.${q("steps")}, struct_pack(
175
+ ${q("edgeId")} := ${edgeIdentity},
176
+ ${q("source")} := ${edgeFrom},
177
+ ${q("target")} := ${edgeTo},
178
+ ${q("weight")} := ${edgeCost},
179
+ ${q("distance")} := ${candidateDistance}
180
+ )), ${candidateDistance},
181
+ ${edgeToKey} = ${q("walks")}.${q("__start_key")}
182
+ FROM ${walksRelation} AS ${q("walks")}
183
+ INNER JOIN ${edgesRelation} AS ${q("edges")}
184
+ ON ${q("walks")}.${q("__node_key")} = ${edgeFromKey}
185
+ WHERE NOT ${q("walks")}.${q("closed")}
186
+ AND NOT list_contains(
187
+ ${q("walks")}.${q("__edge_keys")}, ${edgeIdentityKey}
188
+ )
189
+ AND (
190
+ ${edgeToKey} = ${q("walks")}.${q("__start_key")}
191
+ OR NOT list_contains(
192
+ ${q("walks")}.${q("__visited")}, ${edgeToKey}
193
+ )
194
+ )
195
+ ), ${completeRelation} AS (
196
+ SELECT DISTINCT ${q("start")}, ${q("__start_key")},
197
+ ${q("__edge_keys")}, ${q("steps")}
198
+ FROM ${walksRelation}
199
+ WHERE ${q("closed")}${direction === "both"
200
+ ? `
201
+ AND ${q("__edge_keys")} <= list_reverse(${q("__edge_keys")})`
202
+ : ""}
203
+ ), ${rankedRelation} AS (
204
+ SELECT ${q("start")}, ${q("__start_key")},
205
+ CAST(row_number() OVER (
206
+ PARTITION BY ${q("__start_key")}
207
+ ORDER BY ${q("__edge_keys")}) - 1
208
+ AS BIGINT) AS ${q("pathId")}, ${q("steps")}
209
+ FROM ${completeRelation}
210
+ )
211
+ ${graphRouteResultSelect(rankedRelation, input, edgeIdColumn, true)}`;
212
+ }
213
+ function temporalFindCyclesSelect(prepared, direction, temporal, typedEdgeId, edgeKey, edgeWeight, distanceType, stepType, input, edgeIdColumn) {
214
+ const q = quoteIdentifier;
215
+ const relations = prepared.relationNames([
216
+ "graph_start_values",
217
+ "graph_starts",
218
+ "graph_temporal_settings",
219
+ "graph_event_rows",
220
+ "graph_edges",
221
+ "graph_cycle_walks",
222
+ "graph_complete_cycles",
223
+ "graph_ranked_cycles",
224
+ ]);
225
+ const startValuesRelation = relations.graph_start_values;
226
+ const startsRelation = relations.graph_starts;
227
+ const settingsRelation = relations.graph_temporal_settings;
228
+ const eventRowsRelation = relations.graph_event_rows;
229
+ const edgesRelation = relations.graph_edges;
230
+ const walksRelation = relations.graph_cycle_walks;
231
+ const completeRelation = relations.graph_complete_cycles;
232
+ const rankedRelation = relations.graph_ranked_cycles;
233
+ const edgeFrom = `${q("edges")}.${q("__from")}`;
234
+ const edgeTo = `${q("edges")}.${q("__to")}`;
235
+ const edgeFromKey = `${q("edges")}.${q("__from_key")}`;
236
+ const edgeToKey = `${q("edges")}.${q("__to_key")}`;
237
+ const edgeIdentity = `${q("edges")}.${q("__edge_id")}`;
238
+ const edgeIdentityKey = `${q("edges")}.${q("__edge_key")}`;
239
+ const edgeCost = `${q("edges")}.${q("__weight")}`;
240
+ const walkDistance = `${q("walks")}.${q("distance")}`;
241
+ const candidateDistance = `CAST(${walkDistance} + ${edgeCost} AS ${distanceType})`;
242
+ const gap = `${q("settings")}.${q("__gap")}`;
243
+ const step = (distance) => `struct_pack(
244
+ ${q("edgeId")} := ${edgeIdentity},
245
+ ${q("source")} := ${edgeFrom},
246
+ ${q("target")} := ${edgeTo},
247
+ ${q("weight")} := ${edgeCost},
248
+ ${q("distance")} := ${distance}
249
+ )`;
250
+ return `WITH RECURSIVE ${settingsRelation} AS MATERIALIZED (
251
+ SELECT CAST(? AS HUGEINT) AS ${q("__gap")}
252
+ ), ${startValuesRelation}(${q("start")}) AS (
253
+ VALUES ${prepared.startValues}
254
+ ), ${startsRelation} AS (
255
+ SELECT ${q("start")},
256
+ ${prepared.key(q("start"))} AS ${q("__start_key")}
257
+ FROM ${startValuesRelation}
258
+ ), ${eventRowsRelation} AS MATERIALIZED (
259
+ ${prepared.edges(direction, [
260
+ `${typedEdgeId} AS ${q("__edge_id")}`,
261
+ `${edgeKey} AS ${q("__edge_key")}`,
262
+ `${edgeWeight} AS ${q("__weight")}`,
263
+ ...temporal.eventSelections("edges"),
264
+ ])}
265
+ ), ${edgesRelation} AS MATERIALIZED (
266
+ SELECT *
267
+ FROM ${eventRowsRelation} AS ${q("events")}
268
+ WHERE ${temporal.eventValidity("events")}
269
+ ), ${walksRelation}(
270
+ ${q("start")}, ${q("__start_key")}, ${q("node")},
271
+ ${q("__node_key")}, ${q("__visited")}, ${q("__event_ids")},
272
+ ${q("__edge_keys")}, ${q("steps")}, ${q("distance")},
273
+ ${q("closed")}, ${q("__event_id")}, ${q("__event_start")},
274
+ ${q("__event_end")}
275
+ ) AS (
276
+ SELECT ${q("starts")}.${q("start")},
277
+ ${q("starts")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
278
+ CASE WHEN ${edgeFromKey} = ${edgeToKey}
279
+ THEN [${edgeFromKey}]
280
+ ELSE [${edgeFromKey}, ${edgeToKey}]
281
+ END,
282
+ [${q("edges")}.${q("__event_id")}], [${edgeIdentityKey}],
283
+ [${step(edgeCost)}]::${stepType}[], ${edgeCost},
284
+ ${edgeFromKey} = ${edgeToKey},
285
+ ${q("edges")}.${q("__event_id")},
286
+ ${q("edges")}.${q("__event_start")},
287
+ ${q("edges")}.${q("__event_end")}
288
+ FROM ${edgesRelation} AS ${q("edges")}
289
+ INNER JOIN ${startsRelation} AS ${q("starts")}
290
+ ON ${q("starts")}.${q("__start_key")} = ${edgeFromKey}
291
+ UNION ALL
292
+ SELECT ${q("walks")}.${q("start")},
293
+ ${q("walks")}.${q("__start_key")}, ${edgeTo}, ${edgeToKey},
294
+ list_append(${q("walks")}.${q("__visited")}, ${edgeToKey}),
295
+ list_append(${q("walks")}.${q("__event_ids")},
296
+ ${q("edges")}.${q("__event_id")}),
297
+ list_append(${q("walks")}.${q("__edge_keys")}, ${edgeIdentityKey}),
298
+ list_append(${q("walks")}.${q("steps")}, ${step(candidateDistance)}),
299
+ ${candidateDistance},
300
+ ${edgeToKey} = ${q("walks")}.${q("__start_key")},
301
+ ${q("edges")}.${q("__event_id")},
302
+ ${q("edges")}.${q("__event_start")},
303
+ ${q("edges")}.${q("__event_end")}
304
+ FROM ${walksRelation} AS ${q("walks")}
305
+ INNER JOIN ${edgesRelation} AS ${q("edges")}
306
+ ON ${q("walks")}.${q("__node_key")} = ${edgeFromKey}
307
+ CROSS JOIN ${settingsRelation} AS ${q("settings")}
308
+ WHERE NOT ${q("walks")}.${q("closed")}
309
+ AND NOT list_contains(${q("walks")}.${q("__event_ids")},
310
+ ${q("edges")}.${q("__event_id")})
311
+ AND (
312
+ ${edgeToKey} = ${q("walks")}.${q("__start_key")}
313
+ OR NOT list_contains(${q("walks")}.${q("__visited")}, ${edgeToKey})
314
+ )
315
+ AND ${temporal.transition("walks", "edges", direction, gap)}
316
+ ), ${completeRelation} AS (
317
+ SELECT DISTINCT ${q("start")}, ${q("__start_key")},
318
+ ${q("__edge_keys")}, ${q("steps")}
319
+ FROM ${walksRelation}
320
+ WHERE ${q("closed")}
321
+ ), ${rankedRelation} AS (
322
+ SELECT ${q("start")}, ${q("__start_key")},
323
+ CAST(row_number() OVER (
324
+ PARTITION BY ${q("__start_key")}
325
+ ORDER BY ${q("__edge_keys")}) - 1
326
+ AS BIGINT) AS ${q("pathId")}, ${q("steps")}
327
+ FROM ${completeRelation}
328
+ )
329
+ ${graphRouteResultSelect(rankedRelation, input, edgeIdColumn, true)}`;
330
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"fuzzyClean.d.ts","sourceRoot":"","sources":["../../src/methods/fuzzyClean.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAMvD,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,MAAM,CAAC,EACH,OAAO,GACP,eAAe,GACf,kBAAkB,GAClB,iBAAiB,CAAC;IACtB,QAAQ,CAAC,EACL,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,UAAU,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACL,IAAI,CAYN"}
1
+ {"version":3,"file":"fuzzyClean.d.ts","sourceRoot":"","sources":["../../src/methods/fuzzyClean.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AASvD,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,MAAM,CAAC,EACH,OAAO,GACP,eAAe,GACf,kBAAkB,GAClB,iBAAiB,CAAC;IACtB,QAAQ,CAAC,EACL,YAAY,GACZ,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,UAAU,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC3B,GACL,IAAI,CAWN"}
@@ -1,12 +1,13 @@
1
1
  import quoteIdentifier from "../helpers/quoteIdentifier.js";
2
+ import { DuckDBListValue } from "@duckdb/node-api";
2
3
  import mergeOptions from "../helpers/mergeOptions.js";
3
4
  import queryDB from "../helpers/queryDB.js";
4
5
  import queueOp from "../helpers/queueOp.js";
5
6
  import buildFuzzyMatchSql from "../helpers/buildFuzzyMatchSql.js";
7
+ import selectFuzzyReplacements from "../helpers/selectFuzzyReplacements.js";
6
8
  export default function fuzzyClean(table, column, newColumn, threshold, options = {}) {
7
- // The clustering runs in JS over the fuzzy pairs read from the table, so
8
- // fuzzyClean can't be expressed as a single SELECT over its input: it
9
- // executes as a barrier.
9
+ // This implementation clusters fuzzy pairs in JS and writes the mapping
10
+ // back to DuckDB, so it executes as a barrier.
10
11
  options = structuredClone(options);
11
12
  queueOp(table, {
12
13
  kind: "barrier",
@@ -57,149 +58,29 @@ async function executeFuzzyClean(table, column, newColumn, threshold, options =
57
58
  }
58
59
  return;
59
60
  }
60
- // Build count map from the pairs — no separate query needed.
61
- const countMap = new Map();
62
- for (const { left_value, left_cnt, right_value, right_cnt } of pairs) {
63
- countMap.set(left_value, Number(left_cnt));
64
- countMap.set(right_value, Number(right_cnt));
65
- }
66
- // Union-Find — only over values that actually participate in a pair.
67
- const parent = new Map();
68
- const find = (x) => {
69
- if (!parent.has(x))
70
- parent.set(x, x);
71
- if (parent.get(x) !== x)
72
- parent.set(x, find(parent.get(x)));
73
- return parent.get(x);
74
- };
75
- const union = (a, b) => {
76
- const ra = find(a);
77
- const rb = find(b);
78
- if (ra !== rb)
79
- parent.set(ra, rb);
80
- };
81
- for (const v of countMap.keys())
82
- find(v);
83
- for (const { left_value, right_value } of pairs) {
84
- union(left_value, right_value);
85
- }
86
- // Group values by their cluster root.
87
- const clusters = new Map();
88
- for (const v of countMap.keys()) {
89
- const root = find(v);
90
- if (!clusters.has(root))
91
- clusters.set(root, []);
92
- clusters.get(root).push(v);
93
- }
94
- // Pick the canonical value for each cluster.
95
- const replacement = new Map();
96
- for (const members of clusters.values()) {
97
- if (members.length === 1)
98
- continue; // All pairs are already canonical — skip.
99
- // Score sums and per-member max scores are computed lazily — only when
100
- // actually needed as a primary criterion or tie-breaker.
101
- //
102
- // scoreSum: total similarity to all other cluster members (used by
103
- // "mostCentral" as primary, and as tie-breaker for all strategies).
104
- // scoreMax: highest single pairwise score (used by "maxScore" as primary).
105
- let scoreSum = null;
106
- const getScoreSum = () => {
107
- if (scoreSum === null) {
108
- scoreSum = new Map(members.map((m) => [m, 0]));
109
- for (const { left_value, right_value, score } of pairs) {
110
- if (scoreSum.has(left_value) && scoreSum.has(right_value)) {
111
- scoreSum.set(left_value, (scoreSum.get(left_value) ?? 0) + score);
112
- scoreSum.set(right_value, (scoreSum.get(right_value) ?? 0) + score);
113
- }
114
- }
115
- }
116
- return scoreSum;
117
- };
118
- let scoreMax = null;
119
- const getScoreMax = () => {
120
- if (scoreMax === null) {
121
- scoreMax = new Map(members.map((m) => [m, 0]));
122
- for (const { left_value, right_value, score } of pairs) {
123
- if (scoreMax.has(left_value) && scoreMax.has(right_value)) {
124
- scoreMax.set(left_value, Math.max(scoreMax.get(left_value) ?? 0, score));
125
- scoreMax.set(right_value, Math.max(scoreMax.get(right_value) ?? 0, score));
126
- }
127
- }
128
- }
129
- return scoreMax;
130
- };
131
- // Sum-based comparator: highest total similarity, then alphabetical.
132
- const byScore = (a, b) => {
133
- const sum = getScoreSum();
134
- const sa = sum.get(a) ?? 0;
135
- const sb = sum.get(b) ?? 0;
136
- if (sa !== sb)
137
- return sa > sb ? a : b;
138
- return a <= b ? a : b; // alphabetical tie-break
139
- };
140
- // Max-based comparator: highest single-pair score, then sum, then alphabetical.
141
- const byMaxScore = (a, b) => {
142
- const mx = getScoreMax();
143
- const ma = mx.get(a) ?? 0;
144
- const mb = mx.get(b) ?? 0;
145
- if (ma !== mb)
146
- return ma > mb ? a : b;
147
- return byScore(a, b); // sum then alphabetical tie-break
148
- };
149
- let canonical;
150
- if (strategy === "longestString") {
151
- canonical = members.reduce((a, b) => {
152
- if (a.length !== b.length)
153
- return a.length > b.length ? a : b;
154
- return byScore(a, b);
155
- });
156
- }
157
- else if (strategy === "shortestString") {
158
- canonical = members.reduce((a, b) => {
159
- if (a.length !== b.length)
160
- return a.length < b.length ? a : b;
161
- return byScore(a, b);
162
- });
163
- }
164
- else if (strategy === "mostCommon") {
165
- canonical = members.reduce((a, b) => {
166
- const ca = countMap.get(a) ?? 0;
167
- const cb = countMap.get(b) ?? 0;
168
- if (ca !== cb)
169
- return ca > cb ? a : b;
170
- return byScore(a, b);
171
- });
172
- }
173
- else if (strategy === "mostCentral") {
174
- // Most central string — highest total similarity to all other cluster members.
175
- canonical = members.reduce((a, b) => byScore(a, b));
176
- }
177
- else {
178
- // "maxScore": the string participating in the single highest-scoring pair.
179
- canonical = members.reduce((a, b) => byMaxScore(a, b));
180
- }
181
- for (const m of members) {
182
- if (m !== canonical)
183
- replacement.set(m, canonical);
184
- }
185
- }
61
+ const replacement = selectFuzzyReplacements(pairs, strategy);
186
62
  if (replacement.size === 0)
187
63
  return;
188
- // Use a VALUES-based CTE for the UPDATE so DuckDB can use a hash join
189
- // instead of evaluating a potentially huge CASE WHEN expression.
190
- const replacementEntries = [...replacement.entries()];
191
- const valuesList = replacementEntries.map(() => "(?, ?)").join(",\n ");
192
- const values = replacementEntries.flatMap(([from, to]) => [from, to]);
64
+ // Two bound lists keep the SQL and parameter count fixed as the mapping
65
+ // grows. Side-by-side UNNEST zips the equally sized lists into mapping rows,
66
+ // which DuckDB can hash-join to the original table.
67
+ const values = [
68
+ new DuckDBListValue([...replacement.keys()]),
69
+ new DuckDBListValue([...replacement.values()]),
70
+ ];
71
+ const mapping = `WITH mapping(original, canonical) AS (
72
+ SELECT UNNEST(?::VARCHAR[]), UNNEST(?::VARCHAR[])
73
+ )`;
193
74
  const query = newColumn !== column
194
75
  ? `ALTER TABLE ${quoteIdentifier(table.name)} ADD ${quoteIdentifier(newColumn)} VARCHAR;
195
76
  UPDATE ${quoteIdentifier(table.name)}
196
77
  SET ${quoteIdentifier(newColumn)} = ${quoteIdentifier(column)};
197
- WITH mapping(original, canonical) AS (VALUES ${valuesList})
78
+ ${mapping}
198
79
  UPDATE ${quoteIdentifier(table.name)}
199
80
  SET ${quoteIdentifier(newColumn)} = m.canonical
200
81
  FROM mapping m
201
82
  WHERE ${quoteIdentifier(table.name)}.${quoteIdentifier(newColumn)} = m.original`
202
- : `WITH mapping(original, canonical) AS (VALUES ${valuesList})
83
+ : `${mapping}
203
84
  UPDATE ${quoteIdentifier(table.name)}
204
85
  SET ${quoteIdentifier(column)} = m.canonical
205
86
  FROM mapping m
@@ -48,17 +48,7 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
48
48
  }
49
49
  const method = options.method ?? "ratio";
50
50
  const similarityColumn = options.similarityColumn;
51
- // The right table's copy of a column shared with the left table (only
52
- // rightColumn can be shared, checked above) is excluded from the SELECT
53
- // directly, instead of dropping its _1 duplicate with a rewrite after the
54
- // join.
55
- const rightSelect = rightCols
56
- .filter((d) => !leftCols.includes(d))
57
- .map((d) => `${quoteIdentifier(rightTable.name)}.${quoteIdentifier(d)}`)
58
- .join(", ");
59
- const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
60
- fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength);
61
- await queryDB(leftTable, sql, mergeOptions(leftTable, {
51
+ const queryOptions = mergeOptions(leftTable, {
62
52
  table: outputTable.name,
63
53
  method: "fuzzyJoin()",
64
54
  parameters: {
@@ -68,26 +58,90 @@ async function executeFuzzyJoin(leftTable, rightTable, outputTable, leftColumn,
68
58
  threshold,
69
59
  options,
70
60
  },
71
- }));
61
+ });
62
+ const deduplicate = await shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions);
63
+ // The right table's copy of a column shared with the left table (only
64
+ // rightColumn can be shared, checked above) is excluded from the SELECT
65
+ // directly, instead of dropping its _1 duplicate with a rewrite after the
66
+ // join.
67
+ const rightSelect = rightCols
68
+ .filter((d) => !leftCols.includes(d))
69
+ .map((d) => `${quoteIdentifier(rightTable.name)}.${quoteIdentifier(d)}`)
70
+ .join(", ");
71
+ const sql = `INSTALL rapidfuzz FROM community; LOAD rapidfuzz;\n` +
72
+ fuzzyJoinQuery(leftTable.name, leftColumn, rightTable.name, rightColumn, method, threshold, outputTable.name, similarityColumn, rightSelect, options.prefilterPrefixLength, deduplicate);
73
+ await queryDB(leftTable, sql, queryOptions);
72
74
  }
73
- function fuzzyJoinQuery(leftTable, leftColumn, rightTable, rightColumn, method, threshold, outputTable, similarityColumn, rightSelect, prefilterPrefixLength) {
75
+ async function shouldDeduplicateFuzzyJoin(leftTable, rightTable, leftColumn, rightColumn, queryOptions) {
76
+ const left = quoteIdentifier(leftTable.name);
77
+ const right = quoteIdentifier(rightTable.name);
78
+ const counts = (await queryDB(leftTable, `SELECT (SELECT COUNT(*) FROM ${left}) AS left_count,
79
+ (SELECT COUNT(*) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
80
+ const leftCount = Number(counts.left_count);
81
+ const rightCount = Number(counts.right_count);
82
+ const comparisons = leftCount * rightCount;
83
+ // Avoid distinct scans for small joins and short lookup tables. For larger
84
+ // joins, require at least a twofold reduction to pay for grouping and rejoining.
85
+ if (comparisons < 100_000 || Math.min(leftCount, rightCount) < 32) {
86
+ return false;
87
+ }
88
+ const distinct = (await queryDB(leftTable, `SELECT
89
+ (SELECT COUNT(DISTINCT ENCODE(${quoteIdentifier(leftColumn)})) FROM ${left}) AS left_count,
90
+ (SELECT COUNT(DISTINCT ENCODE(${quoteIdentifier(rightColumn)})) FROM ${right}) AS right_count`, { ...queryOptions, returnData: true }))[0];
91
+ return Number(distinct.left_count) * Number(distinct.right_count) <=
92
+ comparisons / 2;
93
+ }
94
+ function fuzzyJoinQuery(leftTable, leftColumn, rightTable, rightColumn, method, threshold, outputTable, similarityColumn, rightSelect, prefilterPrefixLength, deduplicate = false) {
74
95
  const leftExpression = `${quoteIdentifier(leftTable)}.${quoteIdentifier(leftColumn)}`;
75
96
  const rightExpression = `${quoteIdentifier(rightTable)}.${quoteIdentifier(rightColumn)}`;
76
97
  const { scoreExpression, condition } = buildFuzzyMatchSql(leftExpression, rightExpression, method, threshold, { decimals: 2, prefilterPrefixLength });
98
+ let cte = "";
99
+ let from = `FROM ${quoteIdentifier(leftTable)} LEFT JOIN ${quoteIdentifier(rightTable)} ON ${condition}`;
100
+ let score = scoreExpression;
101
+ if (deduplicate) {
102
+ const matches = quoteIdentifier(`__sda_fuzzy_matches_${crypto.randomUUID().replaceAll("-", "")}`);
103
+ const match = buildFuzzyMatchSql("l.value", "r.value", method, threshold, { decimals: 2, prefilterPrefixLength });
104
+ // Keep the original value's collation for prefix matching, but use byte
105
+ // keys for deduplication and expansion: fuzzy scores distinguish case even
106
+ // when an input column has a case-insensitive collation.
107
+ cte = `WITH ${matches} AS MATERIALIZED (
108
+ SELECT l.key AS left_key, r.key AS right_key,
109
+ ${match.scoreExpression} AS score
110
+ FROM (
111
+ SELECT DISTINCT ${quoteIdentifier(leftColumn)} AS value,
112
+ ENCODE(${quoteIdentifier(leftColumn)}) AS key
113
+ FROM ${quoteIdentifier(leftTable)}
114
+ WHERE ${quoteIdentifier(leftColumn)} IS NOT NULL
115
+ ) l
116
+ INNER JOIN (
117
+ SELECT DISTINCT ${quoteIdentifier(rightColumn)} AS value,
118
+ ENCODE(${quoteIdentifier(rightColumn)}) AS key
119
+ FROM ${quoteIdentifier(rightTable)}
120
+ WHERE ${quoteIdentifier(rightColumn)} IS NOT NULL
121
+ ) r ON ${match.condition}
122
+ )`;
123
+ from = `FROM ${quoteIdentifier(leftTable)}
124
+ LEFT JOIN ${matches} ON ENCODE(${leftExpression}) = ${matches}.left_key
125
+ LEFT JOIN ${quoteIdentifier(rightTable)}
126
+ ON ENCODE(${rightExpression}) = ${matches}.right_key`;
127
+ score = `${matches}.score`;
128
+ }
77
129
  if (similarityColumn) {
78
130
  return `CREATE OR REPLACE TABLE ${quoteIdentifier(outputTable)} AS
131
+ ${cte}
79
132
  SELECT * EXCLUDE ("_sda_score"), "_sda_score" AS ${quoteIdentifier(similarityColumn)}
80
133
  FROM (
81
- SELECT ${quoteIdentifier(leftTable)}.*, ${rightSelect}, ${scoreExpression} AS "_sda_score"
82
- FROM ${quoteIdentifier(leftTable)} LEFT JOIN ${quoteIdentifier(rightTable)} ON ${condition}
134
+ SELECT ${quoteIdentifier(leftTable)}.*, ${rightSelect}, ${score} AS "_sda_score"
135
+ ${from}
83
136
  ) _sda
84
137
  ORDER BY ${quoteIdentifier(leftColumn)}, "_sda_score" DESC;\n`;
85
138
  }
86
139
  return `CREATE OR REPLACE TABLE ${quoteIdentifier(outputTable)} AS
140
+ ${cte}
87
141
  SELECT *
88
142
  FROM (
89
143
  SELECT ${quoteIdentifier(leftTable)}.*, ${rightSelect}
90
- FROM ${quoteIdentifier(leftTable)} LEFT JOIN ${quoteIdentifier(rightTable)} ON ${condition}
144
+ ${from}
91
145
  ) _sda
92
146
  ORDER BY ${quoteIdentifier(leftColumn)}, ${quoteIdentifier(rightColumn)};\n`;
93
147
  }
@@ -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"}