@joystick.js/db-canary 0.0.0-canary.2209

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 (354) hide show
  1. package/.build/getFilesToBuild.js +26 -0
  2. package/.build/getPlatformSafeFilePath.js +6 -0
  3. package/.build/getPlatformSafePath.js +6 -0
  4. package/.build/index.js +88 -0
  5. package/.build/isWindows.js +3 -0
  6. package/API_KEY +1 -0
  7. package/README.md +1821 -0
  8. package/data/data.mdb +0 -0
  9. package/data/lock.mdb +0 -0
  10. package/dist/client/database.js +1 -0
  11. package/dist/client/index.js +1 -0
  12. package/dist/server/cluster/index.js +1 -0
  13. package/dist/server/cluster/master.js +20 -0
  14. package/dist/server/cluster/worker.js +1 -0
  15. package/dist/server/index.js +1 -0
  16. package/dist/server/lib/api_key_manager.js +9 -0
  17. package/dist/server/lib/auth_manager.js +1 -0
  18. package/dist/server/lib/auto_index_manager.js +1 -0
  19. package/dist/server/lib/backup_manager.js +1 -0
  20. package/dist/server/lib/connection_manager.js +1 -0
  21. package/dist/server/lib/disk_utils.js +2 -0
  22. package/dist/server/lib/http_server.js +405 -0
  23. package/dist/server/lib/index_manager.js +1 -0
  24. package/dist/server/lib/load_settings.js +1 -0
  25. package/dist/server/lib/logger.js +1 -0
  26. package/dist/server/lib/op_types.js +1 -0
  27. package/dist/server/lib/operation_dispatcher.js +1 -0
  28. package/dist/server/lib/operations/admin.js +1 -0
  29. package/dist/server/lib/operations/bulk_write.js +1 -0
  30. package/dist/server/lib/operations/create_index.js +1 -0
  31. package/dist/server/lib/operations/delete_one.js +1 -0
  32. package/dist/server/lib/operations/drop_index.js +1 -0
  33. package/dist/server/lib/operations/find.js +1 -0
  34. package/dist/server/lib/operations/find_one.js +1 -0
  35. package/dist/server/lib/operations/get_indexes.js +1 -0
  36. package/dist/server/lib/operations/insert_one.js +1 -0
  37. package/dist/server/lib/operations/update_one.js +1 -0
  38. package/dist/server/lib/performance_monitor.js +1 -0
  39. package/dist/server/lib/query_engine.js +1 -0
  40. package/dist/server/lib/recovery_manager.js +1 -0
  41. package/dist/server/lib/replication_manager.js +1 -0
  42. package/dist/server/lib/safe_json_parse.js +1 -0
  43. package/dist/server/lib/send_response.js +1 -0
  44. package/dist/server/lib/tcp_protocol.js +1 -0
  45. package/dist/server/lib/write_forwarder.js +1 -0
  46. package/dist/server/lib/write_queue.js +1 -0
  47. package/increment_version.js +3 -0
  48. package/logs/.013e15b54597d05db4b4b53ecc37b10c92a72927-audit.json +20 -0
  49. package/logs/.02de550a67ea0f5961faa2dfd458a4d06f59ebd1-audit.json +20 -0
  50. package/logs/.03494ba24eb3c72214b4068a77d54b8993bee651-audit.json +20 -0
  51. package/logs/.06309ec60b339be1259a7993dd09c732f8907fbc-audit.json +20 -0
  52. package/logs/.0663a04dcfa17285661e5e1b8cfa51f41523b210-audit.json +20 -0
  53. package/logs/.0f06e6c4c9b824622729e13927587479e5060391-audit.json +20 -0
  54. package/logs/.16ccf58682ecb22b3e3ec63f0da1b7fe9be56528-audit.json +20 -0
  55. package/logs/.1fa1a5d02f496474b1ab473524c65c984146a9ad-audit.json +20 -0
  56. package/logs/.2223c0ae3bea6f0d62c62b1d319cc8634856abb7-audit.json +20 -0
  57. package/logs/.23dc79ffda3e083665e6f5993f59397adcbf4a46-audit.json +20 -0
  58. package/logs/.28104f49b03906b189eefd1cd462cb46c3c0af22-audit.json +20 -0
  59. package/logs/.29cdbf13808abe6a0ce70ee2f2efdd680ce3fd8e-audit.json +20 -0
  60. package/logs/.2a9889afd071f77f41f5170d08703a0afca866b7-audit.json +20 -0
  61. package/logs/.2acec3d1940a2bbed487528b703ee5948959a599-audit.json +20 -0
  62. package/logs/.2fb60ff326338c02bfedbcd0e936444e4a216750-audit.json +20 -0
  63. package/logs/.318fc7a19530d76a345f030f7cad00dda15300e7-audit.json +20 -0
  64. package/logs/.3cf27043e19085f908cedc7701e6d013463208ee-audit.json +25 -0
  65. package/logs/.3d90d785415817fc443402843b7c95f8371adc9b-audit.json +20 -0
  66. package/logs/.4074bca620375f72966fc52dfd439577727671e5-audit.json +20 -0
  67. package/logs/.40eecf018417ea80a70ea8ec7a3cc9406bc6334b-audit.json +20 -0
  68. package/logs/.50e974f1ef7c365fca6a1251b2e2c2252914cb5e-audit.json +20 -0
  69. package/logs/.52cb7d9e4223cf26ba36006ac26b949a97c7923c-audit.json +20 -0
  70. package/logs/.54befcdb84c15aad980705a31bcc9f555c3577ab-audit.json +20 -0
  71. package/logs/.57dfb70e22eddb84db2e3c0ceeefac5c0b9baffa-audit.json +20 -0
  72. package/logs/.5f0b24705a1eaad4eca4968f2d86f91b3f9be683-audit.json +20 -0
  73. package/logs/.61ba98fdda7db58576b382fee07904e5db1169d6-audit.json +20 -0
  74. package/logs/.6235017727ef6b199d569a99d6aa8c8e80a1b475-audit.json +20 -0
  75. package/logs/.63db16193699219489d218a1ddea5dde3750cae4-audit.json +20 -0
  76. package/logs/.64fb67dfe14149c9eef728d79bf30a54da809c60-audit.json +20 -0
  77. package/logs/.669137453368987c1f311b5345342527afb54e50-audit.json +20 -0
  78. package/logs/.7a71f8c89ea28ae266d356aeff6306e876a30fbb-audit.json +20 -0
  79. package/logs/.7afbaa90fe9dc3a7d682676f9bb79f9a1b1fd9a6-audit.json +20 -0
  80. package/logs/.7ca29e322cd05327035de850099e7610864f2347-audit.json +20 -0
  81. package/logs/.83335ab3347e449dae03455a110aaf7f120d4802-audit.json +20 -0
  82. package/logs/.8c2487b5fd445d2c8e5c483c80b9fa99bbf1ca58-audit.json +20 -0
  83. package/logs/.8c8b9dc386922c9f3b4c13251af7052aac1d24c0-audit.json +20 -0
  84. package/logs/.8d6155d94640c4863301ae0fee5e4e7372a21446-audit.json +20 -0
  85. package/logs/.944a3119a243deea7c8270d5d9e582bb1d0eaa10-audit.json +20 -0
  86. package/logs/.9816a845c30fb2909f3b26a23eeb3538ebcad5db-audit.json +20 -0
  87. package/logs/.9dc08784e38b865488177c26d4af5934555e0323-audit.json +20 -0
  88. package/logs/.9dd27d2e0e454ac0a37600206d1cac5493b0d7ee-audit.json +20 -0
  89. package/logs/.a3d486feeac7654c59b547de96600e8849a06d4f-audit.json +20 -0
  90. package/logs/.a5b811f4def22250f86cc18870d7c4573625df22-audit.json +20 -0
  91. package/logs/.a61648eb5f830e0b6f508ac35e4f8f629d2ad4c7-audit.json +20 -0
  92. package/logs/.a89016d507045771b4b5a65656944a9c0f1e528b-audit.json +20 -0
  93. package/logs/.a99bee160a1c590be959af46bacc02724803f691-audit.json +20 -0
  94. package/logs/.ada7906d6243fd7da802f03d86c4ae5dd9df6236-audit.json +20 -0
  95. package/logs/.b518339ee942143b6af983af167f5bbb6983b4de-audit.json +20 -0
  96. package/logs/.b51b124b166d53c9519017856ea610d61d65fabe-audit.json +20 -0
  97. package/logs/.b7a6aee19f58e55633d5e4a3709041c47dfff975-audit.json +20 -0
  98. package/logs/.bd7a8a6ba9c55d557a4867ab53f02e3ec2e1553d-audit.json +20 -0
  99. package/logs/.c1435dafe453b169d6392b25065f3cf4ab6fbb21-audit.json +20 -0
  100. package/logs/.c17e1ce043109f77dc2f0e2aa290a9d1ed842c03-audit.json +20 -0
  101. package/logs/.ca62637ce9540e5a38a2fbedb2115febb6ad308a-audit.json +15 -0
  102. package/logs/.ccee67b9c176967f8977071409a41f5cb5cd6ad4-audit.json +20 -0
  103. package/logs/.db24043417ea79a6f14cd947476399e53930b48d-audit.json +20 -0
  104. package/logs/.e0f12acccb57829f5f33712bb2e2607ecd808147-audit.json +20 -0
  105. package/logs/.e9b6cc33d0bbd2e644c4e2bf44d177f850016557-audit.json +20 -0
  106. package/logs/.f15291d434808e3bdca7963ccd2e73893be027e6-audit.json +20 -0
  107. package/logs/.f4bdf9e21ef84f8a3fae3ffb32bbc39275991351-audit.json +15 -0
  108. package/logs/.fbac3aefac1e81b4230df5aa50667cb90d51024f-audit.json +20 -0
  109. package/logs/.fcfd495c0a9169db243f4a4f21878ee02b76413c-audit.json +20 -0
  110. package/logs/admin-2025-09-12.log +580 -0
  111. package/logs/admin-2025-09-15.log +283 -0
  112. package/logs/admin-error-2025-09-12.log +22 -0
  113. package/logs/admin-error-2025-09-15.log +10 -0
  114. package/logs/api_key_manager-2025-09-12.log +658 -0
  115. package/logs/api_key_manager-2025-09-15.log +295 -0
  116. package/logs/api_key_manager-error-2025-09-12.log +0 -0
  117. package/logs/api_key_manager-error-2025-09-15.log +0 -0
  118. package/logs/auth_manager-2025-09-12.log +4432 -0
  119. package/logs/auth_manager-2025-09-15.log +2000 -0
  120. package/logs/auth_manager-error-2025-09-12.log +11 -0
  121. package/logs/auth_manager-error-2025-09-15.log +5 -0
  122. package/logs/auto_index_manager-2025-09-12.log +84 -0
  123. package/logs/auto_index_manager-2025-09-15.log +45 -0
  124. package/logs/auto_index_manager-error-2025-09-12.log +6 -0
  125. package/logs/auto_index_manager-error-2025-09-15.log +0 -0
  126. package/logs/backup_manager-2025-09-12.log +198 -0
  127. package/logs/backup_manager-2025-09-15.log +90 -0
  128. package/logs/backup_manager-error-2025-09-12.log +198 -0
  129. package/logs/backup_manager-error-2025-09-15.log +90 -0
  130. package/logs/bulk_write-2025-09-12.log +66 -0
  131. package/logs/bulk_write-2025-09-15.log +38 -0
  132. package/logs/bulk_write-error-2025-09-12.log +0 -0
  133. package/logs/bulk_write-error-2025-09-15.log +0 -0
  134. package/logs/connection_manager-2025-09-12.log +2412 -0
  135. package/logs/connection_manager-2025-09-15.log +1132 -0
  136. package/logs/connection_manager-error-2025-09-12.log +0 -0
  137. package/logs/connection_manager-error-2025-09-15.log +0 -0
  138. package/logs/create_index-2025-09-12.log +302 -0
  139. package/logs/create_index-2025-09-15.log +158 -0
  140. package/logs/create_index-error-2025-09-12.log +30 -0
  141. package/logs/create_index-error-2025-09-15.log +13 -0
  142. package/logs/delete_one-2025-09-12.log +73 -0
  143. package/logs/delete_one-2025-09-15.log +43 -0
  144. package/logs/delete_one-error-2025-09-12.log +0 -0
  145. package/logs/delete_one-error-2025-09-15.log +0 -0
  146. package/logs/disk_utils-2025-09-12.log +4954 -0
  147. package/logs/disk_utils-2025-09-15.log +2446 -0
  148. package/logs/disk_utils-error-2025-09-12.log +0 -0
  149. package/logs/disk_utils-error-2025-09-15.log +0 -0
  150. package/logs/drop_index-2025-09-12.log +41 -0
  151. package/logs/drop_index-2025-09-15.log +23 -0
  152. package/logs/drop_index-error-2025-09-12.log +11 -0
  153. package/logs/drop_index-error-2025-09-15.log +5 -0
  154. package/logs/find-2025-09-12.log +1050 -0
  155. package/logs/find-2025-09-15.log +592 -0
  156. package/logs/find-error-2025-09-12.log +1 -0
  157. package/logs/find-error-2025-09-15.log +0 -0
  158. package/logs/find_one-2025-09-12.log +425 -0
  159. package/logs/find_one-2025-09-15.log +264 -0
  160. package/logs/find_one-error-2025-09-12.log +5 -0
  161. package/logs/find_one-error-2025-09-15.log +0 -0
  162. package/logs/get_indexes-2025-09-12.log +84 -0
  163. package/logs/get_indexes-2025-09-15.log +56 -0
  164. package/logs/get_indexes-error-2025-09-12.log +6 -0
  165. package/logs/get_indexes-error-2025-09-15.log +0 -0
  166. package/logs/http_server-2025-09-12.log +2772 -0
  167. package/logs/http_server-2025-09-15.log +1276 -0
  168. package/logs/http_server-error-2025-09-12.log +212 -0
  169. package/logs/http_server-error-2025-09-15.log +44 -0
  170. package/logs/index_manager-2025-09-12.log +5031 -0
  171. package/logs/index_manager-2025-09-15.log +2909 -0
  172. package/logs/index_manager-error-2025-09-12.log +80 -0
  173. package/logs/index_manager-error-2025-09-15.log +38 -0
  174. package/logs/insert_one-2025-09-12.log +2181 -0
  175. package/logs/insert_one-2025-09-15.log +1293 -0
  176. package/logs/insert_one-error-2025-09-12.log +0 -0
  177. package/logs/insert_one-error-2025-09-15.log +0 -0
  178. package/logs/master-2025-09-12.log +1882 -0
  179. package/logs/master-2025-09-15.log +910 -0
  180. package/logs/master-error-2025-09-12.log +80 -0
  181. package/logs/master-error-2025-09-15.log +0 -0
  182. package/logs/operation_dispatcher-2025-09-12.log +751 -0
  183. package/logs/operation_dispatcher-2025-09-15.log +359 -0
  184. package/logs/operation_dispatcher-error-2025-09-12.log +33 -0
  185. package/logs/operation_dispatcher-error-2025-09-15.log +11 -0
  186. package/logs/performance_monitor-2025-09-12.log +14889 -0
  187. package/logs/performance_monitor-2025-09-15.log +6803 -0
  188. package/logs/performance_monitor-error-2025-09-12.log +0 -0
  189. package/logs/performance_monitor-error-2025-09-15.log +0 -0
  190. package/logs/query_engine-2025-09-12.log +5310 -0
  191. package/logs/query_engine-2025-09-15.log +2639 -0
  192. package/logs/query_engine-error-2025-09-12.log +0 -0
  193. package/logs/query_engine-error-2025-09-15.log +0 -0
  194. package/logs/recovery_manager-2025-09-12.log +462 -0
  195. package/logs/recovery_manager-2025-09-15.log +210 -0
  196. package/logs/recovery_manager-error-2025-09-12.log +22 -0
  197. package/logs/recovery_manager-error-2025-09-15.log +10 -0
  198. package/logs/replication-2025-09-12.log +1923 -0
  199. package/logs/replication-2025-09-15.log +917 -0
  200. package/logs/replication-error-2025-09-12.log +33 -0
  201. package/logs/replication-error-2025-09-15.log +15 -0
  202. package/logs/server-2025-09-12.log +2601 -0
  203. package/logs/server-2025-09-15.log +1191 -0
  204. package/logs/server-error-2025-09-12.log +0 -0
  205. package/logs/server-error-2025-09-15.log +0 -0
  206. package/logs/tcp_protocol-2025-09-12.log +22 -0
  207. package/logs/tcp_protocol-2025-09-15.log +10 -0
  208. package/logs/tcp_protocol-error-2025-09-12.log +22 -0
  209. package/logs/tcp_protocol-error-2025-09-15.log +10 -0
  210. package/logs/test-2025-09-12.log +0 -0
  211. package/logs/test-2025-09-15.log +0 -0
  212. package/logs/test-error-2025-09-12.log +0 -0
  213. package/logs/test-error-2025-09-15.log +0 -0
  214. package/logs/update_one-2025-09-12.log +173 -0
  215. package/logs/update_one-2025-09-15.log +118 -0
  216. package/logs/update_one-error-2025-09-12.log +0 -0
  217. package/logs/update_one-error-2025-09-15.log +0 -0
  218. package/logs/worker-2025-09-12.log +1457 -0
  219. package/logs/worker-2025-09-15.log +695 -0
  220. package/logs/worker-error-2025-09-12.log +0 -0
  221. package/logs/worker-error-2025-09-15.log +0 -0
  222. package/logs/write_forwarder-2025-09-12.log +1956 -0
  223. package/logs/write_forwarder-2025-09-15.log +932 -0
  224. package/logs/write_forwarder-error-2025-09-12.log +66 -0
  225. package/logs/write_forwarder-error-2025-09-15.log +30 -0
  226. package/logs/write_queue-2025-09-12.log +612 -0
  227. package/logs/write_queue-2025-09-15.log +301 -0
  228. package/logs/write_queue-error-2025-09-12.log +184 -0
  229. package/logs/write_queue-error-2025-09-15.log +83 -0
  230. package/package.json +48 -0
  231. package/prompts/01-core-infrastructure.md +56 -0
  232. package/prompts/02-secondary-indexing.md +65 -0
  233. package/prompts/03-write-serialization.md +63 -0
  234. package/prompts/04-enhanced-authentication.md +75 -0
  235. package/prompts/05-comprehensive-admin-operations.md +75 -0
  236. package/prompts/06-backup-and-restore-system.md +106 -0
  237. package/prompts/07-production-safety-features.md +107 -0
  238. package/prompts/08-tcp-client-library.md +121 -0
  239. package/prompts/09-api-method-chaining.md +134 -0
  240. package/prompts/10-automatic-index-creation.md +223 -0
  241. package/prompts/11-operation-naming-consistency.md +268 -0
  242. package/prompts/12-tcp-replication-system.md +333 -0
  243. package/prompts/13-master-read-write-operations.md +57 -0
  244. package/prompts/14-index-upsert-operations.md +68 -0
  245. package/prompts/15-client-api-return-types.md +81 -0
  246. package/prompts/16-server-setup-ui.md +97 -0
  247. package/prompts/17-emergency-password-change.md +108 -0
  248. package/prompts/18-joystick-framework-integration.md +116 -0
  249. package/prompts/19-api-key-authentication-system.md +137 -0
  250. package/prompts/20-configurable-server-port.md +105 -0
  251. package/prompts/21-multi-database-support.md +161 -0
  252. package/prompts/FULL_TEXT_SEARCH.md +293 -0
  253. package/prompts/PROMPTS.md +158 -0
  254. package/prompts/README.md +221 -0
  255. package/prompts/TYPESCRIPT_GENERATION.md +179 -0
  256. package/src/client/database.js +166 -0
  257. package/src/client/index.js +752 -0
  258. package/src/server/cluster/index.js +53 -0
  259. package/src/server/cluster/master.js +774 -0
  260. package/src/server/cluster/worker.js +537 -0
  261. package/src/server/index.js +540 -0
  262. package/src/server/lib/api_key_manager.js +473 -0
  263. package/src/server/lib/auth_manager.js +375 -0
  264. package/src/server/lib/auto_index_manager.js +681 -0
  265. package/src/server/lib/backup_manager.js +650 -0
  266. package/src/server/lib/connection_manager.js +218 -0
  267. package/src/server/lib/disk_utils.js +118 -0
  268. package/src/server/lib/http_server.js +1165 -0
  269. package/src/server/lib/index_manager.js +756 -0
  270. package/src/server/lib/load_settings.js +143 -0
  271. package/src/server/lib/logger.js +135 -0
  272. package/src/server/lib/op_types.js +29 -0
  273. package/src/server/lib/operation_dispatcher.js +268 -0
  274. package/src/server/lib/operations/admin.js +808 -0
  275. package/src/server/lib/operations/bulk_write.js +367 -0
  276. package/src/server/lib/operations/create_index.js +68 -0
  277. package/src/server/lib/operations/delete_one.js +114 -0
  278. package/src/server/lib/operations/drop_index.js +58 -0
  279. package/src/server/lib/operations/find.js +340 -0
  280. package/src/server/lib/operations/find_one.js +319 -0
  281. package/src/server/lib/operations/get_indexes.js +52 -0
  282. package/src/server/lib/operations/insert_one.js +113 -0
  283. package/src/server/lib/operations/update_one.js +225 -0
  284. package/src/server/lib/performance_monitor.js +313 -0
  285. package/src/server/lib/query_engine.js +243 -0
  286. package/src/server/lib/recovery_manager.js +388 -0
  287. package/src/server/lib/replication_manager.js +727 -0
  288. package/src/server/lib/safe_json_parse.js +21 -0
  289. package/src/server/lib/send_response.js +47 -0
  290. package/src/server/lib/tcp_protocol.js +130 -0
  291. package/src/server/lib/write_forwarder.js +636 -0
  292. package/src/server/lib/write_queue.js +335 -0
  293. package/test_data/data.mdb +0 -0
  294. package/test_data/lock.mdb +0 -0
  295. package/tests/client/index.test.js +1232 -0
  296. package/tests/server/cluster/cluster.test.js +248 -0
  297. package/tests/server/cluster/master_read_write_operations.test.js +577 -0
  298. package/tests/server/index.test.js +651 -0
  299. package/tests/server/integration/authentication_integration.test.js +294 -0
  300. package/tests/server/integration/auto_indexing_integration.test.js +268 -0
  301. package/tests/server/integration/backup_integration.test.js +513 -0
  302. package/tests/server/integration/indexing_integration.test.js +126 -0
  303. package/tests/server/integration/production_safety_integration.test.js +358 -0
  304. package/tests/server/integration/replication_integration.test.js +227 -0
  305. package/tests/server/integration/write_serialization_integration.test.js +246 -0
  306. package/tests/server/lib/api_key_manager.test.js +516 -0
  307. package/tests/server/lib/auth_manager.test.js +317 -0
  308. package/tests/server/lib/auto_index_manager.test.js +275 -0
  309. package/tests/server/lib/backup_manager.test.js +238 -0
  310. package/tests/server/lib/connection_manager.test.js +221 -0
  311. package/tests/server/lib/disk_utils.test.js +63 -0
  312. package/tests/server/lib/http_server.test.js +389 -0
  313. package/tests/server/lib/index_manager.test.js +301 -0
  314. package/tests/server/lib/load_settings.test.js +107 -0
  315. package/tests/server/lib/load_settings_port_config.test.js +243 -0
  316. package/tests/server/lib/logger.test.js +282 -0
  317. package/tests/server/lib/operations/admin.test.js +638 -0
  318. package/tests/server/lib/operations/bulk_write.test.js +128 -0
  319. package/tests/server/lib/operations/create_index.test.js +138 -0
  320. package/tests/server/lib/operations/delete_one.test.js +52 -0
  321. package/tests/server/lib/operations/drop_index.test.js +72 -0
  322. package/tests/server/lib/operations/find.test.js +93 -0
  323. package/tests/server/lib/operations/find_one.test.js +91 -0
  324. package/tests/server/lib/operations/get_indexes.test.js +87 -0
  325. package/tests/server/lib/operations/insert_one.test.js +42 -0
  326. package/tests/server/lib/operations/update_one.test.js +89 -0
  327. package/tests/server/lib/performance_monitor.test.js +185 -0
  328. package/tests/server/lib/query_engine.test.js +46 -0
  329. package/tests/server/lib/recovery_manager.test.js +414 -0
  330. package/tests/server/lib/replication_manager.test.js +202 -0
  331. package/tests/server/lib/safe_json_parse.test.js +45 -0
  332. package/tests/server/lib/send_response.test.js +155 -0
  333. package/tests/server/lib/tcp_protocol.test.js +169 -0
  334. package/tests/server/lib/write_forwarder.test.js +258 -0
  335. package/tests/server/lib/write_queue.test.js +255 -0
  336. package/tsconfig.json +30 -0
  337. package/types/client/index.d.ts +447 -0
  338. package/types/server/cluster/index.d.ts +28 -0
  339. package/types/server/cluster/master.d.ts +115 -0
  340. package/types/server/cluster/worker.d.ts +1 -0
  341. package/types/server/lib/auth_manager.d.ts +13 -0
  342. package/types/server/lib/backup_manager.d.ts +43 -0
  343. package/types/server/lib/connection_manager.d.ts +15 -0
  344. package/types/server/lib/disk_utils.d.ts +3 -0
  345. package/types/server/lib/index_manager.d.ts +24 -0
  346. package/types/server/lib/load_settings.d.ts +4 -0
  347. package/types/server/lib/logger.d.ts +44 -0
  348. package/types/server/lib/op_types.d.ts +6 -0
  349. package/types/server/lib/performance_monitor.d.ts +68 -0
  350. package/types/server/lib/query_engine.d.ts +10 -0
  351. package/types/server/lib/safe_json_parse.d.ts +7 -0
  352. package/types/server/lib/send_response.d.ts +3 -0
  353. package/types/server/lib/tcp_protocol.d.ts +12 -0
  354. package/types/server/lib/write_queue.d.ts +2 -0
@@ -0,0 +1,577 @@
1
+ import test from 'ava';
2
+ import net from 'net';
3
+ import cluster from 'cluster';
4
+ import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
5
+ import { start_cluster } from '../../../src/server/cluster/index.js';
6
+ import { setup_authentication, reset_auth_state } from '../../../src/server/lib/auth_manager.js';
7
+
8
+ const create_test_settings = () => ({
9
+ port: 1983,
10
+ cluster: true,
11
+ worker_count: 2,
12
+ authentication: {},
13
+ backup: { enabled: false },
14
+ replication: { enabled: false, role: "primary" },
15
+ auto_indexing: { enabled: true, threshold: 100 },
16
+ performance: {
17
+ monitoring_enabled: true,
18
+ log_slow_queries: true,
19
+ slow_query_threshold_ms: 1000
20
+ },
21
+ logging: { level: "info", structured: true }
22
+ });
23
+
24
+ const cleanup_cluster_state = async () => {
25
+ // Force kill any remaining workers from previous tests
26
+ for (const worker_id in cluster.workers) {
27
+ const worker = cluster.workers[worker_id];
28
+ if (worker && !worker.isDead()) {
29
+ try {
30
+ worker.kill('SIGKILL');
31
+ } catch (error) {
32
+ // Ignore kill errors
33
+ }
34
+ }
35
+ }
36
+
37
+ // Clear cluster workers map
38
+ for (const worker_id in cluster.workers) {
39
+ delete cluster.workers[worker_id];
40
+ }
41
+
42
+ // Remove all cluster event listeners to prevent cross-test interference
43
+ cluster.removeAllListeners();
44
+
45
+ // Wait longer for cleanup to complete
46
+ await new Promise(resolve => setTimeout(resolve, 500));
47
+ };
48
+
49
+ test.beforeEach(async () => {
50
+ reset_auth_state();
51
+ shared_password = null; // Reset shared password for each test
52
+ process.env.JOYSTICK_DB_SETTINGS = JSON.stringify(create_test_settings());
53
+
54
+ // Clean up any lingering cluster state
55
+ await cleanup_cluster_state();
56
+ });
57
+
58
+ test.afterEach(async () => {
59
+ reset_auth_state();
60
+ shared_password = null; // Reset shared password after each test
61
+ delete process.env.JOYSTICK_DB_SETTINGS;
62
+
63
+ // Clean up cluster state after each test
64
+ await cleanup_cluster_state();
65
+ });
66
+
67
+ const create_client = (port) => {
68
+ return new Promise((resolve, reject) => {
69
+ const client = net.createConnection(port, 'localhost');
70
+ const parser = create_message_parser();
71
+
72
+ client.on('connect', () => {
73
+ resolve({
74
+ client,
75
+ send: (data) => {
76
+ const encoded = encode_message(data);
77
+ client.write(encoded);
78
+ },
79
+ receive: () => {
80
+ return new Promise((resolve, reject) => {
81
+ const handler = (data) => {
82
+ try {
83
+ const messages = parser.parse_messages(data);
84
+ for (const message of messages) {
85
+ client.off('data', handler);
86
+ client.off('close', close_handler);
87
+ client.off('error', error_handler);
88
+ resolve(message);
89
+ return;
90
+ }
91
+ } catch (error) {
92
+ // Continue listening
93
+ }
94
+ };
95
+
96
+ const close_handler = () => {
97
+ client.off('data', handler);
98
+ client.off('error', error_handler);
99
+ reject(new Error('Connection closed before receiving response'));
100
+ };
101
+
102
+ const error_handler = (error) => {
103
+ client.off('data', handler);
104
+ client.off('close', close_handler);
105
+ reject(error);
106
+ };
107
+
108
+ client.on('data', handler);
109
+ client.on('close', close_handler);
110
+ client.on('error', error_handler);
111
+ });
112
+ },
113
+ close: () => {
114
+ client.end();
115
+ }
116
+ });
117
+ });
118
+
119
+ client.on('error', reject);
120
+ });
121
+ };
122
+
123
+ let shared_password = null;
124
+
125
+ const authenticate_client = async (client) => {
126
+ // Setup authentication only once and reuse the password
127
+ if (!shared_password) {
128
+ shared_password = setup_authentication();
129
+ }
130
+
131
+ client.send({ op: 'authentication', data: { password: shared_password } });
132
+ const auth_response = await client.receive();
133
+
134
+ if (auth_response.ok !== 1) {
135
+ throw new Error(`Authentication failed: ${auth_response.error || 'Unknown error'}`);
136
+ }
137
+
138
+ return shared_password;
139
+ };
140
+
141
+ test.serial('master node handles read operations - find_one', async (t) => {
142
+ process.env.NODE_ENV = 'test';
143
+
144
+ const master = start_cluster({
145
+ worker_count: 1,
146
+ port: 1990
147
+ });
148
+
149
+ let client = null;
150
+
151
+ try {
152
+ await new Promise(resolve => setTimeout(resolve, 3000));
153
+
154
+ client = await create_client(1990);
155
+
156
+ // Authenticate using setup flow
157
+ await authenticate_client(client);
158
+
159
+ // Insert a document first
160
+ client.send({
161
+ op: 'insert_one',
162
+ data: {
163
+ collection: 'test_master_reads',
164
+ document: { name: 'test_doc', value: 42 }
165
+ }
166
+ });
167
+ const insert_response = await client.receive();
168
+ t.is(insert_response.ok, 1);
169
+
170
+ // Wait a bit before the read operation to ensure write is fully committed
171
+ await new Promise(resolve => setTimeout(resolve, 100));
172
+
173
+ // Test find_one operation (read operation)
174
+ client.send({
175
+ op: 'find_one',
176
+ data: {
177
+ collection: 'test_master_reads',
178
+ filter: { name: 'test_doc' }
179
+ }
180
+ });
181
+ const find_response = await client.receive();
182
+ t.is(find_response.ok, 1);
183
+ t.truthy(find_response.name, 'Response should have name field');
184
+ t.is(find_response.name, 'test_doc');
185
+ t.is(find_response.value, 42);
186
+
187
+ } finally {
188
+ if (client) {
189
+ try {
190
+ client.close();
191
+ } catch (error) {
192
+ // Ignore cleanup errors
193
+ }
194
+ }
195
+
196
+ // Wait for any pending operations to complete before shutdown
197
+ await new Promise(resolve => setTimeout(resolve, 500));
198
+
199
+ try {
200
+ await master.shutdown();
201
+ } catch (error) {
202
+ // Ignore shutdown errors in tests
203
+ }
204
+
205
+ await new Promise(resolve => setTimeout(resolve, 2000));
206
+
207
+ if (global.gc) {
208
+ global.gc();
209
+ }
210
+ }
211
+ });
212
+
213
+ test.serial('master node handles read operations - find', async (t) => {
214
+ process.env.NODE_ENV = 'test';
215
+
216
+ const master = start_cluster({
217
+ worker_count: 1,
218
+ port: 1991
219
+ });
220
+
221
+ let client = null;
222
+
223
+ try {
224
+ await new Promise(resolve => setTimeout(resolve, 3000));
225
+
226
+ client = await create_client(1991);
227
+
228
+ // Authenticate using setup flow
229
+ await authenticate_client(client);
230
+
231
+ // Insert multiple documents with longer wait between inserts
232
+ client.send({
233
+ op: 'insert_one',
234
+ data: {
235
+ collection: 'test_master_find',
236
+ document: { category: 'test', value: 1 }
237
+ }
238
+ });
239
+ const insert1_response = await client.receive();
240
+ t.is(insert1_response.ok, 1);
241
+
242
+ // Wait longer between inserts to ensure proper commit
243
+ await new Promise(resolve => setTimeout(resolve, 200));
244
+
245
+ client.send({
246
+ op: 'insert_one',
247
+ data: {
248
+ collection: 'test_master_find',
249
+ document: { category: 'test', value: 2 }
250
+ }
251
+ });
252
+ const insert2_response = await client.receive();
253
+ t.is(insert2_response.ok, 1);
254
+
255
+ // Wait longer to ensure both documents are fully committed
256
+ await new Promise(resolve => setTimeout(resolve, 300));
257
+
258
+ // Test find operation (read operation)
259
+ client.send({
260
+ op: 'find',
261
+ data: {
262
+ collection: 'test_master_find',
263
+ filter: { category: 'test' }
264
+ }
265
+ });
266
+ const find_response = await client.receive();
267
+ t.is(find_response.ok, 1);
268
+ t.is(Array.isArray(find_response.documents), true);
269
+ t.is(find_response.documents.length >= 2, true);
270
+
271
+ } finally {
272
+ if (client) {
273
+ try {
274
+ client.close();
275
+ } catch (error) {
276
+ // Ignore cleanup errors
277
+ }
278
+ }
279
+
280
+ // Wait for any pending operations to complete before shutdown
281
+ await new Promise(resolve => setTimeout(resolve, 500));
282
+
283
+ try {
284
+ await master.shutdown();
285
+ } catch (error) {
286
+ // Ignore shutdown errors in tests
287
+ }
288
+
289
+ await new Promise(resolve => setTimeout(resolve, 2000));
290
+
291
+ if (global.gc) {
292
+ global.gc();
293
+ }
294
+ }
295
+ });
296
+
297
+ test.serial('master node handles read operations - get_indexes', async (t) => {
298
+ process.env.NODE_ENV = 'test';
299
+
300
+ const master = start_cluster({
301
+ worker_count: 1,
302
+ port: 1992
303
+ });
304
+
305
+ let client = null;
306
+
307
+ try {
308
+ await new Promise(resolve => setTimeout(resolve, 3000));
309
+
310
+ client = await create_client(1992);
311
+
312
+ // Authenticate using setup flow
313
+ await authenticate_client(client);
314
+
315
+ // Create an index first
316
+ client.send({
317
+ op: 'create_index',
318
+ data: {
319
+ collection: 'test_master_indexes',
320
+ field: 'name',
321
+ options: {}
322
+ }
323
+ });
324
+ const create_index_response = await client.receive();
325
+ t.is(create_index_response.ok, 1);
326
+
327
+ // Test get_indexes operation (read operation)
328
+ client.send({
329
+ op: 'get_indexes',
330
+ data: {
331
+ collection: 'test_master_indexes'
332
+ }
333
+ });
334
+ const get_indexes_response = await client.receive();
335
+ t.is(get_indexes_response.ok, 1);
336
+ t.is(Array.isArray(get_indexes_response.indexes), true);
337
+ t.is(get_indexes_response.indexes.length, 1);
338
+ t.is(get_indexes_response.indexes[0].field, 'name');
339
+
340
+ } finally {
341
+ if (client) {
342
+ try {
343
+ client.close();
344
+ } catch (error) {
345
+ // Ignore cleanup errors
346
+ }
347
+ }
348
+
349
+ // Wait for any pending operations to complete before shutdown
350
+ await new Promise(resolve => setTimeout(resolve, 500));
351
+
352
+ try {
353
+ await master.shutdown();
354
+ } catch (error) {
355
+ // Ignore shutdown errors in tests
356
+ }
357
+
358
+ await new Promise(resolve => setTimeout(resolve, 2000));
359
+
360
+ if (global.gc) {
361
+ global.gc();
362
+ }
363
+ }
364
+ });
365
+
366
+ test.serial('master node handles mixed read and write operations', async (t) => {
367
+ process.env.NODE_ENV = 'test';
368
+
369
+ const master = start_cluster({
370
+ worker_count: 2,
371
+ port: 1993
372
+ });
373
+
374
+ let client = null;
375
+
376
+ try {
377
+ await new Promise(resolve => setTimeout(resolve, 3000));
378
+
379
+ client = await create_client(1993);
380
+
381
+ // Authenticate using setup flow
382
+ await authenticate_client(client);
383
+
384
+ // Mixed operations sequence with proper waits
385
+
386
+ // Use unique document name to avoid conflicts with previous test runs
387
+ const unique_doc_name = `doc1_${Date.now()}`;
388
+
389
+ // 1. Write: Insert document
390
+ client.send({
391
+ op: 'insert_one',
392
+ data: {
393
+ collection: 'test_mixed_ops',
394
+ document: { name: unique_doc_name, status: 'active' }
395
+ }
396
+ });
397
+ const insert_response = await client.receive();
398
+ t.is(insert_response.ok, 1);
399
+
400
+ // Wait for write to commit
401
+ await new Promise(resolve => setTimeout(resolve, 100));
402
+
403
+ // 2. Read: Find the document
404
+ client.send({
405
+ op: 'find_one',
406
+ data: {
407
+ collection: 'test_mixed_ops',
408
+ filter: { name: unique_doc_name }
409
+ }
410
+ });
411
+ const find_response = await client.receive();
412
+ t.is(find_response.ok, 1);
413
+ t.is(find_response.name, unique_doc_name);
414
+ t.is(find_response.status, 'active');
415
+
416
+ // 3. Write: Update document
417
+ client.send({
418
+ op: 'update_one',
419
+ data: {
420
+ collection: 'test_mixed_ops',
421
+ filter: { name: unique_doc_name },
422
+ update: { $set: { status: 'updated' } }
423
+ }
424
+ });
425
+ const update_response = await client.receive();
426
+ t.is(update_response.ok, 1);
427
+ t.is(update_response.modified_count, 1);
428
+
429
+ // Wait for update to commit
430
+ await new Promise(resolve => setTimeout(resolve, 100));
431
+
432
+ // 4. Read: Verify update
433
+ client.send({
434
+ op: 'find_one',
435
+ data: {
436
+ collection: 'test_mixed_ops',
437
+ filter: { name: unique_doc_name }
438
+ }
439
+ });
440
+ const find_updated_response = await client.receive();
441
+ t.is(find_updated_response.ok, 1);
442
+ t.is(find_updated_response.status, 'updated');
443
+
444
+ // 5. Write: Create index
445
+ client.send({
446
+ op: 'create_index',
447
+ data: {
448
+ collection: 'test_mixed_ops',
449
+ field: 'status',
450
+ options: {}
451
+ }
452
+ });
453
+ const create_index_response = await client.receive();
454
+ t.is(create_index_response.ok, 1);
455
+
456
+ // 6. Read: Get indexes
457
+ client.send({
458
+ op: 'get_indexes',
459
+ data: {
460
+ collection: 'test_mixed_ops'
461
+ }
462
+ });
463
+ const get_indexes_response = await client.receive();
464
+ t.is(get_indexes_response.ok, 1);
465
+ t.is(get_indexes_response.indexes.length, 1);
466
+
467
+ } finally {
468
+ if (client) {
469
+ try {
470
+ client.close();
471
+ } catch (error) {
472
+ // Ignore cleanup errors
473
+ }
474
+ }
475
+
476
+ // Wait for any pending operations to complete before shutdown
477
+ await new Promise(resolve => setTimeout(resolve, 500));
478
+
479
+ try {
480
+ await master.shutdown();
481
+ } catch (error) {
482
+ // Ignore shutdown errors in tests
483
+ }
484
+
485
+ await new Promise(resolve => setTimeout(resolve, 2000));
486
+
487
+ if (global.gc) {
488
+ global.gc();
489
+ }
490
+ }
491
+ });
492
+
493
+ test.serial('master node handles concurrent read and write operations', async (t) => {
494
+ process.env.NODE_ENV = 'test';
495
+
496
+ const master = start_cluster({
497
+ worker_count: 2,
498
+ port: 1994
499
+ });
500
+
501
+ const clients = [];
502
+
503
+ try {
504
+ await new Promise(resolve => setTimeout(resolve, 3000));
505
+
506
+ // Create multiple clients and authenticate each one separately
507
+ for (let i = 0; i < 3; i++) {
508
+ const client = await create_client(1994);
509
+ await authenticate_client(client);
510
+ clients.push(client);
511
+
512
+ // Wait between client connections to avoid auth conflicts
513
+ await new Promise(resolve => setTimeout(resolve, 100));
514
+ }
515
+
516
+ // Sequential operations instead of concurrent to avoid auth conflicts
517
+
518
+ // Client 1: Write operation
519
+ clients[0].send({
520
+ op: 'insert_one',
521
+ data: {
522
+ collection: 'test_concurrent',
523
+ document: { id: 1, type: 'write' }
524
+ }
525
+ });
526
+ const insert_result = await clients[0].receive();
527
+ t.is(insert_result.ok, 1);
528
+
529
+ // Wait for write to commit
530
+ await new Promise(resolve => setTimeout(resolve, 200));
531
+
532
+ // Client 2: Read operation
533
+ clients[1].send({
534
+ op: 'find',
535
+ data: {
536
+ collection: 'test_concurrent',
537
+ filter: {}
538
+ }
539
+ });
540
+ const find_result = await clients[1].receive();
541
+ t.is(find_result.ok, 1);
542
+
543
+ // Client 3: Index operation
544
+ clients[2].send({
545
+ op: 'get_indexes',
546
+ data: {
547
+ collection: 'test_concurrent'
548
+ }
549
+ });
550
+ const indexes_result = await clients[2].receive();
551
+ t.is(indexes_result.ok, 1);
552
+
553
+ } finally {
554
+ for (const client of clients) {
555
+ try {
556
+ client.close();
557
+ } catch (error) {
558
+ // Ignore cleanup errors
559
+ }
560
+ }
561
+
562
+ // Wait for any pending operations to complete before shutdown
563
+ await new Promise(resolve => setTimeout(resolve, 500));
564
+
565
+ try {
566
+ await master.shutdown();
567
+ } catch (error) {
568
+ // Ignore shutdown errors in tests
569
+ }
570
+
571
+ await new Promise(resolve => setTimeout(resolve, 2000));
572
+
573
+ if (global.gc) {
574
+ global.gc();
575
+ }
576
+ }
577
+ });