harperdb 3.2.1 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (578) hide show
  1. package/README.md +20 -11
  2. package/bin/BinObjects.jsc +0 -0
  3. package/bin/harperdb.jsc +0 -0
  4. package/bin/install.jsc +0 -0
  5. package/bin/register.jsc +0 -0
  6. package/bin/run.jsc +0 -0
  7. package/bin/stop.jsc +0 -0
  8. package/bin/upgrade.jsc +0 -0
  9. package/bin/utility.jsc +0 -0
  10. package/bin/version.jsc +0 -0
  11. package/coverage/lcov.info +7142 -6704
  12. package/data_layer/CreateAttributeObject.jsc +0 -0
  13. package/data_layer/CreateTableObject.jsc +0 -0
  14. package/data_layer/DataLayerObjects.jsc +0 -0
  15. package/data_layer/DeleteBeforeObject.jsc +0 -0
  16. package/data_layer/DeleteObject.jsc +0 -0
  17. package/data_layer/DropAttributeObject.jsc +0 -0
  18. package/data_layer/InsertObject.jsc +0 -0
  19. package/data_layer/ReadTransactionLogObject.jsc +0 -0
  20. package/data_layer/SQLSearch.jsc +0 -0
  21. package/data_layer/SearchByConditionsObject.jsc +0 -0
  22. package/data_layer/SearchByHashObject.jsc +0 -0
  23. package/data_layer/SearchObject.jsc +0 -0
  24. package/data_layer/SqlSearchObject.jsc +0 -0
  25. package/data_layer/UpdateObject.jsc +0 -0
  26. package/data_layer/UpsertObject.jsc +0 -0
  27. package/data_layer/bulkLoad.jsc +0 -0
  28. package/data_layer/data_objects/BulkLoadObjects.jsc +0 -0
  29. package/data_layer/data_objects/UpsertObject.jsc +0 -0
  30. package/data_layer/delete.jsc +0 -0
  31. package/data_layer/export.jsc +0 -0
  32. package/data_layer/harperBridge/BridgeMethods.jsc +0 -0
  33. package/data_layer/harperBridge/bridgeUtility/checkForNewAttr.jsc +0 -0
  34. package/data_layer/harperBridge/bridgeUtility/convertOperationToTransaction.jsc +0 -0
  35. package/data_layer/harperBridge/bridgeUtility/evaluateTableGetAttributes.jsc +0 -0
  36. package/data_layer/harperBridge/bridgeUtility/insertUpdateReturnObj.jsc +0 -0
  37. package/data_layer/harperBridge/bridgeUtility/insertUpdateValidate.jsc +0 -0
  38. package/data_layer/harperBridge/harperBridge.jsc +0 -0
  39. package/data_layer/harperBridge/lmdbBridge/LMDBBridge.jsc +0 -0
  40. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/DeleteTransactionsBeforeResults.jsc +0 -0
  41. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.jsc +0 -0
  42. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.jsc +0 -0
  43. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.jsc +0 -0
  44. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.jsc +0 -0
  45. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.jsc +0 -0
  46. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecordsBefore.jsc +0 -0
  47. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteTransactionLogsBefore.jsc +0 -0
  48. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.jsc +0 -0
  49. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.jsc +0 -0
  50. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.jsc +0 -0
  51. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.jsc +0 -0
  52. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.jsc +0 -0
  53. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadTransactionLog.jsc +0 -0
  54. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.jsc +0 -0
  55. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.jsc +0 -0
  56. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.jsc +0 -0
  57. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.jsc +0 -0
  58. package/data_layer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.jsc +0 -0
  59. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.jsc +0 -0
  60. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.jsc +0 -0
  61. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.jsc +0 -0
  62. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.jsc +0 -0
  63. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.jsc +0 -0
  64. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.jsc +0 -0
  65. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.jsc +0 -0
  66. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/ThreadSearchObject.jsc +0 -0
  67. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.jsc +0 -0
  68. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.jsc +0 -0
  69. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.jsc +0 -0
  70. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsEnvironment.jsc +0 -0
  71. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbDropAllAttributes.jsc +0 -0
  72. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.jsc +0 -0
  73. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.jsc +0 -0
  74. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.jsc +0 -0
  75. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbThreadSearch.jsc +0 -0
  76. package/data_layer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.jsc +0 -0
  77. package/data_layer/hdbInfoController.jsc +0 -0
  78. package/data_layer/insert.jsc +0 -0
  79. package/data_layer/readTransactionLog.jsc +0 -0
  80. package/data_layer/schema.jsc +0 -0
  81. package/data_layer/schemaDescribe.jsc +0 -0
  82. package/data_layer/search.jsc +0 -0
  83. package/data_layer/update.jsc +0 -0
  84. package/events/ClusterStatusEmitter.jsc +0 -0
  85. package/events/SioServerStoppedEvent.jsc +0 -0
  86. package/events/SocketClusterStatusEmitter.jsc +0 -0
  87. package/license/LICENSE +91 -1
  88. package/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/README.md +1 -0
  89. package/node_modules/{node-addon-api/src/nothing.c → @msgpackr-extract/msgpackr-extract-linux-x64/index.js} +0 -0
  90. package/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/node.abi93.glibc.node +0 -0
  91. package/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/node.abi93.musl.node +0 -0
  92. package/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/node.napi.glibc.node +0 -0
  93. package/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/node.napi.musl.node +0 -0
  94. package/node_modules/@msgpackr-extract/msgpackr-extract-linux-x64/package.json +53 -0
  95. package/node_modules/{msgpackr-extract → lmdb-store}/.github/workflows/prebuild.yml +9 -10
  96. package/node_modules/lmdb-store/.idea/lmdb-store.iml +12 -0
  97. package/node_modules/lmdb-store/.idea/misc.xml +6 -0
  98. package/node_modules/lmdb-store/.idea/modules.xml +8 -0
  99. package/node_modules/lmdb-store/.idea/workspace.xml +4 -0
  100. package/node_modules/lmdb-store/README.md +393 -388
  101. package/node_modules/lmdb-store/benchmark/index.js +162 -162
  102. package/node_modules/lmdb-store/binding.gyp +79 -88
  103. package/node_modules/lmdb-store/caching.js +113 -113
  104. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/COPYRIGHT +20 -20
  105. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/Doxyfile +1631 -1631
  106. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/LICENSE +47 -47
  107. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/chacha8.c +183 -183
  108. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/chacha8.h +14 -14
  109. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/crypto.c +121 -121
  110. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/intro.doc +192 -192
  111. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb.c +12125 -12125
  112. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_copy.1 +74 -74
  113. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_copy.c +106 -106
  114. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_drop.1 +53 -53
  115. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_drop.c +154 -154
  116. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_dump.1 +94 -94
  117. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_dump.c +333 -333
  118. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_load.1 +97 -97
  119. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_load.c +530 -530
  120. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_stat.1 +83 -83
  121. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb_stat.c +276 -276
  122. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/midl.c +452 -452
  123. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/midl.h +208 -208
  124. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/module.c +101 -101
  125. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/module.h +16 -16
  126. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest.c +178 -178
  127. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest2.c +124 -124
  128. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest3.c +133 -133
  129. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest4.c +168 -168
  130. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest5.c +135 -135
  131. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest6.c +141 -141
  132. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest_enc.c +190 -190
  133. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest_enc2.c +189 -189
  134. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/mtest_remap.c +177 -177
  135. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/sample-bdb.txt +73 -73
  136. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/sample-mdb.txt +62 -62
  137. package/node_modules/lmdb-store/dependencies/lmdb/libraries/liblmdb/tooltag +27 -27
  138. package/node_modules/lmdb-store/dependencies/lz4/LICENSE +11 -11
  139. package/node_modules/lmdb-store/dependencies/lz4/lib/README.md +137 -137
  140. package/node_modules/lmdb-store/dependencies/lz4/lib/dll/example/README.md +69 -69
  141. package/node_modules/lmdb-store/dependencies/lz4/lib/lz4frame.c +1899 -1899
  142. package/node_modules/lmdb-store/dependencies/lz4/lib/xxhash.c +1030 -1030
  143. package/node_modules/lmdb-store/dependencies/lz4/lib/xxhash.h +328 -328
  144. package/node_modules/lmdb-store/dist/index.cjs +2591 -0
  145. package/node_modules/lmdb-store/dist/index.cjs.map +1 -0
  146. package/node_modules/lmdb-store/index.d.ts +323 -323
  147. package/node_modules/lmdb-store/index.js +1274 -1274
  148. package/node_modules/lmdb-store/index.mjs +3 -3
  149. package/node_modules/lmdb-store/package.json +16 -11
  150. package/node_modules/lmdb-store/prebuilds/darwin-arm64/electron.abi98.node +0 -0
  151. package/node_modules/lmdb-store/prebuilds/darwin-arm64/node.abi83.node +0 -0
  152. package/node_modules/lmdb-store/prebuilds/darwin-arm64/node.abi93.node +0 -0
  153. package/node_modules/lmdb-store/prebuilds/darwin-x64/electron.abi98.node +0 -0
  154. package/node_modules/lmdb-store/prebuilds/darwin-x64/node.abi83.node +0 -0
  155. package/node_modules/lmdb-store/prebuilds/darwin-x64/node.abi93.node +0 -0
  156. package/node_modules/lmdb-store/prebuilds/linux-arm64/electron.abi98.node +0 -0
  157. package/node_modules/lmdb-store/prebuilds/linux-arm64/node.abi83.node +0 -0
  158. package/node_modules/lmdb-store/prebuilds/linux-arm64/node.abi93.node +0 -0
  159. package/node_modules/lmdb-store/prebuilds/linux-x64/electron.abi98.node +0 -0
  160. package/node_modules/lmdb-store/prebuilds/linux-x64/node.abi83.musl.node +0 -0
  161. package/node_modules/lmdb-store/prebuilds/linux-x64/node.abi83.node +0 -0
  162. package/node_modules/lmdb-store/prebuilds/linux-x64/node.abi93.musl.node +0 -0
  163. package/node_modules/lmdb-store/prebuilds/linux-x64/node.abi93.node +0 -0
  164. package/node_modules/lmdb-store/prebuilds/win32-x64/electron.abi98.node +0 -0
  165. package/node_modules/lmdb-store/prebuilds/win32-x64/node.abi83.node +0 -0
  166. package/node_modules/lmdb-store/prebuilds/win32-x64/node.abi93.node +0 -0
  167. package/node_modules/lmdb-store/src/compression.cpp +181 -181
  168. package/node_modules/lmdb-store/src/cursor.cpp +407 -407
  169. package/node_modules/lmdb-store/src/dbi.cpp +354 -354
  170. package/node_modules/lmdb-store/src/env.cpp +1134 -1134
  171. package/node_modules/lmdb-store/src/misc.cpp +528 -528
  172. package/node_modules/lmdb-store/src/node-lmdb.cpp +44 -44
  173. package/node_modules/lmdb-store/src/node-lmdb.h +965 -965
  174. package/node_modules/lmdb-store/src/ordered-binary.cpp +337 -337
  175. package/node_modules/lmdb-store/src/txn.cpp +513 -513
  176. package/node_modules/lmdb-store/src/v8-fast-api-calls.h +419 -419
  177. package/node_modules/lmdb-store/src/windows.c +30 -30
  178. package/node_modules/lmdb-store/test/index.test.js +584 -584
  179. package/node_modules/lmdb-store/test/node-lmdb.test.js +1525 -1525
  180. package/node_modules/lmdb-store/test/threads.js +100 -100
  181. package/node_modules/lmdb-store/util/ArrayLikeIterable.js +136 -136
  182. package/node_modules/lmdb-store/util/WeakValueMap.js +40 -40
  183. package/node_modules/lmdb-store/util/upgrade-lmdb.js +46 -46
  184. package/node_modules/lmdb-store/util/when.js +8 -8
  185. package/node_modules/microtime/.github/workflows/release.yml +76 -0
  186. package/node_modules/microtime/.github/workflows/test.yml +46 -0
  187. package/node_modules/microtime/README.md +0 -2
  188. package/node_modules/microtime/binding.gyp +28 -10
  189. package/node_modules/microtime/package.json +25 -20
  190. package/node_modules/microtime/prebuilds/darwin-x64+arm64/electron.napi.node +0 -0
  191. package/node_modules/microtime/prebuilds/darwin-x64+arm64/node.napi.node +0 -0
  192. package/node_modules/microtime/prebuilds/linux-arm/node.napi.armv7.node +0 -0
  193. package/node_modules/microtime/prebuilds/linux-arm64/node.napi.armv8.node +0 -0
  194. package/node_modules/microtime/prebuilds/linux-x64/electron.napi.node +0 -0
  195. package/node_modules/microtime/prebuilds/linux-x64/node.napi.node +0 -0
  196. package/node_modules/microtime/prebuilds/win32-ia32/electron.napi.node +0 -0
  197. package/node_modules/microtime/prebuilds/win32-ia32/node.napi.node +0 -0
  198. package/node_modules/microtime/prebuilds/win32-x64/electron.napi.node +0 -0
  199. package/node_modules/microtime/prebuilds/win32-x64/node.napi.node +0 -0
  200. package/node_modules/msgpackr/dist/index.js +1929 -1917
  201. package/node_modules/msgpackr/dist/index.min.js +67 -68
  202. package/node_modules/msgpackr/dist/node.cjs +1994 -1980
  203. package/node_modules/msgpackr/dist/test.js +683 -1235
  204. package/node_modules/msgpackr/index.d.ts +23 -12
  205. package/node_modules/msgpackr/node-index.js +23 -21
  206. package/node_modules/msgpackr/pack.js +935 -931
  207. package/node_modules/msgpackr/package.json +24 -12
  208. package/node_modules/msgpackr/unpack.d.ts +52 -50
  209. package/node_modules/msgpackr/unpack.js +1061 -1053
  210. package/node_modules/msgpackr-extract/bin/download-prebuilds.js +11 -0
  211. package/node_modules/msgpackr-extract/binding.gyp +22 -5
  212. package/node_modules/msgpackr-extract/index.js +1 -1
  213. package/node_modules/msgpackr-extract/package.json +46 -21
  214. package/node_modules/msgpackr-extract/src/.vs/ProjectSettings.json +3 -0
  215. package/node_modules/msgpackr-extract/src/.vs/VSWorkspaceState.json +7 -0
  216. package/node_modules/msgpackr-extract/src/.vs/slnx.sqlite +0 -0
  217. package/node_modules/msgpackr-extract/src/.vs/src/v16/.suo +0 -0
  218. package/node_modules/msgpackr-extract/src/.vs/src/v16/Browse.VC.db +0 -0
  219. package/node_modules/msgpackr-extract/{prebuilds/darwin-x64/node.abi72.node → src/.vs/src/v16/Browse.VC.db-shm} +0 -0
  220. package/node_modules/msgpackr-extract/src/.vs/src/v16/Browse.VC.db-wal +0 -0
  221. package/node_modules/msgpackr-extract/src/extract.cpp +272 -269
  222. package/node_modules/nan/package.json +0 -1
  223. package/node_modules/node-addon-api/README.md +146 -53
  224. package/node_modules/node-addon-api/common.gypi +21 -0
  225. package/node_modules/node-addon-api/except.gypi +25 -0
  226. package/node_modules/node-addon-api/index.js +7 -41
  227. package/node_modules/node-addon-api/napi-inl.deprecated.h +8 -8
  228. package/node_modules/node-addon-api/napi-inl.h +2795 -633
  229. package/node_modules/node-addon-api/napi.h +1547 -597
  230. package/node_modules/node-addon-api/node_api.gyp +9 -0
  231. package/node_modules/node-addon-api/noexcept.gypi +26 -0
  232. package/node_modules/node-addon-api/nothing.c +0 -0
  233. package/node_modules/node-addon-api/package-support.json +21 -0
  234. package/node_modules/node-addon-api/package.json +203 -13
  235. package/node_modules/node-addon-api/tools/README.md +12 -6
  236. package/node_modules/node-addon-api/tools/clang-format.js +71 -0
  237. package/node_modules/node-addon-api/tools/conversion.js +4 -8
  238. package/node_modules/node-addon-api/tools/eslint-format.js +71 -0
  239. package/node_modules/node-gyp-build/README.md +17 -14
  240. package/node_modules/node-gyp-build/bin.js +28 -15
  241. package/node_modules/node-gyp-build/index.js +145 -34
  242. package/node_modules/node-gyp-build/package.json +18 -15
  243. package/node_modules/{lmdb-store/node_modules/node-gyp-build → node-gyp-build-optional-packages}/LICENSE +0 -0
  244. package/node_modules/{lmdb-store/node_modules/node-gyp-build → node-gyp-build-optional-packages}/README.md +0 -0
  245. package/node_modules/{lmdb-store/node_modules/node-gyp-build → node-gyp-build-optional-packages}/bin.js +1 -1
  246. package/node_modules/{lmdb-store/node_modules/node-gyp-build → node-gyp-build-optional-packages}/build-test.js +0 -0
  247. package/node_modules/{lmdb-store/node_modules/node-gyp-build → node-gyp-build-optional-packages}/index.js +17 -11
  248. package/node_modules/{lmdb-store/node_modules/node-gyp-build → node-gyp-build-optional-packages}/optional.js +0 -0
  249. package/node_modules/{msgpackr-extract/node_modules/node-gyp-build → node-gyp-build-optional-packages}/package.json +17 -17
  250. package/package.json +12 -11
  251. package/security/JWTObjects.jsc +0 -0
  252. package/security/auth.jsc +0 -0
  253. package/security/cryptoHash.jsc +0 -0
  254. package/security/data_objects/PermissionAttributeResponseObject.jsc +0 -0
  255. package/security/data_objects/PermissionResponseObject.jsc +0 -0
  256. package/security/data_objects/PermissionTableResponseObject.jsc +0 -0
  257. package/security/permissionsTranslator.jsc +0 -0
  258. package/security/role.jsc +0 -0
  259. package/security/tokenAuthentication.jsc +0 -0
  260. package/security/user.jsc +0 -0
  261. package/server/ClusteringOriginObject.jsc +0 -0
  262. package/server/JobObject.jsc +0 -0
  263. package/server/clustering/ClusterStatusObject.jsc +0 -0
  264. package/server/clustering/NodeObject.jsc +0 -0
  265. package/server/clustering/clusterUtilities.jsc +0 -0
  266. package/server/configuration.jsc +0 -0
  267. package/server/customFunctions/customFunctionsServer.jsc +0 -0
  268. package/server/customFunctions/helpers/getCORSOptions.jsc +0 -0
  269. package/server/customFunctions/helpers/getHeaderTimeoutConfig.jsc +0 -0
  270. package/server/customFunctions/helpers/getServerOptions.jsc +0 -0
  271. package/server/customFunctions/operations.jsc +0 -0
  272. package/server/customFunctions/operationsValidation.jsc +0 -0
  273. package/server/harperdb/hdbServer.jsc +0 -0
  274. package/server/ipc/IPCClient.jsc +0 -0
  275. package/server/ipc/hdbIpcServer.jsc +0 -0
  276. package/server/ipc/serverHandlers.jsc +0 -0
  277. package/server/ipc/utility/IPCEventObject.jsc +0 -0
  278. package/server/ipc/utility/ipcUtils.jsc +0 -0
  279. package/server/jobRunner.jsc +0 -0
  280. package/server/jobThread.jsc +0 -0
  281. package/server/jobs.jsc +0 -0
  282. package/server/serverHelpers/OperationFunctionObject.jsc +0 -0
  283. package/server/serverHelpers/requestTimePlugin.jsc +0 -0
  284. package/server/serverHelpers/serverHandlers.jsc +0 -0
  285. package/server/serverHelpers/serverUtilities.jsc +0 -0
  286. package/server/socketcluster/Server.jsc +0 -0
  287. package/server/socketcluster/broker.jsc +0 -0
  288. package/server/socketcluster/connector/HDBSocketConnector.jsc +0 -0
  289. package/server/socketcluster/connector/InterNodeSocketConnector.jsc +0 -0
  290. package/server/socketcluster/connector/SocketConnector.jsc +0 -0
  291. package/server/socketcluster/connector/spawnSCConnection.jsc +0 -0
  292. package/server/socketcluster/decisionMatrix/CoreDecisionMatrix.jsc +0 -0
  293. package/server/socketcluster/decisionMatrix/DecisionMatrixIF.jsc +0 -0
  294. package/server/socketcluster/decisionMatrix/rules/AssignToHdbChildWorkerRule.jsc +0 -0
  295. package/server/socketcluster/decisionMatrix/rules/CallRoomMsgHandlerRule.jsc +0 -0
  296. package/server/socketcluster/decisionMatrix/rules/CleanDataObjectRule.jsc +0 -0
  297. package/server/socketcluster/decisionMatrix/rules/CommandCollection.jsc +0 -0
  298. package/server/socketcluster/decisionMatrix/rules/DummyRule.jsc +0 -0
  299. package/server/socketcluster/decisionMatrix/rules/RulesIF.jsc +0 -0
  300. package/server/socketcluster/decisionMatrix/rules/StripHdbHeaderRule.jsc +0 -0
  301. package/server/socketcluster/decisionMatrix/rules/TestRule.jsc +0 -0
  302. package/server/socketcluster/handlers/NodeConnectionsHandler.jsc +0 -0
  303. package/server/socketcluster/handlers/SCServer.jsc +0 -0
  304. package/server/socketcluster/handlers/ServerSocket.jsc +0 -0
  305. package/server/socketcluster/interNodeConnectionLauncher.jsc +0 -0
  306. package/server/socketcluster/messageQueue/MessageQueueIF.jsc +0 -0
  307. package/server/socketcluster/middleware/AuthMiddleware.jsc +0 -0
  308. package/server/socketcluster/middleware/ConnectionNameCheckMiddleware.jsc +0 -0
  309. package/server/socketcluster/middleware/GenericMiddleware.jsc +0 -0
  310. package/server/socketcluster/middleware/MessagePrepMiddleware.jsc +0 -0
  311. package/server/socketcluster/middleware/MiddlewareFactory.jsc +0 -0
  312. package/server/socketcluster/middleware/MiddlewareIF.jsc +0 -0
  313. package/server/socketcluster/middleware/OriginatorCheckMiddleware.jsc +0 -0
  314. package/server/socketcluster/middleware/RequestDataValidMiddleware.jsc +0 -0
  315. package/server/socketcluster/middleware/StampOriginatorMiddleware.jsc +0 -0
  316. package/server/socketcluster/middleware/StampRequestMiddleware.jsc +0 -0
  317. package/server/socketcluster/observer/EventableIF.jsc +0 -0
  318. package/server/socketcluster/room/AddUserRoom.jsc +0 -0
  319. package/server/socketcluster/room/AlterUserRoom.jsc +0 -0
  320. package/server/socketcluster/room/CoreRoom.jsc +0 -0
  321. package/server/socketcluster/room/CreateAttributeRoom.jsc +0 -0
  322. package/server/socketcluster/room/CreateSchemaRoom.jsc +0 -0
  323. package/server/socketcluster/room/CreateTableRoom.jsc +0 -0
  324. package/server/socketcluster/room/DropUserRoom.jsc +0 -0
  325. package/server/socketcluster/room/HDBNodeRoom.jsc +0 -0
  326. package/server/socketcluster/room/RoomIF.jsc +0 -0
  327. package/server/socketcluster/room/RoomMessageObjects.jsc +0 -0
  328. package/server/socketcluster/room/UsersRoom.jsc +0 -0
  329. package/server/socketcluster/room/WatchHDBWorkersRoom.jsc +0 -0
  330. package/server/socketcluster/room/WorkerRoom.jsc +0 -0
  331. package/server/socketcluster/room/roomFactory.jsc +0 -0
  332. package/server/socketcluster/socketClusterObjects.jsc +0 -0
  333. package/server/socketcluster/types.jsc +0 -0
  334. package/server/socketcluster/util/clusterData.jsc +0 -0
  335. package/server/socketcluster/util/socketClusterUtils.jsc +0 -0
  336. package/server/socketcluster/worker/ClusterWorker.jsc +0 -0
  337. package/server/socketcluster/worker/WorkerIF.jsc +0 -0
  338. package/server/socketcluster/worker/WorkerObjects.jsc +0 -0
  339. package/server/transactToClusteringUtilities.jsc +0 -0
  340. package/sqlTranslator/SelectValidator.jsc +0 -0
  341. package/sqlTranslator/alasqlFunctionImporter.jsc +0 -0
  342. package/sqlTranslator/conditionPatterns.jsc +0 -0
  343. package/sqlTranslator/deleteTranslator.jsc +0 -0
  344. package/sqlTranslator/index.jsc +0 -0
  345. package/sqlTranslator/sql_statement_bucket.jsc +0 -0
  346. package/upgrade/EnvironmentVariable.jsc +0 -0
  347. package/upgrade/UpgradeDirective.jsc +0 -0
  348. package/upgrade/UpgradeObjects.jsc +0 -0
  349. package/upgrade/directives/3-0-0.jsc +0 -0
  350. package/upgrade/directives/3-1-0.jsc +0 -0
  351. package/upgrade/directives/directivesController.jsc +0 -0
  352. package/upgrade/directives/upgrade_scripts/3_0_0_reindex_script.jsc +0 -0
  353. package/upgrade/directivesManager.jsc +0 -0
  354. package/upgrade/lmdb/nodeLMDB/DBIDefinition.jsc +0 -0
  355. package/upgrade/lmdb/nodeLMDB/OpenDBIObject.jsc +0 -0
  356. package/upgrade/lmdb/nodeLMDB/OpenEnvironmentObject.jsc +0 -0
  357. package/upgrade/lmdb/nodeLMDB/commonErrors.jsc +0 -0
  358. package/upgrade/lmdb/nodeLMDB/commonUtility.jsc +0 -0
  359. package/upgrade/lmdb/nodeLMDB/environmentUtility.jsc +0 -0
  360. package/upgrade/lmdb/nodeLMDB/terms.jsc +0 -0
  361. package/upgrade/upgradePrompt.jsc +0 -0
  362. package/upgrade/upgradeUtilities.jsc +0 -0
  363. package/utility/AWS/AWSConnector.jsc +0 -0
  364. package/utility/OperationFunctionCaller.jsc +0 -0
  365. package/utility/common_utils.jsc +0 -0
  366. package/utility/environment/SystemInformationObject.jsc +0 -0
  367. package/utility/environment/SystemInformationOperation.jsc +0 -0
  368. package/utility/environment/environmentManager.jsc +0 -0
  369. package/utility/environment/systemInformation.jsc +0 -0
  370. package/utility/errors/commonErrors.jsc +0 -0
  371. package/utility/errors/hdbError.jsc +0 -0
  372. package/utility/functions/date/dateFunctions.jsc +0 -0
  373. package/utility/functions/geo.jsc +0 -0
  374. package/utility/functions/math/avg.jsc +0 -0
  375. package/utility/functions/math/count.jsc +0 -0
  376. package/utility/functions/sql/alaSQLExtension.jsc +0 -0
  377. package/utility/functions/string/compare.jsc +0 -0
  378. package/utility/globalSchema.jsc +0 -0
  379. package/utility/hdbTerms.jsc +0 -0
  380. package/utility/install/checkJWTTokensExist.jsc +0 -0
  381. package/utility/install/installer.jsc +0 -0
  382. package/utility/install_user_permission.jsc +0 -0
  383. package/utility/lmdb/DBIDefinition.jsc +0 -0
  384. package/utility/lmdb/DeleteRecordsResponseObject.jsc +0 -0
  385. package/utility/lmdb/InsertRecordsResponseObject.jsc +0 -0
  386. package/utility/lmdb/OpenDBIObject.jsc +0 -0
  387. package/utility/lmdb/OpenEnvironmentObject.jsc +0 -0
  388. package/utility/lmdb/UpdateRecordsResponseObject.jsc +0 -0
  389. package/utility/lmdb/UpsertRecordsResponseObject.jsc +0 -0
  390. package/utility/lmdb/cleanLMDBMap.jsc +0 -0
  391. package/utility/lmdb/commonUtility.jsc +0 -0
  392. package/utility/lmdb/deleteUtility.jsc +0 -0
  393. package/utility/lmdb/environmentUtility.jsc +0 -0
  394. package/utility/lmdb/searchCursorFunctions.jsc +0 -0
  395. package/utility/lmdb/searchUtility.jsc +0 -0
  396. package/utility/lmdb/terms.jsc +0 -0
  397. package/utility/lmdb/writeUtility.jsc +0 -0
  398. package/utility/logging/harper_logger.jsc +0 -0
  399. package/utility/mount_hdb.jsc +0 -0
  400. package/utility/npmUtilities.jsc +0 -0
  401. package/utility/operation_authorization.jsc +0 -0
  402. package/utility/password.jsc +0 -0
  403. package/utility/pm2/servicesConfig.jsc +0 -0
  404. package/utility/pm2/utilityFunctions.jsc +0 -0
  405. package/utility/psList.jsc +0 -0
  406. package/utility/registration/hdb_license.jsc +0 -0
  407. package/utility/registration/licenseObjects.jsc +0 -0
  408. package/utility/registration/registrationHandler.jsc +0 -0
  409. package/utility/scripts/restartHdb.jsc +0 -0
  410. package/utility/signalling.jsc +0 -0
  411. package/utility/system_info.jsc +0 -0
  412. package/validation/bulkDeleteValidator.jsc +0 -0
  413. package/validation/check_permissions.jsc +0 -0
  414. package/validation/clustering/configureValidator.jsc +0 -0
  415. package/validation/common_validators.jsc +0 -0
  416. package/validation/conditionalDeleteValidator.jsc +0 -0
  417. package/validation/deleteValidator.jsc +0 -0
  418. package/validation/fileLoadValidator.jsc +0 -0
  419. package/validation/insertValidator.jsc +0 -0
  420. package/validation/nodeSubscriptionValidator.jsc +0 -0
  421. package/validation/nodeValidator.jsc +0 -0
  422. package/validation/readLogValidator.jsc +0 -0
  423. package/validation/registration/license_key_object.jsc +0 -0
  424. package/validation/role_validation.jsc +0 -0
  425. package/validation/schemaMetadataValidator.jsc +0 -0
  426. package/validation/schema_validator.jsc +0 -0
  427. package/validation/searchValidator.jsc +0 -0
  428. package/validation/user_validation.jsc +0 -0
  429. package/validation/validationWrapper.jsc +0 -0
  430. package/node_modules/lmdb-store/build/Makefile +0 -324
  431. package/node_modules/lmdb-store/build/Release/.deps/Release/lmdb-store.node.d +0 -1
  432. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/dependencies/lmdb/libraries/liblmdb/chacha8.o.d +0 -6
  433. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb.o.d +0 -8
  434. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/dependencies/lmdb/libraries/liblmdb/midl.o.d +0 -8
  435. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/dependencies/lz4/lib/lz4.o.d +0 -5
  436. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/compression.o.d +0 -72
  437. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/cursor.o.d +0 -73
  438. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/dbi.o.d +0 -73
  439. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/env.o.d +0 -73
  440. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/misc.o.d +0 -73
  441. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/node-lmdb.o.d +0 -73
  442. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/ordered-binary.o.d +0 -73
  443. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/txn.o.d +0 -73
  444. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store/src/windows.o.d +0 -3
  445. package/node_modules/lmdb-store/build/Release/.deps/Release/obj.target/lmdb-store.node.d +0 -1
  446. package/node_modules/lmdb-store/build/Release/lmdb-store.node +0 -0
  447. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/dependencies/lmdb/libraries/liblmdb/chacha8.o +0 -0
  448. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/dependencies/lmdb/libraries/liblmdb/mdb.o +0 -0
  449. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/dependencies/lmdb/libraries/liblmdb/midl.o +0 -0
  450. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/dependencies/lz4/lib/lz4.o +0 -0
  451. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/compression.o +0 -0
  452. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/cursor.o +0 -0
  453. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/dbi.o +0 -0
  454. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/env.o +0 -0
  455. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/misc.o +0 -0
  456. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/node-lmdb.o +0 -0
  457. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/ordered-binary.o +0 -0
  458. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/txn.o +0 -0
  459. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store/src/windows.o +0 -0
  460. package/node_modules/lmdb-store/build/Release/obj.target/lmdb-store.node +0 -0
  461. package/node_modules/lmdb-store/build/binding.Makefile +0 -6
  462. package/node_modules/lmdb-store/build/config.gypi +0 -426
  463. package/node_modules/lmdb-store/build/lmdb-store.target.mk +0 -206
  464. package/node_modules/lmdb-store/node_modules/node-gyp-build/package.json +0 -60
  465. package/node_modules/lmdb-store/prebuilds/darwin-x64/electron.abi87.node +0 -0
  466. package/node_modules/lmdb-store/prebuilds/darwin-x64/node.abi72.node +0 -0
  467. package/node_modules/lmdb-store/prebuilds/darwin-x64/node.abi88.node +0 -0
  468. package/node_modules/lmdb-store/prebuilds/win32-x64/electron.abi87.node +0 -0
  469. package/node_modules/lmdb-store/prebuilds/win32-x64/node.abi72.node +0 -0
  470. package/node_modules/lmdb-store/prebuilds/win32-x64/node.abi88.node +0 -0
  471. package/node_modules/microtime/prebuilds/darwin-x64/electron-napi.node +0 -0
  472. package/node_modules/microtime/prebuilds/darwin-x64/node-napi.node +0 -0
  473. package/node_modules/microtime/prebuilds/linux-arm/electron-napi.node +0 -0
  474. package/node_modules/microtime/prebuilds/linux-arm/node-napi.node +0 -0
  475. package/node_modules/microtime/prebuilds/linux-x64/electron-napi.node +0 -0
  476. package/node_modules/microtime/prebuilds/linux-x64/node-napi.node +0 -0
  477. package/node_modules/microtime/prebuilds/win32-x64/electron-napi.node +0 -0
  478. package/node_modules/microtime/prebuilds/win32-x64/node-napi.node +0 -0
  479. package/node_modules/msgpackr-extract/.circleci/config.yml +0 -19
  480. package/node_modules/msgpackr-extract/.travis.yml +0 -30
  481. package/node_modules/msgpackr-extract/node_modules/node-gyp-build/LICENSE +0 -21
  482. package/node_modules/msgpackr-extract/node_modules/node-gyp-build/README.md +0 -58
  483. package/node_modules/msgpackr-extract/node_modules/node-gyp-build/bin.js +0 -77
  484. package/node_modules/msgpackr-extract/node_modules/node-gyp-build/build-test.js +0 -19
  485. package/node_modules/msgpackr-extract/node_modules/node-gyp-build/index.js +0 -202
  486. package/node_modules/msgpackr-extract/node_modules/node-gyp-build/optional.js +0 -7
  487. package/node_modules/msgpackr-extract/prebuilds/darwin-arm64/electron.abi98.node +0 -0
  488. package/node_modules/msgpackr-extract/prebuilds/darwin-arm64/node.abi102.node +0 -0
  489. package/node_modules/msgpackr-extract/prebuilds/darwin-arm64/node.abi83.node +0 -0
  490. package/node_modules/msgpackr-extract/prebuilds/darwin-arm64/node.abi93.node +0 -0
  491. package/node_modules/msgpackr-extract/prebuilds/darwin-x64/electron.abi98.node +0 -0
  492. package/node_modules/msgpackr-extract/prebuilds/darwin-x64/node.abi102.node +0 -0
  493. package/node_modules/msgpackr-extract/prebuilds/darwin-x64/node.abi83.node +0 -0
  494. package/node_modules/msgpackr-extract/prebuilds/darwin-x64/node.abi88.node +0 -0
  495. package/node_modules/msgpackr-extract/prebuilds/darwin-x64/node.abi93.node +0 -0
  496. package/node_modules/msgpackr-extract/prebuilds/linux-arm64/electron.abi98.node +0 -0
  497. package/node_modules/msgpackr-extract/prebuilds/linux-arm64/node.abi102.node +0 -0
  498. package/node_modules/msgpackr-extract/prebuilds/linux-arm64/node.abi83.node +0 -0
  499. package/node_modules/msgpackr-extract/prebuilds/linux-arm64/node.abi93.node +0 -0
  500. package/node_modules/msgpackr-extract/prebuilds/linux-x64/electron.abi98.node +0 -0
  501. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi102.musl.node +0 -0
  502. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi102.node +0 -0
  503. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi72.musl.node +0 -0
  504. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi72.node +0 -0
  505. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi83.musl.node +0 -0
  506. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi83.node +0 -0
  507. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi88.node +0 -0
  508. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi93.musl.node +0 -0
  509. package/node_modules/msgpackr-extract/prebuilds/linux-x64/node.abi93.node +0 -0
  510. package/node_modules/msgpackr-extract/prebuilds/win32-x64/electron.abi98.node +0 -0
  511. package/node_modules/msgpackr-extract/prebuilds/win32-x64/node.abi102.node +0 -0
  512. package/node_modules/msgpackr-extract/prebuilds/win32-x64/node.abi72.node +0 -0
  513. package/node_modules/msgpackr-extract/prebuilds/win32-x64/node.abi83.node +0 -0
  514. package/node_modules/msgpackr-extract/prebuilds/win32-x64/node.abi88.node +0 -0
  515. package/node_modules/msgpackr-extract/prebuilds/win32-x64/node.abi93.node +0 -0
  516. package/node_modules/node-addon-api/.editorconfig +0 -8
  517. package/node_modules/node-addon-api/.travis.yml +0 -65
  518. package/node_modules/node-addon-api/CHANGELOG.md +0 -325
  519. package/node_modules/node-addon-api/CODE_OF_CONDUCT.md +0 -4
  520. package/node_modules/node-addon-api/CONTRIBUTING.md +0 -66
  521. package/node_modules/node-addon-api/appveyor.yml +0 -48
  522. package/node_modules/node-addon-api/doc/Doxyfile +0 -2450
  523. package/node_modules/node-addon-api/doc/array_buffer.md +0 -129
  524. package/node_modules/node-addon-api/doc/async_context.md +0 -76
  525. package/node_modules/node-addon-api/doc/async_operations.md +0 -31
  526. package/node_modules/node-addon-api/doc/async_worker.md +0 -397
  527. package/node_modules/node-addon-api/doc/basic_types.md +0 -415
  528. package/node_modules/node-addon-api/doc/bigint.md +0 -92
  529. package/node_modules/node-addon-api/doc/boolean.md +0 -64
  530. package/node_modules/node-addon-api/doc/buffer.md +0 -140
  531. package/node_modules/node-addon-api/doc/callback_scope.md +0 -54
  532. package/node_modules/node-addon-api/doc/callbackinfo.md +0 -97
  533. package/node_modules/node-addon-api/doc/checker-tool.md +0 -32
  534. package/node_modules/node-addon-api/doc/class_property_descriptor.md +0 -118
  535. package/node_modules/node-addon-api/doc/cmake-js.md +0 -19
  536. package/node_modules/node-addon-api/doc/conversion-tool.md +0 -28
  537. package/node_modules/node-addon-api/doc/creating_a_release.md +0 -62
  538. package/node_modules/node-addon-api/doc/dataview.md +0 -244
  539. package/node_modules/node-addon-api/doc/env.md +0 -63
  540. package/node_modules/node-addon-api/doc/error.md +0 -115
  541. package/node_modules/node-addon-api/doc/error_handling.md +0 -186
  542. package/node_modules/node-addon-api/doc/escapable_handle_scope.md +0 -82
  543. package/node_modules/node-addon-api/doc/external.md +0 -59
  544. package/node_modules/node-addon-api/doc/function.md +0 -294
  545. package/node_modules/node-addon-api/doc/function_reference.md +0 -238
  546. package/node_modules/node-addon-api/doc/generator.md +0 -13
  547. package/node_modules/node-addon-api/doc/handle_scope.md +0 -65
  548. package/node_modules/node-addon-api/doc/memory_management.md +0 -27
  549. package/node_modules/node-addon-api/doc/node-gyp.md +0 -82
  550. package/node_modules/node-addon-api/doc/number.md +0 -163
  551. package/node_modules/node-addon-api/doc/object.md +0 -202
  552. package/node_modules/node-addon-api/doc/object_lifetime_management.md +0 -83
  553. package/node_modules/node-addon-api/doc/object_reference.md +0 -117
  554. package/node_modules/node-addon-api/doc/object_wrap.md +0 -546
  555. package/node_modules/node-addon-api/doc/prebuild_tools.md +0 -16
  556. package/node_modules/node-addon-api/doc/promises.md +0 -74
  557. package/node_modules/node-addon-api/doc/property_descriptor.md +0 -231
  558. package/node_modules/node-addon-api/doc/range_error.md +0 -59
  559. package/node_modules/node-addon-api/doc/reference.md +0 -111
  560. package/node_modules/node-addon-api/doc/setup.md +0 -82
  561. package/node_modules/node-addon-api/doc/string.md +0 -89
  562. package/node_modules/node-addon-api/doc/symbol.md +0 -44
  563. package/node_modules/node-addon-api/doc/threadsafe_function.md +0 -303
  564. package/node_modules/node-addon-api/doc/type_error.md +0 -59
  565. package/node_modules/node-addon-api/doc/typed_array.md +0 -74
  566. package/node_modules/node-addon-api/doc/typed_array_of.md +0 -133
  567. package/node_modules/node-addon-api/doc/value.md +0 -269
  568. package/node_modules/node-addon-api/doc/version_management.md +0 -43
  569. package/node_modules/node-addon-api/doc/working_with_javascript_values.md +0 -14
  570. package/node_modules/node-addon-api/external-napi/node_api.h +0 -7
  571. package/node_modules/node-addon-api/src/node_api.cc +0 -3655
  572. package/node_modules/node-addon-api/src/node_api.gyp +0 -21
  573. package/node_modules/node-addon-api/src/node_api.h +0 -588
  574. package/node_modules/node-addon-api/src/node_api_types.h +0 -115
  575. package/node_modules/node-addon-api/src/node_internals.cc +0 -142
  576. package/node_modules/node-addon-api/src/node_internals.h +0 -157
  577. package/node_modules/node-addon-api/src/util-inl.h +0 -38
  578. package/node_modules/node-addon-api/src/util.h +0 -7
@@ -1,388 +1,393 @@
1
- # lmdb-store
2
- [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
3
- [![npm version](https://img.shields.io/npm/v/lmdb-store.svg?style=flat-square)](https://www.npmjs.org/package/lmdb-store)
4
- [![get](https://img.shields.io/badge/get-4.5%20MOPS-yellow)](README.md)
5
- [![put](https://img.shields.io/badge/put-1.7%20MOPS-yellow)](README.md)
6
-
7
- `lmdb-store` is an ultra-fast interface to LMDB; probably the fastest and most efficient NodeJS key-value/database interface that exists for full storage and retrieval of structured JS data (objects, arrays, etc.) in a true persisted, scalable, [ACID compliant](https://en.wikipedia.org/wiki/ACID) database. It provides a simple interface for interacting with LMDB, as a key-value store, that makes it easy to fully leverage the power, crash-proof design, and efficiency of LMDB using intuitive JavaScript, and is designed to scale across multiple processes or threads. `lmdb-store` offers several key features that make it idiomatic, highly performant, and easy to use LMDB efficiently:
8
- * High-performance translation of JS values and data structures to/from binary key/value data
9
- * Queueing asynchronous off-thread write operations with promise-based API
10
- * Simple transaction management
11
- * Iterable queries/cursors
12
- * Automated database growth
13
- * Record versioning and optimistic locking for scalability/concurrency
14
- * Optional native off-main-thread compression with high-performance LZ4 compression
15
- * And ridiculously fast and efficient:
16
-
17
- Benchmarking on Node 14.9, with 3.4Ghz i7-4770 Windows, a `get` operation, using JS numbers as a key, retrieving data from the database (random access), and decoding the data into a structured object with 10 properties (using default [MessagePack encoding](https://github.com/kriszyp/msgpackr)), can be done in less than one microsecond, or a little over a 1,400,000/sec on a single thread. This is almost twice as fast as a single native `JSON.parse` call with the same object without any DB interaction! LMDB scales effortlessly across multiple processes or threads; over 4,500,000 operations/sec on the same 4/8 core computer by running across multiple threads. By running writes on a separate transactional thread, writing is extremely fast as well. With encoding the same objects, full encoding and writes can be performed at about 500,000 puts/second or 1,700,000 puts/second on multiple threads.
18
-
19
- ## Design
20
-
21
- `lmdb-store` handles translation of JavaScript values, primitives, arrays, and objects, to and from the binary storage of LMDB keys and values with highly optimized code using native C++ code for breakneck performance. It supports multiple types of JS values for keys and values, making it easy to use idiomatic JS for storing and retrieving data.
22
-
23
- `lmdb-store` is designed for synchronous reads, and asynchronous writes. In idiomatic NodeJS code, I/O operations are performed asynchronously. `lmdb-store` observes this design pattern; because LMDB is a memory-mapped database, reading and writing within a transaction does not use any I/O (other than the slight possibility of a page fault), and can almost always be performed faster than Node's event queue callbacks can even execute, and it is easier to write code for instant synchronous values from reads. On the otherhand, in default mode with sync'ed/flushed transactions, commiting transactions does involve I/O, and furthermore can achieve vastly higher throughput by batching operations. The entire transaction of a batch operation can be performed in a separate thread. Consequently, `lmdb-store` is designed for transactions to go through this asynchronous batching process and return a simple promise that resolves once data is written and flushed to disk.
24
-
25
- With the default sync'ing functionality, LMDB has a crash-proof design; a machine can be turned off at any point, and data can not be corrupted unless the written data is actually changed or tampered. Writing data and waiting for confirmation that has been writted to the physical medium is critical for data integrity, but is well known to have latency (although not necessarily less efficient). However, by batching writes, when a database is under load, slower transactions enable more writes per transaction, and lmdb-store is able to drive LMDB to achieve the maximum levels of throughput with fully sync'ed operations, preserving both the durability/safety of the transactions and legendary performance.
26
-
27
- `lmdb-store` supports and encourages the use of conditional writes; this allows for atomic operations that are dependendent on previously read data, and most transactional types of operations can be written with an optimistic-locking based, atomic-conditional-write pattern. This allows `lmdb-store` to delegate writes to off-thread execution, and scale to handle concurrent execution across many processes or threads while maintaining data integrity.
28
-
29
- When an `lmdb-store` automatically handles automatically database growth, expanding file size with a smart heuristic that minimizes file fragmentation (as you would expect from a database)..
30
-
31
- `lmdb-store` provides optional compression using LZ4 that works in conjunction with the asynchronous writes by performing the compression in the same thread (off the main thread) that performs the writes in a transaction. LZ4 is extremely fast, and decompression can be performed at roughly 5GB/s, so excellent storage efficiency can be achieved with almost negligible performance impact.
32
-
33
- `lmdb-store` is built on the excellent [node-lmdb](https://github.com/Venemo/node-lmdb) package.
34
-
35
- ## Usage
36
- An lmdb-store instances is created with by using `open` export from the main module:
37
- ```
38
- const { open } = require('lmdb-store');
39
- // or
40
- // import { open } from 'lmdb-store';
41
- let myStore = open({
42
- path: 'my-store',
43
- // any options go here, we can turn on compression like this:
44
- compression: true,
45
- });
46
- await myStore.put('greeting', { someText: 'Hello, World!' });
47
- myStore.get('greeting').someText // 'Hello, World!'
48
- // or
49
- myStore.transactionAsync(() => {
50
- myStore.put('greeting', { someText: 'Hello, World!' });
51
- myStore.get('greeting').someText // 'Hello, World!'
52
- });
53
- ```
54
- (see store options below for more options)
55
-
56
- Once you have created a store, you can store and retrieve values using keys:
57
-
58
- ### Keys
59
- When using the various APIs, keys can be any JS primitive (string, number, boolean, symbol), an array of primitives, or a Buffer. These primitives are translated to binary keys used by LMDB in such a way that consistent ordering is preserved. Numbers are ordered naturally, which come before strings, which are ordered lexically. The keys are stored with type information preserved. The `getRange`operations that return a set of entries will return entries with the original JS primitive values for the keys. If arrays are used as keys, they are ordering by first value in the array, with each subsequent element being a tie-breaker. Numbers are stored as doubles, with reversal of sign bit for proper ordering plus type information, so any JS number can be used as a key. For example, here are the order of some different keys:
60
- ```
61
- Symbol.for('even symbols')
62
- -10 // negative supported
63
- -1.1 // decimals supported
64
- 400
65
- 3E10
66
- 'Hello'
67
- ['Hello', 'World']
68
- 'World'
69
- 'hello'
70
- ['hello', 1, 'world']
71
- ['hello', 'world']
72
- ```
73
- You can override the default encoding of keys, and cause keys to be returned as node buffers using the `keyIsBuffer` database option (generally slower).
74
-
75
- ### Values
76
- You can store a wide variety of JavaScript values and data structures in lmdb-store, including objects (with arbitrary complexity), arrays, buffers, strings, numbers, etc. in your database. Even full structural cloning (with cycles) is an optionally supported. Values are stored and retrieved according the database encoding, which can be set using the `encoding` property on the database options. By default, data is stored using MessagePack, but there are four supported encodings:
77
-
78
- * `msgpack` (default) - All values are stored by serializing the value as MessagePack (using the [msgpackr](https://github.com/kriszyp/msgpackr) package). Values are decoded and parsed on retrieval, so `get` and `getRange` will return the object, array, or other value that you have stored. The msgpackr package is extremely fast (usually faster than native JSON), and provides the most flexibility in storing different value types. See the Shared Structures section for how to achieve maximum efficiency with this.
79
- * `cbor` - This specifies all values use the CBOR format, which requires that the [cbor-x](https://github.com/kriszyp/cbor-x) package be installed. This package is based on [msgpackr](https://github.com/kriszyp/msgpackr) and supports all the same options.
80
- * `json` - All values are stored by serializing the value as JSON (using JSON.stringify) and encoded with UTF-8. Values are decoded and parsed on retrieval using JSON.parse. Generally this does not perform as all as msgpack, nor support as many value types.
81
- * `string` - All values should be strings and stored by encoding with UTF-8. Values are returned as strings from `get`.
82
- * `binary` - Values are returned as (Node) buffer objects, representing the raw binary data. Note that creating buffer objects in NodeJS has some overhead and while this is fast and valuable direct storage of binary data, the data encodings provides faster and more optimized process for serializing and deserializing structured data.
83
- * `ordered-binary` - Use the same encoding as the default encoding for keys, which serializes primitive values with consistent ordering. This is primarily useful in `dupSort` stores where data values are ordered, and having consistent key and value ordering is helpful.
84
-
85
- Once you have a store, the following methods are available:
86
-
87
- ### `store.get(key): any`
88
- This will retrieve the value at the specified key. The `key` must be a JS value/primitive as described above, and the return value will be the stored data (dependent on the encoding), or `undefined` if the entry does not exist.
89
-
90
- ### `store.getEntry(key): any`
91
- This will retrieve the the entry at the specified key. The `key` must be a JS value/primitive as described above, and the return value will be the stored data (dependent on the encoding), or `undefined` if the entry does not exist. An entry is object with a `value` property for the value in the database, and a `version` property for the version number of the entry in the database (if `useVersions` is enabled for the database).
92
-
93
- ### `store.put(key, value, version?: number, ifVersion?: number): Promise<boolean>`
94
- This will store the provided value/data at the specified key. If the database is using versioning (see options below), the `version` parameter will be used to set the version number of the entry. If the `ifVersion` parameter is set, the put will only occur if the existing entry at the provided key has the version specified by `ifVersion` at the instance the commit occurs (LMDB commits are atomic by default). If the `ifVersion` parameter is not set, the put will occur regardless of the previous value.
95
-
96
- This operation will be enqueued to be written in a batch transaction. Any other operations that occur within a certain timeframe (until next event after I/O by default) will also occur in the same transaction. This will return a promise for the completion of the put. The promise will resolve once the transaction has finished committing. The resolved value of the promise will be `true` if the `put` was successful, and `false` if the put did not occur due to the `ifVersion` not matching at the time of the commit. Once the promise resolves, the transaction will have been fully written to the physical storage medium (durable commit, guaranteed available in the future as far as the OS/physical storage can permit and confirm, even if there is power loss or system crash).
97
-
98
- If this is performed inside a transaction, the put will be executed immediately in the current transaction.
99
-
100
- ### `store.remove(key, valueOrIfVersion?: number): Promise<boolean>`
101
- This will delete the entry at the specified key. This functions like `put`, with the same optional conditional version. This is batched along with put operations, and returns a promise indicating the success of the operation. If you are using a database with duplicate entries per key (with `dupSort` flag), you can specify the value to remove as the second parameter (instead of a version).
102
-
103
- Again, if this is performed inside a transation, the removal will be performed in the current transaction.
104
-
105
- ### `store.transactionAsync(callback: Function): Promise`
106
- This will run the provided callback in a transaction, asynchronously starting the transaction, then running the callback, then later committing the transaction. By running within a transaction, the code in the callback can perform multiple database operations atomically and isolated (fully [ACID compliant](https://en.wikipedia.org/wiki/ACID)). Any `put` or `remove` operations are immediately written to the transaction and can be immediately read afterwards (you can call `get()` or `getRange()` without awaiting for a returned promise) in the transaction.
107
-
108
- The callback function will be queued along with other `put` and `remove` operations, and run in the same transaction as other operations that have been queued in the current event turn, and will be executed in the order they were called. `transactionAsync` will return a promise that will resolve once its transaction has been committed. The promise will resolve to the value returned by the callback function.
109
-
110
- For example:
111
- ```
112
- let products = open(...);
113
- // decrement count if above zero
114
- function buyShoe() {
115
- return products.transactionAsync(() => {
116
- let shoe = products.get('shoe')
117
- // this is performed atomically, so we can guarantee no other processes
118
- // modify this entry before we write the new value
119
- if (shoe.count > 0) {
120
- shoe.count--
121
- products.put('shoe', shoe)
122
- return true // succeeded
123
- }
124
- return false // count is zero, no shoes to buy
125
- })
126
- }
127
- ```
128
-
129
- Note that `store.transactionAsync(() => store.put(...))` is functionally equivalent to simply calling `store.put(...)`, queuing the put for asynchronously being committed in transaction, except that `put` executes the db write operation entirely in separate worker thread, whereas `transactionAsync` must also synchronize the callback function in the main JS thread to execute (so it is a little bit less efficient, although still quite fast).
130
-
131
- Also, the callback function can be an async function (or return a promise), but this is not recommended. If the function returns a promise, this will delay/defer the commit until the callback's promise is resolved. However, while waiting for the callback to finish, other code may execute operations that would end up in the current transaction and may result in a surprising order of operations, and long running transactions are generally discouraged since they extend the single write lock.
132
-
133
- ### `store.childTransaction(callback: Function): Promise`
134
- This will run the provided callback in a transaction much like `transactionAsync` except an explicit child transaction will be used specifically for this callback. This makes it possible for the operations to be aborted and rolled back. The callback may return the lmdb-store exported `ABORT` constant to abort the child transaction for this callback. Also, if the callback function throws an error (or returns a reject promise), this will also abort the child transaction. This childTransaction function is not available if caching or `useWritemap` is enabled.
135
-
136
- The `childTransaction` function can be executed on its own (to run the child transaction inside the next queued transaction), or it can be executed inside another transaction callback, executing the child transaction within the current transaction.
137
-
138
- ### `store.putSync(key, value, versionOrOptions?: number | PutOptions): boolean`
139
- This will set the provided value at the specified key, but will do so synchronously. If this is called inside of a synchronous transaction, the put will be performed in the current transaction. If not, a transaction will be started, the put will be executed, the transaction will be committed, and then the function will return. We do not recommend this be used for any high-frequency operations as it can be vastly slower (often blocking the main JS thread for multiple milliseconds) than the `put` operation (typically consumes a few _microseconds_ on a worker thread). The third argument may be a version number or an options object that supports `append`, `appendDup`, `noOverwrite`, `noDupData`, and `version` for corresponding LMDB put flags.
140
-
141
- ### `store.removeSync(key, valueOrIfVersion?: number): boolean`
142
- This will delete the entry at the specified key. This functions like `putSync`, providing synchronous entry deletion, and uses the same arguments as `remove`. This returns `true` if there was an existing entry deleted, `false` if there was no matching entry.
143
-
144
- ### `store.ifVersion(key, ifVersion: number, callback): Promise<boolean>`
145
- This executes a block of conditional writes, and conditionally execute any puts or removes that are called in the callback, using the provided condition that requires the provided key's entry to have the provided version.
146
-
147
- ### `store.ifNoExists(key, callback): Promise<boolean>`
148
- This executes a block of conditional writes, and conditionally execute any puts or removes that are called in the callback, using the provided condition that requires the provided key's entry does not exist yet.
149
-
150
- ### `store.transactionSync(callback: Function)`
151
- This will begin a synchronous transaction, executing the provided callback function, and then commit the transaction. The provided function can perform `get`s, `put`s, and `remove`s within the transaction, and the result will be committed. The `callback` function can return a promise to indicate an ongoing asynchronous transaction, but generally you want to minimize how long a transaction is open on the main thread, at least if you are potentially operating with multiple processes.
152
-
153
- The callback may return the lmdb-store exported `ABORT` constant, or throw an error from the callback, to abort the transaction for this callback.
154
-
155
- If this is called inside an existing transaction and child transactions are supported (no write maps or caching), this will execute as a child transaction (and can be aborted), otherwise it will simply execute as part of the existing transaction (in which case it can't be aborted).
156
-
157
- ### `store.getRange(options: RangeOptions): Iterable<{ key, value: Buffer }>`
158
- This starts a cursor-based query of a range of data in the database, returning an iterable that also has `map`, `filter`, and `forEach` methods. The `start` and `end` indicate the starting and ending key for the range. The `reverse` flag can be used to indicate reverse traversal. The `limit` can limit the number of entries returned. The returned cursor/query is lazy, and retrieves data _as_ iteration takes place, so a large range could specified without forcing all the entries to be read and loaded in memory upfront, and one can exit out of the loop without traversing the whole range in the database. The query is iterable, we can use it directly in a for-of:
159
- ```
160
- for (let { key, value } of db.getRange({ start, end })) {
161
- // for each key-value pair in the given range
162
- }
163
- ```
164
- Or we can use the provided iterative methods on the returned results:
165
- ```
166
- db.getRange({ start, end })
167
- .filter(({ key, value }) => test(key))
168
- .forEach(({ key, value }) => {
169
- // for each key-value pair in the given range that matched the filter
170
- })
171
- ```
172
- Note that `map` and `filter` are also lazy, they will only be executed once their returned iterable is iterated or `forEach` is called on it. The `map` and `filter` functions also support async/promise-based functions, and you can create async iterable if the callback functions execute asynchronously (return a promise).
173
-
174
- We can also query with offset to skip a certain number of entries, and limit the number of entries to iterate through:
175
- ```
176
- db.getRange({ start, end, offset: 10, limit: 10 }) // skip first 10 and get next 10
177
- ```
178
-
179
- If you want to get a true array from the range results, the `asArray` property will return the results as an array.
180
-
181
- #### Snapshots
182
- By default a range iterator will use a database snapshot, using a single read transaction that remains open and gives a consistent view of the database at the time it was started, for the duration of iterating through the range. However, if the iteration will take place over a long period of time, keeping a read transaction open for a long time can interfere with LMDB's free space collection and reuse and increase the database size. If you will be using a long duration iterator, you can specify `snapshot: false` flag in the range options to indicate that it snapshotting is not necessary, and it can reset and renew read transactions while iterating, to allow LMDB to collect any space that was freed during iteration.
183
-
184
- ### `store.getValues(key, options?: RangeOptions): Iterable<any>`
185
- When using a store with duplicate entries per key (with `dupSort` flag), you can use this to retrieve all the values for a given key. This will return an iterator just like `getRange`, except each entry will be the value from the database:
186
- ```
187
- let db = store.openDB('my-index', {
188
- dupSort: true
189
- })
190
- await db.put('key1', 'value1')
191
- await db.put('key1', 'value2')
192
- for (let value of db.getValues('key1')) {
193
- // iterate values 'value1', 'value2'
194
- }
195
- await db.remove('key', 'value1') // only remove the second value under key1
196
- for (let value of db.getValues('key1')) {
197
- // just iterate value 'value1'
198
- }
199
- ```
200
- You can optionally provide a second argument with the same `options` that `getRange` handles.
201
-
202
- ### `store.getKeys(options: RangeOptions): Iterable<any>`
203
- This behaves like `getRange`, but only returns the keys. If this is duplicate key database, each key is only returned once (even if it has multiple values/entries).
204
-
205
- ### `RangeOptions`
206
- Here are the options that can be provided to the range methods (all are optional):
207
- * `start`: Starting key (will start at beginning of db, if not provided), can be any valid key type (primitive or array of primitives).
208
- * `end`: Ending key (will finish at end of db, if not provided), can be any valid key type (primitive or array of primitives).
209
- * `reverse`: Boolean key indicating reverse traversal through keys (does not do reverse by default).
210
- * `limit`: Number indicating maximum number of entries to read (no limit by default).
211
- * `offset`: Number indicating number of entries to skip before starting iteration (starts at 0 by default).
212
- * `versions`: Boolean indicating if versions should be included in returned entries (not by default).
213
- * `snapshot`: Boolean indicating if a database snapshot is used for iteration (true by default).
214
-
215
- ### `store.openDB(database: string|{name:string,...})`
216
- LMDB supports multiple databases per environment (an environment is a single memory-mapped file). When you initialize an LMDB store with `open`, the store uses the default root database. However, you can use multiple databases per environment/file and instantiate a store for each one. If you are going to be opening many databases, make sure you set the `maxDbs` (it defaults to 12). For example, we can open multiple stores for a single environment:
217
- ```
218
- const { open } = require('lmdb-store');
219
- let rootStore = open('all-my-data');
220
- let usersStore = myStore.openDB('users');
221
- let groupsStore = myStore.openDB('groups');
222
- let productsStore = myStore.openDB('products');
223
- ```
224
- Each of the opened/returned stores has the same API as the default store for the environment. Each of the stores for one environment also share the same batch queue and automated transactions with each other, so immediately writing data from two stores with the same environment will be batched together in the same commit. For example:
225
- ```
226
- usersStore.put('some-user', { data: userInfo });
227
- groupsStore.put('some-group', { groupData: moreData });
228
- ```
229
- Both these puts will be batched and committed in the same transaction in the next event turn.
230
- Also, you can start a transaction from one store and make writes from any of the stores in that same environment (and they will be a part of the same transaction:
231
- ```
232
- rootStore.transactionAsync(() => {
233
- usersStore.put('some-user', { data: userInfo });
234
- groupsStore.put('some-group', { groupData: moreData });
235
- });
236
- ```
237
-
238
- ### `getLastVersion(): number`
239
- This returns the version number of the last entry that was retrieved with `get` (assuming it was a versioned database). If you are using a database with `cache` enabled, use `getEntry` instead.
240
-
241
- ### `close(): void`
242
- This will close the current store. This closes the underlying LMDB database, and if this is the root database (opened with `open` as opposed to `store.openDB`), it will close the environment (and child stores will no longer be able to interact with the database).
243
-
244
- ### `store.doesExist(key, valueOrVersion): boolean`
245
- This checks if an entry exists for the given key, and optionally verifies that the version or value exists. If this is a `dupSort` enabled database, you can provide the key and value to check if that key/value entry exists. If you are using a versioned database, you can provide a version number to verify if the entry for the provided key has the specific version number. This returns true if the entry does exist.
246
-
247
- ### `resetReadTxn(): void`
248
- Normally, lmdb-store will automatically start a reader transaction for get and range operations, periodically reseting the read transaction on new event turns and after any write transactions are committed, to ensure it is using an up-to-date snapshot of the database. However, you can call `resetReadTxn` if you need to manually force the read transaction to reset to the latest snapshot/version of the database. In particular, this may be useful running with multiple processes where you need to immediately reset the read transaction based on a known update in another process (rather than waiting for the next event turn).
249
-
250
- ## Concurrency and Versioning
251
- LMDB and lmdb-store are designed for high concurrency, and we recommend using multiple processes to achieve concurrency with lmdb-store (processes are more robust than threads, and thread's advantage of shared memory is minimal with separate NodeJS isolates, and you still get shared memory access with processes when using LMDB). Versioning or asynchronous transactions are the preferred method for achieving atomicity with data updates with concurrency. A version can be stored with an entry, and later the data can be updated, conditional on the version being the expected version. This provides a robust mechanism for concurrent data updates even with multiple processes accessing the same database. To enable versioning, make sure to set the `useVersions` option when opening the database:
252
- ```
253
- let myStore = open('my-store', { useVersions: true })
254
- ```
255
- You can set a version by using the `version` argument in `put` calls. You can later update data and ensure that the data will only be updated if the version matches the expected version by using the `ifVersion` argument. When retrieving entries, you can access the version number by calling `getLastVersion()`.
256
-
257
- You can then make conditional writes, examples:
258
-
259
- ```
260
- myStore.put('key1', 'value1', 4, 3); // new version of 4, only if previous version was 3
261
- ```
262
- ```
263
- myStore.ifVersion('key1', 4, () => {
264
- myStore.put('key1', 'value2', 5); // equivalent to myStore.put('key1', 'value2', 5, 4);
265
- myStore.put('anotherKey', 'value', 3); // we can do other puts based on the same condition above
266
- // we can make puts in other stores (from the same db environment) based on same condition too
267
- myStore2.put('keyInOtherDb', 'value');
268
- });
269
- ```
270
- Asynchronous transactions are also a robust way to handle concurrency with multiple processes and provides a more traditional and flexible mechanism for making atomic ACID-compliant transactional data changes.
271
-
272
- ## Shared Structures
273
- Shared structures are mechanism for storing the structural information about objects stored in database in dedicated entry, outside of individual entries, for reuse across all of the data in database, for much more efficient storage and faster retrieval of data when storing objects that have the same or similar structures (note that this is only available using the default MessagePack or CBOR encoding, using the msgpackr or cbor-x package). This is highly recommended when storing structured objects with similiar object structures (including inside of array) in lmdb-store. When enabled, when data is stored, any structural information (the set of property names) is automatically generated and stored in separate entry to be reused for storing and retrieving all data for the database. To enable this feature, simply specify the key where lmdb-store can store the shared structures. You can use a symbol as a metadata key, as symbols are outside of the range of the standard JS primitive values:
274
- ```
275
- let myStore = open('my-store', {
276
- sharedStructuresKey: Symbol.for('structures')
277
- })
278
- ```
279
- Once shared structures has been enabled, you can store JavaScript objects just as you would normally would, and lmdb-store will automatically generate, increment, and save the structural information in the provided key to improve storage efficiency and performance. You never need to directly access this key, just be aware that that entry is being used by lmdb-store.
280
-
281
- ## Compression
282
- lmdb-store can optionally use off-thread LZ4 compression as part of the asynchronous writes to enable efficient compression with virtually no overhead to the main thread. LZ4 decompression (in `get` and `getRange` calls) is extremely fast and generally has little impact on performance. Compression is turned off by default, but can be turned on by setting the `compression` property when opening a database. The value of compression can be `true` or an object with compression settings, including properties:
283
- * `threshold` - Only entries that are larger than this value (in bytes) will be compressed. This defaults to 1000 (if compression is enabled)
284
- * `dictionary` - This can be buffer to use as a shared dictionary. This is defaults to a shared dictionary in lmdb-store that helps with compressing JSON and English words in small entries. [Zstandard](https://facebook.github.io/zstd/#small-data) provides utilities for [creating your own optimized shared dictionary](https://github.com/lz4/lz4/releases/tag/v1.8.1.2).
285
- For example:
286
- ```
287
- let myStore = open('my-store', {
288
- compression: {
289
- threshold: 500, // compress any entry larger than 500 bytes
290
- dictionary: fs.readFileSync('dict.txt') // use your own shared dictionary
291
- }
292
- })
293
- ```
294
- Compression is recommended for large databases that may be close to or larger than available RAM, to improve caching and reduce page faults. If you use enable compression for a database, you must ensure that the data is always opened with the same compression setting, so that the data will be properly decompressed.
295
-
296
- ## Caching
297
- lmdb-store supports caching of entries from stores, and uses a [LRU/LFU (LRFU) and weak-referencing caching mechanism](https://github.com/kriszyp/weak-lru-cache) for highly optimized caching and object tracking. There are several key potential benefits to using caching, including performance, key correlation with object identity, and immediate/synchronous access to saved data. Enabling caching will cache `get`s and `put`s, which can make frequent `get`s much faster. Caching is enabled by providing a truthy value for the `cache` property on the store `options`.
298
-
299
- The weak-referencing mechanism works in harmony with JS garbage collection to allow objects to be cached without preventing GC, and retrieved from the cache until they have actually been collected from memory, making more efficient use of memory. This also can provide a guarantee of object identity correlation with keys: as long as retrieved object is in memory, a `get` will always return the existing object, and `get` never will return two copies of the same object (for the same key). The LRFU caching mechanism is scan-resistant, tracking frequency of usage as well as recency.
300
-
301
- Because asynchronous `put` operations immediately go in the cache (and are pinned in the cache until committed), the caching enabled, `put` values can be retrieved via `get`, immediately and synchronously after the `put` call. Without caching enabled, you need wait for the `put` promise to resolve (or use asynchronous transactions) before you can access the stored value, but the cache enables the value to be immediately without waiting for the commit to finish:
302
- ```
303
- store.put('hi', 'there');
304
- store.get('hi'); // can immediately access value without having to await the promise
305
- ```
306
-
307
- While caching can improve performance, LMDB itself is extremely fast, and for small objects with sporadic access, caching may not improve performance. Caching tends to provide the most performance benefits for larger objects that may have more significant deserialization costs. Caching does not apply to `getRange` queries. Also note that this requires Node 14.10 or higher (or Node v13.0 with `--harmony-weak-ref` flag).
308
-
309
- If you are using caching with a database that has versions enabled, you should use the `getEntry` method to get the `value` and `version`, as `getLastVersion` will not be reliable (only returns the version when the data is accessed from the database).
310
-
311
- ### Asynchronous Transaction Ordering
312
- Asynchronous single operations (`put` and `remove`) are executed in the order they were called, relative to each other. Likewise, asynchronous transaction callbacks (`transactionAsync` and `childTransaction`) are also executed in order relative to other asynchronous transaction callbacks. However, by default all queued asynchronous transaction callbacks are executed _after_ all queued asynchronous single operations. But, you can enable strict ordering so that asynchronous transactions executed in order _with_ the asynchronous single operations, by setting the `asyncTransactionOrder` property to 'strict'.
313
-
314
- However, strict ordering comes with a couple of caveats. First, because lmdb-store executes asynchronous single operations on a separate transaction thread, but asynchronous transaction callbacks must execute on the main JS thread, if there is a lot of frequent switching back and forth between single operations and callbacks, this can significantly reduce performance since it requires substantial thread switching and event queuing.
315
-
316
- Second, if there are asynchronous operations that have been performed, and asynchronous transaction callbacks that are waiting to be called, and a synchronous transaction is executed (`transactionSync`), this must interrupt and split the current asynchronous transaction batch, so the synchronous transaction can be executed (the synchronous transaction can not block to wait for the asynchronous if there are outstanding callbacks to execute as part of that async transaction, as that would result in a deadlock). This can potentially create an exception to the general rule that all asynchronous operations that are performed in one event turn will be part of the same transaction. Of course, each single asynchronous transaction callback is still guaranteed to execute in a single atomic transaction (and calls to `transactionSync` _during_ a asynchronous transaction callback are simply executed as part of the current transaction). With the default ordering of 'after', it is possible for the async transactions to be performed in a separate transaction than the single operations if executed. Setting the ordering to 'before' ensures they are always in the same transaction.
317
-
318
- ### Store Options
319
- The open method can be used to create the main database/environment with the following signature:
320
- `open(path, options)` or `open(options)`
321
- Additional databases can be opened within the main database environment with:
322
- `store.openDB(name, options)` or `store.openDB(options)`
323
- If the `path` has an `.` in it, it is treated as a file name, otherwise it is treated as a directory name, where the data will be stored. The `options` argument to either of the functions should be an object, and supports the following properties, all of which are optional (except `name` if not otherwise specified):
324
- * `name` - This is the name of the database. This defaults to null (which is the root database) when opening the database environment (`open`). When an opening a database within an environment (`openDB`), this is required, if not specified in first parameter.
325
- * `encoding` - Sets the encoding for the database, which can be `'msgpack'`, `'json'`, `'cbor'`, `'string'`, or `'binary'`.
326
- * `sharedStructuresKey` - Enables shared structures and sets the key where the shared structures will be stored.
327
- * `compression` - This enables compression. This can be set a truthy value to enable compression with default settings, or it can be an object with compression settings.
328
- * `cache` - Setting this to true enables caching. This can also be set to an object specifying the settings/options for the cache (see [settings for weak-lru-cache](https://github.com/kriszyp/weak-lru-cache#weaklrucacheoptions-constructor)).
329
- * `useVersions` - Set this to true if you will be setting version numbers on the entries in the database. Note that you can not change this flag once a database has entries in it (or they won't be read correctly).
330
- * `encryptionKey` - This enables encryption, and the provided value is the key that is used for encryption. This may be a buffer or string, but must be 32 bytes/characters long. This uses the Chacha8 cipher for fast and secure on-disk encryption of data.
331
- * `keyIsBuffer` - This will cause the database to expect and return keys as node buffers.
332
- * `keyIsUint32` - This will cause the database to expect and return keys as unsigned 32-bit integers.
333
- * `dupSort` - Enables duplicate entries for keys. You will usually want to retrieve the values for a key with `getValues`.
334
- * `strictAsyncOrder` - Maintain strict ordering of execution of asynchronous transaction callbacks relative to asynchronous single operations.
335
- The following additional option properties are only available when creating the main database environment (`open`):
336
- * `path` - This is the file path to the database environment file you will use.
337
- * `maxDbs` - The maximum number of databases to be able to open ([there is some extra overhead if this is set very high](http://www.lmdb.tech/doc/group__mdb.html#gaa2fc2f1f37cb1115e733b62cab2fcdbc)).
338
- * `maxReaders` - The maximum number of concurrent read transactions (readers) to be able to open ([more information](http://www.lmdb.tech/doc/group__mdb.html#gae687966c24b790630be2a41573fe40e2)).
339
- * `commitDelay` - This is the amount of time to wait (in milliseconds) for batching write operations before committing the writes (in a transaction). This defaults to 0. A delay of 0 means more immediate commits with less latency (uses `setImmediate`), but a longer delay (which uses `setTimeout`) can be more efficient at collecting more writes into a single transaction and reducing I/O load. Note that NodeJS timers only have an effective resolution of about 10ms, so a `commitDelay` of 1ms will generally wait about 10ms.
340
-
341
- #### LMDB Flags
342
- In addition, the following options map to LMDB's env flags, <a href="http://www.lmdb.tech/doc/group__mdb.html">described here</a>. None of these need to be set, the defaults can always be used, and only `noMemInit` is recommended, but others are available for boosting performance:
343
- * `noMemInit` - This provides a small performance boost (when not using useWritemap) for writes, by skipping zero'ing out malloc'ed data, but can leave application data in unused portions of the database.
344
- * `remapChunks` - This a flag to specify if dynamic memory mapping should be used. Enabling this generally makes read operations a little bit slower, but frees up more mapped memory, making it friendlier to other applications. This is enabled by default on 32-bit operating systems (which require this to go beyond 4GB database size) if `mapSize` is not specified, otherwise it is disabled by default.
345
- * `mapSize` - This can be used to specify the initial amount of how much virtual memory address space (in bytes) to allocate for mapping to the database files. Setting a map size will typically disable `remapChunks` by default unless the size is larger than appropriate for the OS. Different OSes have different allocation limits.
346
- * `pageSize` - This changes the page size of the database.
347
- * `noReadAhead` - This disables read-ahead caching. Turning it off may help random read performance when the DB is larger than RAM and system RAM is full. However, this is not supported by all OSes, including Windows.
348
- * `useWritemap` - Use writemaps, this improves performance by reducing malloc calls, but can increase risk of a stray pointer corrupting data. This is currently disabled on Windows.
349
- * `noSubdir` - Treat `path` as a filename instead of directory (this is the default if the path appears to end with an extension and has '.' in it)
350
- * `noSync` - Doesn't sync the data to disk. We highly discourage this flag, since it can result in data corruption and lmdb-store mitigates performance issues associated with disk syncs by batching.
351
- * `noMetaSync` - This isn't as dangerous as `noSync`, but doesn't improve performance much either.
352
- * `readOnly` - Self-descriptive.
353
- * `mapAsync` - Not recommended, lmdb-store provides the means to ensure commits are performed in a separate thread (asyncronous to JS), and this prevents accurate notification of when flushes finish.
354
-
355
- #### Serialization options
356
- If you are using the default encoding of `'msgpack'`, the [msgpackr](https://github.com/kriszyp/msgpackr) package is used for serialization and deserialization. You can provide store options that are passed to msgpackr, as well. For example, these options can be potentially useful:
357
- * `structuredClone` - This enables the structured cloning extensions that will encode object/cyclic references and additional built-in types/classes.
358
- * `useFloat32: 4` - Encode floating point numbers in 32-bit format when possible.
359
-
360
- You can also use the CBOR format by specifying the encoding of `'cbor'` and installing the [cbor-x](https://github.com/kriszyp/cbor-x) package, which supports the same options.
361
-
362
- ## Events
363
-
364
- The `lmdb-store` instance is an <a href="https://nodejs.org/dist/latest-v11.x/docs/api/events.html#events_class_eventemitter">EventEmitter</a>, allowing application to listen to database events. There is just one event right now:
365
-
366
- `beforecommit` - This event is fired before a batched operation begins to start a transaction to write all queued writes to the database. The callback function can perform additional (asynchronous) writes (`put` and `remove`) and they will be included in the transaction about to be performed (this can be useful for updating a global version stamp based on all previous writes, for example).
367
-
368
- ##### Build Options
369
- A few LMDB options are available at build time, and can be specified with options with `npm install` (which can be specified in your package.json install script):
370
- `npm install --use_robust=true`: This will enable LMDB's MDB_USE_ROBUST option, which uses robust semaphores/mutexes so that if you are using multiple processes, and one process dies in the middle of transaction, the OS will cleanup the semaphore/mutex, aborting the transaction and allowing other processes to run without hanging. There is a slight performance overhead, but this is recommended if you will be using multiple processes.
371
-
372
- On MacOS, there is a default limit of 10 robust locked semaphores, which imposes a limit on the number of open write transactions (if you have over 10 db environments with a write transaction). If you need more concurrent write transactions, you can increase your maximum undoable semaphore count by setting kern.sysv.semmnu on your local computer. Otherwise don't use the robust mutex option. You can also try to minimize overlapping transactions and/or reduce the number of db environments (and use more databases within each environment).
373
-
374
- ## License
375
-
376
- `lmdb-store` is licensed under the terms of the MIT license.
377
-
378
- Also note that LMDB: Symas (the authors of LMDB) [offers commercial support of LMDB](https://symas.com/lightning-memory-mapped-database/).
379
-
380
- This project has no funding needs. If you feel inclined to donate, donate to one of Kris's favorite charities like [Innovations in Poverty Action](https://www.poverty-action.org/) or any of [GiveWell](https://givewell.org)'s recommended charities.
381
-
382
- ## Related Projects
383
-
384
- * lmdb-store is built on top of [node-lmdb](https://github.com/Venemo/node-lmdb)
385
- * lmdb-store uses msgpackr for the default serialization of data [msgpackr](https://github.com/kriszyp/msgpackr)
386
- * cobase is built on top of lmdb-store: [cobase](https://github.com/DoctorEvidence/cobase)
387
-
388
- <a href="https://dev.doctorevidence.com/"><img src="./assets/powers-dre.png" width="203"/></a>
1
+ [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
2
+ [![npm version](https://img.shields.io/npm/v/lmdb.svg?style=flat-square)](https://www.npmjs.org/package/lmdb)
3
+ [![get](https://img.shields.io/badge/get-4.5%20MOPS-yellow)](README.md)
4
+ [![put](https://img.shields.io/badge/put-1.7%20MOPS-yellow)](README.md)
5
+
6
+ This library is an ultra-fast NodeJS interface to LMDB; probably the fastest and most efficient NodeJS key-value/database interface that exists for full storage and retrieval of structured JS data (objects, arrays, etc.) in a true persisted, scalable, [ACID compliant](https://en.wikipedia.org/wiki/ACID) database. It provides a simple interface for interacting with LMDB, as a key-value store, that makes it easy to fully leverage the power, crash-proof design, and efficiency of LMDB using intuitive JavaScript, and is designed to scale across multiple processes or threads. Several key features that make it idiomatic, highly performant, and easy to use LMDB efficiently:
7
+ * High-performance translation of JS values and data structures to/from binary key/value data
8
+ * Queueing asynchronous off-thread write operations with promise-based API
9
+ * Simple transaction management
10
+ * Iterable queries/cursors
11
+ * Automated database growth
12
+ * Record versioning and optimistic locking for scalability/concurrency
13
+ * Optional native off-main-thread compression with high-performance LZ4 compression
14
+ * And ridiculously fast and efficient:
15
+
16
+ Benchmarking on Node 14.9, with 3.4Ghz i7-4770 Windows, a `get` operation, using JS numbers as a key, retrieving data from the database (random access), and decoding the data into a structured object with 10 properties (using default [MessagePack encoding](https://github.com/kriszyp/msgpackr)), can be done in less than one microsecond, or a little over a 1,400,000/sec on a single thread. This is almost twice as fast as a single native `JSON.parse` call with the same object without any DB interaction! LMDB scales effortlessly across multiple processes or threads; over 4,500,000 operations/sec on the same 4/8 core computer by running across multiple threads. By running writes on a separate transactional thread, writing is extremely fast as well. With encoding the same objects, full encoding and writes can be performed at about 500,000 puts/second or 1,700,000 puts/second on multiple threads.
17
+
18
+ This library has replaced the previous deprecated (LevelDOWN) `lmdb` package in the NPM package registry, but existing versions of that library are [still available](https://www.npmjs.com/package/lmdb/v/0.2.0).
19
+
20
+ ## Design
21
+
22
+ This library handles translation of JavaScript values, primitives, arrays, and objects, to and from the binary storage of LMDB keys and values with highly optimized code using native C++ code for breakneck performance. It supports multiple types of JS values for keys and values, making it easy to use idiomatic JS for storing and retrieving data.
23
+
24
+ This is designed for synchronous reads, and asynchronous writes. In idiomatic NodeJS code, I/O operations are performed asynchronously. LMDB is a memory-mapped database, reading and writing within a transaction does not use any I/O (other than the slight possibility of a page fault), and can almost always be performed faster than Node's event queue callbacks can even execute, and it is easier to write code for instant synchronous values from reads. On the otherhand, in default mode with sync'ed/flushed transactions, commiting transactions does involve I/O, and furthermore can achieve vastly higher throughput by batching operations. The entire transaction of a batch operation can be performed in a separate thread. Consequently, this library is designed for transactions to go through this asynchronous batching process and return a simple promise that resolves once data is written and flushed to disk.
25
+
26
+ With the default sync'ing configuration, LMDB has a crash-proof design; a machine can be turned off at any point, and data can not be corrupted unless the written data is actually changed or tampered. Writing data and waiting for confirmation that has been writted to the physical medium is critical for data integrity, but is well known to have latency (although not necessarily less efficient). However, by batching writes, when a database is under load, slower transactions enable more writes per transaction, and this library is able to drive LMDB to achieve the maximum levels of throughput with fully sync'ed operations, preserving both the durability/safety of the transactions and legendary performance.
27
+
28
+ This library supports and encourages the use of conditional writes; this allows for atomic operations that are dependendent on previously read data, and most transactional types of operations can be written with an optimistic-locking based, atomic-conditional-write pattern. This allows this library to delegate writes to off-thread execution, and scale to handle concurrent execution across many processes or threads while maintaining data integrity.
29
+
30
+ This library automatically handles automatically database growth, expanding file size with a smart heuristic that minimizes file fragmentation (as you would expect from a database).
31
+
32
+ This library provides optional compression using LZ4 that works in conjunction with the asynchronous writes by performing the compression in the same thread (off the main thread) that performs the writes in a transaction. LZ4 is extremely fast, and decompression can be performed at roughly 5GB/s, so excellent storage efficiency can be achieved with almost negligible performance impact.
33
+
34
+ ## Usage
35
+ An lmdb database instance is created with by using `open` export from the main module:
36
+ ```
37
+ const { open } = require('lmdb');
38
+ // or
39
+ // import { open } from 'lmdb';
40
+ let myStore = open({
41
+ path: 'my-db',
42
+ // any options go here, we can turn on compression like this:
43
+ compression: true,
44
+ });
45
+ await myStore.put('greeting', { someText: 'Hello, World!' });
46
+ myStore.get('greeting').someText // 'Hello, World!'
47
+ // or
48
+ myStore.transactionAsync(() => {
49
+ myStore.put('greeting', { someText: 'Hello, World!' });
50
+ myStore.get('greeting').someText // 'Hello, World!'
51
+ });
52
+ ```
53
+ (see database options below for more options)
54
+
55
+ Once you have opened a database, you can store and retrieve values using keys:
56
+
57
+ ### Keys
58
+ When using the various APIs, keys can be any JS primitive (string, number, boolean, symbol), an array of primitives, or a Buffer. These primitives are translated to binary keys used by LMDB in such a way that consistent ordering is preserved. Numbers are ordered naturally, which come before strings, which are ordered lexically. The keys are stored with type information preserved. The `getRange`operations that return a set of entries will return entries with the original JS primitive values for the keys. If arrays are used as keys, they are ordering by first value in the array, with each subsequent element being a tie-breaker. Numbers are stored as doubles, with reversal of sign bit for proper ordering plus type information, so any JS number can be used as a key. For example, here are the order of some different keys:
59
+ ```
60
+ Symbol.for('even symbols')
61
+ -10 // negative supported
62
+ -1.1 // decimals supported
63
+ 400
64
+ 3E10
65
+ 'Hello'
66
+ ['Hello', 'World']
67
+ 'World'
68
+ 'hello'
69
+ ['hello', 1, 'world']
70
+ ['hello', 'world']
71
+ ```
72
+ You can override the default encoding of keys, and cause keys to be returned as node buffers using the `keyIsBuffer` database option (generally slower).
73
+
74
+ ### Values
75
+ You can store a wide variety of JavaScript values and data structures in this library, including objects (with arbitrary complexity), arrays, buffers, strings, numbers, etc. in your database. Even full structural cloning (with cycles) is an optionally supported. Values are stored and retrieved according the database encoding, which can be set using the `encoding` property on the database options. By default, data is stored using MessagePack, but there are four supported encodings:
76
+
77
+ * `msgpack` (default) - All values are stored by serializing the value as MessagePack (using the [msgpackr](https://github.com/kriszyp/msgpackr) package). Values are decoded and parsed on retrieval, so `get` and `getRange` will return the object, array, or other value that you have stored. The msgpackr package is extremely fast (usually faster than native JSON), and provides the most flexibility in storing different value types. See the Shared Structures section for how to achieve maximum efficiency with this.
78
+ * `cbor` - This specifies all values use the CBOR format, which requires that the [cbor-x](https://github.com/kriszyp/cbor-x) package be installed. This package is based on [msgpackr](https://github.com/kriszyp/msgpackr) and supports all the same options.
79
+ * `json` - All values are stored by serializing the value as JSON (using JSON.stringify) and encoded with UTF-8. Values are decoded and parsed on retrieval using JSON.parse. Generally this does not perform as all as msgpack, nor support as many value types.
80
+ * `string` - All values should be strings and stored by encoding with UTF-8. Values are returned as strings from `get`.
81
+ * `binary` - Values are returned as (Node) buffer objects, representing the raw binary data. Note that creating buffer objects in NodeJS has some overhead and while this is fast and valuable direct storage of binary data, the data encodings provides faster and more optimized process for serializing and deserializing structured data.
82
+ * `ordered-binary` - Use the same encoding as the default encoding for keys, which serializes primitive values with consistent ordering. This is primarily useful in `dupSort` stores where data values are ordered, and having consistent key and value ordering is helpful.
83
+
84
+ Once you have a store, the following methods are available:
85
+
86
+ ### `store.get(key): any`
87
+ This will retrieve the value at the specified key. The `key` must be a JS value/primitive as described above, and the return value will be the stored data (dependent on the encoding), or `undefined` if the entry does not exist.
88
+
89
+ ### `store.getEntry(key): any`
90
+ This will retrieve the the entry at the specified key. The `key` must be a JS value/primitive as described above, and the return value will be the stored data (dependent on the encoding), or `undefined` if the entry does not exist. An entry is object with a `value` property for the value in the database, and a `version` property for the version number of the entry in the database (if `useVersions` is enabled for the database).
91
+
92
+ ### `store.put(key, value, version?: number, ifVersion?: number): Promise<boolean>`
93
+ This will store the provided value/data at the specified key. If the database is using versioning (see options below), the `version` parameter will be used to set the version number of the entry. If the `ifVersion` parameter is set, the put will only occur if the existing entry at the provided key has the version specified by `ifVersion` at the instance the commit occurs (LMDB commits are atomic by default). If the `ifVersion` parameter is not set, the put will occur regardless of the previous value.
94
+
95
+ This operation will be enqueued to be written in a batch transaction. Any other operations that occur within a certain timeframe (until next event after I/O by default) will also occur in the same transaction. This will return a promise for the completion of the put. The promise will resolve once the transaction has finished committing. The resolved value of the promise will be `true` if the `put` was successful, and `false` if the put did not occur due to the `ifVersion` not matching at the time of the commit. Once the promise resolves, the transaction will have been fully written to the physical storage medium (durable commit, guaranteed available in the future as far as the OS/physical storage can permit and confirm, even if there is power loss or system crash).
96
+
97
+ If this is performed inside a transaction, the put will be executed immediately in the current transaction.
98
+
99
+ ### `store.remove(key, valueOrIfVersion?: number): Promise<boolean>`
100
+ This will delete the entry at the specified key. This functions like `put`, with the same optional conditional version. This is batched along with put operations, and returns a promise indicating the success of the operation. If you are using a database with duplicate entries per key (with `dupSort` flag), you can specify the value to remove as the second parameter (instead of a version).
101
+
102
+ Again, if this is performed inside a transation, the removal will be performed in the current transaction.
103
+
104
+ ### `store.transactionAsync(callback: Function): Promise`
105
+ This will run the provided callback in a transaction, asynchronously starting the transaction, then running the callback, then later committing the transaction. By running within a transaction, the code in the callback can perform multiple database operations atomically and isolated (fully [ACID compliant](https://en.wikipedia.org/wiki/ACID)). Any `put` or `remove` operations are immediately written to the transaction and can be immediately read afterwards (you can call `get()` or `getRange()` without awaiting for a returned promise) in the transaction.
106
+
107
+ The callback function will be queued along with other `put` and `remove` operations, and run in the same transaction as other operations that have been queued in the current event turn, and will be executed in the order they were called. `transactionAsync` will return a promise that will resolve once its transaction has been committed. The promise will resolve to the value returned by the callback function.
108
+
109
+ For example:
110
+ ```
111
+ let products = open(...);
112
+ // decrement count if above zero
113
+ function buyShoe() {
114
+ return products.transactionAsync(() => {
115
+ let shoe = products.get('shoe')
116
+ // this is performed atomically, so we can guarantee no other processes
117
+ // modify this entry before we write the new value
118
+ if (shoe.count > 0) {
119
+ shoe.count--
120
+ products.put('shoe', shoe)
121
+ return true // succeeded
122
+ }
123
+ return false // count is zero, no shoes to buy
124
+ })
125
+ }
126
+ ```
127
+
128
+ Note that `store.transactionAsync(() => store.put(...))` is functionally equivalent to simply calling `store.put(...)`, queuing the put for asynchronously being committed in transaction, except that `put` executes the db write operation entirely in separate worker thread, whereas `transactionAsync` must also synchronize the callback function in the main JS thread to execute (so it is a little bit less efficient, although still quite fast).
129
+
130
+ Also, the callback function can be an async function (or return a promise), but this is not recommended. If the function returns a promise, this will delay/defer the commit until the callback's promise is resolved. However, while waiting for the callback to finish, other code may execute operations that would end up in the current transaction and may result in a surprising order of operations, and long running transactions are generally discouraged since they extend the single write lock.
131
+
132
+ ### `store.childTransaction(callback: Function): Promise`
133
+ This will run the provided callback in a transaction much like `transactionAsync` except an explicit child transaction will be used specifically for this callback. This makes it possible for the operations to be aborted and rolled back. The callback may return the exported `ABORT` constant to abort the child transaction for this callback. Also, if the callback function throws an error (or returns a reject promise), this will also abort the child transaction. This childTransaction function is not available if caching or `useWritemap` is enabled.
134
+
135
+ The `childTransaction` function can be executed on its own (to run the child transaction inside the next queued transaction), or it can be executed inside another transaction callback, executing the child transaction within the current transaction.
136
+
137
+ ### `store.putSync(key, value, versionOrOptions?: number | PutOptions): boolean`
138
+ This will set the provided value at the specified key, but will do so synchronously. If this is called inside of a synchronous transaction, the put will be performed in the current transaction. If not, a transaction will be started, the put will be executed, the transaction will be committed, and then the function will return. We do not recommend this be used for any high-frequency operations as it can be vastly slower (often blocking the main JS thread for multiple milliseconds) than the `put` operation (typically consumes a few _microseconds_ on a worker thread). The third argument may be a version number or an options object that supports `append`, `appendDup`, `noOverwrite`, `noDupData`, and `version` for corresponding LMDB put flags.
139
+
140
+ ### `store.removeSync(key, valueOrIfVersion?: number): boolean`
141
+ This will delete the entry at the specified key. This functions like `putSync`, providing synchronous entry deletion, and uses the same arguments as `remove`. This returns `true` if there was an existing entry deleted, `false` if there was no matching entry.
142
+
143
+ ### `store.ifVersion(key, ifVersion: number, callback): Promise<boolean>`
144
+ This executes a block of conditional writes, and conditionally execute any puts or removes that are called in the callback, using the provided condition that requires the provided key's entry to have the provided version.
145
+
146
+ ### `store.ifNoExists(key, callback): Promise<boolean>`
147
+ This executes a block of conditional writes, and conditionally execute any puts or removes that are called in the callback, using the provided condition that requires the provided key's entry does not exist yet.
148
+
149
+ ### `store.transactionSync(callback: Function)`
150
+ This will begin a synchronous transaction, executing the provided callback function, and then commit the transaction. The provided function can perform `get`s, `put`s, and `remove`s within the transaction, and the result will be committed. The `callback` function can return a promise to indicate an ongoing asynchronous transaction, but generally you want to minimize how long a transaction is open on the main thread, at least if you are potentially operating with multiple processes.
151
+
152
+ The callback may return the exported `ABORT` constant, or throw an error from the callback, to abort the transaction for this callback.
153
+
154
+ If this is called inside an existing transaction and child transactions are supported (no write maps or caching), this will execute as a child transaction (and can be aborted), otherwise it will simply execute as part of the existing transaction (in which case it can't be aborted).
155
+
156
+ ### `store.getRange(options: RangeOptions): Iterable<{ key, value: Buffer }>`
157
+ This starts a cursor-based query of a range of data in the database, returning an iterable that also has `map`, `filter`, and `forEach` methods. The `start` and `end` indicate the starting and ending key for the range. The `reverse` flag can be used to indicate reverse traversal. The `limit` can limit the number of entries returned. The returned cursor/query is lazy, and retrieves data _as_ iteration takes place, so a large range could specified without forcing all the entries to be read and loaded in memory upfront, and one can exit out of the loop without traversing the whole range in the database. The query is iterable, we can use it directly in a for-of:
158
+ ```
159
+ for (let { key, value } of db.getRange({ start, end })) {
160
+ // for each key-value pair in the given range
161
+ }
162
+ ```
163
+ Or we can use the provided iterative methods on the returned results:
164
+ ```
165
+ db.getRange({ start, end })
166
+ .filter(({ key, value }) => test(key))
167
+ .forEach(({ key, value }) => {
168
+ // for each key-value pair in the given range that matched the filter
169
+ })
170
+ ```
171
+ Note that `map` and `filter` are also lazy, they will only be executed once their returned iterable is iterated or `forEach` is called on it. The `map` and `filter` functions also support async/promise-based functions, and you can create async iterable if the callback functions execute asynchronously (return a promise).
172
+
173
+ We can also query with offset to skip a certain number of entries, and limit the number of entries to iterate through:
174
+ ```
175
+ db.getRange({ start, end, offset: 10, limit: 10 }) // skip first 10 and get next 10
176
+ ```
177
+
178
+ If you want to get a true array from the range results, the `asArray` property will return the results as an array.
179
+
180
+ #### Snapshots
181
+ By default a range iterator will use a database snapshot, using a single read transaction that remains open and gives a consistent view of the database at the time it was started, for the duration of iterating through the range. However, if the iteration will take place over a long period of time, keeping a read transaction open for a long time can interfere with LMDB's free space collection and reuse and increase the database size. If you will be using a long duration iterator, you can specify `snapshot: false` flag in the range options to indicate that it snapshotting is not necessary, and it can reset and renew read transactions while iterating, to allow LMDB to collect any space that was freed during iteration.
182
+
183
+ ### `store.getValues(key, options?: RangeOptions): Iterable<any>`
184
+ When using a store with duplicate entries per key (with `dupSort` flag), you can use this to retrieve all the values for a given key. This will return an iterator just like `getRange`, except each entry will be the value from the database:
185
+ ```
186
+ let db = store.openDB('my-index', {
187
+ dupSort: true
188
+ })
189
+ await db.put('key1', 'value1')
190
+ await db.put('key1', 'value2')
191
+ for (let value of db.getValues('key1')) {
192
+ // iterate values 'value1', 'value2'
193
+ }
194
+ await db.remove('key', 'value1') // only remove the second value under key1
195
+ for (let value of db.getValues('key1')) {
196
+ // just iterate value 'value1'
197
+ }
198
+ ```
199
+ You can optionally provide a second argument with the same `options` that `getRange` handles.
200
+
201
+ ### `store.getKeys(options: RangeOptions): Iterable<any>`
202
+ This behaves like `getRange`, but only returns the keys. If this is duplicate key database, each key is only returned once (even if it has multiple values/entries).
203
+
204
+ ### `RangeOptions`
205
+ Here are the options that can be provided to the range methods (all are optional):
206
+ * `start`: Starting key (will start at beginning of db, if not provided), can be any valid key type (primitive or array of primitives).
207
+ * `end`: Ending key (will finish at end of db, if not provided), can be any valid key type (primitive or array of primitives).
208
+ * `reverse`: Boolean key indicating reverse traversal through keys (does not do reverse by default).
209
+ * `limit`: Number indicating maximum number of entries to read (no limit by default).
210
+ * `offset`: Number indicating number of entries to skip before starting iteration (starts at 0 by default).
211
+ * `versions`: Boolean indicating if versions should be included in returned entries (not by default).
212
+ * `snapshot`: Boolean indicating if a database snapshot is used for iteration (true by default).
213
+
214
+ ### `store.openDB(database: string|{name:string,...})`
215
+ LMDB supports multiple databases per environment (an environment is a single memory-mapped file). When you initialize an LMDB store with `open`, the store uses the default root database. However, you can use multiple databases per environment/file and instantiate a store for each one. If you are going to be opening many databases, make sure you set the `maxDbs` (it defaults to 12). For example, we can open multiple stores for a single environment:
216
+ ```
217
+ const { open } = require('lmdb');
218
+ let rootStore = open('all-my-data');
219
+ let usersStore = myStore.openDB('users');
220
+ let groupsStore = myStore.openDB('groups');
221
+ let productsStore = myStore.openDB('products');
222
+ ```
223
+ Each of the opened/returned stores has the same API as the default store for the environment. Each of the stores for one environment also share the same batch queue and automated transactions with each other, so immediately writing data from two stores with the same environment will be batched together in the same commit. For example:
224
+ ```
225
+ usersStore.put('some-user', { data: userInfo });
226
+ groupsStore.put('some-group', { groupData: moreData });
227
+ ```
228
+ Both these puts will be batched and committed in the same transaction in the next event turn.
229
+ Also, you can start a transaction from one store and make writes from any of the stores in that same environment (and they will be a part of the same transaction:
230
+ ```
231
+ rootStore.transactionAsync(() => {
232
+ usersStore.put('some-user', { data: userInfo });
233
+ groupsStore.put('some-group', { groupData: moreData });
234
+ });
235
+ ```
236
+
237
+ ### `getLastVersion(): number`
238
+ This returns the version number of the last entry that was retrieved with `get` (assuming it was a versioned database). If you are using a database with `cache` enabled, use `getEntry` instead.
239
+
240
+ ### `close(): void`
241
+ This will close the current store. This closes the underlying LMDB database, and if this is the root database (opened with `open` as opposed to `store.openDB`), it will close the environment (and child stores will no longer be able to interact with the database).
242
+
243
+ ### `store.doesExist(key, valueOrVersion): boolean`
244
+ This checks if an entry exists for the given key, and optionally verifies that the version or value exists. If this is a `dupSort` enabled database, you can provide the key and value to check if that key/value entry exists. If you are using a versioned database, you can provide a version number to verify if the entry for the provided key has the specific version number. This returns true if the entry does exist.
245
+
246
+ ### `resetReadTxn(): void`
247
+ Normally, this library will automatically start a reader transaction for get and range operations, periodically reseting the read transaction on new event turns and after any write transactions are committed, to ensure it is using an up-to-date snapshot of the database. However, you can call `resetReadTxn` if you need to manually force the read transaction to reset to the latest snapshot/version of the database. In particular, this may be useful running with multiple processes where you need to immediately reset the read transaction based on a known update in another process (rather than waiting for the next event turn).
248
+
249
+ ## Concurrency and Versioning
250
+ LMDB and this library are designed for high concurrency, and we recommend using multiple processes to achieve concurrency (processes are more robust than threads, and thread's advantage of shared memory is minimal with separate NodeJS isolates, and you still get shared memory access with processes when using LMDB). Versioning or asynchronous transactions are the preferred method for achieving atomicity with data updates with concurrency. A version can be stored with an entry, and later the data can be updated, conditional on the version being the expected version. This provides a robust mechanism for concurrent data updates even with multiple processes accessing the same database. To enable versioning, make sure to set the `useVersions` option when opening the database:
251
+ ```
252
+ let myStore = open('my-store', { useVersions: true })
253
+ ```
254
+ You can set a version by using the `version` argument in `put` calls. You can later update data and ensure that the data will only be updated if the version matches the expected version by using the `ifVersion` argument. When retrieving entries, you can access the version number by calling `getLastVersion()`.
255
+
256
+ You can then make conditional writes, examples:
257
+
258
+ ```
259
+ myStore.put('key1', 'value1', 4, 3); // new version of 4, only if previous version was 3
260
+ ```
261
+ ```
262
+ myStore.ifVersion('key1', 4, () => {
263
+ myStore.put('key1', 'value2', 5); // equivalent to myStore.put('key1', 'value2', 5, 4);
264
+ myStore.put('anotherKey', 'value', 3); // we can do other puts based on the same condition above
265
+ // we can make puts in other stores (from the same db environment) based on same condition too
266
+ myStore2.put('keyInOtherDb', 'value');
267
+ });
268
+ ```
269
+ Asynchronous transactions are also a robust way to handle concurrency with multiple processes and provides a more traditional and flexible mechanism for making atomic ACID-compliant transactional data changes.
270
+
271
+ ## Shared Structures
272
+ Shared structures are mechanism for storing the structural information about objects stored in database in dedicated entry, outside of individual entries, for reuse across all of the data in database, for much more efficient storage and faster retrieval of data when storing objects that have the same or similar structures (note that this is only available using the default MessagePack or CBOR encoding, using the msgpackr or cbor-x package). This is highly recommended when storing structured objects with similiar object structures (including inside of array). When enabled, when data is stored, any structural information (the set of property names) is automatically generated and stored in separate entry to be reused for storing and retrieving all data for the database. To enable this feature, simply specify the key where shared structures can be stored. You can use a symbol as a metadata key, as symbols are outside of the range of the standard JS primitive values:
273
+ ```
274
+ let myStore = open('my-store', {
275
+ sharedStructuresKey: Symbol.for('structures')
276
+ })
277
+ ```
278
+ Once shared structures has been enabled, you can store JavaScript objects just as you would normally would, and this library will automatically generate, increment, and save the structural information in the provided key to improve storage efficiency and performance. You never need to directly access this key, just be aware that that entry is being used by this library.
279
+
280
+ ## Compression
281
+ This library can optionally use off-thread LZ4 compression as part of the asynchronous writes to enable efficient compression with virtually no overhead to the main thread. LZ4 decompression (in `get` and `getRange` calls) is extremely fast and generally has a low impact on performance. Compression is turned off by default, but can be turned on by setting the `compression` property when opening a database. The value of compression can be `true` or an object with compression settings, including properties:
282
+ * `threshold` - Only entries that are larger than this value (in bytes) will be compressed. This defaults to 1000 (if compression is enabled)
283
+ * `dictionary` - This can be buffer to use as a shared dictionary. This is defaults to a shared dictionary that helps with compressing JSON and English words in small entries. [Zstandard](https://facebook.github.io/zstd/#small-data) provides utilities for [creating your own optimized shared dictionary](https://github.com/lz4/lz4/releases/tag/v1.8.1.2).
284
+ For example:
285
+ ```
286
+ let myStore = open('my-store', {
287
+ compression: {
288
+ threshold: 500, // compress any entry larger than 500 bytes
289
+ dictionary: fs.readFileSync('dict.txt') // use your own shared dictionary
290
+ }
291
+ })
292
+ ```
293
+ Compression is recommended for large databases that may be close to or larger than available RAM, to improve caching and reduce page faults. If you use enable compression for a database, you must ensure that the data is always opened with the same compression setting, so that the data will be properly decompressed.
294
+
295
+ ## Caching
296
+ This library supports caching of entries from stores, and uses a [LRU/LFU (LRFU) and weak-referencing caching mechanism](https://github.com/kriszyp/weak-lru-cache) for highly optimized caching and object tracking. There are several key potential benefits to using caching, including performance, key correlation with object identity, and immediate/synchronous access to saved data. Enabling caching will cache `get`s and `put`s, which can make frequent `get`s much faster. Caching is enabled by providing a truthy value for the `cache` property on the store `options`.
297
+
298
+ The weak-referencing mechanism works in harmony with JS garbage collection to allow objects to be cached without preventing GC, and retrieved from the cache until they have actually been collected from memory, making more efficient use of memory. This also can provide a guarantee of object identity correlation with keys: as long as retrieved object is in memory, a `get` will always return the existing object, and `get` never will return two copies of the same object (for the same key). The LRFU caching mechanism is scan-resistant, tracking frequency of usage as well as recency.
299
+
300
+ Because asynchronous `put` operations immediately go in the cache (and are pinned in the cache until committed), the caching enabled, `put` values can be retrieved via `get`, immediately and synchronously after the `put` call. Without caching enabled, you need wait for the `put` promise to resolve (or use asynchronous transactions) before you can access the stored value, but the cache enables the value to be immediately without waiting for the commit to finish:
301
+ ```
302
+ store.put('hi', 'there');
303
+ store.get('hi'); // can immediately access value without having to await the promise
304
+ ```
305
+
306
+ While caching can improve performance, LMDB itself is extremely fast, and for small objects with sporadic access, caching may not improve performance. Caching tends to provide the most performance benefits for larger objects that may have more significant deserialization costs. Caching does not apply to `getRange` queries. Also note that this requires Node 14.10 or higher (or Node v13.0 with `--harmony-weak-ref` flag).
307
+
308
+ If you are using caching with a database that has versions enabled, you should use the `getEntry` method to get the `value` and `version`, as `getLastVersion` will not be reliable (only returns the version when the data is accessed from the database).
309
+
310
+ ### Asynchronous Transaction Ordering
311
+ Asynchronous single operations (`put` and `remove`) are executed in the order they were called, relative to each other. Likewise, asynchronous transaction callbacks (`transactionAsync` and `childTransaction`) are also executed in order relative to other asynchronous transaction callbacks. However, by default all queued asynchronous transaction callbacks are executed _after_ all queued asynchronous single operations. But, you can enable strict ordering so that asynchronous transactions executed in order _with_ the asynchronous single operations, by setting the `asyncTransactionOrder` property to 'strict'.
312
+
313
+ However, strict ordering comes with a couple of caveats. First, because asynchronous single operations are executed on separate transaction threads, but asynchronous transaction callbacks must execute on the main JS thread, if there is a lot of frequent switching back and forth between single operations and callbacks, this can significantly reduce performance since it requires substantial thread switching and event queuing.
314
+
315
+ Second, if there are asynchronous operations that have been performed, and asynchronous transaction callbacks that are waiting to be called, and a synchronous transaction is executed (`transactionSync`), this must interrupt and split the current asynchronous transaction batch, so the synchronous transaction can be executed (the synchronous transaction can not block to wait for the asynchronous if there are outstanding callbacks to execute as part of that async transaction, as that would result in a deadlock). This can potentially create an exception to the general rule that all asynchronous operations that are performed in one event turn will be part of the same transaction. Of course, each single asynchronous transaction callback is still guaranteed to execute in a single atomic transaction (and calls to `transactionSync` _during_ a asynchronous transaction callback are simply executed as part of the current transaction). With the default ordering of 'after', it is possible for the async transactions to be performed in a separate transaction than the single operations if executed. Setting the ordering to 'before' ensures they are always in the same transaction.
316
+
317
+ ### Store Options
318
+ The open method can be used to create the main database/environment with the following signature:
319
+ `open(path, options)` or `open(options)`
320
+ Additional databases can be opened within the main database environment with:
321
+ `store.openDB(name, options)` or `store.openDB(options)`
322
+ If the `path` has an `.` in it, it is treated as a file name, otherwise it is treated as a directory name, where the data will be stored. The `options` argument to either of the functions should be an object, and supports the following properties, all of which are optional (except `name` if not otherwise specified):
323
+ * `name` - This is the name of the database. This defaults to null (which is the root database) when opening the database environment (`open`). When an opening a database within an environment (`openDB`), this is required, if not specified in first parameter.
324
+ * `encoding` - Sets the encoding for the database, which can be `'msgpack'`, `'json'`, `'cbor'`, `'string'`, or `'binary'`.
325
+ * `sharedStructuresKey` - Enables shared structures and sets the key where the shared structures will be stored.
326
+ * `compression` - This enables compression. This can be set a truthy value to enable compression with default settings, or it can be an object with compression settings.
327
+ * `cache` - Setting this to true enables caching. This can also be set to an object specifying the settings/options for the cache (see [settings for weak-lru-cache](https://github.com/kriszyp/weak-lru-cache#weaklrucacheoptions-constructor)).
328
+ * `useVersions` - Set this to true if you will be setting version numbers on the entries in the database. Note that you can not change this flag once a database has entries in it (or they won't be read correctly).
329
+ * `encryptionKey` - This enables encryption, and the provided value is the key that is used for encryption. This may be a buffer or string, but must be 32 bytes/characters long. This uses the Chacha8 cipher for fast and secure on-disk encryption of data.
330
+ * `keyIsBuffer` - This will cause the database to expect and return keys as node buffers.
331
+ * `keyIsUint32` - This will cause the database to expect and return keys as unsigned 32-bit integers.
332
+ * `dupSort` - Enables duplicate entries for keys. You will usually want to retrieve the values for a key with `getValues`.
333
+ * `strictAsyncOrder` - Maintain strict ordering of execution of asynchronous transaction callbacks relative to asynchronous single operations.
334
+ The following additional option properties are only available when creating the main database environment (`open`):
335
+ * `path` - This is the file path to the database environment file you will use.
336
+ * `maxDbs` - The maximum number of databases to be able to open ([there is some extra overhead if this is set very high](http://www.lmdb.tech/doc/group__mdb.html#gaa2fc2f1f37cb1115e733b62cab2fcdbc)).
337
+ * `maxReaders` - The maximum number of concurrent read transactions (readers) to be able to open ([more information](http://www.lmdb.tech/doc/group__mdb.html#gae687966c24b790630be2a41573fe40e2)).
338
+ * `commitDelay` - This is the amount of time to wait (in milliseconds) for batching write operations before committing the writes (in a transaction). This defaults to 0. A delay of 0 means more immediate commits with less latency (uses `setImmediate`), but a longer delay (which uses `setTimeout`) can be more efficient at collecting more writes into a single transaction and reducing I/O load. Note that NodeJS timers only have an effective resolution of about 10ms, so a `commitDelay` of 1ms will generally wait about 10ms.
339
+
340
+ #### LMDB Flags
341
+ In addition, the following options map to LMDB's env flags, <a href="http://www.lmdb.tech/doc/group__mdb.html">described here</a>. None of these need to be set, the defaults can always be used, and only `noMemInit` is recommended, but others are available for boosting performance:
342
+ * `noMemInit` - This provides a small performance boost (when not using useWritemap) for writes, by skipping zero'ing out malloc'ed data, but can leave application data in unused portions of the database.
343
+ * `remapChunks` - This a flag to specify if dynamic memory mapping should be used. Enabling this generally makes read operations a little bit slower, but frees up more mapped memory, making it friendlier to other applications. This is enabled by default on 32-bit operating systems (which require this to go beyond 4GB database size) if `mapSize` is not specified, otherwise it is disabled by default.
344
+ * `mapSize` - This can be used to specify the initial amount of how much virtual memory address space (in bytes) to allocate for mapping to the database files. Setting a map size will typically disable `remapChunks` by default unless the size is larger than appropriate for the OS. Different OSes have different allocation limits.
345
+ * `pageSize` - This changes the page size of the database.
346
+ * `noReadAhead` - This disables read-ahead caching. Turning it off may help random read performance when the DB is larger than RAM and system RAM is full. However, this is not supported by all OSes, including Windows.
347
+ * `useWritemap` - Use writemaps, this improves performance by reducing malloc calls, but can increase risk of a stray pointer corrupting data. This is currently disabled on Windows.
348
+ * `noSubdir` - Treat `path` as a filename instead of directory (this is the default if the path appears to end with an extension and has '.' in it)
349
+ * `noSync` - Doesn't sync the data to disk. We highly discourage this flag, since it can result in data corruption and batching mitigates performance issues associated with disk syncs.
350
+ * `noMetaSync` - This isn't as dangerous as `noSync`, but doesn't improve performance much either.
351
+ * `readOnly` - Self-descriptive.
352
+ * `mapAsync` - Not recommended, commits are already performed in a separate thread (asyncronous to JS), and this prevents accurate notification of when flushes finish.
353
+
354
+ #### Serialization options
355
+ If you are using the default encoding of `'msgpack'`, the [msgpackr](https://github.com/kriszyp/msgpackr) package is used for serialization and deserialization. You can provide store options that are passed to msgpackr, as well. For example, these options can be potentially useful:
356
+ * `structuredClone` - This enables the structured cloning extensions that will encode object/cyclic references and additional built-in types/classes.
357
+ * `useFloat32: 4` - Encode floating point numbers in 32-bit format when possible.
358
+
359
+ You can also use the CBOR format by specifying the encoding of `'cbor'` and installing the [cbor-x](https://github.com/kriszyp/cbor-x) package, which supports the same options.
360
+
361
+ ## Events
362
+
363
+ The database instance is an <a href="https://nodejs.org/dist/latest-v11.x/docs/api/events.html#events_class_eventemitter">EventEmitter</a>, allowing application to listen to database events. There is just one event right now:
364
+
365
+ `beforecommit` - This event is fired before a batched operation begins to start a transaction to write all queued writes to the database. The callback function can perform additional (asynchronous) writes (`put` and `remove`) and they will be included in the transaction about to be performed (this can be useful for updating a global version stamp based on all previous writes, for example).
366
+
367
+ ##### Build Options
368
+ A few LMDB options are available at build time, and can be specified with options with `npm install` (which can be specified in your package.json install script):
369
+ `npm install --use_robust=true`: This will enable LMDB's MDB_USE_ROBUST option, which uses robust semaphores/mutexes so that if you are using multiple processes, and one process dies in the middle of transaction, the OS will cleanup the semaphore/mutex, aborting the transaction and allowing other processes to run without hanging. There is a slight performance overhead, but this is recommended if you will be using multiple processes.
370
+
371
+ On MacOS, there is a default limit of 10 robust locked semaphores, which imposes a limit on the number of open write transactions (if you have over 10 db environments with a write transaction). If you need more concurrent write transactions, you can increase your maximum undoable semaphore count by setting kern.sysv.semmnu on your local computer. Otherwise don't use the robust mutex option. You can also try to minimize overlapping transactions and/or reduce the number of db environments (and use more databases within each environment).
372
+
373
+ ## Credits
374
+
375
+ This library is built on [LMDB](https://symas.com/lmdb/) and is built from and derived from the excellent [node-lmdb](https://github.com/Venemo/node-lmdb) package.
376
+
377
+ Many thanks to [Rod Vagg](https://www.npmjs.com/~rvagg) for donating the `lmdb` package name in the NPM registry.
378
+
379
+ ## License
380
+
381
+ This library is licensed under the terms of the MIT license.
382
+
383
+ Also note that LMDB: Symas (the authors of LMDB) [offers commercial support of LMDB](https://symas.com/lightning-memory-mapped-database/).
384
+
385
+ This project has no funding needs. If you feel inclined to donate, donate to one of Kris's favorite charities like [Innovations in Poverty Action](https://www.poverty-action.org/) or any of [GiveWell](https://givewell.org)'s recommended charities.
386
+
387
+ ## Related Projects
388
+
389
+ * This library is built on top of [node-lmdb](https://github.com/Venemo/node-lmdb)
390
+ * This library uses msgpackr for the default serialization of data [msgpackr](https://github.com/kriszyp/msgpackr)
391
+ * cobase is built on top of this library: [cobase](https://github.com/DoctorEvidence/cobase)
392
+
393
+ <a href="https://dev.doctorevidence.com/"><img src="./assets/powers-dre.png" width="203"/></a>