pure-js-db 0.0.0-stage → 2.53.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 (541) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +747 -3
  3. package/bindings/java/pom.xml +18 -0
  4. package/bindings/java/src/main/java/purejsdb/PureJsDBClient.java +146 -0
  5. package/bindings/java/src/main/java/purejsdb/TransactionClient.java +65 -0
  6. package/bindings/java/src/test/java/TestClient.java +68 -0
  7. package/bindings/orm/sequelize-adapter.js +1236 -0
  8. package/bindings/python/purejsdb/client.py +81 -0
  9. package/bindings/python/setup.py +9 -0
  10. package/bindings/python/test_client.py +63 -0
  11. package/config/datagrip-config.md +206 -0
  12. package/config/grafana-dashboard.json +1510 -0
  13. package/config/production.config.js +126 -0
  14. package/config/prometheus-scrape.yml +39 -0
  15. package/native/index.node +0 -0
  16. package/package.json +205 -6
  17. package/scripts/mcp-server.mjs +208 -0
  18. package/src/adapter/dialect-adapter.js +179 -0
  19. package/src/adapter/oracle-adapter.js +191 -0
  20. package/src/ai/ai-service.js +713 -0
  21. package/src/ai/rag-pipeline.js +160 -0
  22. package/src/alerting/alert-manager.js +622 -0
  23. package/src/alerting/index.js +10 -0
  24. package/src/arrow/arrow-ipc.js +973 -0
  25. package/src/arrow/flatbuffer.js +521 -0
  26. package/src/arrow/index.js +261 -0
  27. package/src/arrow/parquet.js +1525 -0
  28. package/src/audit/audit-log.js +1345 -0
  29. package/src/audit/audit-report.js +571 -0
  30. package/src/audit/index.js +6 -0
  31. package/src/backpressure/backpressure-controller.js +262 -0
  32. package/src/backpressure/index.js +6 -0
  33. package/src/backpressure/write-rate-limiter.js +243 -0
  34. package/src/backup/backup-manager.js +416 -0
  35. package/src/backup/index.js +8 -0
  36. package/src/backup/logical-backup.js +228 -0
  37. package/src/backup/snapshot.js +111 -0
  38. package/src/backup/toolkit.js +410 -0
  39. package/src/bindings/orm/prisma-adapter.js +571 -0
  40. package/src/bindings/orm/typeorm-adapter.js +477 -0
  41. package/src/cache/adaptive-cache-size.js +288 -0
  42. package/src/cache/adaptive-ttl.js +139 -0
  43. package/src/cache/cache-adapter.js +304 -0
  44. package/src/cache/circuit-breaker.js +294 -0
  45. package/src/cache/index.js +31 -0
  46. package/src/cache/lru-cache.js +353 -0
  47. package/src/cache/redis-adapter.js +391 -0
  48. package/src/cache/resilient-adapter.js +391 -0
  49. package/src/cache/result-cache.js +493 -0
  50. package/src/cache/semantic-cache.js +339 -0
  51. package/src/cdc/cdc-engine.js +1061 -0
  52. package/src/cdc/cdc-handlers.js +289 -0
  53. package/src/cdc/ddl-capture.js +330 -0
  54. package/src/cdc/debezium-adapter.js +366 -0
  55. package/src/cdc/schema-history.js +414 -0
  56. package/src/changelog/changelog-buffer.js +881 -0
  57. package/src/changelog/changelog-wal.js +299 -0
  58. package/src/changelog/linear-regression-predictor.js +186 -0
  59. package/src/changelog/predictive-growth.js +348 -0
  60. package/src/changelog/seasonal-predictor.js +450 -0
  61. package/src/changelog/write-rate-sampler.js +141 -0
  62. package/src/cli/dump-command.js +944 -0
  63. package/src/cli/interactive.js +188 -0
  64. package/src/cli/migrate-command.js +252 -0
  65. package/src/cli.js +533 -0
  66. package/src/cluster/failover.js +477 -0
  67. package/src/cluster/index.js +19 -0
  68. package/src/cluster/persistent-state.js +203 -0
  69. package/src/cluster/public-api.js +58 -0
  70. package/src/cluster/raft-http-transport.js +280 -0
  71. package/src/cluster/raft-log.js +313 -0
  72. package/src/cluster/raft.js +912 -0
  73. package/src/cluster/snapshot-persistence.js +131 -0
  74. package/src/concurrency/async-mutex.js +365 -0
  75. package/src/concurrency/circuit-breaker.js +326 -0
  76. package/src/concurrency/connection-pool.js +409 -0
  77. package/src/concurrency/connection-session.js +498 -0
  78. package/src/concurrency/index.js +29 -0
  79. package/src/concurrency/lock-manager.js +363 -0
  80. package/src/concurrency/lockfree-executor.js +322 -0
  81. package/src/concurrency/lockfree-manager.js +570 -0
  82. package/src/concurrency/mvcc.js +499 -0
  83. package/src/concurrency/occ-hot-row.js +726 -0
  84. package/src/concurrency/query-degradation.js +380 -0
  85. package/src/concurrency/query-isolation.js +374 -0
  86. package/src/concurrency/shared-memory-pool.js +459 -0
  87. package/src/concurrency/snapshot-buffer.js +461 -0
  88. package/src/concurrency/transaction-context.js +193 -0
  89. package/src/copy/copy-stream.js +643 -0
  90. package/src/copy/index.js +5 -0
  91. package/src/core/database.js +1947 -0
  92. package/src/core/index.js +13 -0
  93. package/src/daemon/compact-daemon.js +535 -0
  94. package/src/daemon/index.js +14 -0
  95. package/src/daemon/soa-daemon-integration.js +333 -0
  96. package/src/ddl/online-ddl.js +348 -0
  97. package/src/disruptor/disruptor.js +348 -0
  98. package/src/disruptor/event-bus.js +238 -0
  99. package/src/disruptor/event-pool.js +62 -0
  100. package/src/disruptor/index.js +31 -0
  101. package/src/disruptor/ring-buffer.js +150 -0
  102. package/src/disruptor/sequence.js +88 -0
  103. package/src/disruptor/wait-strategy.js +160 -0
  104. package/src/engine/public-api.js +210 -0
  105. package/src/executor/asof-join-executor.js +265 -0
  106. package/src/executor/bitmap-filter.js +1382 -0
  107. package/src/executor/compiled-expression.js +472 -0
  108. package/src/executor/compiled-predicate.js +458 -0
  109. package/src/executor/constraint-executor.js +577 -0
  110. package/src/executor/copy-executor.js +210 -0
  111. package/src/executor/cte/recursive-cte.js +89 -0
  112. package/src/executor/cte-executor.js +501 -0
  113. package/src/executor/cursor-executor.js +216 -0
  114. package/src/executor/database.js +41 -0
  115. package/src/executor/ddl-executor.js +3531 -0
  116. package/src/executor/dml-executor.js +3557 -0
  117. package/src/executor/executor-worker.js +331 -0
  118. package/src/executor/executor.js +10889 -0
  119. package/src/executor/explain-analyzer.js +422 -0
  120. package/src/executor/explain-executor.js +324 -0
  121. package/src/executor/expression.js +4972 -0
  122. package/src/executor/foreign-key-executor.js +691 -0
  123. package/src/executor/graph-table-executor.js +451 -0
  124. package/src/executor/grouping-executor.js +251 -0
  125. package/src/executor/hotpath.js +232 -0
  126. package/src/executor/hybrid-search-executor.js +326 -0
  127. package/src/executor/incremental-live-query.js +866 -0
  128. package/src/executor/index-maintenance-executor.js +731 -0
  129. package/src/executor/index.js +16 -0
  130. package/src/executor/info-schema-executor.js +123 -0
  131. package/src/executor/join/lateral-join.js +64 -0
  132. package/src/executor/join-executor.js +530 -0
  133. package/src/executor/lineage-executor.js +85 -0
  134. package/src/executor/live-query-manager.js +350 -0
  135. package/src/executor/loop-unroll.js +539 -0
  136. package/src/executor/match-recognize-executor.js +918 -0
  137. package/src/executor/multi-stream-wal.js +140 -0
  138. package/src/executor/nl2sql-executor.js +309 -0
  139. package/src/executor/parallel-dml.js +258 -0
  140. package/src/executor/pivot-executor.js +458 -0
  141. package/src/executor/pragma-executor.js +661 -0
  142. package/src/executor/select-executor.js +857 -0
  143. package/src/executor/sequence.js +139 -0
  144. package/src/executor/sql-reconstructor.js +296 -0
  145. package/src/executor/subquery-cache.js +186 -0
  146. package/src/executor/subquery-executor.js +1390 -0
  147. package/src/executor/system-catalog.js +731 -0
  148. package/src/executor/table-function-executor.js +656 -0
  149. package/src/executor/topn.js +103 -0
  150. package/src/executor/transaction-executor.js +926 -0
  151. package/src/executor/trigger-executor.js +441 -0
  152. package/src/executor/v8-turbofan-optimizer.js +363 -0
  153. package/src/executor/vector-acceleration.js +456 -0
  154. package/src/executor/vector-executor.js +847 -0
  155. package/src/executor/vectorized-columnar-engine.js +1130 -0
  156. package/src/executor/vectorized-executor-v2.js +993 -0
  157. package/src/executor/view-executor.js +149 -0
  158. package/src/executor/wal.js +1945 -0
  159. package/src/executor/wasm-simd-engine.js +929 -0
  160. package/src/executor/window-functions.js +894 -0
  161. package/src/fdw/fdw-manager.js +642 -0
  162. package/src/fdw/index.js +5 -0
  163. package/src/geo/geometry.js +447 -0
  164. package/src/geo/index.js +16 -0
  165. package/src/geo/spatial-functions.js +1241 -0
  166. package/src/graph/graph-helper.js +243 -0
  167. package/src/graph/pgq-matcher.js +2545 -0
  168. package/src/graph/property-graph.js +123 -0
  169. package/src/graphql-bridge.js +881 -0
  170. package/src/hotspot/access-tracker.js +188 -0
  171. package/src/hotspot/hotspot-detector.js +140 -0
  172. package/src/hotspot/hotspot-prefetcher.js +210 -0
  173. package/src/hotspot/index.js +7 -0
  174. package/src/http-api.js +1182 -0
  175. package/src/http-server/handlers/audit.js +224 -0
  176. package/src/http-server/handlers/changes-feed.js +261 -0
  177. package/src/http-server/handlers/management.js +464 -0
  178. package/src/http-server/handlers/query.js +573 -0
  179. package/src/http-server/handlers/transaction.js +251 -0
  180. package/src/http-server/index.js +89 -0
  181. package/src/http-server/openapi.js +656 -0
  182. package/src/http-server/router.js +120 -0
  183. package/src/http-server/server.js +1915 -0
  184. package/src/http-server/tls.js +126 -0
  185. package/src/http-server/ws-server.js +873 -0
  186. package/src/index/adaptive-hash-index.js +176 -0
  187. package/src/index/bitmap-index.js +429 -0
  188. package/src/index/brin-index.js +246 -0
  189. package/src/index/btree-index.js +428 -0
  190. package/src/index/btree.js +690 -0
  191. package/src/index/diskann-index.js +1903 -0
  192. package/src/index/fulltext/fulltext-index.js +66 -0
  193. package/src/index/fulltext/index.js +3 -0
  194. package/src/index/fulltext/inverted-index.js +197 -0
  195. package/src/index/fulltext/tokenizer.js +154 -0
  196. package/src/index/fulltext.js +287 -0
  197. package/src/index/gin-index.js +316 -0
  198. package/src/index/gist-index.js +463 -0
  199. package/src/index/gist-ops.js +325 -0
  200. package/src/index/graph-compressor.js +505 -0
  201. package/src/index/hash-index.js +180 -0
  202. package/src/index/hnsw-index.js +1232 -0
  203. package/src/index/hnsw-pq-index.js +1147 -0
  204. package/src/index/index-auto-tuner.js +1341 -0
  205. package/src/index/index-interface.js +364 -0
  206. package/src/index/index-selector.js +523 -0
  207. package/src/index/index.js +28 -0
  208. package/src/index/ivfpqsq-index.js +1163 -0
  209. package/src/index/offheap-btree-index.js +395 -0
  210. package/src/index/offheap-btree.js +748 -0
  211. package/src/index/product-quantizer.js +1447 -0
  212. package/src/index/robin-hood-hash-index.js +384 -0
  213. package/src/index/rtree-index.js +982 -0
  214. package/src/index/scalar-quantizer.js +411 -0
  215. package/src/index/semantic-index.js +283 -0
  216. package/src/index/string-interner.js +238 -0
  217. package/src/index/timestamp-index-advisor.js +491 -0
  218. package/src/index/timestamp-index-compressed.js +800 -0
  219. package/src/index/timestamp-index-compressor.js +547 -0
  220. package/src/index/timestamp-index.js +579 -0
  221. package/src/index/vector-index-serializer.js +499 -0
  222. package/src/index/vector-index-stats.js +450 -0
  223. package/src/index/vector-index.js +615 -0
  224. package/src/index-v3.js +27 -0
  225. package/src/index.js +33 -0
  226. package/src/internal/public-api.js +198 -0
  227. package/src/lineage/column-lineage.js +393 -0
  228. package/src/lineage/index.js +11 -0
  229. package/src/lineage/lineage-store.js +701 -0
  230. package/src/lineage/table-lineage.js +68 -0
  231. package/src/mcp/index.js +176 -0
  232. package/src/mcp/mcp-server.js +334 -0
  233. package/src/mcp/protocol.js +195 -0
  234. package/src/mcp/tools/backup-restore.js +131 -0
  235. package/src/mcp/tools/cdc-tools.js +201 -0
  236. package/src/mcp/tools/describe-table.js +100 -0
  237. package/src/mcp/tools/execute-sql.js +210 -0
  238. package/src/mcp/tools/explain-query.js +75 -0
  239. package/src/mcp/tools/index-management.js +191 -0
  240. package/src/mcp/tools/lineage.js +64 -0
  241. package/src/mcp/tools/list-tables.js +46 -0
  242. package/src/mcp/tools/monitoring.js +195 -0
  243. package/src/mcp/tools/schema-management.js +229 -0
  244. package/src/mcp/tools/text-to-sql.js +84 -0
  245. package/src/mcp/tools/transaction-management.js +191 -0
  246. package/src/mcp/tools/vector-search.js +101 -0
  247. package/src/mcp/transport/http.js +352 -0
  248. package/src/mcp/transport/stdio.js +117 -0
  249. package/src/memory/memory-manager.js +437 -0
  250. package/src/migration/migrator.js +389 -0
  251. package/src/monitor/index.js +36 -0
  252. package/src/monitor/metrics-exporter.js +517 -0
  253. package/src/monitor/monitor.js +385 -0
  254. package/src/monitor/performance-monitor.js +204 -0
  255. package/src/monitor/soa-monitor.js +628 -0
  256. package/src/multitenant/index.js +1 -0
  257. package/src/multitenant/tenant-manager.js +238 -0
  258. package/src/native/native-acceleration.js +3493 -0
  259. package/src/optimizer/adaptive-optimizer.js +666 -0
  260. package/src/optimizer/cse.js +383 -0
  261. package/src/optimizer/decorrelator.js +958 -0
  262. package/src/optimizer/derived-table-eliminator.js +367 -0
  263. package/src/optimizer/explain-visualizer.js +266 -0
  264. package/src/optimizer/histogram.js +290 -0
  265. package/src/optimizer/index.js +78 -0
  266. package/src/optimizer/jit-compiler.js +1200 -0
  267. package/src/optimizer/join-order-optimizer.js +717 -0
  268. package/src/optimizer/limit-pushdown.js +70 -0
  269. package/src/optimizer/optimized-plan.js +54 -0
  270. package/src/optimizer/optimizer-rule.js +295 -0
  271. package/src/optimizer/optimizer.js +1515 -0
  272. package/src/optimizer/pipeline.js +263 -0
  273. package/src/optimizer/predicate-pushdown.js +599 -0
  274. package/src/optimizer/query-plan-cache.js +275 -0
  275. package/src/optimizer/rule-adapters.js +343 -0
  276. package/src/optimizer/subquery-flattener.js +689 -0
  277. package/src/optimizer/timestamp-query-rewriter.js +498 -0
  278. package/src/orm/collection.js +160 -0
  279. package/src/orm/errors.js +76 -0
  280. package/src/orm/hooks.js +184 -0
  281. package/src/orm/index.js +93 -0
  282. package/src/orm/mixins/soft-delete.js +271 -0
  283. package/src/orm/model.js +951 -0
  284. package/src/orm/query-builder.js +681 -0
  285. package/src/orm/relations.js +303 -0
  286. package/src/orm/schema.js +443 -0
  287. package/src/orm/seeder.js +350 -0
  288. package/src/parallel/dml-pushdown-executor.js +430 -0
  289. package/src/parallel/dml-worker.js +151 -0
  290. package/src/parallel/morsel-queue.js +358 -0
  291. package/src/parallel/parallel-executor.js +277 -0
  292. package/src/parallel/pipeline-executor.js +423 -0
  293. package/src/parallel/shared-cache.js +206 -0
  294. package/src/parser/ast.js +3853 -0
  295. package/src/parser/parser.js +7909 -0
  296. package/src/parser/tokenizer.js +542 -0
  297. package/src/query/relation-preloader.js +327 -0
  298. package/src/replication/index.js +15 -0
  299. package/src/replication/lag-monitor.js +163 -0
  300. package/src/replication/master.js +117 -0
  301. package/src/replication/multi-master.js +495 -0
  302. package/src/replication/read-replica.js +490 -0
  303. package/src/replication/replica.js +395 -0
  304. package/src/replication/replication-http-transport.js +421 -0
  305. package/src/replication/wal-standby.js +334 -0
  306. package/src/runtime/index.js +4 -0
  307. package/src/runtime/plpgsql-interpreter.js +766 -0
  308. package/src/runtime/plpgsql-parser.js +852 -0
  309. package/src/runtime/stored-procedure.js +149 -0
  310. package/src/runtime/udf.js +194 -0
  311. package/src/schema/dsl-parser.js +896 -0
  312. package/src/schema/index.js +113 -0
  313. package/src/schema/introspector.js +246 -0
  314. package/src/schema/pg-migrator.js +599 -0
  315. package/src/schema/schema-differ.js +504 -0
  316. package/src/schema/schema-versioning.js +426 -0
  317. package/src/schema/type-generator.js +537 -0
  318. package/src/sdk/README.md +277 -0
  319. package/src/sdk/go/README.md +19 -0
  320. package/src/sdk/go/go.mod +3 -0
  321. package/src/sdk/go/pureclient/client.go +663 -0
  322. package/src/sdk/go/pureclient/client_test.go +413 -0
  323. package/src/sdk/java/README.md +19 -0
  324. package/src/sdk/java/pom.xml +87 -0
  325. package/src/sdk/java/pureclient/JsonUtil.java +366 -0
  326. package/src/sdk/java/pureclient/PureClient.java +835 -0
  327. package/src/sdk/java/pureclient/PureClientTest.java +570 -0
  328. package/src/sdk/java/pureclient/PureError.java +158 -0
  329. package/src/sdk/java/pureclient/Transaction.java +242 -0
  330. package/src/sdk/javascript/README.md +19 -0
  331. package/src/sdk/javascript/cdc.js +230 -0
  332. package/src/sdk/javascript/client.js +420 -0
  333. package/src/sdk/javascript/errors.js +66 -0
  334. package/src/sdk/javascript/index.js +35 -0
  335. package/src/sdk/javascript/pool.js +199 -0
  336. package/src/sdk/javascript/transaction.js +114 -0
  337. package/src/sdk/php/README.md +19 -0
  338. package/src/sdk/php/composer.json +30 -0
  339. package/src/sdk/php/src/PureClient.php +550 -0
  340. package/src/sdk/php/src/PureError.php +130 -0
  341. package/src/sdk/php/src/Transaction.php +172 -0
  342. package/src/sdk/public-api.js +16 -0
  343. package/src/sdk/python/README.md +19 -0
  344. package/src/sdk/python/pure_client.py +388 -0
  345. package/src/sdk/react-native/README.md +161 -0
  346. package/src/sdk/react-native/async-storage-adapter.js +147 -0
  347. package/src/sdk/react-native/embedded/embedded-client.js +266 -0
  348. package/src/sdk/react-native/embedded/hermes-jsi-bridge.js +207 -0
  349. package/src/sdk/react-native/embedded/sqlite-kv-adapter.js +345 -0
  350. package/src/sdk/react-native/expo-file-adapter.js +315 -0
  351. package/src/sdk/react-native/index.js +52 -0
  352. package/src/sdk/react-native/mobile-client.js +759 -0
  353. package/src/sdk/react-native/sync-manager.js +455 -0
  354. package/src/sdk/react-native/vector-search.js +322 -0
  355. package/src/sdk/rust/CHANGELOG.md +104 -0
  356. package/src/sdk/rust/Cargo.toml +35 -0
  357. package/src/sdk/rust/LICENSE +21 -0
  358. package/src/sdk/rust/PUBLISHING.md +202 -0
  359. package/src/sdk/rust/README.md +471 -0
  360. package/src/sdk/rust/RELEASE-CHECKLIST.md +340 -0
  361. package/src/sdk/rust/examples/basic_usage.rs +181 -0
  362. package/src/sdk/rust/scripts/publish.sh +233 -0
  363. package/src/sdk/rust/src/client.rs +481 -0
  364. package/src/sdk/rust/src/error.rs +95 -0
  365. package/src/sdk/rust/src/index/hnswpq.rs +626 -0
  366. package/src/sdk/rust/src/index/mod.rs +7 -0
  367. package/src/sdk/rust/src/lib.rs +66 -0
  368. package/src/sdk/rust/src/models.rs +198 -0
  369. package/src/sdk/rust/src/transaction.rs +123 -0
  370. package/src/sdk/rust/tests/concurrent_vector_search.rs +534 -0
  371. package/src/sdk/wechat/README.md +19 -0
  372. package/src/sdk/wechat/index.js +42 -0
  373. package/src/sdk/wechat/pure-js-db.js +105 -0
  374. package/src/sdk/wechat/stubs/empty.js +85 -0
  375. package/src/sdk/wechat/wx-database.js +225 -0
  376. package/src/sdk/wechat/wx-lite.js +191 -0
  377. package/src/sdk/wechat/wx-sqlite-adapter.js +655 -0
  378. package/src/sdk/wechat/wx-sqlite-database.js +146 -0
  379. package/src/sdk/wechat/wx-storage-adapter.js +609 -0
  380. package/src/security/api-key.js +215 -0
  381. package/src/security/auth.js +179 -0
  382. package/src/security/column-encryption-optimized.js +352 -0
  383. package/src/security/column-encryption.js +330 -0
  384. package/src/security/crypto-provider.js +345 -0
  385. package/src/security/data-masking.js +370 -0
  386. package/src/security/field-encryption.js +238 -0
  387. package/src/security/index.js +41 -0
  388. package/src/security/jwt.js +202 -0
  389. package/src/security/rbac.js +702 -0
  390. package/src/security/regex-guard.js +277 -0
  391. package/src/security/row-level-security.js +192 -0
  392. package/src/security/secure-erase.js +258 -0
  393. package/src/security/sql-firewall.js +185 -0
  394. package/src/security/sql-injection-detector.js +647 -0
  395. package/src/security/sql-rate-limiter.js +168 -0
  396. package/src/security/ssrf-guard.js +790 -0
  397. package/src/security/timing-safe.js +203 -0
  398. package/src/serializer/codecs.js +1155 -0
  399. package/src/serializer/index.js +13 -0
  400. package/src/serializer/serializer.js +468 -0
  401. package/src/server/public-api.js +14 -0
  402. package/src/server.js +31 -0
  403. package/src/service/log-service.js +593 -0
  404. package/src/sharding/cluster-manager.js +161 -0
  405. package/src/sharding/consistent-hash-ring-optimized.js +421 -0
  406. package/src/sharding/consistent-hash-ring.js +252 -0
  407. package/src/sharding/consistent-hash.js +175 -0
  408. package/src/sharding/distributed-executor.js +120 -0
  409. package/src/sharding/distributed-lock.js +256 -0
  410. package/src/sharding/distributed-transaction.js +262 -0
  411. package/src/sharding/failure-recovery.js +267 -0
  412. package/src/sharding/global-tx-coordinator.js +1299 -0
  413. package/src/sharding/index.js +16 -0
  414. package/src/sharding/parallel-write-coordinator.js +370 -0
  415. package/src/sharding/partition-manager.js +382 -0
  416. package/src/sharding/pushdown-executor.js +1101 -0
  417. package/src/sharding/scatter-gather-executor.js +460 -0
  418. package/src/sharding/shard-executor.js +624 -0
  419. package/src/sharding/shard-manager.js +717 -0
  420. package/src/sharding/three-phase-commit.js +699 -0
  421. package/src/sharding/two-phase-commit.js +1243 -0
  422. package/src/snapshot/historical-reader.js +257 -0
  423. package/src/snapshot/index.js +7 -0
  424. package/src/storage/batch-writer.js +110 -0
  425. package/src/storage/binary-storage-adapter.js +738 -0
  426. package/src/storage/blob-kv-adapter.js +253 -0
  427. package/src/storage/buffer-pool.js +458 -0
  428. package/src/storage/buffered-kv-adapter.js +325 -0
  429. package/src/storage/cold-data-migrator.js +519 -0
  430. package/src/storage/column-compression.js +878 -0
  431. package/src/storage/column-store-table.js +627 -0
  432. package/src/storage/column-store.js +1094 -0
  433. package/src/storage/columnar-file.js +489 -0
  434. package/src/storage/columnar-storage.js +485 -0
  435. package/src/storage/compact-recovery.js +394 -0
  436. package/src/storage/encrypted-kv-adapter.js +271 -0
  437. package/src/storage/file-kv-adapter.js +468 -0
  438. package/src/storage/hybrid-engine.js +1480 -0
  439. package/src/storage/importer.js +125 -0
  440. package/src/storage/in-memory-table-storage.js +291 -0
  441. package/src/storage/index.js +78 -0
  442. package/src/storage/io-thread-pool.js +240 -0
  443. package/src/storage/io-worker.js +42 -0
  444. package/src/storage/kv-adapter.js +322 -0
  445. package/src/storage/lsm/active-table.js +240 -0
  446. package/src/storage/lsm/block-cache.js +64 -0
  447. package/src/storage/lsm/bloom-filter.js +174 -0
  448. package/src/storage/lsm/compactor.js +460 -0
  449. package/src/storage/lsm/database-manager.js +177 -0
  450. package/src/storage/lsm/full-text-search.js +385 -0
  451. package/src/storage/lsm/index.js +14 -0
  452. package/src/storage/lsm/internal-key.js +140 -0
  453. package/src/storage/lsm/lsm-engine.js +798 -0
  454. package/src/storage/lsm/lsm-kv-adapter.js +137 -0
  455. package/src/storage/lsm/memtable.js +628 -0
  456. package/src/storage/lsm/mmap-region.js +289 -0
  457. package/src/storage/lsm/sstable-reader.js +403 -0
  458. package/src/storage/lsm/sstable-repair.js +437 -0
  459. package/src/storage/lsm/sstable-writer.js +202 -0
  460. package/src/storage/lsm/wal.js +800 -0
  461. package/src/storage/offheap-allocator.js +298 -0
  462. package/src/storage/page-checksum.js +221 -0
  463. package/src/storage/page-compression.js +95 -0
  464. package/src/storage/page-store.js +418 -0
  465. package/src/storage/page.js +261 -0
  466. package/src/storage/persisted-db.js +1885 -0
  467. package/src/storage/persisted-table-storage.js +280 -0
  468. package/src/storage/read-ahead.js +95 -0
  469. package/src/storage/shared-storage.js +688 -0
  470. package/src/storage/soa-table-storage.js +418 -0
  471. package/src/storage/storage-engine.js +187 -0
  472. package/src/storage/table-storage.js +215 -0
  473. package/src/storage/tiered-kv-adapter.js +381 -0
  474. package/src/storage/version-history-cleaner.js +888 -0
  475. package/src/studio/index.html +1503 -0
  476. package/src/studio/server.js +204 -0
  477. package/src/sync/change-log.js +144 -0
  478. package/src/sync/index.js +2 -0
  479. package/src/sync/sync-engine.js +428 -0
  480. package/src/sync/sync-handlers.js +196 -0
  481. package/src/test-utils.js +11 -0
  482. package/src/transaction/index.js +8 -0
  483. package/src/transaction/read-uncommitted.js +37 -0
  484. package/src/transaction/repeatable-read.js +380 -0
  485. package/src/transaction/rr-transaction-manager.js +262 -0
  486. package/src/transaction/ru-transaction-manager.js +76 -0
  487. package/src/transaction/serializable.js +205 -0
  488. package/src/transaction/transaction-manager.js +259 -0
  489. package/src/transaction/tx-manager.js +490 -0
  490. package/src/transaction/tx-state.js +43 -0
  491. package/src/tx/bfmark-snapshot.js +193 -0
  492. package/src/tx/row-lock.js +246 -0
  493. package/src/tx/ssi.js +229 -0
  494. package/src/types/datetime.js +621 -0
  495. package/src/types/decimal.js +220 -0
  496. package/src/types/enum-type.js +131 -0
  497. package/src/types/interval.js +565 -0
  498. package/src/types/json-type.js +376 -0
  499. package/src/types/jsonb.js +227 -0
  500. package/src/types/udt.js +180 -0
  501. package/src/utils/batch-processor.js +46 -0
  502. package/src/utils/debug-logger.js +116 -0
  503. package/src/utils/index-helper.js +74 -0
  504. package/src/utils/index.js +9 -0
  505. package/src/utils/join-engine.js +1713 -0
  506. package/src/utils/object-pool.js +610 -0
  507. package/src/utils/query-tracer.js +489 -0
  508. package/src/utils/timeout-util.js +92 -0
  509. package/src/utils/tx-log-persist.js +197 -0
  510. package/src/utils/undo-compress.js +93 -0
  511. package/src/utils/undo-log.js +196 -0
  512. package/src/utils/wal-common.js +138 -0
  513. package/src/vector/adaptive-ef.js +213 -0
  514. package/src/vector/distributed-vector-search.js +542 -0
  515. package/src/vector/federated-vector-search.js +707 -0
  516. package/src/vector/gpu-distance.js +647 -0
  517. package/src/vector/gpu-sq-distance.js +444 -0
  518. package/src/vector/hnsw-acceleration.js +298 -0
  519. package/src/vector/hnsw-profiler.js +341 -0
  520. package/src/vector/index.js +90 -0
  521. package/src/vector/public-api.js +29 -0
  522. package/src/vector/recall-benchmark.js +333 -0
  523. package/src/vector/simd-distance.js +511 -0
  524. package/src/vector/vector-scan.js +646 -0
  525. package/src/vector/wasm-hnsw.js +714 -0
  526. package/src/version/version-chain-manager.js +1277 -0
  527. package/src/version/version-delta-encoder.js +819 -0
  528. package/src/version.js +19 -0
  529. package/src/view/incremental-refresher.js +1015 -0
  530. package/src/view/index.js +12 -0
  531. package/src/view/materialized-view.js +204 -0
  532. package/src/view/view-manager.js +1368 -0
  533. package/src/wasm/bridge.js +79 -0
  534. package/src/worker/query-dispatcher.js +277 -0
  535. package/src/worker/session-worker-pool.js +355 -0
  536. package/src/worker/task-defs.js +330 -0
  537. package/src/worker/task-worker.js +406 -0
  538. package/src/worker/worker-pool.js +651 -0
  539. package/src/xml/xml-support.js +647 -0
  540. package/types/pure-js-db.d.ts +1988 -0
  541. package/types/schema.d.ts +65 -0
@@ -0,0 +1,651 @@
1
+ /**
2
+ * worker-pool.js — Worker Thread 池化管理
3
+ *
4
+ * 管理一组 Worker Thread,支持任务分发、空闲复用、超时回收。
5
+ *
6
+ * 用法:
7
+ * import { WorkerPool } from './worker-pool.js';
8
+ * const pool = new WorkerPool({ size: 4 });
9
+ * await pool.init();
10
+ *
11
+ * // 并行排序: 数据分块 → 各 Worker 排序 → 主线程 K-way Merge
12
+ * const chunks = splitIntoChunks(data, pool.size);
13
+ * const tasks = chunks.map(c => createSortTask(c, 'id'));
14
+ * const sortedChunks = await pool.execAll(tasks);
15
+ * const result = kWayMerge(sortedChunks, (a,b) => a.id - b.id);
16
+ *
17
+ * // 并行过滤: 数据分块 → 各 Worker 过滤 → 结果拼接
18
+ * const filterTasks = chunks.map(c => createFilterTask(c, row => row.age > 18));
19
+ * const filtered = await pool.execAll(filterTasks);
20
+ * const all = filtered.flat();
21
+ *
22
+ * await pool.terminate();
23
+ */
24
+
25
+ import { Worker } from 'node:worker_threads';
26
+ import { fileURLToPath } from 'node:url';
27
+ import path from 'node:path';
28
+ import os from 'node:os';
29
+ import { performance } from 'node:perf_hooks';
30
+ import { WORKER_TIMEOUT } from './task-defs.js';
31
+ import { MorselQueue } from '../parallel/morsel-queue.js';
32
+
33
+ // Worker 脚本的绝对路径
34
+ const __filename = fileURLToPath(import.meta.url);
35
+ const __dirname = path.dirname(__filename);
36
+ const WORKER_SCRIPT = path.join(__dirname, 'task-worker.js');
37
+
38
+ // ── 默认配置 ──
39
+
40
+ /** 默认池大小: CPU 核心数 - 1(保留一个给主线程) */
41
+ const DEFAULT_POOL_SIZE = Math.max(1, (os.cpus().length || 4) - 1);
42
+
43
+ /**
44
+ * @typedef {object} WorkerPoolOptions
45
+ * @property {number} [size=DEFAULT_POOL_SIZE] - Worker 数量
46
+ * @property {number} [taskTimeout=WORKER_TIMEOUT] - 单个任务超时(ms)
47
+ * @property {boolean} [lazy=false] - 延迟初始化(首次任务时才创建 Worker)
48
+ * @property {SharedArrayBuffer} [sharedBuffer] - 共享内存(通过 workerData 传给所有 Worker)
49
+ */
50
+ export class WorkerPool {
51
+ /**
52
+ * @param {WorkerPoolOptions} [options]
53
+ */
54
+ constructor(options = {}) {
55
+ const opts = {
56
+ size: DEFAULT_POOL_SIZE,
57
+ taskTimeout: WORKER_TIMEOUT,
58
+ lazy: false,
59
+ log: null,
60
+ ...options,
61
+ };
62
+
63
+ /** @type {number} Worker 数量 */
64
+ this.size = opts.size;
65
+
66
+ /** @type {number} 任务超时(ms) */
67
+ this.taskTimeout = opts.taskTimeout;
68
+
69
+ /** @type {boolean} 是否已初始化 */
70
+ this.initialized = false;
71
+
72
+ /** @type {object[]} Worker 状态列表 */
73
+ this._workers = [];
74
+
75
+ /** @type {number} 下一个任务 ID */
76
+ this._nextTaskId = 1;
77
+
78
+ /** @type {Map<number, { resolve, reject, timeout }>} 待处理的 Promise */
79
+ this._pending = new Map();
80
+
81
+ /** @type {Map<number, number>} 任务开始时间(用于计时) */
82
+ this._taskStartTimes = new Map();
83
+
84
+ // 延迟初始化时在首次 exec 前创建 Worker
85
+ this._lazy = opts.lazy;
86
+
87
+ /** @type {function(string):void} 日志函数 */
88
+ this._log = opts.log || null;
89
+
90
+ /** @type {SharedArrayBuffer|null} 共享内存(通过 workerData 传给 Worker) */
91
+ this._sharedBuffer = opts.sharedBuffer || null;
92
+ }
93
+
94
+ /**
95
+ * 内部日志(仅在有日志函数时输出)
96
+ */
97
+ _debug(event, details = '') {
98
+ if (this._log) {
99
+ this._log(`[POOL] ${event}: ${details}`);
100
+ }
101
+ }
102
+
103
+ /**
104
+ * 设置共享内存(必须在 init 之前或 terminate 之后调用)
105
+ * @param {SharedArrayBuffer|null} buffer
106
+ */
107
+ setSharedBuffer(buffer) {
108
+ if (this.initialized) {
109
+ throw new Error('Worker Pool 已初始化,请先 terminate() 再设置 sharedBuffer');
110
+ }
111
+ this._sharedBuffer = buffer;
112
+ }
113
+
114
+ /**
115
+ * 获取共享内存
116
+ * @returns {SharedArrayBuffer|null}
117
+ */
118
+ getSharedBuffer() {
119
+ return this._sharedBuffer;
120
+ }
121
+
122
+ /**
123
+ * 初始化 Worker Pool(创建所有 Worker)
124
+ */
125
+ async init() {
126
+ if (this.initialized) {
127
+ return;
128
+ }
129
+ this.initialized = true;
130
+
131
+ this._debug('INIT_START', `size=${this.size}, lazy=${this._lazy}`);
132
+
133
+ const promises = [];
134
+ for (let i = 0; i < this.size; i++) {
135
+ promises.push(this._createWorker());
136
+ }
137
+ await Promise.all(promises);
138
+
139
+ this._debug('INIT_DONE', `workers=${this._workers.length}`);
140
+ }
141
+
142
+ /**
143
+ * 创建一个 Worker
144
+ */
145
+ async _createWorker() {
146
+ const workerOptions = this._sharedBuffer
147
+ ? { workerData: { sab: this._sharedBuffer } }
148
+ : {};
149
+ const worker = new Worker(WORKER_SCRIPT, workerOptions);
150
+ const workerId = this._workers.length;
151
+
152
+ const entry = {
153
+ worker,
154
+ busy: false,
155
+ id: workerId,
156
+ taskCount: 0,
157
+ totalTime: 0,
158
+ };
159
+ this._workers.push(entry);
160
+
161
+ return new Promise((resolve) => {
162
+ // worker 就绪后 resolve
163
+ worker.on('online', () => {
164
+ this._debug('WORKER_ONLINE', `id=${workerId}`);
165
+ resolve();
166
+ });
167
+
168
+ worker.on('message', (msg) => {
169
+ this._handleResult(entry, msg);
170
+ });
171
+
172
+ worker.on('error', (err) => {
173
+ this._debug('WORKER_ERROR', `id=${workerId} error="${err.message}"`);
174
+ this._handleError(entry, err);
175
+ });
176
+
177
+ worker.on('exit', (code) => {
178
+ this._debug('WORKER_EXIT', `id=${workerId} code=${code}`);
179
+ if (code !== 0) {
180
+ this._handleError(entry, new Error(`Worker 异常退出, code=${code}`));
181
+ }
182
+ // 从 workers 列表中移除
183
+ const idx = this._workers.indexOf(entry);
184
+ if (idx !== -1) {
185
+ this._workers.splice(idx, 1);
186
+ }
187
+ });
188
+ });
189
+ }
190
+
191
+ /**
192
+ * 处理 Worker 返回结果
193
+ */
194
+ _handleResult(entry, msg) {
195
+ entry.busy = false;
196
+ const pending = this._pending.get(msg.taskId);
197
+ if (!pending) {
198
+ this._debug('RESULT_ORPHAN', `taskId=${msg.taskId} (already cancelled)`);
199
+ return;
200
+ }
201
+
202
+ this._pending.delete(msg.taskId);
203
+ clearTimeout(pending.timeout);
204
+
205
+ const taskTime = this._taskStartTimes.has(msg.taskId)
206
+ ? (performance.now() - this._taskStartTimes.get(msg.taskId)).toFixed(1)
207
+ : '?';
208
+ this._taskStartTimes.delete(msg.taskId);
209
+
210
+ if (msg.error) {
211
+ this._debug('RESULT_ERROR', `taskId=${msg.taskId} worker=${entry.id} time=${taskTime}ms error="${msg.error}"`);
212
+ pending.reject(new Error(msg.error));
213
+ } else {
214
+ this._debug('RESULT_OK', `taskId=${msg.taskId} worker=${entry.id} time=${taskTime}ms`);
215
+ pending.resolve(msg.result);
216
+ }
217
+ }
218
+
219
+ /**
220
+ * 处理 Worker 错误
221
+ */
222
+ _handleError(entry, err) {
223
+ entry.busy = false;
224
+ let cancelledCount = 0;
225
+ // 将所有属于此 Worker 的待处理任务 reject
226
+ for (const [taskId, pending] of this._pending) {
227
+ if (pending.workerEntry === entry) {
228
+ this._pending.delete(taskId);
229
+ clearTimeout(pending.timeout);
230
+ this._taskStartTimes.delete(taskId);
231
+ pending.reject(err);
232
+ cancelledCount++;
233
+ }
234
+ }
235
+ if (cancelledCount > 0) {
236
+ this._debug('HANDLE_ERROR', `worker=${entry.id} cancelled=${cancelledCount} error="${err.message}"`);
237
+ }
238
+ }
239
+
240
+ /**
241
+ * 选择一个空闲 Worker(Round-Robin 调度)
242
+ */
243
+ _pickWorker() {
244
+ const idle = this._workers.filter(w => !w.busy);
245
+ if (idle.length === 0) {
246
+ this._debug('PICK_WORKER', 'none_idle');
247
+ return null;
248
+ }
249
+
250
+ // 选择任务数最少的空闲 Worker(负载均衡)
251
+ idle.sort((a, b) => a.taskCount - b.taskCount);
252
+ this._debug('PICK_WORKER', `id=${idle[0].id} idle_count=${idle.length}`);
253
+ return idle[0];
254
+ }
255
+
256
+ /**
257
+ * 向指定 Worker 提交一个任务
258
+ * @param {object} entry - Worker 条目
259
+ * @param {object} task - 任务对象
260
+ * @returns {Promise<any>}
261
+ */
262
+ _submitTask(entry, task) {
263
+ const taskId = this._nextTaskId++;
264
+ this._taskStartTimes.set(taskId, performance.now());
265
+
266
+ this._debug('SUBMIT_TASK', `taskId=${taskId} type=${task.type} worker=${entry.id}`);
267
+
268
+ return new Promise((resolve, reject) => {
269
+ const timeout = setTimeout(() => {
270
+ this._pending.delete(taskId);
271
+ this._taskStartTimes.delete(taskId);
272
+ this._debug('TASK_TIMEOUT', `taskId=${taskId} type=${task.type} worker=${entry.id} timeout=${this.taskTimeout}ms`);
273
+ reject(new Error(`任务超时 (${this.taskTimeout}ms): ${task.type}`));
274
+ }, this.taskTimeout);
275
+
276
+ this._pending.set(taskId, { resolve, reject, timeout, workerEntry: entry, startTime: performance.now() });
277
+
278
+ entry.busy = true;
279
+ entry.taskCount++;
280
+ entry.worker.postMessage({ taskId, task });
281
+ });
282
+ }
283
+
284
+ /**
285
+ * 在单个空闲 Worker 上执行任务
286
+ * @param {object} task
287
+ * @returns {Promise<any>}
288
+ */
289
+ async exec(task) {
290
+ if (!this.initialized) {
291
+ await this.init();
292
+ }
293
+
294
+ const entry = this._pickWorker();
295
+ if (!entry) {
296
+ // 没有空闲 Worker,等待 10ms 后重试
297
+ this._debug('EXEC_WAIT', `type=${task.type} (no idle worker, retry after 10ms)`);
298
+ await new Promise(r => setTimeout(r, 10));
299
+ return this.exec(task);
300
+ }
301
+
302
+ const start = performance.now();
303
+ try {
304
+ const result = await this._submitTask(entry, task);
305
+ entry.totalTime += performance.now() - start;
306
+ return result;
307
+ } catch (err) {
308
+ entry.totalTime += performance.now() - start;
309
+ throw err;
310
+ }
311
+ }
312
+
313
+ /**
314
+ * 在所有 Worker 上执行一组任务(每个 Worker 一个任务)
315
+ * @param {object[]} tasks - 任务数组,长度应 <= pool.size
316
+ * @returns {Promise<any[]>} 结果数组(顺序与 tasks 一致)
317
+ */
318
+ async execAll(tasks) {
319
+ if (!this.initialized) {
320
+ await this.init();
321
+ }
322
+
323
+ if (tasks.length === 0) {
324
+ return [];
325
+ }
326
+ if (tasks.length > this._workers.length) {
327
+ // 超出 Worker 数量,分批执行
328
+ this._debug('EXECALL_BATCHED', `tasks=${tasks.length} workers=${this._workers.length} batches=${Math.ceil(tasks.length / this._workers.length)}`);
329
+ const results = [];
330
+ for (let i = 0; i < tasks.length; i += this._workers.length) {
331
+ const batch = tasks.slice(i, i + this._workers.length);
332
+ const batchResults = await this._execBatch(batch);
333
+ results.push(...batchResults);
334
+ }
335
+ return results;
336
+ }
337
+
338
+ this._debug('EXECALL', `tasks=${tasks.length} workers=${this._workers.length}`);
339
+ return this._execBatch(tasks);
340
+ }
341
+
342
+ /**
343
+ * L2.3: Morsel-Driven 动态调度执行
344
+ *
345
+ * 与 execAll 的区别:
346
+ * - execAll: 静态分配(每个 Worker 一个任务),分批阻塞等待
347
+ * - execAllMorsels: 动态调度(Worker 空闲就分配下一个 morsel),无分批阻塞
348
+ *
349
+ * 优势:
350
+ * 1. 长尾 morsel 不拖慢整批(其他 Worker 继续拉取新 morsel)
351
+ * 2. 负载倾斜自动均衡(数据密集 morsel 慢,稀疏 morsel 快,Worker 自适应)
352
+ * 3. 支持 work stealing(僵死 morsel 可被重新分配)
353
+ *
354
+ * @param {Object} config
355
+ * @param {number} config.totalRows - 总行数(用于切分 morsel)
356
+ * @param {function(startRow: number, endRow: number): object} config.buildTask
357
+ * - 根据行范围构造 Worker 任务
358
+ * @param {number} [config.morselSize=65536] - 每个 morsel 的行数
359
+ * @param {number} [config.timeout=WORKER_TIMEOUT] - 单任务超时
360
+ * @param {boolean} [config.enableSteal=true] - 是否启用 work stealing
361
+ * @returns {Promise<Array<{morselId: number, result: any}>>}
362
+ * 结果数组(按 morselId 排序,调用方负责合并)
363
+ */
364
+ async execAllMorsels(config) {
365
+ if (!this.initialized) {
366
+ await this.init();
367
+ }
368
+
369
+ const {
370
+ totalRows,
371
+ buildTask,
372
+ morselSize = 65536,
373
+ timeout = WORKER_TIMEOUT,
374
+ enableSteal = true,
375
+ } = config;
376
+
377
+ if (totalRows <= 0) {
378
+ return [];
379
+ }
380
+
381
+ // 初始化 MorselQueue(无 SAB 时降级为内存模式,仍走动态调度)
382
+ const queue = new MorselQueue({ morselSize });
383
+ const morselCount = queue.isAvailable() ? queue.init(totalRows) : 0;
384
+
385
+ // 无 SAB 降级:用普通数组模拟 morsel 状态
386
+ const fallbackMorsels = queue.isAvailable() ? null : _buildFallbackMorsels(totalRows, morselSize);
387
+ const useFallback = !queue.isAvailable();
388
+
389
+ this._debug('EXECALL_MORSELS_START',
390
+ `rows=${totalRows} morsels=${useFallback ? fallbackMorsels.length : morselCount} ` +
391
+ `morselSize=${morselSize} sab=${!useFallback} steal=${enableSteal}`);
392
+
393
+ const results = new Array(useFallback ? fallbackMorsels.length : morselCount);
394
+ let completedCount = 0;
395
+ let nextFallbackIdx = 0;
396
+ const totalMorsels = useFallback ? fallbackMorsels.length : morselCount;
397
+ const startTime = performance.now();
398
+
399
+ // 提交下一个 morsel 给指定 Worker
400
+ const _submitNextMorsel = async (entry) => {
401
+ let morselIdx = -1;
402
+ let morsel = null;
403
+
404
+ if (useFallback) {
405
+ // 降级模式:从数组顺序取
406
+ morselIdx = nextFallbackIdx++;
407
+ if (morselIdx >= fallbackMorsels.length) {
408
+ return false;
409
+ }
410
+ morsel = fallbackMorsels[morselIdx];
411
+ } else {
412
+ // SAB 模式:原子抢占
413
+ morselIdx = queue.acquireNext(entry.id);
414
+ if (morselIdx < 0) {
415
+ // 无可用 morsel,尝试窃取
416
+ if (enableSteal) {
417
+ const stolen = queue.trySteal();
418
+ if (stolen >= 0) {
419
+ morselIdx = queue.acquireNext(entry.id);
420
+ }
421
+ }
422
+ if (morselIdx < 0) {
423
+ return false;
424
+ }
425
+ }
426
+ morsel = queue.getMorsel(morselIdx);
427
+ }
428
+
429
+ if (!morsel) {
430
+ return false;
431
+ }
432
+
433
+ const task = buildTask(morsel.startRow, morsel.endRow);
434
+ const taskStart = performance.now();
435
+
436
+ try {
437
+ const result = await this._submitTaskWithTimeout(entry, task, timeout);
438
+ const elapsed = performance.now() - taskStart;
439
+ entry.totalTime += elapsed;
440
+
441
+ if (!useFallback) {
442
+ queue.markCompleted(morselIdx);
443
+ }
444
+ results[morsel.id] = { morselId: morsel.id, result };
445
+ completedCount++;
446
+
447
+ this._debug('MORSEL_DONE',
448
+ `worker=${entry.id} morselId=${morsel.id} rows=${morsel.endRow - morsel.startRow} ` +
449
+ `elapsed=${elapsed.toFixed(1)}ms completed=${completedCount}/${totalMorsels}`);
450
+ return true;
451
+ } catch (err) {
452
+ const elapsed = performance.now() - taskStart;
453
+ entry.totalTime += elapsed;
454
+ this._debug('MORSEL_ERROR',
455
+ `worker=${entry.id} morselId=${morsel.id} elapsed=${elapsed.toFixed(1)}ms error="${err.message}"`);
456
+ // 不标记 completed,让 steal 机制重试(或降级时直接标记失败)
457
+ if (useFallback) {
458
+ results[morsel.id] = { morselId: morsel.id, result: null, error: err.message };
459
+ completedCount++;
460
+ }
461
+ return false;
462
+ }
463
+ };
464
+
465
+ // 动态调度循环:所有 Worker 并发拉取 morsel
466
+ const workerPromises = this._workers.map(async (entry) => {
467
+ // 每个 Worker 持续拉取 morsel 直到无可用
468
+ while (completedCount + (totalMorsels - completedCount) > 0) {
469
+ // 检查是否还有未完成的 morsel
470
+ if (!useFallback && queue.isAllCompleted()) {
471
+ break;
472
+ }
473
+ if (useFallback && nextFallbackIdx >= fallbackMorsels.length) {
474
+ break;
475
+ }
476
+
477
+ const got = await _submitNextMorsel(entry);
478
+ if (!got) {
479
+ // 无可用 morsel,短暂等待(可能有 morsel 即将完成或被窃取)
480
+ if (!useFallback && !queue.isAllCompleted()) {
481
+ await new Promise(r => setTimeout(r, 1));
482
+ // 重试一次,可能其他 Worker 完成后释放了 morsel
483
+ const got2 = await _submitNextMorsel(entry);
484
+ if (!got2) {
485
+ break;
486
+ }
487
+ } else {
488
+ break;
489
+ }
490
+ }
491
+ }
492
+ });
493
+
494
+ await Promise.all(workerPromises);
495
+
496
+ // 过滤掉 null 结果(失败但未重试的 morsel)
497
+ const validResults = results.filter(r => r !== undefined && r !== null);
498
+
499
+ this._debug('EXECALL_MORSELS_DONE',
500
+ `morsels=${totalMorsels} completed=${completedCount} ` +
501
+ `valid=${validResults.length} duration=${(performance.now() - startTime).toFixed(1)}ms`);
502
+
503
+ return validResults;
504
+ }
505
+
506
+ /**
507
+ * 向指定 Worker 提交任务(带超时)
508
+ * @param {object} entry - Worker 条目
509
+ * @param {object} task - 任务对象
510
+ * @param {number} timeout - 超时(ms)
511
+ * @returns {Promise<any>}
512
+ */
513
+ async _submitTaskWithTimeout(entry, task, timeout) {
514
+ return new Promise((resolve, reject) => {
515
+ const taskId = this._nextTaskId++;
516
+ this._taskStartTimes.set(taskId, performance.now());
517
+
518
+ const timer = setTimeout(() => {
519
+ this._pending.delete(taskId);
520
+ this._taskStartTimes.delete(taskId);
521
+ entry.busy = false;
522
+ reject(new Error(`Morsel 任务超时 (${timeout}ms): ${task.type}`));
523
+ }, timeout);
524
+ timer.unref();
525
+
526
+ this._pending.set(taskId, {
527
+ resolve: (v) => {
528
+ clearTimeout(timer); entry.busy = false; resolve(v);
529
+ },
530
+ reject: (e) => {
531
+ clearTimeout(timer); entry.busy = false; reject(e);
532
+ },
533
+ timeout: timer,
534
+ workerEntry: entry,
535
+ startTime: performance.now(),
536
+ });
537
+
538
+ entry.busy = true;
539
+ entry.taskCount++;
540
+ entry.worker.postMessage({ taskId, task });
541
+ });
542
+ }
543
+
544
+ /**
545
+ * 执行一批任务(每个 Worker 一个任务)
546
+ */
547
+ async _execBatch(tasks) {
548
+ this._debug('EXECBATCH_START', `tasks=${tasks.length}`);
549
+ const batchStart = performance.now();
550
+ const promises = [];
551
+ let taskIdx = 0;
552
+
553
+ // 分配任务到空闲 Worker
554
+ for (const entry of this._workers) {
555
+ if (taskIdx >= tasks.length) {
556
+ break;
557
+ }
558
+ const task = tasks[taskIdx++];
559
+ const start = performance.now();
560
+ // 使用 allSettled 模式:单个 Worker 崩溃不影响其他 Worker 结果
561
+ const promise = this._submitTask(entry, task).then(result => {
562
+ entry.totalTime += performance.now() - start;
563
+ return { status: 'fulfilled', value: result, taskIdx: taskIdx - 1 };
564
+ }).catch(err => {
565
+ entry.totalTime += performance.now() - start;
566
+ return { status: 'rejected', reason: err, taskIdx: taskIdx - 1 };
567
+ });
568
+ promises.push(promise);
569
+ }
570
+
571
+ const settled = await Promise.all(promises);
572
+ const errors = settled.filter(r => r.status === 'rejected');
573
+ const results = settled.filter(r => r.status === 'fulfilled').map(r => r.value);
574
+
575
+ if (errors.length > 0) {
576
+ this._debug('EXECBATCH_PARTIAL_FAILURE',
577
+ `total=${tasks.length} succeeded=${results.length} failed=${errors.length} first_error="${errors[0].reason.message}"`);
578
+ // 如果全部失败才抛异常,部分成功则返回成功结果
579
+ if (results.length === 0) {
580
+ throw errors[0].reason;
581
+ }
582
+ }
583
+
584
+ this._debug('EXECBATCH_DONE',
585
+ `tasks=${tasks.length} results=${results.length} errors=${errors.length} duration=${(performance.now() - batchStart).toFixed(1)}ms`);
586
+ return results;
587
+ }
588
+
589
+ /**
590
+ * 获取 Pool 统计信息
591
+ */
592
+ getStats() {
593
+ const stats = {
594
+ poolSize: this.size,
595
+ activeWorkers: this._workers.length,
596
+ busyCount: this._workers.filter(w => w.busy).length,
597
+ idleCount: this._workers.filter(w => !w.busy).length,
598
+ pendingTasks: this._pending.size,
599
+ workers: this._workers.map(w => ({
600
+ id: w.id,
601
+ busy: w.busy,
602
+ taskCount: w.taskCount,
603
+ totalTimeMs: +w.totalTime.toFixed(2),
604
+ })),
605
+ };
606
+ this._debug('GET_STATS', `busy=${stats.busyCount} idle=${stats.idleCount} pending=${stats.pendingTasks}`);
607
+ return stats;
608
+ }
609
+
610
+ /**
611
+ * 终止所有 Worker
612
+ */
613
+ async terminate() {
614
+ const pendingCount = this._pending.size;
615
+ this._debug('TERMINATE_START', `workers=${this._workers.length} pending=${pendingCount}`);
616
+
617
+ for (const [, pending] of this._pending) {
618
+ clearTimeout(pending.timeout);
619
+ pending.reject(new Error('Worker Pool 已关闭'));
620
+ }
621
+ this._pending.clear();
622
+ this._taskStartTimes.clear();
623
+
624
+ await Promise.all(this._workers.map(w => w.worker.terminate()));
625
+ this._workers = [];
626
+ this.initialized = false;
627
+ this._debug('TERMINATE_DONE', '');
628
+ }
629
+ }
630
+
631
+ // ── 模块级辅助函数 ──
632
+
633
+ /**
634
+ * 无 SAB 环境下的降级 morsel 列表构建
635
+ * 用普通数组模拟 morsel 状态,仍支持动态调度(但不支持跨 Worker 共享状态)
636
+ *
637
+ * @param {number} totalRows - 总行数
638
+ * @param {number} morselSize - 每个 morsel 的行数
639
+ * @returns {Array<{id: number, startRow: number, endRow: number}>}
640
+ */
641
+ function _buildFallbackMorsels(totalRows, morselSize) {
642
+ const morsels = [];
643
+ const size = Math.max(1, morselSize);
644
+ const count = Math.ceil(totalRows / size);
645
+ for (let i = 0; i < count; i++) {
646
+ const start = i * size;
647
+ const end = Math.min(start + size, totalRows);
648
+ morsels.push({ id: i, startRow: start, endRow: end });
649
+ }
650
+ return morsels;
651
+ }