@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,155 @@
1
+ import test from 'ava';
2
+ import { decode as decode_messagepack } from 'msgpackr';
3
+ import { send_success, send_error, send_message } from '../../../src/server/lib/send_response.js';
4
+
5
+ class MockSocket {
6
+ constructor() {
7
+ this.written_data = [];
8
+ }
9
+
10
+ write(data) {
11
+ this.written_data.push(data);
12
+ }
13
+
14
+ get_last_written() {
15
+ return this.written_data[this.written_data.length - 1];
16
+ }
17
+
18
+ get_decoded_last_written() {
19
+ const last_data = this.get_last_written();
20
+
21
+ if (last_data.length < 4) {
22
+ throw new Error('Invalid message format: too short');
23
+ }
24
+
25
+ const length = last_data.readUInt32BE(0);
26
+ const payload = last_data.slice(4);
27
+
28
+ if (payload.length !== length) {
29
+ throw new Error(`Invalid message format: expected ${length} bytes, got ${payload.length}`);
30
+ }
31
+
32
+ return decode_messagepack(payload);
33
+ }
34
+ }
35
+
36
+ test('send_success sends properly formatted success response', (t) => {
37
+ const mock_socket = new MockSocket();
38
+ const test_data = { user_id: 123, name: 'test' };
39
+
40
+ send_success(mock_socket, test_data);
41
+
42
+ const response = mock_socket.get_decoded_last_written();
43
+
44
+ t.is(response.ok, true);
45
+ t.deepEqual(response.data, test_data);
46
+ t.is(response.error, undefined);
47
+ });
48
+
49
+ test('send_success with empty data object', (t) => {
50
+ const mock_socket = new MockSocket();
51
+
52
+ send_success(mock_socket, {});
53
+
54
+ const response = mock_socket.get_decoded_last_written();
55
+
56
+ t.is(response.ok, true);
57
+ t.deepEqual(response.data, {});
58
+ });
59
+
60
+ test('send_success with no data parameter uses empty object', (t) => {
61
+ const mock_socket = new MockSocket();
62
+
63
+ send_success(mock_socket);
64
+
65
+ const response = mock_socket.get_decoded_last_written();
66
+
67
+ t.is(response.ok, true);
68
+ t.deepEqual(response.data, {});
69
+ });
70
+
71
+ test('send_error sends properly formatted error response', (t) => {
72
+ const mock_socket = new MockSocket();
73
+ const test_error = { message: 'Something went wrong', code: 500 };
74
+
75
+ send_error(mock_socket, test_error);
76
+
77
+ const response = mock_socket.get_decoded_last_written();
78
+
79
+ t.is(response.ok, false);
80
+ t.deepEqual(response.error, test_error);
81
+ t.is(response.data, undefined);
82
+ });
83
+
84
+ test('send_error with empty error object', (t) => {
85
+ const mock_socket = new MockSocket();
86
+
87
+ send_error(mock_socket, {});
88
+
89
+ const response = mock_socket.get_decoded_last_written();
90
+
91
+ t.is(response.ok, false);
92
+ t.deepEqual(response.error, {});
93
+ });
94
+
95
+ test('send_error with no error parameter uses empty object', (t) => {
96
+ const mock_socket = new MockSocket();
97
+
98
+ send_error(mock_socket);
99
+
100
+ const response = mock_socket.get_decoded_last_written();
101
+
102
+ t.is(response.ok, false);
103
+ t.deepEqual(response.error, {});
104
+ });
105
+
106
+ test('send_message sends message in data object', (t) => {
107
+ const mock_socket = new MockSocket();
108
+ const test_message = 'Operation completed successfully';
109
+
110
+ send_message(mock_socket, test_message);
111
+
112
+ const response = mock_socket.get_decoded_last_written();
113
+
114
+ t.is(response.ok, true);
115
+ t.deepEqual(response.data, { message: test_message });
116
+ t.is(response.error, undefined);
117
+ });
118
+
119
+ test('send_message with empty string', (t) => {
120
+ const mock_socket = new MockSocket();
121
+
122
+ send_message(mock_socket, '');
123
+
124
+ const response = mock_socket.get_decoded_last_written();
125
+
126
+ t.is(response.ok, true);
127
+ t.deepEqual(response.data, { message: '' });
128
+ });
129
+
130
+ test('send_message with no message parameter uses empty string', (t) => {
131
+ const mock_socket = new MockSocket();
132
+
133
+ send_message(mock_socket);
134
+
135
+ const response = mock_socket.get_decoded_last_written();
136
+
137
+ t.is(response.ok, true);
138
+ t.deepEqual(response.data, { message: '' });
139
+ });
140
+
141
+ test('all functions encode responses as messagepack', (t) => {
142
+ const mock_socket = new MockSocket();
143
+
144
+ send_success(mock_socket, { test: 'data' });
145
+ const success_data = mock_socket.get_last_written();
146
+ t.true(Buffer.isBuffer(success_data));
147
+
148
+ send_error(mock_socket, { test: 'error' });
149
+ const error_data = mock_socket.get_last_written();
150
+ t.true(Buffer.isBuffer(error_data));
151
+
152
+ send_message(mock_socket, 'test message');
153
+ const message_data = mock_socket.get_last_written();
154
+ t.true(Buffer.isBuffer(message_data));
155
+ });
@@ -0,0 +1,169 @@
1
+ import test from 'ava';
2
+ import { encode_message, create_message_parser } from '../../../src/server/lib/tcp_protocol.js';
3
+
4
+ test('encode_message - should encode message with length prefix', (t) => {
5
+ const data = { test: 'data', number: 42 };
6
+ const result = encode_message(data);
7
+
8
+ t.true(Buffer.isBuffer(result));
9
+ t.true(result.length > 4);
10
+
11
+ const length = result.readUInt32BE(0);
12
+ const payload = result.slice(4);
13
+
14
+ t.is(payload.length, length);
15
+ });
16
+
17
+ test('encode_message - should handle empty object', (t) => {
18
+ const data = {};
19
+ const result = encode_message(data);
20
+
21
+ t.true(Buffer.isBuffer(result));
22
+
23
+ const length = result.readUInt32BE(0);
24
+ t.true(length > 0);
25
+ });
26
+
27
+ test('encode_message - should handle complex nested data', (t) => {
28
+ const data = {
29
+ nested: {
30
+ array: [1, 2, 3],
31
+ string: 'test',
32
+ boolean: true
33
+ }
34
+ };
35
+
36
+ const result = encode_message(data);
37
+
38
+ t.true(Buffer.isBuffer(result));
39
+ t.true(result.length > 4);
40
+ });
41
+
42
+ test('create_message_parser - should parse single complete message', (t) => {
43
+ const parser = create_message_parser();
44
+ const test_data = { op: 'test', data: { value: 123 } };
45
+ const encoded = encode_message(test_data);
46
+
47
+ const messages = parser.parse_messages(encoded);
48
+
49
+ t.is(messages.length, 1);
50
+ t.deepEqual(messages[0], test_data);
51
+ });
52
+
53
+ test('create_message_parser - should parse multiple messages', (t) => {
54
+ const parser = create_message_parser();
55
+ const test_data_1 = { op: 'test1', data: { value: 123 } };
56
+ const test_data_2 = { op: 'test2', data: { value: 456 } };
57
+
58
+ const encoded_1 = encode_message(test_data_1);
59
+ const encoded_2 = encode_message(test_data_2);
60
+ const combined = Buffer.concat([encoded_1, encoded_2]);
61
+
62
+ const messages = parser.parse_messages(combined);
63
+
64
+ t.is(messages.length, 2);
65
+ t.deepEqual(messages[0], test_data_1);
66
+ t.deepEqual(messages[1], test_data_2);
67
+ });
68
+
69
+ test('create_message_parser - should handle partial messages', (t) => {
70
+ const parser = create_message_parser();
71
+ const test_data = { op: 'test', data: { value: 123 } };
72
+ const encoded = encode_message(test_data);
73
+
74
+ const partial_1 = encoded.slice(0, 2);
75
+ const partial_2 = encoded.slice(2);
76
+
77
+ let messages = parser.parse_messages(partial_1);
78
+ t.is(messages.length, 0);
79
+
80
+ messages = parser.parse_messages(partial_2);
81
+ t.is(messages.length, 1);
82
+ t.deepEqual(messages[0], test_data);
83
+ });
84
+
85
+ test('create_message_parser - should handle partial length prefix', (t) => {
86
+ const parser = create_message_parser();
87
+ const test_data = { op: 'test', data: { value: 123 } };
88
+ const encoded = encode_message(test_data);
89
+
90
+ const partial_length = encoded.slice(0, 3);
91
+ const remaining = encoded.slice(3);
92
+
93
+ let messages = parser.parse_messages(partial_length);
94
+ t.is(messages.length, 0);
95
+
96
+ messages = parser.parse_messages(remaining);
97
+ t.is(messages.length, 1);
98
+ t.deepEqual(messages[0], test_data);
99
+ });
100
+
101
+ test('create_message_parser - should handle partial payload', (t) => {
102
+ const parser = create_message_parser();
103
+ const test_data = { op: 'test', data: { value: 123 } };
104
+ const encoded = encode_message(test_data);
105
+
106
+ const length_and_partial = encoded.slice(0, encoded.length - 2);
107
+ const remaining_payload = encoded.slice(encoded.length - 2);
108
+
109
+ let messages = parser.parse_messages(length_and_partial);
110
+ t.is(messages.length, 0);
111
+
112
+ messages = parser.parse_messages(remaining_payload);
113
+ t.is(messages.length, 1);
114
+ t.deepEqual(messages[0], test_data);
115
+ });
116
+
117
+ test('create_message_parser - should throw on invalid messagepack', (t) => {
118
+ const parser = create_message_parser();
119
+
120
+ const invalid_length = Buffer.allocUnsafe(4);
121
+ invalid_length.writeUInt32BE(5, 0);
122
+ const invalid_payload = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
123
+ const invalid_message = Buffer.concat([invalid_length, invalid_payload]);
124
+
125
+ t.throws(
126
+ () => {
127
+ parser.parse_messages(invalid_message);
128
+ },
129
+ { message: /Invalid message format/ }
130
+ );
131
+ });
132
+
133
+ test('create_message_parser - reset should clear internal state', (t) => {
134
+ const parser = create_message_parser();
135
+ const test_data = { op: 'test', data: { value: 123 } };
136
+ const encoded = encode_message(test_data);
137
+
138
+ const partial = encoded.slice(0, 2);
139
+ parser.parse_messages(partial);
140
+
141
+ parser.reset();
142
+
143
+ const messages = parser.parse_messages(encoded);
144
+ t.is(messages.length, 1);
145
+ t.deepEqual(messages[0], test_data);
146
+ });
147
+
148
+ test('create_message_parser - should handle empty buffer', (t) => {
149
+ const parser = create_message_parser();
150
+ const empty_buffer = Buffer.alloc(0);
151
+
152
+ const messages = parser.parse_messages(empty_buffer);
153
+
154
+ t.is(messages.length, 0);
155
+ });
156
+
157
+ test('create_message_parser - should handle zero-length message', (t) => {
158
+ const parser = create_message_parser();
159
+
160
+ const zero_length = Buffer.allocUnsafe(4);
161
+ zero_length.writeUInt32BE(0, 0);
162
+
163
+ t.throws(
164
+ () => {
165
+ parser.parse_messages(zero_length);
166
+ },
167
+ { message: /Invalid message format/ }
168
+ );
169
+ });
@@ -0,0 +1,258 @@
1
+ import test from 'ava';
2
+ import { get_write_forwarder, initialize_write_forwarder, shutdown_write_forwarder } from '../../../src/server/lib/write_forwarder.js';
3
+
4
+ test.beforeEach(async () => {
5
+ // Clean up any existing write forwarder
6
+ await shutdown_write_forwarder();
7
+ });
8
+
9
+ test.afterEach(async () => {
10
+ // Clean up after each test
11
+ await shutdown_write_forwarder();
12
+ });
13
+
14
+ test('write forwarder singleton', t => {
15
+ const forwarder1 = get_write_forwarder();
16
+ const forwarder2 = get_write_forwarder();
17
+
18
+ t.is(forwarder1, forwarder2, 'Should return same instance');
19
+ });
20
+
21
+ test('write forwarder initialization without settings', t => {
22
+ const forwarder = get_write_forwarder();
23
+
24
+ // Should not throw when no settings are available
25
+ t.notThrows(() => {
26
+ forwarder.initialize();
27
+ });
28
+
29
+ t.false(forwarder.is_secondary_mode, 'Should not be in secondary mode without settings');
30
+ });
31
+
32
+ test('write forwarder default configuration', t => {
33
+ const forwarder = get_write_forwarder();
34
+
35
+ t.false(forwarder.is_secondary_mode, 'Should not be in secondary mode by default');
36
+ t.is(forwarder.primary_config, null, 'Should have no primary config by default');
37
+ t.is(forwarder.pending_forwards.size, 0, 'Should have no pending forwards');
38
+ t.is(forwarder.forward_timeout_ms, 10000, 'Should have default timeout');
39
+ t.is(forwarder.reconnect_delay_ms, 5000, 'Should have default reconnect delay');
40
+ });
41
+
42
+ test('write forwarder should forward operation check', t => {
43
+ const forwarder = get_write_forwarder();
44
+
45
+ // Not in secondary mode
46
+ t.false(forwarder.should_forward_operation('insert_one'), 'Should not forward when not in secondary mode');
47
+
48
+ // Enable secondary mode
49
+ forwarder.is_secondary_mode = true;
50
+
51
+ // Test write operations
52
+ t.true(forwarder.should_forward_operation('insert_one'), 'Should forward insert_one');
53
+ t.true(forwarder.should_forward_operation('update_one'), 'Should forward update_one');
54
+ t.true(forwarder.should_forward_operation('delete_one'), 'Should forward delete_one');
55
+ t.true(forwarder.should_forward_operation('bulk_write'), 'Should forward bulk_write');
56
+ t.true(forwarder.should_forward_operation('create_index'), 'Should forward create_index');
57
+ t.true(forwarder.should_forward_operation('drop_index'), 'Should forward drop_index');
58
+
59
+ // Test read operations
60
+ t.false(forwarder.should_forward_operation('find_one'), 'Should not forward find_one');
61
+ t.false(forwarder.should_forward_operation('find'), 'Should not forward find');
62
+ t.false(forwarder.should_forward_operation('get_indexes'), 'Should not forward get_indexes');
63
+
64
+ // Clean up
65
+ forwarder.is_secondary_mode = false;
66
+ });
67
+
68
+ test('write forwarder forward operation when not in secondary mode', async t => {
69
+ const forwarder = get_write_forwarder();
70
+ const mockSocket = { id: 'test-socket' };
71
+
72
+ const forwarded = await forwarder.forward_operation(mockSocket, 'insert_one', { collection: 'test' });
73
+
74
+ t.false(forwarded, 'Should not forward when not in secondary mode');
75
+ });
76
+
77
+ test('write forwarder forward operation when not connected', async t => {
78
+ const forwarder = get_write_forwarder();
79
+ const mockSocket = {
80
+ id: 'test-socket',
81
+ write: () => {}
82
+ };
83
+
84
+ // Enable secondary mode but no connection
85
+ forwarder.is_secondary_mode = true;
86
+ forwarder.primary_connection = null;
87
+
88
+ const forwarded = await forwarder.forward_operation(mockSocket, 'insert_one', { collection: 'test' });
89
+
90
+ t.true(forwarded, 'Should handle forward attempt');
91
+
92
+ // Clean up
93
+ forwarder.is_secondary_mode = false;
94
+ });
95
+
96
+ test('write forwarder generate forward ID', t => {
97
+ const forwarder = get_write_forwarder();
98
+
99
+ const id1 = forwarder.generate_forward_id();
100
+ const id2 = forwarder.generate_forward_id();
101
+
102
+ t.is(typeof id1, 'string', 'Should return string ID');
103
+ t.is(typeof id2, 'string', 'Should return string ID');
104
+ t.not(id1, id2, 'Should generate unique IDs');
105
+ t.true(id1.startsWith('fwd_'), 'Should start with fwd_ prefix');
106
+ });
107
+
108
+ test('write forwarder get status when disabled', t => {
109
+ const forwarder = get_write_forwarder();
110
+
111
+ const status = forwarder.get_forwarder_status();
112
+
113
+ t.false(status.enabled, 'Should report as disabled');
114
+ t.false(status.connected_to_primary, 'Should not be connected to primary');
115
+ t.is(status.primary_config, null, 'Should have no primary config');
116
+ t.is(status.pending_forwards, 0, 'Should have no pending forwards');
117
+ t.is(status.stats.total_forwards, 0, 'Should have zero total forwards');
118
+ });
119
+
120
+ test('write forwarder statistics tracking', t => {
121
+ const forwarder = get_write_forwarder();
122
+
123
+ const initialStats = forwarder.stats;
124
+
125
+ t.is(initialStats.total_forwards, 0, 'Should start with zero forwards');
126
+ t.is(initialStats.successful_forwards, 0, 'Should start with zero successful forwards');
127
+ t.is(initialStats.failed_forwards, 0, 'Should start with zero failed forwards');
128
+ t.is(initialStats.avg_forward_latency_ms, 0, 'Should start with zero average latency');
129
+ t.is(initialStats.connection_attempts, 0, 'Should start with zero connection attempts');
130
+ t.is(initialStats.last_connection_attempt, null, 'Should have no last connection attempt');
131
+ });
132
+
133
+ test('write forwarder handle forward timeout', t => {
134
+ const forwarder = get_write_forwarder();
135
+ const forwardId = 'test-forward-id';
136
+
137
+ // Add a pending forward
138
+ forwarder.pending_forwards.set(forwardId, {
139
+ client_socket: { write: () => {} },
140
+ operation: 'insert_one',
141
+ data: { collection: 'test' },
142
+ sent_at: Date.now(),
143
+ timeout: null
144
+ });
145
+
146
+ const initialFailed = forwarder.stats.failed_forwards;
147
+
148
+ forwarder.handle_forward_timeout(forwardId);
149
+
150
+ t.false(forwarder.pending_forwards.has(forwardId), 'Should remove pending forward');
151
+ t.is(forwarder.stats.failed_forwards, initialFailed + 1, 'Should increment failed forwards');
152
+ });
153
+
154
+ test('write forwarder fail pending forwards', t => {
155
+ const forwarder = get_write_forwarder();
156
+
157
+ // Add multiple pending forwards
158
+ for (let i = 0; i < 3; i++) {
159
+ forwarder.pending_forwards.set(`forward-${i}`, {
160
+ client_socket: { write: () => {} },
161
+ operation: 'insert_one',
162
+ data: { collection: 'test' },
163
+ sent_at: Date.now(),
164
+ timeout: null
165
+ });
166
+ }
167
+
168
+ const initialFailed = forwarder.stats.failed_forwards;
169
+ const pendingCount = forwarder.pending_forwards.size;
170
+
171
+ forwarder.fail_pending_forwards('Test reason');
172
+
173
+ t.is(forwarder.pending_forwards.size, 0, 'Should clear all pending forwards');
174
+ t.is(forwarder.stats.failed_forwards, initialFailed + pendingCount, 'Should increment failed forwards by pending count');
175
+ });
176
+
177
+ test('write forwarder shutdown', async t => {
178
+ const forwarder = get_write_forwarder();
179
+
180
+ // Add some pending forwards
181
+ forwarder.pending_forwards.set('test-forward', {
182
+ client_socket: { write: () => {} },
183
+ operation: 'insert_one',
184
+ data: { collection: 'test' },
185
+ sent_at: Date.now(),
186
+ timeout: null
187
+ });
188
+
189
+ forwarder.is_secondary_mode = true;
190
+
191
+ // Should not throw when shutting down
192
+ await t.notThrowsAsync(async () => {
193
+ await forwarder.shutdown();
194
+ });
195
+
196
+ t.false(forwarder.is_secondary_mode, 'Should disable secondary mode after shutdown');
197
+ t.is(forwarder.pending_forwards.size, 0, 'Should clear pending forwards after shutdown');
198
+ t.is(forwarder.primary_connection, null, 'Should clear primary connection after shutdown');
199
+ });
200
+
201
+ test('write forwarder handle primary response with unknown forward', t => {
202
+ const forwarder = get_write_forwarder();
203
+
204
+ // Set up primary connection
205
+ forwarder.primary_connection = {
206
+ authenticated: true,
207
+ last_ping: Date.now()
208
+ };
209
+
210
+ const response = {
211
+ forward_id: 'unknown-forward-id',
212
+ ok: 1,
213
+ result: 'success'
214
+ };
215
+
216
+ // Should not throw when handling unknown forward response
217
+ t.notThrows(() => {
218
+ forwarder.handle_forward_response(response);
219
+ });
220
+ });
221
+
222
+ test('write forwarder handle authentication success', t => {
223
+ const forwarder = get_write_forwarder();
224
+
225
+ // Set up primary connection
226
+ forwarder.primary_connection = {
227
+ authenticated: false,
228
+ last_ping: Date.now()
229
+ };
230
+
231
+ const authResponse = {
232
+ ok: 1,
233
+ message: 'Authentication successful'
234
+ };
235
+
236
+ forwarder.handle_primary_response(authResponse);
237
+
238
+ t.true(forwarder.primary_connection.authenticated, 'Should set authenticated to true');
239
+ });
240
+
241
+ test('write forwarder handle ping response', t => {
242
+ const forwarder = get_write_forwarder();
243
+
244
+ // Set up primary connection
245
+ const initialPing = Date.now() - 1000;
246
+ forwarder.primary_connection = {
247
+ authenticated: true,
248
+ last_ping: initialPing
249
+ };
250
+
251
+ const pingResponse = {
252
+ ok: 1
253
+ };
254
+
255
+ forwarder.handle_primary_response(pingResponse);
256
+
257
+ t.true(forwarder.primary_connection.last_ping > initialPing, 'Should update last ping time');
258
+ });