@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,294 @@
1
+ import test from 'ava';
2
+ import sinon from 'sinon';
3
+ import net from 'net';
4
+ import { create_server } from '../../../src/server/index.js';
5
+ import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
6
+ import { initialize_database, cleanup_database } from '../../../src/server/lib/query_engine.js';
7
+ import { setup_authentication, reset_auth_state } from '../../../src/server/lib/auth_manager.js';
8
+
9
+ // Dynamic port allocation
10
+ let current_port = 3000;
11
+ const get_next_port = () => {
12
+ return ++current_port;
13
+ };
14
+
15
+ let server;
16
+ let port;
17
+
18
+ test.beforeEach(async () => {
19
+ // Reset auth state and clean up environment variables
20
+ reset_auth_state();
21
+ delete process.env.JOYSTICK_DB_SETTINGS;
22
+
23
+ // Initialize database for testing
24
+ initialize_database();
25
+
26
+ // Create server with dynamic port
27
+ const test_port = get_next_port();
28
+ server = await create_server();
29
+
30
+ // Start server on specific port
31
+ await new Promise((resolve) => {
32
+ server.listen(test_port, () => {
33
+ port = test_port;
34
+ setTimeout(resolve, 100);
35
+ });
36
+ });
37
+ });
38
+
39
+ test.afterEach(async () => {
40
+ if (server) {
41
+ await server.cleanup();
42
+ server.close();
43
+ server = null;
44
+ }
45
+
46
+ // Clean up database
47
+ try {
48
+ await cleanup_database(true); // Remove test database directory
49
+ } catch (error) {
50
+ // Ignore cleanup errors
51
+ }
52
+
53
+ // Clean up environment variables
54
+ reset_auth_state();
55
+ delete process.env.JOYSTICK_DB_SETTINGS;
56
+ });
57
+
58
+ const create_client = () => {
59
+ return new Promise((resolve, reject) => {
60
+ const client = net.createConnection(port, 'localhost');
61
+ const parser = create_message_parser();
62
+
63
+ client.on('connect', () => {
64
+ resolve({
65
+ client,
66
+ send: (data) => {
67
+ const encoded = encode_message(data);
68
+ client.write(encoded);
69
+ },
70
+ receive: () => {
71
+ return new Promise((resolve) => {
72
+ const handler = (data) => {
73
+ try {
74
+ const messages = parser.parse_messages(data);
75
+ for (const message of messages) {
76
+ client.off('data', handler);
77
+ resolve(message);
78
+ return;
79
+ }
80
+ } catch (error) {
81
+ // Continue listening
82
+ }
83
+ };
84
+ client.on('data', handler);
85
+ });
86
+ },
87
+ close: () => {
88
+ client.end();
89
+ }
90
+ });
91
+ });
92
+
93
+ client.on('error', reject);
94
+ });
95
+ };
96
+
97
+ test('integration - setup command creates authentication and returns password', async (t) => {
98
+ const { client, send, receive, close } = await create_client();
99
+
100
+ try {
101
+ send({ op: 'setup' });
102
+ const response = await receive();
103
+
104
+ t.true(response.ok === 1 || response.ok === true);
105
+ t.is(typeof response.password, 'string');
106
+ t.is(response.password.length, 32);
107
+ t.true(response.message.includes('Authentication setup completed'));
108
+
109
+ // Verify environment variable was created
110
+ t.true(process.env.JOYSTICK_DB_SETTINGS !== undefined);
111
+
112
+ const settings_data = JSON.parse(process.env.JOYSTICK_DB_SETTINGS);
113
+ t.true(typeof settings_data.authentication.password_hash === 'string');
114
+ t.true(typeof settings_data.authentication.created_at === 'string');
115
+ } finally {
116
+ close();
117
+ }
118
+ });
119
+
120
+ test('integration - authentication succeeds with correct password', async (t) => {
121
+ // Setup authentication first
122
+ const password = setup_authentication();
123
+
124
+ const { client, send, receive, close } = await create_client();
125
+
126
+ try {
127
+ send({ op: 'authentication', data: { password } });
128
+ const response = await receive();
129
+
130
+ t.is(response.ok, 1);
131
+ t.is(response.version, '1.0.0');
132
+ t.is(response.message, 'Authentication successful');
133
+ } finally {
134
+ close();
135
+ }
136
+ });
137
+
138
+ test('integration - authentication fails with incorrect password', async (t) => {
139
+ // Setup authentication first
140
+ setup_authentication();
141
+
142
+ const { client, send, receive, close } = await create_client();
143
+
144
+ try {
145
+ send({ op: 'authentication', data: { password: 'wrong_password' } });
146
+ const response = await receive();
147
+
148
+ t.true(response.ok === 0 || response.ok === false);
149
+ t.is(response.error, 'Authentication failed');
150
+ } finally {
151
+ close();
152
+ }
153
+ });
154
+
155
+ test('integration - database operations require authentication', async (t) => {
156
+ // Setup authentication first
157
+ setup_authentication();
158
+
159
+ const { client, send, receive, close } = await create_client();
160
+
161
+ try {
162
+ // Try to perform find operation without authentication
163
+ send({ op: 'find', data: { collection: 'users', filter: {} } });
164
+ const response = await receive();
165
+
166
+ t.true(response.ok === 0 || response.ok === false);
167
+ t.is(response.error, 'Authentication required');
168
+ } finally {
169
+ close();
170
+ }
171
+ });
172
+
173
+ test('integration - database operations work after authentication', async (t) => {
174
+ // Setup authentication first
175
+ const password = setup_authentication();
176
+
177
+ const { client, send, receive, close } = await create_client();
178
+
179
+ try {
180
+ // First authenticate
181
+ send({ op: 'authentication', data: { password } });
182
+ const auth_response = await receive();
183
+ t.is(auth_response.ok, 1);
184
+ t.is(auth_response.version, '1.0.0');
185
+
186
+ // Now try a database operation
187
+ send({ op: 'ping' });
188
+ const ping_response = await receive();
189
+ t.is(ping_response.ok, 1);
190
+ } finally {
191
+ close();
192
+ }
193
+ });
194
+
195
+ test('integration - admin operation includes authentication stats', async (t) => {
196
+ // Setup authentication first
197
+ const password = setup_authentication();
198
+
199
+ const { client, send, receive, close } = await create_client();
200
+
201
+ try {
202
+ // First authenticate
203
+ send({ op: 'authentication', data: { password } });
204
+ const auth_response = await receive();
205
+ t.is(auth_response.ok, 1);
206
+ t.is(auth_response.version, '1.0.0');
207
+
208
+ // Now try admin operation
209
+ send({ op: 'admin' });
210
+ const admin_response = await receive();
211
+
212
+ // This should be the admin response
213
+ t.true(typeof admin_response.authentication === 'object');
214
+ t.is(admin_response.authentication.authenticated_clients, 1);
215
+ t.true(admin_response.authentication.configured);
216
+ t.is(typeof admin_response.authentication.created_at, 'string');
217
+ t.true(typeof admin_response.server === 'object');
218
+ t.true(typeof admin_response.database === 'object');
219
+ } finally {
220
+ close();
221
+ }
222
+ });
223
+
224
+ test('integration - rate limiting blocks multiple failed attempts', async (t) => {
225
+ // Setup authentication first
226
+ setup_authentication();
227
+
228
+ // Make 5 failed attempts
229
+ for (let i = 0; i < 5; i++) {
230
+ const { client, send, receive, close } = await create_client();
231
+
232
+ try {
233
+ send({ op: 'authentication', data: { password: 'wrong_password' } });
234
+ const response = await receive();
235
+
236
+ t.true(response.ok === 0 || response.ok === false);
237
+ t.is(response.error, 'Authentication failed');
238
+ } finally {
239
+ close();
240
+ }
241
+
242
+ // Small delay between attempts
243
+ await new Promise(resolve => setTimeout(resolve, 100));
244
+ }
245
+
246
+ // 6th attempt should be rate limited
247
+ const { client, send, receive, close } = await create_client();
248
+
249
+ try {
250
+ send({ op: 'authentication', data: { password: 'wrong_password' } });
251
+ const response = await receive();
252
+
253
+ t.true(response.ok === 0 || response.ok === false);
254
+ t.true(response.error.includes('Too many failed attempts'));
255
+ } finally {
256
+ close();
257
+ }
258
+ });
259
+
260
+ test('integration - setup fails when authentication already configured', async (t) => {
261
+ // Setup authentication first
262
+ setup_authentication();
263
+
264
+ const { client, send, receive, close } = await create_client();
265
+
266
+ try {
267
+ // Try to setup again
268
+ send({ op: 'setup' });
269
+ const response = await receive();
270
+
271
+ t.true(response.ok === 0 || response.ok === false);
272
+ t.true(response.error.includes('Authentication already configured'));
273
+ } finally {
274
+ close();
275
+ }
276
+ });
277
+
278
+ test('integration - protocol versioning returns correct version', async (t) => {
279
+ // Setup authentication first
280
+ const password = setup_authentication();
281
+
282
+ const { client, send, receive, close } = await create_client();
283
+
284
+ try {
285
+ send({ op: 'authentication', data: { password } });
286
+ const response = await receive();
287
+
288
+ t.is(response.ok, 1);
289
+ t.is(response.version, '1.0.0');
290
+ t.is(response.message, 'Authentication successful');
291
+ } finally {
292
+ close();
293
+ }
294
+ });
@@ -0,0 +1,268 @@
1
+ import test from 'ava';
2
+ import { initialize_database, cleanup_database } from '../../../src/server/lib/query_engine.js';
3
+ import { initialize_index_database, get_indexes, cleanup_index_database } from '../../../src/server/lib/index_manager.js';
4
+ import { initialize_auto_index_database, cleanup_auto_index_database } from '../../../src/server/lib/auto_index_manager.js';
5
+ import find from '../../../src/server/lib/operations/find.js';
6
+ import find_one from '../../../src/server/lib/operations/find_one.js';
7
+ import insert_one from '../../../src/server/lib/operations/insert_one.js';
8
+ import admin from '../../../src/server/lib/operations/admin.js';
9
+
10
+ test.beforeEach(async (t) => {
11
+ initialize_database('./test_data');
12
+ initialize_index_database();
13
+ initialize_auto_index_database();
14
+
15
+ const test_documents = [
16
+ { name: 'Alice', age: 25, department: 'Engineering', salary: 75000 },
17
+ { name: 'Bob', age: 30, department: 'Marketing', salary: 65000 },
18
+ { name: 'Charlie', age: 35, department: 'Engineering', salary: 85000 },
19
+ { name: 'Diana', age: 28, department: 'Sales', salary: 70000 },
20
+ { name: 'Eve', age: 32, department: 'Engineering', salary: 80000 }
21
+ ];
22
+
23
+ for (const doc of test_documents) {
24
+ await insert_one('default', 'employees', doc);
25
+ }
26
+ });
27
+
28
+ test.afterEach(async (t) => {
29
+ cleanup_auto_index_database();
30
+ cleanup_index_database();
31
+ await cleanup_database();
32
+ });
33
+
34
+ test('should record query statistics during find operations', async (t) => {
35
+ await find('default', 'employees', { name: 'Alice' });
36
+ await find('default', 'employees', { age: 25 });
37
+ await find('default', 'employees', { department: 'Engineering' });
38
+
39
+ const stats = await admin('get_query_stats', { collection: 'employees' });
40
+
41
+ t.truthy(stats.name);
42
+ t.truthy(stats.age);
43
+ t.truthy(stats.department);
44
+ t.is(stats.name.query_count, 1);
45
+ t.is(stats.age.query_count, 1);
46
+ t.is(stats.department.query_count, 1);
47
+ });
48
+
49
+ test('should record query statistics during find_one operations', async (t) => {
50
+ await find_one('default', 'employees', { name: 'Bob' });
51
+ await find_one('default', 'employees', { age: 30 });
52
+
53
+ const stats = await admin('get_query_stats', { collection: 'employees' });
54
+
55
+ t.truthy(stats.name);
56
+ t.truthy(stats.age);
57
+ t.is(stats.name.query_count, 1);
58
+ t.is(stats.age.query_count, 1);
59
+ });
60
+
61
+ test('should track execution times for queries', async (t) => {
62
+ await find('default', 'employees', { name: 'Alice' });
63
+ await find('default', 'employees', { name: 'Bob' });
64
+ await find('default', 'employees', { name: 'Charlie' });
65
+
66
+ const stats = await admin('get_query_stats', { collection: 'employees' });
67
+
68
+ t.is(stats.name.query_count, 3);
69
+ t.true(stats.name.total_time_ms >= 0);
70
+ t.true(stats.name.avg_time_ms >= 0);
71
+ t.is(stats.name.avg_time_ms, stats.name.total_time_ms / 3);
72
+ });
73
+
74
+ test('should get auto index statistics', async (t) => {
75
+ const stats = await admin('get_auto_index_stats');
76
+
77
+ t.is(typeof stats, 'object');
78
+ t.is(stats.total_auto_indexes, 0);
79
+ t.is(typeof stats.collections, 'object');
80
+ });
81
+
82
+ test('should force index evaluation', async (t) => {
83
+ for (let i = 0; i < 50; i++) {
84
+ await find('default', 'employees', { name: `User${i}` });
85
+ }
86
+
87
+ const result = await admin('evaluate_auto_indexes', { collection: 'employees' });
88
+ t.is(result.acknowledged, true);
89
+ });
90
+
91
+ test('should force index evaluation for all collections', async (t) => {
92
+ await find('default', 'employees', { name: 'Alice' });
93
+ await find('default', 'products', { category: 'Electronics' });
94
+
95
+ const result = await admin('evaluate_auto_indexes');
96
+ t.is(result.acknowledged, true);
97
+ });
98
+
99
+ test('should remove automatic indexes', async (t) => {
100
+ const result = await admin('remove_auto_indexes', {
101
+ collection: 'employees',
102
+ field_names: ['name']
103
+ });
104
+
105
+ t.is(result.acknowledged, true);
106
+ t.is(typeof result.removed_count, 'number');
107
+ });
108
+
109
+ test('should remove all automatic indexes from collection', async (t) => {
110
+ const result = await admin('remove_auto_indexes', { collection: 'employees' });
111
+
112
+ t.is(result.acknowledged, true);
113
+ t.is(typeof result.removed_count, 'number');
114
+ });
115
+
116
+ test('should handle complex query filters', async (t) => {
117
+ await find('default', 'employees', {
118
+ age: { $gte: 25, $lte: 35 },
119
+ department: { $in: ['Engineering', 'Marketing'] },
120
+ salary: { $gt: 70000 }
121
+ });
122
+
123
+ const stats = await admin('get_query_stats', { collection: 'employees' });
124
+
125
+ t.truthy(stats.age);
126
+ t.truthy(stats.department);
127
+ t.truthy(stats.salary);
128
+ t.is(stats.age.query_count, 1);
129
+ t.is(stats.department.query_count, 1);
130
+ t.is(stats.salary.query_count, 1);
131
+ });
132
+
133
+ test('should track index usage when indexes exist', async (t) => {
134
+ await admin('create_index', { collection: 'employees', field: 'name' });
135
+
136
+ await find('default', 'employees', { name: 'Alice' });
137
+ await find('default', 'employees', { name: 'Bob' });
138
+
139
+ const stats = await admin('get_query_stats', { collection: 'employees' });
140
+
141
+ t.is(stats.name.query_count, 2);
142
+ t.is(stats.name.used_index_count, 2);
143
+ });
144
+
145
+ test('should differentiate between indexed and non-indexed queries', async (t) => {
146
+ await admin('create_index', { collection: 'employees', field: 'name' });
147
+
148
+ await find('default', 'employees', { name: 'Alice' });
149
+ await find('default', 'employees', { age: 25 });
150
+
151
+ const stats = await admin('get_query_stats', { collection: 'employees' });
152
+
153
+ t.is(stats.name.used_index_count, 1);
154
+ t.is(stats.age.used_index_count, 0);
155
+ });
156
+
157
+ test('should handle queries with projection and sorting', async (t) => {
158
+ await find('default', 'employees', { department: 'Engineering' }, {
159
+ projection: { name: 1, salary: 1 },
160
+ sort: { salary: -1 },
161
+ limit: 2
162
+ });
163
+
164
+ const stats = await admin('get_query_stats', { collection: 'employees' });
165
+
166
+ t.truthy(stats.department);
167
+ t.is(stats.department.query_count, 1);
168
+ });
169
+
170
+ test('should handle find_one with projection', async (t) => {
171
+ await find_one('default', 'employees', { name: 'Alice' }, {
172
+ projection: { age: 1, department: 1 }
173
+ });
174
+
175
+ const stats = await admin('get_query_stats', { collection: 'employees' });
176
+
177
+ t.truthy(stats.name);
178
+ t.is(stats.name.query_count, 1);
179
+ });
180
+
181
+ test('should accumulate statistics across multiple operations', async (t) => {
182
+ await find('default', 'employees', { name: 'Alice' });
183
+ await find_one('default', 'employees', { name: 'Bob' });
184
+ await find('default', 'employees', { name: 'Charlie' });
185
+
186
+ const stats = await admin('get_query_stats', { collection: 'employees' });
187
+
188
+ t.is(stats.name.query_count, 3);
189
+ t.true(stats.name.total_time_ms > 0);
190
+ });
191
+
192
+ test('should handle empty result sets', async (t) => {
193
+ await find('default', 'employees', { name: 'NonExistent' });
194
+ await find_one('default', 'employees', { age: 999 });
195
+
196
+ const stats = await admin('get_query_stats', { collection: 'employees' });
197
+
198
+ t.truthy(stats.name);
199
+ t.truthy(stats.age);
200
+ t.is(stats.name.query_count, 1);
201
+ t.is(stats.age.query_count, 1);
202
+ });
203
+
204
+ test('should handle queries on non-existent collections', async (t) => {
205
+ await find('default', 'non_existent_collection', { field: 'value' });
206
+
207
+ const stats = await admin('get_query_stats', { collection: 'non_existent_collection' });
208
+
209
+ t.truthy(stats.field);
210
+ t.is(stats.field.query_count, 1);
211
+ });
212
+
213
+ test('should track slow queries correctly', async (t) => {
214
+ for (let i = 0; i < 10; i++) {
215
+ await find('default', 'employees', { department: 'Engineering' });
216
+ }
217
+
218
+ const stats = await admin('get_query_stats', { collection: 'employees' });
219
+
220
+ t.is(stats.department.query_count, 10);
221
+ t.true(stats.department.slow_query_count >= 0);
222
+ });
223
+
224
+ test('should get statistics for specific collection only', async (t) => {
225
+ await find('default', 'employees', { name: 'Alice' });
226
+ await find('default', 'products', { category: 'Electronics' });
227
+
228
+ const employee_stats = await admin('get_query_stats', { collection: 'employees' });
229
+ const product_stats = await admin('get_query_stats', { collection: 'products' });
230
+
231
+ t.truthy(employee_stats.name);
232
+ t.falsy(employee_stats.category);
233
+ t.truthy(product_stats.category);
234
+ t.falsy(product_stats.name);
235
+ });
236
+
237
+ test('should get statistics for all collections', async (t) => {
238
+ await find('default', 'employees', { name: 'Alice' });
239
+ await find('default', 'products', { category: 'Electronics' });
240
+
241
+ const all_stats = await admin('get_query_stats');
242
+
243
+ t.truthy(all_stats.employees);
244
+ t.truthy(all_stats.products);
245
+ t.truthy(all_stats.employees.name);
246
+ t.truthy(all_stats.products.category);
247
+ });
248
+
249
+ test('should handle admin operations without errors', async (t) => {
250
+ await t.notThrowsAsync(async () => {
251
+ await admin('get_auto_index_stats');
252
+ await admin('get_query_stats');
253
+ await admin('evaluate_auto_indexes');
254
+ await admin('remove_auto_indexes', { collection: 'test' });
255
+ });
256
+ });
257
+
258
+ test('should maintain statistics persistence across operations', async (t) => {
259
+ await find('default', 'employees', { name: 'Alice' });
260
+
261
+ let stats = await admin('get_query_stats', { collection: 'employees' });
262
+ t.is(stats.name.query_count, 1);
263
+
264
+ await find('default', 'employees', { name: 'Bob' });
265
+
266
+ stats = await admin('get_query_stats', { collection: 'employees' });
267
+ t.is(stats.name.query_count, 2);
268
+ });