harperdb 3.2.0 → 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 +6624 -6141
  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
@@ -2,18 +2,26 @@
2
2
  #define SRC_NAPI_INL_H_
3
3
 
4
4
  ////////////////////////////////////////////////////////////////////////////////
5
- // N-API C++ Wrapper Classes
5
+ // Node-API C++ Wrapper Classes
6
6
  //
7
- // Inline header-only implementations for "N-API" ABI-stable C APIs for Node.js.
7
+ // Inline header-only implementations for "Node-API" ABI-stable C APIs for
8
+ // Node.js.
8
9
  ////////////////////////////////////////////////////////////////////////////////
9
10
 
10
11
  // Note: Do not include this file directly! Include "napi.h" instead.
11
12
 
13
+ #include <algorithm>
12
14
  #include <cstring>
15
+ #include <mutex>
13
16
  #include <type_traits>
17
+ #include <utility>
14
18
 
15
19
  namespace Napi {
16
20
 
21
+ #ifdef NAPI_CPP_CUSTOM_NAMESPACE
22
+ namespace NAPI_CPP_CUSTOM_NAMESPACE {
23
+ #endif
24
+
17
25
  // Helpers to handle functions exposed from C++.
18
26
  namespace details {
19
27
 
@@ -24,16 +32,23 @@ namespace details {
24
32
  template <typename FreeType>
25
33
  static inline napi_status AttachData(napi_env env,
26
34
  napi_value obj,
27
- FreeType* data) {
35
+ FreeType* data,
36
+ napi_finalize finalizer = nullptr,
37
+ void* hint = nullptr) {
38
+ napi_status status;
39
+ if (finalizer == nullptr) {
40
+ finalizer = [](napi_env /*env*/, void* data, void* /*hint*/) {
41
+ delete static_cast<FreeType*>(data);
42
+ };
43
+ }
44
+ #if (NAPI_VERSION < 5)
28
45
  napi_value symbol, external;
29
- napi_status status = napi_create_symbol(env, nullptr, &symbol);
46
+ status = napi_create_symbol(env, nullptr, &symbol);
30
47
  if (status == napi_ok) {
31
48
  status = napi_create_external(env,
32
49
  data,
33
- [](napi_env /*env*/, void* data, void* /*hint*/) {
34
- delete static_cast<FreeType*>(data);
35
- },
36
- nullptr,
50
+ finalizer,
51
+ hint,
37
52
  &external);
38
53
  if (status == napi_ok) {
39
54
  napi_property_descriptor desc = {
@@ -49,6 +64,9 @@ static inline napi_status AttachData(napi_env env,
49
64
  status = napi_define_properties(env, obj, 1, &desc);
50
65
  }
51
66
  }
67
+ #else // NAPI_VERSION >= 5
68
+ status = napi_add_finalizer(env, obj, data, finalizer, hint, nullptr);
69
+ #endif
52
70
  return status;
53
71
  }
54
72
 
@@ -70,6 +88,24 @@ inline napi_value WrapCallback(Callable callback) {
70
88
  #endif // NAPI_CPP_EXCEPTIONS
71
89
  }
72
90
 
91
+ // For use in JS to C++ void callback wrappers to catch any Napi::Error
92
+ // exceptions and rethrow them as JavaScript exceptions before returning from the
93
+ // callback.
94
+ template <typename Callable>
95
+ inline void WrapVoidCallback(Callable callback) {
96
+ #ifdef NAPI_CPP_EXCEPTIONS
97
+ try {
98
+ callback();
99
+ } catch (const Error& e) {
100
+ e.ThrowAsJavaScriptException();
101
+ }
102
+ #else // NAPI_CPP_EXCEPTIONS
103
+ // When C++ exceptions are disabled, errors are immediately thrown as JS
104
+ // exceptions, so there is no need to catch and rethrow them here.
105
+ callback();
106
+ #endif // NAPI_CPP_EXCEPTIONS
107
+ }
108
+
73
109
  template <typename Callable, typename Return>
74
110
  struct CallbackData {
75
111
  static inline
@@ -105,27 +141,75 @@ struct CallbackData<Callable, void> {
105
141
  void* data;
106
142
  };
107
143
 
144
+ template <void (*Callback)(const CallbackInfo& info)>
145
+ static napi_value
146
+ TemplatedVoidCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
147
+ return details::WrapCallback([&] {
148
+ CallbackInfo cbInfo(env, info);
149
+ Callback(cbInfo);
150
+ return nullptr;
151
+ });
152
+ }
153
+
154
+ template <Napi::Value (*Callback)(const CallbackInfo& info)>
155
+ static napi_value
156
+ TemplatedCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
157
+ return details::WrapCallback([&] {
158
+ CallbackInfo cbInfo(env, info);
159
+ return Callback(cbInfo);
160
+ });
161
+ }
162
+
163
+ template <typename T,
164
+ Napi::Value (T::*UnwrapCallback)(const CallbackInfo& info)>
165
+ static napi_value
166
+ TemplatedInstanceCallback(napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
167
+ return details::WrapCallback([&] {
168
+ CallbackInfo cbInfo(env, info);
169
+ T* instance = T::Unwrap(cbInfo.This().As<Object>());
170
+ return (instance->*UnwrapCallback)(cbInfo);
171
+ });
172
+ }
173
+
174
+ template <typename T, void (T::*UnwrapCallback)(const CallbackInfo& info)>
175
+ static napi_value
176
+ TemplatedInstanceVoidCallback(napi_env env,
177
+ napi_callback_info info) NAPI_NOEXCEPT {
178
+ return details::WrapCallback([&] {
179
+ CallbackInfo cbInfo(env, info);
180
+ T* instance = T::Unwrap(cbInfo.This().As<Object>());
181
+ (instance->*UnwrapCallback)(cbInfo);
182
+ return nullptr;
183
+ });
184
+ }
185
+
108
186
  template <typename T, typename Finalizer, typename Hint = void>
109
187
  struct FinalizeData {
110
- static inline
111
- void Wrapper(napi_env env, void* data, void* finalizeHint) {
112
- FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
113
- finalizeData->callback(Env(env), static_cast<T*>(data));
114
- delete finalizeData;
188
+ static inline void Wrapper(napi_env env,
189
+ void* data,
190
+ void* finalizeHint) NAPI_NOEXCEPT {
191
+ WrapVoidCallback([&] {
192
+ FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
193
+ finalizeData->callback(Env(env), static_cast<T*>(data));
194
+ delete finalizeData;
195
+ });
115
196
  }
116
197
 
117
- static inline
118
- void WrapperWithHint(napi_env env, void* data, void* finalizeHint) {
119
- FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
120
- finalizeData->callback(Env(env), static_cast<T*>(data), finalizeData->hint);
121
- delete finalizeData;
198
+ static inline void WrapperWithHint(napi_env env,
199
+ void* data,
200
+ void* finalizeHint) NAPI_NOEXCEPT {
201
+ WrapVoidCallback([&] {
202
+ FinalizeData* finalizeData = static_cast<FinalizeData*>(finalizeHint);
203
+ finalizeData->callback(Env(env), static_cast<T*>(data), finalizeData->hint);
204
+ delete finalizeData;
205
+ });
122
206
  }
123
207
 
124
208
  Finalizer callback;
125
209
  Hint* hint;
126
210
  };
127
211
 
128
- #if (NAPI_VERSION > 3)
212
+ #if (NAPI_VERSION > 3 && !defined(__wasm32__))
129
213
  template <typename ContextType=void,
130
214
  typename Finalizer=std::function<void(Env, void*, ContextType*)>,
131
215
  typename FinalizerDataType=void>
@@ -138,9 +222,6 @@ struct ThreadSafeFinalize {
138
222
  ThreadSafeFinalize* finalizeData =
139
223
  static_cast<ThreadSafeFinalize*>(rawFinalizeData);
140
224
  finalizeData->callback(Env(env));
141
- if (finalizeData->tsfn) {
142
- *finalizeData->tsfn = nullptr;
143
- }
144
225
  delete finalizeData;
145
226
  }
146
227
 
@@ -154,9 +235,6 @@ struct ThreadSafeFinalize {
154
235
  ThreadSafeFinalize* finalizeData =
155
236
  static_cast<ThreadSafeFinalize*>(rawFinalizeData);
156
237
  finalizeData->callback(Env(env), finalizeData->data);
157
- if (finalizeData->tsfn) {
158
- *finalizeData->tsfn = nullptr;
159
- }
160
238
  delete finalizeData;
161
239
  }
162
240
 
@@ -170,9 +248,6 @@ struct ThreadSafeFinalize {
170
248
  ThreadSafeFinalize* finalizeData =
171
249
  static_cast<ThreadSafeFinalize*>(rawFinalizeData);
172
250
  finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));
173
- if (finalizeData->tsfn) {
174
- *finalizeData->tsfn = nullptr;
175
- }
176
251
  delete finalizeData;
177
252
  }
178
253
 
@@ -187,17 +262,52 @@ struct ThreadSafeFinalize {
187
262
  static_cast<ThreadSafeFinalize*>(rawFinalizeData);
188
263
  finalizeData->callback(Env(env), finalizeData->data,
189
264
  static_cast<ContextType*>(rawContext));
190
- if (finalizeData->tsfn) {
191
- *finalizeData->tsfn = nullptr;
192
- }
193
265
  delete finalizeData;
194
266
  }
195
267
 
196
268
  FinalizerDataType* data;
197
269
  Finalizer callback;
198
- napi_threadsafe_function* tsfn;
199
270
  };
200
- #endif
271
+
272
+ template <typename ContextType, typename DataType, typename CallJs, CallJs call>
273
+ typename std::enable_if<call != nullptr>::type static inline CallJsWrapper(
274
+ napi_env env, napi_value jsCallback, void* context, void* data) {
275
+ call(env,
276
+ Function(env, jsCallback),
277
+ static_cast<ContextType*>(context),
278
+ static_cast<DataType*>(data));
279
+ }
280
+
281
+ template <typename ContextType, typename DataType, typename CallJs, CallJs call>
282
+ typename std::enable_if<call == nullptr>::type static inline CallJsWrapper(
283
+ napi_env env, napi_value jsCallback, void* /*context*/, void* /*data*/) {
284
+ if (jsCallback != nullptr) {
285
+ Function(env, jsCallback).Call(0, nullptr);
286
+ }
287
+ }
288
+
289
+ #if NAPI_VERSION > 4
290
+
291
+ template <typename CallbackType, typename TSFN>
292
+ napi_value DefaultCallbackWrapper(napi_env /*env*/, std::nullptr_t /*cb*/) {
293
+ return nullptr;
294
+ }
295
+
296
+ template <typename CallbackType, typename TSFN>
297
+ napi_value DefaultCallbackWrapper(napi_env /*env*/, Napi::Function cb) {
298
+ return cb;
299
+ }
300
+
301
+ #else
302
+ template <typename CallbackType, typename TSFN>
303
+ napi_value DefaultCallbackWrapper(napi_env env, Napi::Function cb) {
304
+ if (cb.IsEmpty()) {
305
+ return TSFN::EmptyFunctionFactory(env);
306
+ }
307
+ return cb;
308
+ }
309
+ #endif // NAPI_VERSION > 4
310
+ #endif // NAPI_VERSION > 3 && !defined(__wasm32__)
201
311
 
202
312
  template <typename Getter, typename Setter>
203
313
  struct AccessorCallbackData {
@@ -239,12 +349,26 @@ struct AccessorCallbackData {
239
349
  // Module registration
240
350
  ////////////////////////////////////////////////////////////////////////////////
241
351
 
242
- #define NODE_API_MODULE(modname, regfunc) \
243
- napi_value __napi_ ## regfunc(napi_env env, \
244
- napi_value exports) { \
245
- return Napi::RegisterModule(env, exports, regfunc); \
246
- } \
247
- NAPI_MODULE(modname, __napi_ ## regfunc)
352
+ // Register an add-on based on an initializer function.
353
+ #define NODE_API_MODULE(modname, regfunc) \
354
+ static napi_value __napi_##regfunc(napi_env env, napi_value exports) { \
355
+ return Napi::RegisterModule(env, exports, regfunc); \
356
+ } \
357
+ NAPI_MODULE(modname, __napi_##regfunc)
358
+
359
+ // Register an add-on based on a subclass of `Addon<T>` with a custom Node.js
360
+ // module name.
361
+ #define NODE_API_NAMED_ADDON(modname, classname) \
362
+ static napi_value __napi_ ## classname(napi_env env, \
363
+ napi_value exports) { \
364
+ return Napi::RegisterModule(env, exports, &classname::Init); \
365
+ } \
366
+ NAPI_MODULE(modname, __napi_ ## classname)
367
+
368
+ // Register an add-on based on a subclass of `Addon<T>` with the Node.js module
369
+ // name given by node-gyp from the `target_name` in binding.gyp.
370
+ #define NODE_API_ADDON(classname) \
371
+ NODE_API_NAMED_ADDON(NODE_GYP_MODULE_NAME, classname)
248
372
 
249
373
  // Adapt the NAPI_MODULE registration function:
250
374
  // - Wrap the arguments in NAPI wrappers.
@@ -258,6 +382,72 @@ inline napi_value RegisterModule(napi_env env,
258
382
  });
259
383
  }
260
384
 
385
+ ////////////////////////////////////////////////////////////////////////////////
386
+ // Maybe class
387
+ ////////////////////////////////////////////////////////////////////////////////
388
+
389
+ template <class T>
390
+ bool Maybe<T>::IsNothing() const {
391
+ return !_has_value;
392
+ }
393
+
394
+ template <class T>
395
+ bool Maybe<T>::IsJust() const {
396
+ return _has_value;
397
+ }
398
+
399
+ template <class T>
400
+ void Maybe<T>::Check() const {
401
+ NAPI_CHECK(IsJust(), "Napi::Maybe::Check", "Maybe value is Nothing.");
402
+ }
403
+
404
+ template <class T>
405
+ T Maybe<T>::Unwrap() const {
406
+ NAPI_CHECK(IsJust(), "Napi::Maybe::Unwrap", "Maybe value is Nothing.");
407
+ return _value;
408
+ }
409
+
410
+ template <class T>
411
+ T Maybe<T>::UnwrapOr(const T& default_value) const {
412
+ return _has_value ? _value : default_value;
413
+ }
414
+
415
+ template <class T>
416
+ bool Maybe<T>::UnwrapTo(T* out) const {
417
+ if (IsJust()) {
418
+ *out = _value;
419
+ return true;
420
+ };
421
+ return false;
422
+ }
423
+
424
+ template <class T>
425
+ bool Maybe<T>::operator==(const Maybe& other) const {
426
+ return (IsJust() == other.IsJust()) &&
427
+ (!IsJust() || Unwrap() == other.Unwrap());
428
+ }
429
+
430
+ template <class T>
431
+ bool Maybe<T>::operator!=(const Maybe& other) const {
432
+ return !operator==(other);
433
+ }
434
+
435
+ template <class T>
436
+ Maybe<T>::Maybe() : _has_value(false) {}
437
+
438
+ template <class T>
439
+ Maybe<T>::Maybe(const T& t) : _has_value(true), _value(t) {}
440
+
441
+ template <class T>
442
+ inline Maybe<T> Nothing() {
443
+ return Maybe<T>();
444
+ }
445
+
446
+ template <class T>
447
+ inline Maybe<T> Just(const T& t) {
448
+ return Maybe<T>(t);
449
+ }
450
+
261
451
  ////////////////////////////////////////////////////////////////////////////////
262
452
  // Env class
263
453
  ////////////////////////////////////////////////////////////////////////////////
@@ -297,7 +487,7 @@ inline bool Env::IsExceptionPending() const {
297
487
  return result;
298
488
  }
299
489
 
300
- inline Error Env::GetAndClearPendingException() {
490
+ inline Error Env::GetAndClearPendingException() const {
301
491
  napi_value value;
302
492
  napi_status status = napi_get_and_clear_last_exception(_env, &value);
303
493
  if (status != napi_ok) {
@@ -307,6 +497,84 @@ inline Error Env::GetAndClearPendingException() {
307
497
  return Error(_env, value);
308
498
  }
309
499
 
500
+ inline MaybeOrValue<Value> Env::RunScript(const char* utf8script) const {
501
+ String script = String::New(_env, utf8script);
502
+ return RunScript(script);
503
+ }
504
+
505
+ inline MaybeOrValue<Value> Env::RunScript(const std::string& utf8script) const {
506
+ return RunScript(utf8script.c_str());
507
+ }
508
+
509
+ inline MaybeOrValue<Value> Env::RunScript(String script) const {
510
+ napi_value result;
511
+ napi_status status = napi_run_script(_env, script, &result);
512
+ NAPI_RETURN_OR_THROW_IF_FAILED(
513
+ _env, status, Napi::Value(_env, result), Napi::Value);
514
+ }
515
+
516
+ #if NAPI_VERSION > 2
517
+ template <typename Hook, typename Arg>
518
+ void Env::CleanupHook<Hook, Arg>::Wrapper(void* data) NAPI_NOEXCEPT {
519
+ auto* cleanupData =
520
+ static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(
521
+ data);
522
+ cleanupData->hook();
523
+ delete cleanupData;
524
+ }
525
+
526
+ template <typename Hook, typename Arg>
527
+ void Env::CleanupHook<Hook, Arg>::WrapperWithArg(void* data) NAPI_NOEXCEPT {
528
+ auto* cleanupData =
529
+ static_cast<typename Napi::Env::CleanupHook<Hook, Arg>::CleanupData*>(
530
+ data);
531
+ cleanupData->hook(static_cast<Arg*>(cleanupData->arg));
532
+ delete cleanupData;
533
+ }
534
+ #endif // NAPI_VERSION > 2
535
+
536
+ #if NAPI_VERSION > 5
537
+ template <typename T, Env::Finalizer<T> fini>
538
+ inline void Env::SetInstanceData(T* data) const {
539
+ napi_status status =
540
+ napi_set_instance_data(_env, data, [](napi_env env, void* data, void*) {
541
+ fini(env, static_cast<T*>(data));
542
+ }, nullptr);
543
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
544
+ }
545
+
546
+ template <typename DataType,
547
+ typename HintType,
548
+ Napi::Env::FinalizerWithHint<DataType, HintType> fini>
549
+ inline void Env::SetInstanceData(DataType* data, HintType* hint) const {
550
+ napi_status status =
551
+ napi_set_instance_data(_env, data,
552
+ [](napi_env env, void* data, void* hint) {
553
+ fini(env, static_cast<DataType*>(data), static_cast<HintType*>(hint));
554
+ }, hint);
555
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
556
+ }
557
+
558
+ template <typename T>
559
+ inline T* Env::GetInstanceData() const {
560
+ void* data = nullptr;
561
+
562
+ napi_status status = napi_get_instance_data(_env, &data);
563
+ NAPI_THROW_IF_FAILED(_env, status, nullptr);
564
+
565
+ return static_cast<T*>(data);
566
+ }
567
+
568
+ template <typename T> void Env::DefaultFini(Env, T* data) {
569
+ delete data;
570
+ }
571
+
572
+ template <typename DataType, typename HintType>
573
+ void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) {
574
+ delete data;
575
+ }
576
+ #endif // NAPI_VERSION > 5
577
+
310
578
  ////////////////////////////////////////////////////////////////////////////////
311
579
  // Value class
312
580
  ////////////////////////////////////////////////////////////////////////////////
@@ -371,13 +639,24 @@ inline bool Value::IsNumber() const {
371
639
  return Type() == napi_number;
372
640
  }
373
641
 
374
- // currently experimental guard with version of NAPI_VERSION that it is
375
- // released in once it is no longer experimental
376
- #if (NAPI_VERSION > 2147483646)
642
+ #if NAPI_VERSION > 5
377
643
  inline bool Value::IsBigInt() const {
378
644
  return Type() == napi_bigint;
379
645
  }
380
- #endif // NAPI_EXPERIMENTAL
646
+ #endif // NAPI_VERSION > 5
647
+
648
+ #if (NAPI_VERSION > 4)
649
+ inline bool Value::IsDate() const {
650
+ if (IsEmpty()) {
651
+ return false;
652
+ }
653
+
654
+ bool result;
655
+ napi_status status = napi_is_date(_env, _value, &result);
656
+ NAPI_THROW_IF_FAILED(_env, status, false);
657
+ return result;
658
+ }
659
+ #endif
381
660
 
382
661
  inline bool Value::IsString() const {
383
662
  return Type() == napi_string;
@@ -470,32 +749,32 @@ inline T Value::As() const {
470
749
  return T(_env, _value);
471
750
  }
472
751
 
473
- inline Boolean Value::ToBoolean() const {
752
+ inline MaybeOrValue<Boolean> Value::ToBoolean() const {
474
753
  napi_value result;
475
754
  napi_status status = napi_coerce_to_bool(_env, _value, &result);
476
- NAPI_THROW_IF_FAILED(_env, status, Boolean());
477
- return Boolean(_env, result);
755
+ NAPI_RETURN_OR_THROW_IF_FAILED(
756
+ _env, status, Napi::Boolean(_env, result), Napi::Boolean);
478
757
  }
479
758
 
480
- inline Number Value::ToNumber() const {
759
+ inline MaybeOrValue<Number> Value::ToNumber() const {
481
760
  napi_value result;
482
761
  napi_status status = napi_coerce_to_number(_env, _value, &result);
483
- NAPI_THROW_IF_FAILED(_env, status, Number());
484
- return Number(_env, result);
762
+ NAPI_RETURN_OR_THROW_IF_FAILED(
763
+ _env, status, Napi::Number(_env, result), Napi::Number);
485
764
  }
486
765
 
487
- inline String Value::ToString() const {
766
+ inline MaybeOrValue<String> Value::ToString() const {
488
767
  napi_value result;
489
768
  napi_status status = napi_coerce_to_string(_env, _value, &result);
490
- NAPI_THROW_IF_FAILED(_env, status, String());
491
- return String(_env, result);
769
+ NAPI_RETURN_OR_THROW_IF_FAILED(
770
+ _env, status, Napi::String(_env, result), Napi::String);
492
771
  }
493
772
 
494
- inline Object Value::ToObject() const {
773
+ inline MaybeOrValue<Object> Value::ToObject() const {
495
774
  napi_value result;
496
775
  napi_status status = napi_coerce_to_object(_env, _value, &result);
497
- NAPI_THROW_IF_FAILED(_env, status, Object());
498
- return Object(_env, result);
776
+ NAPI_RETURN_OR_THROW_IF_FAILED(
777
+ _env, status, Napi::Object(_env, result), Napi::Object);
499
778
  }
500
779
 
501
780
  ////////////////////////////////////////////////////////////////////////////////
@@ -595,9 +874,7 @@ inline double Number::DoubleValue() const {
595
874
  return result;
596
875
  }
597
876
 
598
- // currently experimental guard with version of NAPI_VERSION that it is
599
- // released in once it is no longer experimental
600
- #if (NAPI_VERSION > 2147483646)
877
+ #if NAPI_VERSION > 5
601
878
  ////////////////////////////////////////////////////////////////////////////////
602
879
  // BigInt Class
603
880
  ////////////////////////////////////////////////////////////////////////////////
@@ -658,7 +935,38 @@ inline void BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words)
658
935
  _env, _value, sign_bit, word_count, words);
659
936
  NAPI_THROW_IF_FAILED_VOID(_env, status);
660
937
  }
661
- #endif // NAPI_EXPERIMENTAL
938
+ #endif // NAPI_VERSION > 5
939
+
940
+ #if (NAPI_VERSION > 4)
941
+ ////////////////////////////////////////////////////////////////////////////////
942
+ // Date Class
943
+ ////////////////////////////////////////////////////////////////////////////////
944
+
945
+ inline Date Date::New(napi_env env, double val) {
946
+ napi_value value;
947
+ napi_status status = napi_create_date(env, val, &value);
948
+ NAPI_THROW_IF_FAILED(env, status, Date());
949
+ return Date(env, value);
950
+ }
951
+
952
+ inline Date::Date() : Value() {
953
+ }
954
+
955
+ inline Date::Date(napi_env env, napi_value value) : Value(env, value) {
956
+ }
957
+
958
+ inline Date::operator double() const {
959
+ return ValueOf();
960
+ }
961
+
962
+ inline double Date::ValueOf() const {
963
+ double result;
964
+ napi_status status = napi_get_date_value(
965
+ _env, _value, &result);
966
+ NAPI_THROW_IF_FAILED(_env, status, 0);
967
+ return result;
968
+ }
969
+ #endif
662
970
 
663
971
  ////////////////////////////////////////////////////////////////////////////////
664
972
  // Name class
@@ -683,6 +991,12 @@ inline String String::New(napi_env env, const std::u16string& val) {
683
991
  }
684
992
 
685
993
  inline String String::New(napi_env env, const char* val) {
994
+ // TODO(@gabrielschulhof) Remove if-statement when core's error handling is
995
+ // available in all supported versions.
996
+ if (val == nullptr) {
997
+ // Throw an error that looks like it came from core.
998
+ NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());
999
+ }
686
1000
  napi_value value;
687
1001
  napi_status status = napi_create_string_utf8(env, val, std::strlen(val), &value);
688
1002
  NAPI_THROW_IF_FAILED(env, status, String());
@@ -691,6 +1005,12 @@ inline String String::New(napi_env env, const char* val) {
691
1005
 
692
1006
  inline String String::New(napi_env env, const char16_t* val) {
693
1007
  napi_value value;
1008
+ // TODO(@gabrielschulhof) Remove if-statement when core's error handling is
1009
+ // available in all supported versions.
1010
+ if (val == nullptr) {
1011
+ // Throw an error that looks like it came from core.
1012
+ NAPI_THROW_IF_FAILED(env, napi_invalid_arg, String());
1013
+ }
694
1014
  napi_status status = napi_create_string_utf16(env, val, std::u16string(val).size(), &value);
695
1015
  NAPI_THROW_IF_FAILED(env, status, String());
696
1016
  return String(env, value);
@@ -777,8 +1097,56 @@ inline Symbol Symbol::New(napi_env env, napi_value description) {
777
1097
  return Symbol(env, value);
778
1098
  }
779
1099
 
780
- inline Symbol Symbol::WellKnown(napi_env env, const std::string& name) {
1100
+ inline MaybeOrValue<Symbol> Symbol::WellKnown(napi_env env,
1101
+ const std::string& name) {
1102
+ #if defined(NODE_ADDON_API_ENABLE_MAYBE)
1103
+ Value symbol_obj;
1104
+ Value symbol_value;
1105
+ if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
1106
+ symbol_obj.As<Object>().Get(name).UnwrapTo(&symbol_value)) {
1107
+ return Just<Symbol>(symbol_value.As<Symbol>());
1108
+ }
1109
+ return Nothing<Symbol>();
1110
+ #else
781
1111
  return Napi::Env(env).Global().Get("Symbol").As<Object>().Get(name).As<Symbol>();
1112
+ #endif
1113
+ }
1114
+
1115
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env,
1116
+ const std::string& description) {
1117
+ napi_value descriptionValue = String::New(env, description);
1118
+ return Symbol::For(env, descriptionValue);
1119
+ }
1120
+
1121
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, const char* description) {
1122
+ napi_value descriptionValue = String::New(env, description);
1123
+ return Symbol::For(env, descriptionValue);
1124
+ }
1125
+
1126
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, String description) {
1127
+ return Symbol::For(env, static_cast<napi_value>(description));
1128
+ }
1129
+
1130
+ inline MaybeOrValue<Symbol> Symbol::For(napi_env env, napi_value description) {
1131
+ #if defined(NODE_ADDON_API_ENABLE_MAYBE)
1132
+ Value symbol_obj;
1133
+ Value symbol_for_value;
1134
+ Value symbol_value;
1135
+ if (Napi::Env(env).Global().Get("Symbol").UnwrapTo(&symbol_obj) &&
1136
+ symbol_obj.As<Object>().Get("for").UnwrapTo(&symbol_for_value) &&
1137
+ symbol_for_value.As<Function>()
1138
+ .Call(symbol_obj, {description})
1139
+ .UnwrapTo(&symbol_value)) {
1140
+ return Just<Symbol>(symbol_value.As<Symbol>());
1141
+ }
1142
+ return Nothing<Symbol>();
1143
+ #else
1144
+ Object symbol_obj = Napi::Env(env).Global().Get("Symbol").As<Object>();
1145
+ return symbol_obj.Get("for")
1146
+ .As<Function>()
1147
+ .Call(symbol_obj, {description})
1148
+ .As<Symbol>();
1149
+ #endif
782
1150
  }
783
1151
 
784
1152
  inline Symbol::Symbol() : Name() {
@@ -893,12 +1261,23 @@ String String::From(napi_env env, const T& value) {
893
1261
 
894
1262
  template <typename Key>
895
1263
  inline Object::PropertyLValue<Key>::operator Value() const {
896
- return Object(_env, _object).Get(_key);
1264
+ MaybeOrValue<Value> val = Object(_env, _object).Get(_key);
1265
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
1266
+ return val.Unwrap();
1267
+ #else
1268
+ return val;
1269
+ #endif
897
1270
  }
898
1271
 
899
1272
  template <typename Key> template <typename ValueType>
900
1273
  inline Object::PropertyLValue<Key>& Object::PropertyLValue<Key>::operator =(ValueType value) {
901
- Object(_env, _object).Set(_key, value);
1274
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
1275
+ MaybeOrValue<bool> result =
1276
+ #endif
1277
+ Object(_env, _object).Set(_key, value);
1278
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
1279
+ result.Unwrap();
1280
+ #endif
902
1281
  return *this;
903
1282
  }
904
1283
 
@@ -919,213 +1298,339 @@ inline Object::Object() : Value() {
919
1298
  inline Object::Object(napi_env env, napi_value value) : Value(env, value) {
920
1299
  }
921
1300
 
922
- inline Object::PropertyLValue<std::string> Object::operator [](const char* utf8name) {
1301
+ inline Object::PropertyLValue<std::string> Object::operator[](
1302
+ const char* utf8name) {
923
1303
  return PropertyLValue<std::string>(*this, utf8name);
924
1304
  }
925
1305
 
926
- inline Object::PropertyLValue<std::string> Object::operator [](const std::string& utf8name) {
1306
+ inline Object::PropertyLValue<std::string> Object::operator[](
1307
+ const std::string& utf8name) {
927
1308
  return PropertyLValue<std::string>(*this, utf8name);
928
1309
  }
929
1310
 
930
- inline Object::PropertyLValue<uint32_t> Object::operator [](uint32_t index) {
1311
+ inline Object::PropertyLValue<uint32_t> Object::operator[](uint32_t index) {
931
1312
  return PropertyLValue<uint32_t>(*this, index);
932
1313
  }
933
1314
 
934
- inline Value Object::operator [](const char* utf8name) const {
1315
+ inline Object::PropertyLValue<Value> Object::operator[](Value index) const {
1316
+ return PropertyLValue<Value>(*this, index);
1317
+ }
1318
+
1319
+ inline MaybeOrValue<Value> Object::operator[](const char* utf8name) const {
935
1320
  return Get(utf8name);
936
1321
  }
937
1322
 
938
- inline Value Object::operator [](const std::string& utf8name) const {
1323
+ inline MaybeOrValue<Value> Object::operator[](
1324
+ const std::string& utf8name) const {
939
1325
  return Get(utf8name);
940
1326
  }
941
1327
 
942
- inline Value Object::operator [](uint32_t index) const {
1328
+ inline MaybeOrValue<Value> Object::operator[](uint32_t index) const {
943
1329
  return Get(index);
944
1330
  }
945
1331
 
946
- inline bool Object::Has(napi_value key) const {
1332
+ inline MaybeOrValue<bool> Object::Has(napi_value key) const {
947
1333
  bool result;
948
1334
  napi_status status = napi_has_property(_env, _value, key, &result);
949
- NAPI_THROW_IF_FAILED(_env, status, false);
950
- return result;
1335
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
951
1336
  }
952
1337
 
953
- inline bool Object::Has(Value key) const {
1338
+ inline MaybeOrValue<bool> Object::Has(Value key) const {
954
1339
  bool result;
955
1340
  napi_status status = napi_has_property(_env, _value, key, &result);
956
- NAPI_THROW_IF_FAILED(_env, status, false);
957
- return result;
1341
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
958
1342
  }
959
1343
 
960
- inline bool Object::Has(const char* utf8name) const {
1344
+ inline MaybeOrValue<bool> Object::Has(const char* utf8name) const {
961
1345
  bool result;
962
1346
  napi_status status = napi_has_named_property(_env, _value, utf8name, &result);
963
- NAPI_THROW_IF_FAILED(_env, status, false);
964
- return result;
1347
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
965
1348
  }
966
1349
 
967
- inline bool Object::Has(const std::string& utf8name) const {
1350
+ inline MaybeOrValue<bool> Object::Has(const std::string& utf8name) const {
968
1351
  return Has(utf8name.c_str());
969
1352
  }
970
1353
 
971
- inline bool Object::HasOwnProperty(napi_value key) const {
1354
+ inline MaybeOrValue<bool> Object::HasOwnProperty(napi_value key) const {
972
1355
  bool result;
973
1356
  napi_status status = napi_has_own_property(_env, _value, key, &result);
974
- NAPI_THROW_IF_FAILED(_env, status, false);
975
- return result;
1357
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
976
1358
  }
977
1359
 
978
- inline bool Object::HasOwnProperty(Value key) const {
1360
+ inline MaybeOrValue<bool> Object::HasOwnProperty(Value key) const {
979
1361
  bool result;
980
1362
  napi_status status = napi_has_own_property(_env, _value, key, &result);
981
- NAPI_THROW_IF_FAILED(_env, status, false);
982
- return result;
1363
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
983
1364
  }
984
1365
 
985
- inline bool Object::HasOwnProperty(const char* utf8name) const {
1366
+ inline MaybeOrValue<bool> Object::HasOwnProperty(const char* utf8name) const {
986
1367
  napi_value key;
987
1368
  napi_status status = napi_create_string_utf8(_env, utf8name, std::strlen(utf8name), &key);
988
- NAPI_THROW_IF_FAILED(_env, status, false);
1369
+ NAPI_MAYBE_THROW_IF_FAILED(_env, status, bool);
989
1370
  return HasOwnProperty(key);
990
1371
  }
991
1372
 
992
- inline bool Object::HasOwnProperty(const std::string& utf8name) const {
1373
+ inline MaybeOrValue<bool> Object::HasOwnProperty(
1374
+ const std::string& utf8name) const {
993
1375
  return HasOwnProperty(utf8name.c_str());
994
1376
  }
995
1377
 
996
- inline Value Object::Get(napi_value key) const {
1378
+ inline MaybeOrValue<Value> Object::Get(napi_value key) const {
997
1379
  napi_value result;
998
1380
  napi_status status = napi_get_property(_env, _value, key, &result);
999
- NAPI_THROW_IF_FAILED(_env, status, Value());
1000
- return Value(_env, result);
1381
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1001
1382
  }
1002
1383
 
1003
- inline Value Object::Get(Value key) const {
1384
+ inline MaybeOrValue<Value> Object::Get(Value key) const {
1004
1385
  napi_value result;
1005
1386
  napi_status status = napi_get_property(_env, _value, key, &result);
1006
- NAPI_THROW_IF_FAILED(_env, status, Value());
1007
- return Value(_env, result);
1387
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1008
1388
  }
1009
1389
 
1010
- inline Value Object::Get(const char* utf8name) const {
1390
+ inline MaybeOrValue<Value> Object::Get(const char* utf8name) const {
1011
1391
  napi_value result;
1012
1392
  napi_status status = napi_get_named_property(_env, _value, utf8name, &result);
1013
- NAPI_THROW_IF_FAILED(_env, status, Value());
1014
- return Value(_env, result);
1393
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, result), Value);
1015
1394
  }
1016
1395
 
1017
- inline Value Object::Get(const std::string& utf8name) const {
1396
+ inline MaybeOrValue<Value> Object::Get(const std::string& utf8name) const {
1018
1397
  return Get(utf8name.c_str());
1019
1398
  }
1020
1399
 
1021
1400
  template <typename ValueType>
1022
- inline void Object::Set(napi_value key, const ValueType& value) {
1401
+ inline MaybeOrValue<bool> Object::Set(napi_value key,
1402
+ const ValueType& value) const {
1023
1403
  napi_status status =
1024
1404
  napi_set_property(_env, _value, key, Value::From(_env, value));
1025
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1405
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1026
1406
  }
1027
1407
 
1028
1408
  template <typename ValueType>
1029
- inline void Object::Set(Value key, const ValueType& value) {
1409
+ inline MaybeOrValue<bool> Object::Set(Value key, const ValueType& value) const {
1030
1410
  napi_status status =
1031
1411
  napi_set_property(_env, _value, key, Value::From(_env, value));
1032
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1412
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1033
1413
  }
1034
1414
 
1035
1415
  template <typename ValueType>
1036
- inline void Object::Set(const char* utf8name, const ValueType& value) {
1416
+ inline MaybeOrValue<bool> Object::Set(const char* utf8name,
1417
+ const ValueType& value) const {
1037
1418
  napi_status status =
1038
1419
  napi_set_named_property(_env, _value, utf8name, Value::From(_env, value));
1039
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1420
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1040
1421
  }
1041
1422
 
1042
1423
  template <typename ValueType>
1043
- inline void Object::Set(const std::string& utf8name, const ValueType& value) {
1044
- Set(utf8name.c_str(), value);
1424
+ inline MaybeOrValue<bool> Object::Set(const std::string& utf8name,
1425
+ const ValueType& value) const {
1426
+ return Set(utf8name.c_str(), value);
1045
1427
  }
1046
1428
 
1047
- inline bool Object::Delete(napi_value key) {
1429
+ inline MaybeOrValue<bool> Object::Delete(napi_value key) const {
1048
1430
  bool result;
1049
1431
  napi_status status = napi_delete_property(_env, _value, key, &result);
1050
- NAPI_THROW_IF_FAILED(_env, status, false);
1051
- return result;
1432
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1052
1433
  }
1053
1434
 
1054
- inline bool Object::Delete(Value key) {
1435
+ inline MaybeOrValue<bool> Object::Delete(Value key) const {
1055
1436
  bool result;
1056
1437
  napi_status status = napi_delete_property(_env, _value, key, &result);
1057
- NAPI_THROW_IF_FAILED(_env, status, false);
1058
- return result;
1438
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1059
1439
  }
1060
1440
 
1061
- inline bool Object::Delete(const char* utf8name) {
1441
+ inline MaybeOrValue<bool> Object::Delete(const char* utf8name) const {
1062
1442
  return Delete(String::New(_env, utf8name));
1063
1443
  }
1064
1444
 
1065
- inline bool Object::Delete(const std::string& utf8name) {
1445
+ inline MaybeOrValue<bool> Object::Delete(const std::string& utf8name) const {
1066
1446
  return Delete(String::New(_env, utf8name));
1067
1447
  }
1068
1448
 
1069
- inline bool Object::Has(uint32_t index) const {
1449
+ inline MaybeOrValue<bool> Object::Has(uint32_t index) const {
1070
1450
  bool result;
1071
1451
  napi_status status = napi_has_element(_env, _value, index, &result);
1072
- NAPI_THROW_IF_FAILED(_env, status, false);
1073
- return result;
1452
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1074
1453
  }
1075
1454
 
1076
- inline Value Object::Get(uint32_t index) const {
1455
+ inline MaybeOrValue<Value> Object::Get(uint32_t index) const {
1077
1456
  napi_value value;
1078
1457
  napi_status status = napi_get_element(_env, _value, index, &value);
1079
- NAPI_THROW_IF_FAILED(_env, status, Value());
1080
- return Value(_env, value);
1458
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Value(_env, value), Value);
1081
1459
  }
1082
1460
 
1083
1461
  template <typename ValueType>
1084
- inline void Object::Set(uint32_t index, const ValueType& value) {
1462
+ inline MaybeOrValue<bool> Object::Set(uint32_t index,
1463
+ const ValueType& value) const {
1085
1464
  napi_status status =
1086
1465
  napi_set_element(_env, _value, index, Value::From(_env, value));
1087
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1466
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1088
1467
  }
1089
1468
 
1090
- inline bool Object::Delete(uint32_t index) {
1469
+ inline MaybeOrValue<bool> Object::Delete(uint32_t index) const {
1091
1470
  bool result;
1092
1471
  napi_status status = napi_delete_element(_env, _value, index, &result);
1093
- NAPI_THROW_IF_FAILED(_env, status, false);
1094
- return result;
1472
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1095
1473
  }
1096
1474
 
1097
- inline Array Object::GetPropertyNames() const {
1475
+ inline MaybeOrValue<Array> Object::GetPropertyNames() const {
1098
1476
  napi_value result;
1099
1477
  napi_status status = napi_get_property_names(_env, _value, &result);
1100
- NAPI_THROW_IF_FAILED(_env, status, Array());
1101
- return Array(_env, result);
1478
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, Array(_env, result), Array);
1102
1479
  }
1103
1480
 
1104
- inline void Object::DefineProperty(const PropertyDescriptor& property) {
1481
+ inline MaybeOrValue<bool> Object::DefineProperty(
1482
+ const PropertyDescriptor& property) const {
1105
1483
  napi_status status = napi_define_properties(_env, _value, 1,
1106
1484
  reinterpret_cast<const napi_property_descriptor*>(&property));
1107
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1485
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1108
1486
  }
1109
1487
 
1110
- inline void Object::DefineProperties(const std::initializer_list<PropertyDescriptor>& properties) {
1488
+ inline MaybeOrValue<bool> Object::DefineProperties(
1489
+ const std::initializer_list<PropertyDescriptor>& properties) const {
1111
1490
  napi_status status = napi_define_properties(_env, _value, properties.size(),
1112
1491
  reinterpret_cast<const napi_property_descriptor*>(properties.begin()));
1113
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1492
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1114
1493
  }
1115
1494
 
1116
- inline void Object::DefineProperties(const std::vector<PropertyDescriptor>& properties) {
1495
+ inline MaybeOrValue<bool> Object::DefineProperties(
1496
+ const std::vector<PropertyDescriptor>& properties) const {
1117
1497
  napi_status status = napi_define_properties(_env, _value, properties.size(),
1118
1498
  reinterpret_cast<const napi_property_descriptor*>(properties.data()));
1119
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1499
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1120
1500
  }
1121
1501
 
1122
- inline bool Object::InstanceOf(const Function& constructor) const {
1502
+ inline MaybeOrValue<bool> Object::InstanceOf(
1503
+ const Function& constructor) const {
1123
1504
  bool result;
1124
1505
  napi_status status = napi_instanceof(_env, _value, constructor, &result);
1125
- NAPI_THROW_IF_FAILED(_env, status, false);
1126
- return result;
1506
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, result, bool);
1507
+ }
1508
+
1509
+ template <typename Finalizer, typename T>
1510
+ inline void Object::AddFinalizer(Finalizer finalizeCallback, T* data) const {
1511
+ details::FinalizeData<T, Finalizer>* finalizeData =
1512
+ new details::FinalizeData<T, Finalizer>(
1513
+ {std::move(finalizeCallback), nullptr});
1514
+ napi_status status =
1515
+ details::AttachData(_env,
1516
+ *this,
1517
+ data,
1518
+ details::FinalizeData<T, Finalizer>::Wrapper,
1519
+ finalizeData);
1520
+ if (status != napi_ok) {
1521
+ delete finalizeData;
1522
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1523
+ }
1524
+ }
1525
+
1526
+ template <typename Finalizer, typename T, typename Hint>
1527
+ inline void Object::AddFinalizer(Finalizer finalizeCallback,
1528
+ T* data,
1529
+ Hint* finalizeHint) const {
1530
+ details::FinalizeData<T, Finalizer, Hint>* finalizeData =
1531
+ new details::FinalizeData<T, Finalizer, Hint>(
1532
+ {std::move(finalizeCallback), finalizeHint});
1533
+ napi_status status =
1534
+ details::AttachData(_env,
1535
+ *this,
1536
+ data,
1537
+ details::FinalizeData<T, Finalizer, Hint>::WrapperWithHint,
1538
+ finalizeData);
1539
+ if (status != napi_ok) {
1540
+ delete finalizeData;
1541
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1542
+ }
1543
+ }
1544
+
1545
+ #ifdef NAPI_CPP_EXCEPTIONS
1546
+ inline Object::const_iterator::const_iterator(const Object* object,
1547
+ const Type type) {
1548
+ _object = object;
1549
+ _keys = object->GetPropertyNames();
1550
+ _index = type == Type::BEGIN ? 0 : _keys.Length();
1551
+ }
1552
+
1553
+ inline Object::const_iterator Napi::Object::begin() const {
1554
+ const_iterator it(this, Object::const_iterator::Type::BEGIN);
1555
+ return it;
1556
+ }
1557
+
1558
+ inline Object::const_iterator Napi::Object::end() const {
1559
+ const_iterator it(this, Object::const_iterator::Type::END);
1560
+ return it;
1561
+ }
1562
+
1563
+ inline Object::const_iterator& Object::const_iterator::operator++() {
1564
+ ++_index;
1565
+ return *this;
1566
+ }
1567
+
1568
+ inline bool Object::const_iterator::operator==(
1569
+ const const_iterator& other) const {
1570
+ return _index == other._index;
1571
+ }
1572
+
1573
+ inline bool Object::const_iterator::operator!=(
1574
+ const const_iterator& other) const {
1575
+ return _index != other._index;
1576
+ }
1577
+
1578
+ inline const std::pair<Value, Object::PropertyLValue<Value>>
1579
+ Object::const_iterator::operator*() const {
1580
+ const Value key = _keys[_index];
1581
+ const PropertyLValue<Value> value = (*_object)[key];
1582
+ return {key, value};
1583
+ }
1584
+
1585
+ inline Object::iterator::iterator(Object* object, const Type type) {
1586
+ _object = object;
1587
+ _keys = object->GetPropertyNames();
1588
+ _index = type == Type::BEGIN ? 0 : _keys.Length();
1589
+ }
1590
+
1591
+ inline Object::iterator Napi::Object::begin() {
1592
+ iterator it(this, Object::iterator::Type::BEGIN);
1593
+ return it;
1127
1594
  }
1128
1595
 
1596
+ inline Object::iterator Napi::Object::end() {
1597
+ iterator it(this, Object::iterator::Type::END);
1598
+ return it;
1599
+ }
1600
+
1601
+ inline Object::iterator& Object::iterator::operator++() {
1602
+ ++_index;
1603
+ return *this;
1604
+ }
1605
+
1606
+ inline bool Object::iterator::operator==(const iterator& other) const {
1607
+ return _index == other._index;
1608
+ }
1609
+
1610
+ inline bool Object::iterator::operator!=(const iterator& other) const {
1611
+ return _index != other._index;
1612
+ }
1613
+
1614
+ inline std::pair<Value, Object::PropertyLValue<Value>>
1615
+ Object::iterator::operator*() {
1616
+ Value key = _keys[_index];
1617
+ PropertyLValue<Value> value = (*_object)[key];
1618
+ return {key, value};
1619
+ }
1620
+ #endif // NAPI_CPP_EXCEPTIONS
1621
+
1622
+ #if NAPI_VERSION >= 8
1623
+ inline MaybeOrValue<bool> Object::Freeze() const {
1624
+ napi_status status = napi_object_freeze(_env, _value);
1625
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1626
+ }
1627
+
1628
+ inline MaybeOrValue<bool> Object::Seal() const {
1629
+ napi_status status = napi_object_seal(_env, _value);
1630
+ NAPI_RETURN_OR_THROW_IF_FAILED(_env, status, status == napi_ok, bool);
1631
+ }
1632
+ #endif // NAPI_VERSION >= 8
1633
+
1129
1634
  ////////////////////////////////////////////////////////////////////////////////
1130
1635
  // External class
1131
1636
  ////////////////////////////////////////////////////////////////////////////////
@@ -1145,7 +1650,8 @@ inline External<T> External<T>::New(napi_env env,
1145
1650
  Finalizer finalizeCallback) {
1146
1651
  napi_value value;
1147
1652
  details::FinalizeData<T, Finalizer>* finalizeData =
1148
- new details::FinalizeData<T, Finalizer>({ finalizeCallback, nullptr });
1653
+ new details::FinalizeData<T, Finalizer>(
1654
+ {std::move(finalizeCallback), nullptr});
1149
1655
  napi_status status = napi_create_external(
1150
1656
  env,
1151
1657
  data,
@@ -1167,7 +1673,8 @@ inline External<T> External<T>::New(napi_env env,
1167
1673
  Hint* finalizeHint) {
1168
1674
  napi_value value;
1169
1675
  details::FinalizeData<T, Finalizer, Hint>* finalizeData =
1170
- new details::FinalizeData<T, Finalizer, Hint>({ finalizeCallback, finalizeHint });
1676
+ new details::FinalizeData<T, Finalizer, Hint>(
1677
+ {std::move(finalizeCallback), finalizeHint});
1171
1678
  napi_status status = napi_create_external(
1172
1679
  env,
1173
1680
  data,
@@ -1238,7 +1745,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, size_t byteLength) {
1238
1745
  napi_status status = napi_create_arraybuffer(env, byteLength, &data, &value);
1239
1746
  NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1240
1747
 
1241
- return ArrayBuffer(env, value, data, byteLength);
1748
+ return ArrayBuffer(env, value);
1242
1749
  }
1243
1750
 
1244
1751
  inline ArrayBuffer ArrayBuffer::New(napi_env env,
@@ -1249,7 +1756,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1249
1756
  env, externalData, byteLength, nullptr, nullptr, &value);
1250
1757
  NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1251
1758
 
1252
- return ArrayBuffer(env, value, externalData, byteLength);
1759
+ return ArrayBuffer(env, value);
1253
1760
  }
1254
1761
 
1255
1762
  template <typename Finalizer>
@@ -1259,7 +1766,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1259
1766
  Finalizer finalizeCallback) {
1260
1767
  napi_value value;
1261
1768
  details::FinalizeData<void, Finalizer>* finalizeData =
1262
- new details::FinalizeData<void, Finalizer>({ finalizeCallback, nullptr });
1769
+ new details::FinalizeData<void, Finalizer>(
1770
+ {std::move(finalizeCallback), nullptr});
1263
1771
  napi_status status = napi_create_external_arraybuffer(
1264
1772
  env,
1265
1773
  externalData,
@@ -1272,7 +1780,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1272
1780
  NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1273
1781
  }
1274
1782
 
1275
- return ArrayBuffer(env, value, externalData, byteLength);
1783
+ return ArrayBuffer(env, value);
1276
1784
  }
1277
1785
 
1278
1786
  template <typename Finalizer, typename Hint>
@@ -1283,7 +1791,8 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1283
1791
  Hint* finalizeHint) {
1284
1792
  napi_value value;
1285
1793
  details::FinalizeData<void, Finalizer, Hint>* finalizeData =
1286
- new details::FinalizeData<void, Finalizer, Hint>({ finalizeCallback, finalizeHint });
1794
+ new details::FinalizeData<void, Finalizer, Hint>(
1795
+ {std::move(finalizeCallback), finalizeHint});
1287
1796
  napi_status status = napi_create_external_arraybuffer(
1288
1797
  env,
1289
1798
  externalData,
@@ -1296,39 +1805,43 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
1296
1805
  NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
1297
1806
  }
1298
1807
 
1299
- return ArrayBuffer(env, value, externalData, byteLength);
1808
+ return ArrayBuffer(env, value);
1300
1809
  }
1301
1810
 
1302
- inline ArrayBuffer::ArrayBuffer() : Object(), _data(nullptr), _length(0) {
1811
+ inline ArrayBuffer::ArrayBuffer() : Object() {
1303
1812
  }
1304
1813
 
1305
1814
  inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value)
1306
- : Object(env, value), _data(nullptr), _length(0) {
1307
- }
1308
-
1309
- inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value, void* data, size_t length)
1310
- : Object(env, value), _data(data), _length(length) {
1815
+ : Object(env, value) {
1311
1816
  }
1312
1817
 
1313
1818
  inline void* ArrayBuffer::Data() {
1314
- EnsureInfo();
1315
- return _data;
1819
+ void* data;
1820
+ napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr);
1821
+ NAPI_THROW_IF_FAILED(_env, status, nullptr);
1822
+ return data;
1316
1823
  }
1317
1824
 
1318
1825
  inline size_t ArrayBuffer::ByteLength() {
1319
- EnsureInfo();
1320
- return _length;
1826
+ size_t length;
1827
+ napi_status status = napi_get_arraybuffer_info(_env, _value, nullptr, &length);
1828
+ NAPI_THROW_IF_FAILED(_env, status, 0);
1829
+ return length;
1321
1830
  }
1322
1831
 
1323
- inline void ArrayBuffer::EnsureInfo() const {
1324
- // The ArrayBuffer instance may have been constructed from a napi_value whose
1325
- // length/data are not yet known. Fetch and cache these values just once,
1326
- // since they can never change during the lifetime of the ArrayBuffer.
1327
- if (_data == nullptr) {
1328
- napi_status status = napi_get_arraybuffer_info(_env, _value, &_data, &_length);
1329
- NAPI_THROW_IF_FAILED_VOID(_env, status);
1330
- }
1832
+ #if NAPI_VERSION >= 7
1833
+ inline bool ArrayBuffer::IsDetached() const {
1834
+ bool detached;
1835
+ napi_status status = napi_is_detached_arraybuffer(_env, _value, &detached);
1836
+ NAPI_THROW_IF_FAILED(_env, status, false);
1837
+ return detached;
1838
+ }
1839
+
1840
+ inline void ArrayBuffer::Detach() {
1841
+ napi_status status = napi_detach_arraybuffer(_env, _value);
1842
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
1331
1843
  }
1844
+ #endif // NAPI_VERSION >= 7
1332
1845
 
1333
1846
  ////////////////////////////////////////////////////////////////////////////////
1334
1847
  // DataView class
@@ -1543,6 +2056,10 @@ inline uint8_t TypedArray::ElementSize() const {
1543
2056
  case napi_float32_array:
1544
2057
  return 4;
1545
2058
  case napi_float64_array:
2059
+ #if (NAPI_VERSION > 5)
2060
+ case napi_bigint64_array:
2061
+ case napi_biguint64_array:
2062
+ #endif // (NAPI_VERSION > 5)
1546
2063
  return 8;
1547
2064
  default:
1548
2065
  return 0;
@@ -1615,8 +2132,16 @@ inline TypedArrayOf<T>::TypedArrayOf() : TypedArray(), _data(nullptr) {
1615
2132
  template <typename T>
1616
2133
  inline TypedArrayOf<T>::TypedArrayOf(napi_env env, napi_value value)
1617
2134
  : TypedArray(env, value), _data(nullptr) {
1618
- napi_status status = napi_get_typedarray_info(
1619
- _env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
2135
+ napi_status status = napi_ok;
2136
+ if (value != nullptr) {
2137
+ void* data = nullptr;
2138
+ status = napi_get_typedarray_info(
2139
+ _env, _value, &_type, &_length, &data, nullptr, nullptr);
2140
+ _data = static_cast<T*>(data);
2141
+ } else {
2142
+ _type = TypedArrayTypeForPrimitiveType<T>();
2143
+ _length = 0;
2144
+ }
1620
2145
  NAPI_THROW_IF_FAILED_VOID(_env, status);
1621
2146
  }
1622
2147
 
@@ -1674,14 +2199,54 @@ CreateFunction(napi_env env,
1674
2199
  return status;
1675
2200
  }
1676
2201
 
2202
+ template <Function::VoidCallback cb>
2203
+ inline Function Function::New(napi_env env, const char* utf8name, void* data) {
2204
+ napi_value result = nullptr;
2205
+ napi_status status = napi_create_function(env,
2206
+ utf8name,
2207
+ NAPI_AUTO_LENGTH,
2208
+ details::TemplatedVoidCallback<cb>,
2209
+ data,
2210
+ &result);
2211
+ NAPI_THROW_IF_FAILED(env, status, Function());
2212
+ return Function(env, result);
2213
+ }
2214
+
2215
+ template <Function::Callback cb>
2216
+ inline Function Function::New(napi_env env, const char* utf8name, void* data) {
2217
+ napi_value result = nullptr;
2218
+ napi_status status = napi_create_function(env,
2219
+ utf8name,
2220
+ NAPI_AUTO_LENGTH,
2221
+ details::TemplatedCallback<cb>,
2222
+ data,
2223
+ &result);
2224
+ NAPI_THROW_IF_FAILED(env, status, Function());
2225
+ return Function(env, result);
2226
+ }
2227
+
2228
+ template <Function::VoidCallback cb>
2229
+ inline Function Function::New(napi_env env,
2230
+ const std::string& utf8name,
2231
+ void* data) {
2232
+ return Function::New<cb>(env, utf8name.c_str(), data);
2233
+ }
2234
+
2235
+ template <Function::Callback cb>
2236
+ inline Function Function::New(napi_env env,
2237
+ const std::string& utf8name,
2238
+ void* data) {
2239
+ return Function::New<cb>(env, utf8name.c_str(), data);
2240
+ }
2241
+
1677
2242
  template <typename Callable>
1678
2243
  inline Function Function::New(napi_env env,
1679
2244
  Callable cb,
1680
2245
  const char* utf8name,
1681
2246
  void* data) {
1682
- typedef decltype(cb(CallbackInfo(nullptr, nullptr))) ReturnType;
1683
- typedef details::CallbackData<Callable, ReturnType> CbData;
1684
- auto callbackData = new CbData({ cb, data });
2247
+ using ReturnType = decltype(cb(CallbackInfo(nullptr, nullptr)));
2248
+ using CbData = details::CallbackData<Callable, ReturnType>;
2249
+ auto callbackData = new CbData{std::move(cb), data};
1685
2250
 
1686
2251
  napi_value value;
1687
2252
  napi_status status = CreateFunction(env,
@@ -1711,53 +2276,87 @@ inline Function::Function() : Object() {
1711
2276
  inline Function::Function(napi_env env, napi_value value) : Object(env, value) {
1712
2277
  }
1713
2278
 
1714
- inline Value Function::operator ()(const std::initializer_list<napi_value>& args) const {
2279
+ inline MaybeOrValue<Value> Function::operator()(
2280
+ const std::initializer_list<napi_value>& args) const {
2281
+ return Call(Env().Undefined(), args);
2282
+ }
2283
+
2284
+ inline MaybeOrValue<Value> Function::Call(
2285
+ const std::initializer_list<napi_value>& args) const {
1715
2286
  return Call(Env().Undefined(), args);
1716
2287
  }
1717
2288
 
1718
- inline Value Function::Call(const std::initializer_list<napi_value>& args) const {
2289
+ inline MaybeOrValue<Value> Function::Call(
2290
+ const std::vector<napi_value>& args) const {
1719
2291
  return Call(Env().Undefined(), args);
1720
2292
  }
1721
2293
 
1722
- inline Value Function::Call(const std::vector<napi_value>& args) const {
2294
+ inline MaybeOrValue<Value> Function::Call(
2295
+ const std::vector<Value>& args) const {
1723
2296
  return Call(Env().Undefined(), args);
1724
2297
  }
1725
2298
 
1726
- inline Value Function::Call(size_t argc, const napi_value* args) const {
2299
+ inline MaybeOrValue<Value> Function::Call(size_t argc,
2300
+ const napi_value* args) const {
1727
2301
  return Call(Env().Undefined(), argc, args);
1728
2302
  }
1729
2303
 
1730
- inline Value Function::Call(napi_value recv, const std::initializer_list<napi_value>& args) const {
2304
+ inline MaybeOrValue<Value> Function::Call(
2305
+ napi_value recv, const std::initializer_list<napi_value>& args) const {
1731
2306
  return Call(recv, args.size(), args.begin());
1732
2307
  }
1733
2308
 
1734
- inline Value Function::Call(napi_value recv, const std::vector<napi_value>& args) const {
2309
+ inline MaybeOrValue<Value> Function::Call(
2310
+ napi_value recv, const std::vector<napi_value>& args) const {
1735
2311
  return Call(recv, args.size(), args.data());
1736
2312
  }
1737
2313
 
1738
- inline Value Function::Call(napi_value recv, size_t argc, const napi_value* args) const {
2314
+ inline MaybeOrValue<Value> Function::Call(
2315
+ napi_value recv, const std::vector<Value>& args) const {
2316
+ const size_t argc = args.size();
2317
+ const size_t stackArgsCount = 6;
2318
+ napi_value stackArgs[stackArgsCount];
2319
+ std::vector<napi_value> heapArgs;
2320
+ napi_value* argv;
2321
+ if (argc <= stackArgsCount) {
2322
+ argv = stackArgs;
2323
+ } else {
2324
+ heapArgs.resize(argc);
2325
+ argv = heapArgs.data();
2326
+ }
2327
+
2328
+ for (size_t index = 0; index < argc; index++) {
2329
+ argv[index] = static_cast<napi_value>(args[index]);
2330
+ }
2331
+
2332
+ return Call(recv, argc, argv);
2333
+ }
2334
+
2335
+ inline MaybeOrValue<Value> Function::Call(napi_value recv,
2336
+ size_t argc,
2337
+ const napi_value* args) const {
1739
2338
  napi_value result;
1740
2339
  napi_status status = napi_call_function(
1741
2340
  _env, recv, _value, argc, args, &result);
1742
- NAPI_THROW_IF_FAILED(_env, status, Value());
1743
- return Value(_env, result);
2341
+ NAPI_RETURN_OR_THROW_IF_FAILED(
2342
+ _env, status, Napi::Value(_env, result), Napi::Value);
1744
2343
  }
1745
2344
 
1746
- inline Value Function::MakeCallback(
2345
+ inline MaybeOrValue<Value> Function::MakeCallback(
1747
2346
  napi_value recv,
1748
2347
  const std::initializer_list<napi_value>& args,
1749
2348
  napi_async_context context) const {
1750
2349
  return MakeCallback(recv, args.size(), args.begin(), context);
1751
2350
  }
1752
2351
 
1753
- inline Value Function::MakeCallback(
2352
+ inline MaybeOrValue<Value> Function::MakeCallback(
1754
2353
  napi_value recv,
1755
2354
  const std::vector<napi_value>& args,
1756
2355
  napi_async_context context) const {
1757
2356
  return MakeCallback(recv, args.size(), args.data(), context);
1758
2357
  }
1759
2358
 
1760
- inline Value Function::MakeCallback(
2359
+ inline MaybeOrValue<Value> Function::MakeCallback(
1761
2360
  napi_value recv,
1762
2361
  size_t argc,
1763
2362
  const napi_value* args,
@@ -1765,24 +2364,27 @@ inline Value Function::MakeCallback(
1765
2364
  napi_value result;
1766
2365
  napi_status status = napi_make_callback(
1767
2366
  _env, context, recv, _value, argc, args, &result);
1768
- NAPI_THROW_IF_FAILED(_env, status, Value());
1769
- return Value(_env, result);
2367
+ NAPI_RETURN_OR_THROW_IF_FAILED(
2368
+ _env, status, Napi::Value(_env, result), Napi::Value);
1770
2369
  }
1771
2370
 
1772
- inline Object Function::New(const std::initializer_list<napi_value>& args) const {
2371
+ inline MaybeOrValue<Object> Function::New(
2372
+ const std::initializer_list<napi_value>& args) const {
1773
2373
  return New(args.size(), args.begin());
1774
2374
  }
1775
2375
 
1776
- inline Object Function::New(const std::vector<napi_value>& args) const {
2376
+ inline MaybeOrValue<Object> Function::New(
2377
+ const std::vector<napi_value>& args) const {
1777
2378
  return New(args.size(), args.data());
1778
2379
  }
1779
2380
 
1780
- inline Object Function::New(size_t argc, const napi_value* args) const {
2381
+ inline MaybeOrValue<Object> Function::New(size_t argc,
2382
+ const napi_value* args) const {
1781
2383
  napi_value result;
1782
2384
  napi_status status = napi_new_instance(
1783
2385
  _env, _value, argc, args, &result);
1784
- NAPI_THROW_IF_FAILED(_env, status, Object());
1785
- return Object(_env, result);
2386
+ NAPI_RETURN_OR_THROW_IF_FAILED(
2387
+ _env, status, Napi::Object(_env, result), Napi::Object);
1786
2388
  }
1787
2389
 
1788
2390
  ////////////////////////////////////////////////////////////////////////////////
@@ -1849,7 +2451,8 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
1849
2451
  Finalizer finalizeCallback) {
1850
2452
  napi_value value;
1851
2453
  details::FinalizeData<T, Finalizer>* finalizeData =
1852
- new details::FinalizeData<T, Finalizer>({ finalizeCallback, nullptr });
2454
+ new details::FinalizeData<T, Finalizer>(
2455
+ {std::move(finalizeCallback), nullptr});
1853
2456
  napi_status status = napi_create_external_buffer(
1854
2457
  env,
1855
2458
  length * sizeof (T),
@@ -1873,7 +2476,8 @@ inline Buffer<T> Buffer<T>::New(napi_env env,
1873
2476
  Hint* finalizeHint) {
1874
2477
  napi_value value;
1875
2478
  details::FinalizeData<T, Finalizer, Hint>* finalizeData =
1876
- new details::FinalizeData<T, Finalizer, Hint>({ finalizeCallback, finalizeHint });
2479
+ new details::FinalizeData<T, Finalizer, Hint>(
2480
+ {std::move(finalizeCallback), finalizeHint});
1877
2481
  napi_status status = napi_create_external_buffer(
1878
2482
  env,
1879
2483
  length * sizeof (T),
@@ -1945,52 +2549,58 @@ inline void Buffer<T>::EnsureInfo() const {
1945
2549
  inline Error Error::New(napi_env env) {
1946
2550
  napi_status status;
1947
2551
  napi_value error = nullptr;
2552
+ bool is_exception_pending;
2553
+ napi_extended_error_info last_error_info_copy;
2554
+
2555
+ {
2556
+ // We must retrieve the last error info before doing anything else because
2557
+ // doing anything else will replace the last error info.
2558
+ const napi_extended_error_info* last_error_info;
2559
+ status = napi_get_last_error_info(env, &last_error_info);
2560
+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
2561
+
2562
+ // All fields of the `napi_extended_error_info` structure gets reset in
2563
+ // subsequent Node-API function calls on the same `env`. This includes a
2564
+ // call to `napi_is_exception_pending()`. So here it is necessary to make a
2565
+ // copy of the information as the `error_code` field is used later on.
2566
+ memcpy(&last_error_info_copy,
2567
+ last_error_info,
2568
+ sizeof(napi_extended_error_info));
2569
+ }
1948
2570
 
1949
- const napi_extended_error_info* info;
1950
- status = napi_get_last_error_info(env, &info);
1951
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
1952
-
1953
- if (status == napi_ok) {
1954
- if (info->error_code == napi_pending_exception) {
1955
- status = napi_get_and_clear_last_exception(env, &error);
1956
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
1957
- }
1958
- else {
1959
- const char* error_message = info->error_message != nullptr ?
1960
- info->error_message : "Error in native callback";
1961
-
1962
- bool isExceptionPending;
1963
- status = napi_is_exception_pending(env, &isExceptionPending);
1964
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
1965
-
1966
- if (isExceptionPending) {
1967
- status = napi_get_and_clear_last_exception(env, &error);
1968
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
1969
- }
2571
+ status = napi_is_exception_pending(env, &is_exception_pending);
2572
+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
1970
2573
 
1971
- napi_value message;
1972
- status = napi_create_string_utf8(
1973
- env,
1974
- error_message,
1975
- std::strlen(error_message),
1976
- &message);
1977
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_string_utf8");
1978
-
1979
- if (status == napi_ok) {
1980
- switch (info->error_code) {
1981
- case napi_object_expected:
1982
- case napi_string_expected:
1983
- case napi_boolean_expected:
1984
- case napi_number_expected:
1985
- status = napi_create_type_error(env, nullptr, message, &error);
1986
- break;
1987
- default:
1988
- status = napi_create_error(env, nullptr, message, &error);
1989
- break;
1990
- }
1991
- NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_error");
1992
- }
2574
+ // A pending exception takes precedence over any internal error status.
2575
+ if (is_exception_pending) {
2576
+ status = napi_get_and_clear_last_exception(env, &error);
2577
+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
2578
+ }
2579
+ else {
2580
+ const char* error_message = last_error_info_copy.error_message != nullptr
2581
+ ? last_error_info_copy.error_message
2582
+ : "Error in native callback";
2583
+
2584
+ napi_value message;
2585
+ status = napi_create_string_utf8(
2586
+ env,
2587
+ error_message,
2588
+ std::strlen(error_message),
2589
+ &message);
2590
+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_string_utf8");
2591
+
2592
+ switch (last_error_info_copy.error_code) {
2593
+ case napi_object_expected:
2594
+ case napi_string_expected:
2595
+ case napi_boolean_expected:
2596
+ case napi_number_expected:
2597
+ status = napi_create_type_error(env, nullptr, message, &error);
2598
+ break;
2599
+ default:
2600
+ status = napi_create_error(env, nullptr, message, &error);
2601
+ break;
1993
2602
  }
2603
+ NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_create_error");
1994
2604
  }
1995
2605
 
1996
2606
  return Error(env, error);
@@ -2013,14 +2623,82 @@ inline Error::Error() : ObjectReference() {
2013
2623
 
2014
2624
  inline Error::Error(napi_env env, napi_value value) : ObjectReference(env, nullptr) {
2015
2625
  if (value != nullptr) {
2626
+ // Attempting to create a reference on the error object.
2627
+ // If it's not a Object/Function/Symbol, this call will return an error
2628
+ // status.
2016
2629
  napi_status status = napi_create_reference(env, value, 1, &_ref);
2017
2630
 
2631
+ if (status != napi_ok) {
2632
+ napi_value wrappedErrorObj;
2633
+
2634
+ // Create an error object
2635
+ status = napi_create_object(env, &wrappedErrorObj);
2636
+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_create_object");
2637
+
2638
+ // property flag that we attach to show the error object is wrapped
2639
+ napi_property_descriptor wrapObjFlag = {
2640
+ ERROR_WRAP_VALUE(), // Unique GUID identifier since Symbol isn't a
2641
+ // viable option
2642
+ nullptr,
2643
+ nullptr,
2644
+ nullptr,
2645
+ nullptr,
2646
+ Value::From(env, value),
2647
+ napi_enumerable,
2648
+ nullptr};
2649
+
2650
+ status = napi_define_properties(env, wrappedErrorObj, 1, &wrapObjFlag);
2651
+ NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_define_properties");
2652
+
2653
+ // Create a reference on the newly wrapped object
2654
+ status = napi_create_reference(env, wrappedErrorObj, 1, &_ref);
2655
+ }
2656
+
2018
2657
  // Avoid infinite recursion in the failure case.
2019
- // Don't try to construct & throw another Error instance.
2020
2658
  NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_create_reference");
2021
2659
  }
2022
2660
  }
2023
2661
 
2662
+ inline Object Error::Value() const {
2663
+ if (_ref == nullptr) {
2664
+ return Object(_env, nullptr);
2665
+ }
2666
+
2667
+ napi_value refValue;
2668
+ napi_status status = napi_get_reference_value(_env, _ref, &refValue);
2669
+ NAPI_THROW_IF_FAILED(_env, status, Object());
2670
+
2671
+ napi_valuetype type;
2672
+ status = napi_typeof(_env, refValue, &type);
2673
+ NAPI_THROW_IF_FAILED(_env, status, Object());
2674
+
2675
+ // If refValue isn't a symbol, then we proceed to whether the refValue has the
2676
+ // wrapped error flag
2677
+ if (type != napi_symbol) {
2678
+ // We are checking if the object is wrapped
2679
+ bool isWrappedObject = false;
2680
+
2681
+ status = napi_has_property(_env,
2682
+ refValue,
2683
+ String::From(_env, ERROR_WRAP_VALUE()),
2684
+ &isWrappedObject);
2685
+
2686
+ // Don't care about status
2687
+ if (isWrappedObject) {
2688
+ napi_value unwrappedValue;
2689
+ status = napi_get_property(_env,
2690
+ refValue,
2691
+ String::From(_env, ERROR_WRAP_VALUE()),
2692
+ &unwrappedValue);
2693
+ NAPI_THROW_IF_FAILED(_env, status, Object());
2694
+
2695
+ return Object(_env, unwrappedValue);
2696
+ }
2697
+ }
2698
+
2699
+ return Object(_env, refValue);
2700
+ }
2701
+
2024
2702
  inline Error::Error(Error&& other) : ObjectReference(std::move(other)) {
2025
2703
  }
2026
2704
 
@@ -2032,7 +2710,7 @@ inline Error& Error::operator =(Error&& other) {
2032
2710
  inline Error::Error(const Error& other) : ObjectReference(other) {
2033
2711
  }
2034
2712
 
2035
- inline Error& Error::operator =(Error& other) {
2713
+ inline Error& Error::operator =(const Error& other) {
2036
2714
  Reset();
2037
2715
 
2038
2716
  _env = other.Env();
@@ -2058,21 +2736,55 @@ inline const std::string& Error::Message() const NAPI_NOEXCEPT {
2058
2736
  // the std::string::operator=, because this method may not throw.
2059
2737
  }
2060
2738
  #else // NAPI_CPP_EXCEPTIONS
2739
+ #if defined(NODE_ADDON_API_ENABLE_MAYBE)
2740
+ Napi::Value message_val;
2741
+ if (Get("message").UnwrapTo(&message_val)) {
2742
+ _message = message_val.As<String>();
2743
+ }
2744
+ #else
2061
2745
  _message = Get("message").As<String>();
2746
+ #endif
2062
2747
  #endif // NAPI_CPP_EXCEPTIONS
2063
2748
  }
2064
2749
  return _message;
2065
2750
  }
2066
2751
 
2752
+ // we created an object on the &_ref
2067
2753
  inline void Error::ThrowAsJavaScriptException() const {
2068
2754
  HandleScope scope(_env);
2069
2755
  if (!IsEmpty()) {
2070
-
2756
+ #ifdef NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS
2757
+ bool pendingException = false;
2758
+
2759
+ // check if there is already a pending exception. If so don't try to throw a
2760
+ // new one as that is not allowed/possible
2761
+ napi_status status = napi_is_exception_pending(_env, &pendingException);
2762
+
2763
+ if ((status != napi_ok) ||
2764
+ ((status == napi_ok) && (pendingException == false))) {
2765
+ // We intentionally don't use `NAPI_THROW_*` macros here to ensure
2766
+ // that there is no possible recursion as `ThrowAsJavaScriptException`
2767
+ // is part of `NAPI_THROW_*` macro definition for noexcept.
2768
+
2769
+ status = napi_throw(_env, Value());
2770
+
2771
+ if (status == napi_pending_exception) {
2772
+ // The environment must be terminating as we checked earlier and there
2773
+ // was no pending exception. In this case continuing will result
2774
+ // in a fatal error and there is nothing the author has done incorrectly
2775
+ // in their code that is worth flagging through a fatal error
2776
+ return;
2777
+ }
2778
+ } else {
2779
+ status = napi_pending_exception;
2780
+ }
2781
+ #else
2071
2782
  // We intentionally don't use `NAPI_THROW_*` macros here to ensure
2072
2783
  // that there is no possible recursion as `ThrowAsJavaScriptException`
2073
2784
  // is part of `NAPI_THROW_*` macro definition for noexcept.
2074
2785
 
2075
2786
  napi_status status = napi_throw(_env, Value());
2787
+ #endif
2076
2788
 
2077
2789
  #ifdef NAPI_CPP_EXCEPTIONS
2078
2790
  if (status != napi_ok) {
@@ -2092,6 +2804,10 @@ inline const char* Error::what() const NAPI_NOEXCEPT {
2092
2804
 
2093
2805
  #endif // NAPI_CPP_EXCEPTIONS
2094
2806
 
2807
+ inline const char* Error::ERROR_WRAP_VALUE() NAPI_NOEXCEPT {
2808
+ return "4bda9e7e-4913-4dbc-95de-891cbf66598e-errorVal";
2809
+ }
2810
+
2095
2811
  template <typename TError>
2096
2812
  inline TError Error::New(napi_env env,
2097
2813
  const char* message,
@@ -2250,18 +2966,18 @@ inline T Reference<T>::Value() const {
2250
2966
  }
2251
2967
 
2252
2968
  template <typename T>
2253
- inline uint32_t Reference<T>::Ref() {
2969
+ inline uint32_t Reference<T>::Ref() const {
2254
2970
  uint32_t result;
2255
2971
  napi_status status = napi_reference_ref(_env, _ref, &result);
2256
- NAPI_THROW_IF_FAILED(_env, status, 1);
2972
+ NAPI_THROW_IF_FAILED(_env, status, 0);
2257
2973
  return result;
2258
2974
  }
2259
2975
 
2260
2976
  template <typename T>
2261
- inline uint32_t Reference<T>::Unref() {
2977
+ inline uint32_t Reference<T>::Unref() const {
2262
2978
  uint32_t result;
2263
2979
  napi_status status = napi_reference_unref(_env, _ref, &result);
2264
- NAPI_THROW_IF_FAILED(_env, status, 1);
2980
+ NAPI_THROW_IF_FAILED(_env, status, 0);
2265
2981
  return result;
2266
2982
  }
2267
2983
 
@@ -2349,99 +3065,150 @@ inline ObjectReference::ObjectReference(const ObjectReference& other)
2349
3065
  : Reference<Object>(other) {
2350
3066
  }
2351
3067
 
2352
- inline Napi::Value ObjectReference::Get(const char* utf8name) const {
3068
+ inline MaybeOrValue<Napi::Value> ObjectReference::Get(
3069
+ const char* utf8name) const {
2353
3070
  EscapableHandleScope scope(_env);
2354
- return scope.Escape(Value().Get(utf8name));
3071
+ MaybeOrValue<Napi::Value> result = Value().Get(utf8name);
3072
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3073
+ if (result.IsJust()) {
3074
+ return Just(scope.Escape(result.Unwrap()));
3075
+ }
3076
+ return result;
3077
+ #else
3078
+ if (scope.Env().IsExceptionPending()) {
3079
+ return Value();
3080
+ }
3081
+ return scope.Escape(result);
3082
+ #endif
2355
3083
  }
2356
3084
 
2357
- inline Napi::Value ObjectReference::Get(const std::string& utf8name) const {
3085
+ inline MaybeOrValue<Napi::Value> ObjectReference::Get(
3086
+ const std::string& utf8name) const {
2358
3087
  EscapableHandleScope scope(_env);
2359
- return scope.Escape(Value().Get(utf8name));
3088
+ MaybeOrValue<Napi::Value> result = Value().Get(utf8name);
3089
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3090
+ if (result.IsJust()) {
3091
+ return Just(scope.Escape(result.Unwrap()));
3092
+ }
3093
+ return result;
3094
+ #else
3095
+ if (scope.Env().IsExceptionPending()) {
3096
+ return Value();
3097
+ }
3098
+ return scope.Escape(result);
3099
+ #endif
2360
3100
  }
2361
3101
 
2362
- inline void ObjectReference::Set(const char* utf8name, napi_value value) {
3102
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3103
+ napi_value value) const {
2363
3104
  HandleScope scope(_env);
2364
- Value().Set(utf8name, value);
3105
+ return Value().Set(utf8name, value);
2365
3106
  }
2366
3107
 
2367
- inline void ObjectReference::Set(const char* utf8name, Napi::Value value) {
3108
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3109
+ Napi::Value value) const {
2368
3110
  HandleScope scope(_env);
2369
- Value().Set(utf8name, value);
3111
+ return Value().Set(utf8name, value);
2370
3112
  }
2371
3113
 
2372
- inline void ObjectReference::Set(const char* utf8name, const char* utf8value) {
3114
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3115
+ const char* utf8value) const {
2373
3116
  HandleScope scope(_env);
2374
- Value().Set(utf8name, utf8value);
3117
+ return Value().Set(utf8name, utf8value);
2375
3118
  }
2376
3119
 
2377
- inline void ObjectReference::Set(const char* utf8name, bool boolValue) {
3120
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3121
+ bool boolValue) const {
2378
3122
  HandleScope scope(_env);
2379
- Value().Set(utf8name, boolValue);
3123
+ return Value().Set(utf8name, boolValue);
2380
3124
  }
2381
3125
 
2382
- inline void ObjectReference::Set(const char* utf8name, double numberValue) {
3126
+ inline MaybeOrValue<bool> ObjectReference::Set(const char* utf8name,
3127
+ double numberValue) const {
2383
3128
  HandleScope scope(_env);
2384
- Value().Set(utf8name, numberValue);
3129
+ return Value().Set(utf8name, numberValue);
2385
3130
  }
2386
3131
 
2387
- inline void ObjectReference::Set(const std::string& utf8name, napi_value value) {
3132
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3133
+ napi_value value) const {
2388
3134
  HandleScope scope(_env);
2389
- Value().Set(utf8name, value);
3135
+ return Value().Set(utf8name, value);
2390
3136
  }
2391
3137
 
2392
- inline void ObjectReference::Set(const std::string& utf8name, Napi::Value value) {
3138
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3139
+ Napi::Value value) const {
2393
3140
  HandleScope scope(_env);
2394
- Value().Set(utf8name, value);
3141
+ return Value().Set(utf8name, value);
2395
3142
  }
2396
3143
 
2397
- inline void ObjectReference::Set(const std::string& utf8name, std::string& utf8value) {
3144
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3145
+ std::string& utf8value) const {
2398
3146
  HandleScope scope(_env);
2399
- Value().Set(utf8name, utf8value);
3147
+ return Value().Set(utf8name, utf8value);
2400
3148
  }
2401
3149
 
2402
- inline void ObjectReference::Set(const std::string& utf8name, bool boolValue) {
3150
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3151
+ bool boolValue) const {
2403
3152
  HandleScope scope(_env);
2404
- Value().Set(utf8name, boolValue);
3153
+ return Value().Set(utf8name, boolValue);
2405
3154
  }
2406
3155
 
2407
- inline void ObjectReference::Set(const std::string& utf8name, double numberValue) {
3156
+ inline MaybeOrValue<bool> ObjectReference::Set(const std::string& utf8name,
3157
+ double numberValue) const {
2408
3158
  HandleScope scope(_env);
2409
- Value().Set(utf8name, numberValue);
3159
+ return Value().Set(utf8name, numberValue);
2410
3160
  }
2411
3161
 
2412
- inline Napi::Value ObjectReference::Get(uint32_t index) const {
3162
+ inline MaybeOrValue<Napi::Value> ObjectReference::Get(uint32_t index) const {
2413
3163
  EscapableHandleScope scope(_env);
2414
- return scope.Escape(Value().Get(index));
3164
+ MaybeOrValue<Napi::Value> result = Value().Get(index);
3165
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3166
+ if (result.IsJust()) {
3167
+ return Just(scope.Escape(result.Unwrap()));
3168
+ }
3169
+ return result;
3170
+ #else
3171
+ if (scope.Env().IsExceptionPending()) {
3172
+ return Value();
3173
+ }
3174
+ return scope.Escape(result);
3175
+ #endif
2415
3176
  }
2416
3177
 
2417
- inline void ObjectReference::Set(uint32_t index, napi_value value) {
3178
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3179
+ napi_value value) const {
2418
3180
  HandleScope scope(_env);
2419
- Value().Set(index, value);
3181
+ return Value().Set(index, value);
2420
3182
  }
2421
3183
 
2422
- inline void ObjectReference::Set(uint32_t index, Napi::Value value) {
3184
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3185
+ Napi::Value value) const {
2423
3186
  HandleScope scope(_env);
2424
- Value().Set(index, value);
3187
+ return Value().Set(index, value);
2425
3188
  }
2426
3189
 
2427
- inline void ObjectReference::Set(uint32_t index, const char* utf8value) {
3190
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3191
+ const char* utf8value) const {
2428
3192
  HandleScope scope(_env);
2429
- Value().Set(index, utf8value);
3193
+ return Value().Set(index, utf8value);
2430
3194
  }
2431
3195
 
2432
- inline void ObjectReference::Set(uint32_t index, const std::string& utf8value) {
3196
+ inline MaybeOrValue<bool> ObjectReference::Set(
3197
+ uint32_t index, const std::string& utf8value) const {
2433
3198
  HandleScope scope(_env);
2434
- Value().Set(index, utf8value);
3199
+ return Value().Set(index, utf8value);
2435
3200
  }
2436
3201
 
2437
- inline void ObjectReference::Set(uint32_t index, bool boolValue) {
3202
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3203
+ bool boolValue) const {
2438
3204
  HandleScope scope(_env);
2439
- Value().Set(index, boolValue);
3205
+ return Value().Set(index, boolValue);
2440
3206
  }
2441
3207
 
2442
- inline void ObjectReference::Set(uint32_t index, double numberValue) {
3208
+ inline MaybeOrValue<bool> ObjectReference::Set(uint32_t index,
3209
+ double numberValue) const {
2443
3210
  HandleScope scope(_env);
2444
- Value().Set(index, numberValue);
3211
+ return Value().Set(index, numberValue);
2445
3212
  }
2446
3213
 
2447
3214
  ////////////////////////////////////////////////////////////////////////////////
@@ -2473,105 +3240,200 @@ inline FunctionReference& FunctionReference::operator =(FunctionReference&& othe
2473
3240
  return *this;
2474
3241
  }
2475
3242
 
2476
- inline Napi::Value FunctionReference::operator ()(
3243
+ inline MaybeOrValue<Napi::Value> FunctionReference::operator()(
2477
3244
  const std::initializer_list<napi_value>& args) const {
2478
3245
  EscapableHandleScope scope(_env);
2479
- return scope.Escape(Value()(args));
3246
+ MaybeOrValue<Napi::Value> result = Value()(args);
3247
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3248
+ if (result.IsJust()) {
3249
+ return Just(scope.Escape(result.Unwrap()));
3250
+ }
3251
+ return result;
3252
+ #else
3253
+ if (scope.Env().IsExceptionPending()) {
3254
+ return Value();
3255
+ }
3256
+ return scope.Escape(result);
3257
+ #endif
2480
3258
  }
2481
3259
 
2482
- inline Napi::Value FunctionReference::Call(const std::initializer_list<napi_value>& args) const {
3260
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3261
+ const std::initializer_list<napi_value>& args) const {
2483
3262
  EscapableHandleScope scope(_env);
2484
- Napi::Value result = Value().Call(args);
3263
+ MaybeOrValue<Napi::Value> result = Value().Call(args);
3264
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3265
+ if (result.IsJust()) {
3266
+ return Just(scope.Escape(result.Unwrap()));
3267
+ }
3268
+ return result;
3269
+ #else
2485
3270
  if (scope.Env().IsExceptionPending()) {
2486
3271
  return Value();
2487
3272
  }
2488
3273
  return scope.Escape(result);
3274
+ #endif
2489
3275
  }
2490
3276
 
2491
- inline Napi::Value FunctionReference::Call(const std::vector<napi_value>& args) const {
3277
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
3278
+ const std::vector<napi_value>& args) const {
2492
3279
  EscapableHandleScope scope(_env);
2493
- Napi::Value result = Value().Call(args);
3280
+ MaybeOrValue<Napi::Value> result = Value().Call(args);
3281
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3282
+ if (result.IsJust()) {
3283
+ return Just(scope.Escape(result.Unwrap()));
3284
+ }
3285
+ return result;
3286
+ #else
2494
3287
  if (scope.Env().IsExceptionPending()) {
2495
3288
  return Value();
2496
3289
  }
2497
3290
  return scope.Escape(result);
3291
+ #endif
2498
3292
  }
2499
3293
 
2500
- inline Napi::Value FunctionReference::Call(
3294
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
2501
3295
  napi_value recv, const std::initializer_list<napi_value>& args) const {
2502
3296
  EscapableHandleScope scope(_env);
2503
- Napi::Value result = Value().Call(recv, args);
3297
+ MaybeOrValue<Napi::Value> result = Value().Call(recv, args);
3298
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3299
+ if (result.IsJust()) {
3300
+ return Just(scope.Escape(result.Unwrap()));
3301
+ }
3302
+ return result;
3303
+ #else
2504
3304
  if (scope.Env().IsExceptionPending()) {
2505
3305
  return Value();
2506
3306
  }
2507
3307
  return scope.Escape(result);
3308
+ #endif
2508
3309
  }
2509
3310
 
2510
- inline Napi::Value FunctionReference::Call(
3311
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
2511
3312
  napi_value recv, const std::vector<napi_value>& args) const {
2512
3313
  EscapableHandleScope scope(_env);
2513
- Napi::Value result = Value().Call(recv, args);
3314
+ MaybeOrValue<Napi::Value> result = Value().Call(recv, args);
3315
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3316
+ if (result.IsJust()) {
3317
+ return Just(scope.Escape(result.Unwrap()));
3318
+ }
3319
+ return result;
3320
+ #else
2514
3321
  if (scope.Env().IsExceptionPending()) {
2515
3322
  return Value();
2516
3323
  }
2517
3324
  return scope.Escape(result);
3325
+ #endif
2518
3326
  }
2519
3327
 
2520
- inline Napi::Value FunctionReference::Call(
3328
+ inline MaybeOrValue<Napi::Value> FunctionReference::Call(
2521
3329
  napi_value recv, size_t argc, const napi_value* args) const {
2522
3330
  EscapableHandleScope scope(_env);
2523
- Napi::Value result = Value().Call(recv, argc, args);
3331
+ MaybeOrValue<Napi::Value> result = Value().Call(recv, argc, args);
3332
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3333
+ if (result.IsJust()) {
3334
+ return Just(scope.Escape(result.Unwrap()));
3335
+ }
3336
+ return result;
3337
+ #else
2524
3338
  if (scope.Env().IsExceptionPending()) {
2525
3339
  return Value();
2526
3340
  }
2527
3341
  return scope.Escape(result);
3342
+ #endif
2528
3343
  }
2529
3344
 
2530
- inline Napi::Value FunctionReference::MakeCallback(
3345
+ inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
2531
3346
  napi_value recv,
2532
3347
  const std::initializer_list<napi_value>& args,
2533
3348
  napi_async_context context) const {
2534
3349
  EscapableHandleScope scope(_env);
2535
- Napi::Value result = Value().MakeCallback(recv, args, context);
3350
+ MaybeOrValue<Napi::Value> result = Value().MakeCallback(recv, args, context);
3351
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3352
+ if (result.IsJust()) {
3353
+ return Just(scope.Escape(result.Unwrap()));
3354
+ }
3355
+
3356
+ return result;
3357
+ #else
2536
3358
  if (scope.Env().IsExceptionPending()) {
2537
3359
  return Value();
2538
3360
  }
2539
3361
  return scope.Escape(result);
3362
+ #endif
2540
3363
  }
2541
3364
 
2542
- inline Napi::Value FunctionReference::MakeCallback(
3365
+ inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
2543
3366
  napi_value recv,
2544
3367
  const std::vector<napi_value>& args,
2545
3368
  napi_async_context context) const {
2546
3369
  EscapableHandleScope scope(_env);
2547
- Napi::Value result = Value().MakeCallback(recv, args, context);
3370
+ MaybeOrValue<Napi::Value> result = Value().MakeCallback(recv, args, context);
3371
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3372
+ if (result.IsJust()) {
3373
+ return Just(scope.Escape(result.Unwrap()));
3374
+ }
3375
+ return result;
3376
+ #else
2548
3377
  if (scope.Env().IsExceptionPending()) {
2549
3378
  return Value();
2550
3379
  }
2551
3380
  return scope.Escape(result);
3381
+ #endif
2552
3382
  }
2553
3383
 
2554
- inline Napi::Value FunctionReference::MakeCallback(
3384
+ inline MaybeOrValue<Napi::Value> FunctionReference::MakeCallback(
2555
3385
  napi_value recv,
2556
3386
  size_t argc,
2557
3387
  const napi_value* args,
2558
3388
  napi_async_context context) const {
2559
3389
  EscapableHandleScope scope(_env);
2560
- Napi::Value result = Value().MakeCallback(recv, argc, args, context);
3390
+ MaybeOrValue<Napi::Value> result =
3391
+ Value().MakeCallback(recv, argc, args, context);
3392
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3393
+ if (result.IsJust()) {
3394
+ return Just(scope.Escape(result.Unwrap()));
3395
+ }
3396
+ return result;
3397
+ #else
2561
3398
  if (scope.Env().IsExceptionPending()) {
2562
3399
  return Value();
2563
3400
  }
2564
3401
  return scope.Escape(result);
3402
+ #endif
2565
3403
  }
2566
3404
 
2567
- inline Object FunctionReference::New(const std::initializer_list<napi_value>& args) const {
3405
+ inline MaybeOrValue<Object> FunctionReference::New(
3406
+ const std::initializer_list<napi_value>& args) const {
2568
3407
  EscapableHandleScope scope(_env);
2569
- return scope.Escape(Value().New(args)).As<Object>();
3408
+ MaybeOrValue<Object> result = Value().New(args);
3409
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3410
+ if (result.IsJust()) {
3411
+ return Just(scope.Escape(result.Unwrap()).As<Object>());
3412
+ }
3413
+ return result;
3414
+ #else
3415
+ if (scope.Env().IsExceptionPending()) {
3416
+ return Object();
3417
+ }
3418
+ return scope.Escape(result).As<Object>();
3419
+ #endif
2570
3420
  }
2571
3421
 
2572
- inline Object FunctionReference::New(const std::vector<napi_value>& args) const {
3422
+ inline MaybeOrValue<Object> FunctionReference::New(
3423
+ const std::vector<napi_value>& args) const {
2573
3424
  EscapableHandleScope scope(_env);
2574
- return scope.Escape(Value().New(args)).As<Object>();
3425
+ MaybeOrValue<Object> result = Value().New(args);
3426
+ #ifdef NODE_ADDON_API_ENABLE_MAYBE
3427
+ if (result.IsJust()) {
3428
+ return Just(scope.Escape(result.Unwrap()).As<Object>());
3429
+ }
3430
+ return result;
3431
+ #else
3432
+ if (scope.Env().IsExceptionPending()) {
3433
+ return Object();
3434
+ }
3435
+ return scope.Escape(result).As<Object>();
3436
+ #endif
2575
3437
  }
2576
3438
 
2577
3439
  ////////////////////////////////////////////////////////////////////////////////
@@ -2644,6 +3506,91 @@ inline void CallbackInfo::SetData(void* data) {
2644
3506
  // PropertyDescriptor class
2645
3507
  ////////////////////////////////////////////////////////////////////////////////
2646
3508
 
3509
+ template <typename PropertyDescriptor::GetterCallback Getter>
3510
+ PropertyDescriptor
3511
+ PropertyDescriptor::Accessor(const char* utf8name,
3512
+ napi_property_attributes attributes,
3513
+ void* data) {
3514
+ napi_property_descriptor desc = napi_property_descriptor();
3515
+
3516
+ desc.utf8name = utf8name;
3517
+ desc.getter = details::TemplatedCallback<Getter>;
3518
+ desc.attributes = attributes;
3519
+ desc.data = data;
3520
+
3521
+ return desc;
3522
+ }
3523
+
3524
+ template <typename PropertyDescriptor::GetterCallback Getter>
3525
+ PropertyDescriptor
3526
+ PropertyDescriptor::Accessor(const std::string& utf8name,
3527
+ napi_property_attributes attributes,
3528
+ void* data) {
3529
+ return Accessor<Getter>(utf8name.c_str(), attributes, data);
3530
+ }
3531
+
3532
+ template <typename PropertyDescriptor::GetterCallback Getter>
3533
+ PropertyDescriptor
3534
+ PropertyDescriptor::Accessor(Name name,
3535
+ napi_property_attributes attributes,
3536
+ void* data) {
3537
+ napi_property_descriptor desc = napi_property_descriptor();
3538
+
3539
+ desc.name = name;
3540
+ desc.getter = details::TemplatedCallback<Getter>;
3541
+ desc.attributes = attributes;
3542
+ desc.data = data;
3543
+
3544
+ return desc;
3545
+ }
3546
+
3547
+ template <
3548
+ typename PropertyDescriptor::GetterCallback Getter,
3549
+ typename PropertyDescriptor::SetterCallback Setter>
3550
+ PropertyDescriptor
3551
+ PropertyDescriptor::Accessor(const char* utf8name,
3552
+ napi_property_attributes attributes,
3553
+ void* data) {
3554
+
3555
+ napi_property_descriptor desc = napi_property_descriptor();
3556
+
3557
+ desc.utf8name = utf8name;
3558
+ desc.getter = details::TemplatedCallback<Getter>;
3559
+ desc.setter = details::TemplatedVoidCallback<Setter>;
3560
+ desc.attributes = attributes;
3561
+ desc.data = data;
3562
+
3563
+ return desc;
3564
+ }
3565
+
3566
+ template <
3567
+ typename PropertyDescriptor::GetterCallback Getter,
3568
+ typename PropertyDescriptor::SetterCallback Setter>
3569
+ PropertyDescriptor
3570
+ PropertyDescriptor::Accessor(const std::string& utf8name,
3571
+ napi_property_attributes attributes,
3572
+ void* data) {
3573
+ return Accessor<Getter, Setter>(utf8name.c_str(), attributes, data);
3574
+ }
3575
+
3576
+ template <
3577
+ typename PropertyDescriptor::GetterCallback Getter,
3578
+ typename PropertyDescriptor::SetterCallback Setter>
3579
+ PropertyDescriptor
3580
+ PropertyDescriptor::Accessor(Name name,
3581
+ napi_property_attributes attributes,
3582
+ void* data) {
3583
+ napi_property_descriptor desc = napi_property_descriptor();
3584
+
3585
+ desc.name = name;
3586
+ desc.getter = details::TemplatedCallback<Getter>;
3587
+ desc.setter = details::TemplatedVoidCallback<Setter>;
3588
+ desc.attributes = attributes;
3589
+ desc.data = data;
3590
+
3591
+ return desc;
3592
+ }
3593
+
2647
3594
  template <typename Getter>
2648
3595
  inline PropertyDescriptor
2649
3596
  PropertyDescriptor::Accessor(Napi::Env env,
@@ -2652,7 +3599,7 @@ PropertyDescriptor::Accessor(Napi::Env env,
2652
3599
  Getter getter,
2653
3600
  napi_property_attributes attributes,
2654
3601
  void* data) {
2655
- typedef details::CallbackData<Getter, Napi::Value> CbData;
3602
+ using CbData = details::CallbackData<Getter, Napi::Value>;
2656
3603
  auto callbackData = new CbData({ getter, data });
2657
3604
 
2658
3605
  napi_status status = AttachData(env, object, callbackData);
@@ -2690,7 +3637,7 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
2690
3637
  Getter getter,
2691
3638
  napi_property_attributes attributes,
2692
3639
  void* data) {
2693
- typedef details::CallbackData<Getter, Napi::Value> CbData;
3640
+ using CbData = details::CallbackData<Getter, Napi::Value>;
2694
3641
  auto callbackData = new CbData({ getter, data });
2695
3642
 
2696
3643
  napi_status status = AttachData(env, object, callbackData);
@@ -2719,7 +3666,7 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
2719
3666
  Setter setter,
2720
3667
  napi_property_attributes attributes,
2721
3668
  void* data) {
2722
- typedef details::AccessorCallbackData<Getter, Setter> CbData;
3669
+ using CbData = details::AccessorCallbackData<Getter, Setter>;
2723
3670
  auto callbackData = new CbData({ getter, setter, data });
2724
3671
 
2725
3672
  napi_status status = AttachData(env, object, callbackData);
@@ -2759,7 +3706,7 @@ inline PropertyDescriptor PropertyDescriptor::Accessor(Napi::Env env,
2759
3706
  Setter setter,
2760
3707
  napi_property_attributes attributes,
2761
3708
  void* data) {
2762
- typedef details::AccessorCallbackData<Getter, Setter> CbData;
3709
+ using CbData = details::AccessorCallbackData<Getter, Setter>;
2763
3710
  auto callbackData = new CbData({ getter, setter, data });
2764
3711
 
2765
3712
  napi_status status = AttachData(env, object, callbackData);
@@ -2871,45 +3818,379 @@ inline PropertyDescriptor::operator const napi_property_descriptor&() const {
2871
3818
  }
2872
3819
 
2873
3820
  ////////////////////////////////////////////////////////////////////////////////
2874
- // ObjectWrap<T> class
3821
+ // InstanceWrap<T> class
2875
3822
  ////////////////////////////////////////////////////////////////////////////////
2876
3823
 
2877
3824
  template <typename T>
2878
- inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
2879
- napi_env env = callbackInfo.Env();
2880
- napi_value wrapper = callbackInfo.This();
3825
+ inline void InstanceWrap<T>::AttachPropData(napi_env env,
3826
+ napi_value value,
3827
+ const napi_property_descriptor* prop) {
2881
3828
  napi_status status;
2882
- napi_ref ref;
2883
- T* instance = static_cast<T*>(this);
2884
- status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
2885
- NAPI_THROW_IF_FAILED_VOID(env, status);
2886
-
2887
- Reference<Object>* instanceRef = instance;
2888
- *instanceRef = Reference<Object>(env, ref);
3829
+ if (!(prop->attributes & napi_static)) {
3830
+ if (prop->method == T::InstanceVoidMethodCallbackWrapper) {
3831
+ status = Napi::details::AttachData(env,
3832
+ value,
3833
+ static_cast<InstanceVoidMethodCallbackData*>(prop->data));
3834
+ NAPI_THROW_IF_FAILED_VOID(env, status);
3835
+ } else if (prop->method == T::InstanceMethodCallbackWrapper) {
3836
+ status = Napi::details::AttachData(env,
3837
+ value,
3838
+ static_cast<InstanceMethodCallbackData*>(prop->data));
3839
+ NAPI_THROW_IF_FAILED_VOID(env, status);
3840
+ } else if (prop->getter == T::InstanceGetterCallbackWrapper ||
3841
+ prop->setter == T::InstanceSetterCallbackWrapper) {
3842
+ status = Napi::details::AttachData(env,
3843
+ value,
3844
+ static_cast<InstanceAccessorCallbackData*>(prop->data));
3845
+ NAPI_THROW_IF_FAILED_VOID(env, status);
3846
+ }
3847
+ }
2889
3848
  }
2890
3849
 
2891
- template<typename T>
2892
- inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
2893
- T* unwrapped;
2894
- napi_status status = napi_unwrap(wrapper.Env(), wrapper, reinterpret_cast<void**>(&unwrapped));
2895
- NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
2896
- return unwrapped;
3850
+ template <typename T>
3851
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3852
+ const char* utf8name,
3853
+ InstanceVoidMethodCallback method,
3854
+ napi_property_attributes attributes,
3855
+ void* data) {
3856
+ InstanceVoidMethodCallbackData* callbackData =
3857
+ new InstanceVoidMethodCallbackData({ method, data});
3858
+
3859
+ napi_property_descriptor desc = napi_property_descriptor();
3860
+ desc.utf8name = utf8name;
3861
+ desc.method = T::InstanceVoidMethodCallbackWrapper;
3862
+ desc.data = callbackData;
3863
+ desc.attributes = attributes;
3864
+ return desc;
2897
3865
  }
2898
3866
 
2899
3867
  template <typename T>
2900
- inline Function
2901
- ObjectWrap<T>::DefineClass(Napi::Env env,
2902
- const char* utf8name,
2903
- const size_t props_count,
2904
- const napi_property_descriptor* descriptors,
2905
- void* data) {
2906
- napi_status status;
2907
- std::vector<napi_property_descriptor> props(props_count);
3868
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3869
+ const char* utf8name,
3870
+ InstanceMethodCallback method,
3871
+ napi_property_attributes attributes,
3872
+ void* data) {
3873
+ InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
2908
3874
 
2909
- // We copy the descriptors to a local array because before defining the class
2910
- // we must replace static method property descriptors with value property
2911
- // descriptors such that the value is a function-valued `napi_value` created
2912
- // with `CreateFunction()`.
3875
+ napi_property_descriptor desc = napi_property_descriptor();
3876
+ desc.utf8name = utf8name;
3877
+ desc.method = T::InstanceMethodCallbackWrapper;
3878
+ desc.data = callbackData;
3879
+ desc.attributes = attributes;
3880
+ return desc;
3881
+ }
3882
+
3883
+ template <typename T>
3884
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3885
+ Symbol name,
3886
+ InstanceVoidMethodCallback method,
3887
+ napi_property_attributes attributes,
3888
+ void* data) {
3889
+ InstanceVoidMethodCallbackData* callbackData =
3890
+ new InstanceVoidMethodCallbackData({ method, data});
3891
+
3892
+ napi_property_descriptor desc = napi_property_descriptor();
3893
+ desc.name = name;
3894
+ desc.method = T::InstanceVoidMethodCallbackWrapper;
3895
+ desc.data = callbackData;
3896
+ desc.attributes = attributes;
3897
+ return desc;
3898
+ }
3899
+
3900
+ template <typename T>
3901
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3902
+ Symbol name,
3903
+ InstanceMethodCallback method,
3904
+ napi_property_attributes attributes,
3905
+ void* data) {
3906
+ InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
3907
+
3908
+ napi_property_descriptor desc = napi_property_descriptor();
3909
+ desc.name = name;
3910
+ desc.method = T::InstanceMethodCallbackWrapper;
3911
+ desc.data = callbackData;
3912
+ desc.attributes = attributes;
3913
+ return desc;
3914
+ }
3915
+
3916
+ template <typename T>
3917
+ template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
3918
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3919
+ const char* utf8name,
3920
+ napi_property_attributes attributes,
3921
+ void* data) {
3922
+ napi_property_descriptor desc = napi_property_descriptor();
3923
+ desc.utf8name = utf8name;
3924
+ desc.method = details::TemplatedInstanceVoidCallback<T, method>;
3925
+ desc.data = data;
3926
+ desc.attributes = attributes;
3927
+ return desc;
3928
+ }
3929
+
3930
+ template <typename T>
3931
+ template <typename InstanceWrap<T>::InstanceMethodCallback method>
3932
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3933
+ const char* utf8name,
3934
+ napi_property_attributes attributes,
3935
+ void* data) {
3936
+ napi_property_descriptor desc = napi_property_descriptor();
3937
+ desc.utf8name = utf8name;
3938
+ desc.method = details::TemplatedInstanceCallback<T, method>;
3939
+ desc.data = data;
3940
+ desc.attributes = attributes;
3941
+ return desc;
3942
+ }
3943
+
3944
+ template <typename T>
3945
+ template <typename InstanceWrap<T>::InstanceVoidMethodCallback method>
3946
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3947
+ Symbol name,
3948
+ napi_property_attributes attributes,
3949
+ void* data) {
3950
+ napi_property_descriptor desc = napi_property_descriptor();
3951
+ desc.name = name;
3952
+ desc.method = details::TemplatedInstanceVoidCallback<T, method>;
3953
+ desc.data = data;
3954
+ desc.attributes = attributes;
3955
+ return desc;
3956
+ }
3957
+
3958
+ template <typename T>
3959
+ template <typename InstanceWrap<T>::InstanceMethodCallback method>
3960
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceMethod(
3961
+ Symbol name,
3962
+ napi_property_attributes attributes,
3963
+ void* data) {
3964
+ napi_property_descriptor desc = napi_property_descriptor();
3965
+ desc.name = name;
3966
+ desc.method = details::TemplatedInstanceCallback<T, method>;
3967
+ desc.data = data;
3968
+ desc.attributes = attributes;
3969
+ return desc;
3970
+ }
3971
+
3972
+ template <typename T>
3973
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
3974
+ const char* utf8name,
3975
+ InstanceGetterCallback getter,
3976
+ InstanceSetterCallback setter,
3977
+ napi_property_attributes attributes,
3978
+ void* data) {
3979
+ InstanceAccessorCallbackData* callbackData =
3980
+ new InstanceAccessorCallbackData({ getter, setter, data });
3981
+
3982
+ napi_property_descriptor desc = napi_property_descriptor();
3983
+ desc.utf8name = utf8name;
3984
+ desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
3985
+ desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
3986
+ desc.data = callbackData;
3987
+ desc.attributes = attributes;
3988
+ return desc;
3989
+ }
3990
+
3991
+ template <typename T>
3992
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
3993
+ Symbol name,
3994
+ InstanceGetterCallback getter,
3995
+ InstanceSetterCallback setter,
3996
+ napi_property_attributes attributes,
3997
+ void* data) {
3998
+ InstanceAccessorCallbackData* callbackData =
3999
+ new InstanceAccessorCallbackData({ getter, setter, data });
4000
+
4001
+ napi_property_descriptor desc = napi_property_descriptor();
4002
+ desc.name = name;
4003
+ desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
4004
+ desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
4005
+ desc.data = callbackData;
4006
+ desc.attributes = attributes;
4007
+ return desc;
4008
+ }
4009
+
4010
+ template <typename T>
4011
+ template <typename InstanceWrap<T>::InstanceGetterCallback getter,
4012
+ typename InstanceWrap<T>::InstanceSetterCallback setter>
4013
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
4014
+ const char* utf8name,
4015
+ napi_property_attributes attributes,
4016
+ void* data) {
4017
+ napi_property_descriptor desc = napi_property_descriptor();
4018
+ desc.utf8name = utf8name;
4019
+ desc.getter = details::TemplatedInstanceCallback<T, getter>;
4020
+ desc.setter = This::WrapSetter(This::SetterTag<setter>());
4021
+ desc.data = data;
4022
+ desc.attributes = attributes;
4023
+ return desc;
4024
+ }
4025
+
4026
+ template <typename T>
4027
+ template <typename InstanceWrap<T>::InstanceGetterCallback getter,
4028
+ typename InstanceWrap<T>::InstanceSetterCallback setter>
4029
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceAccessor(
4030
+ Symbol name,
4031
+ napi_property_attributes attributes,
4032
+ void* data) {
4033
+ napi_property_descriptor desc = napi_property_descriptor();
4034
+ desc.name = name;
4035
+ desc.getter = details::TemplatedInstanceCallback<T, getter>;
4036
+ desc.setter = This::WrapSetter(This::SetterTag<setter>());
4037
+ desc.data = data;
4038
+ desc.attributes = attributes;
4039
+ return desc;
4040
+ }
4041
+
4042
+ template <typename T>
4043
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
4044
+ const char* utf8name,
4045
+ Napi::Value value,
4046
+ napi_property_attributes attributes) {
4047
+ napi_property_descriptor desc = napi_property_descriptor();
4048
+ desc.utf8name = utf8name;
4049
+ desc.value = value;
4050
+ desc.attributes = attributes;
4051
+ return desc;
4052
+ }
4053
+
4054
+ template <typename T>
4055
+ inline ClassPropertyDescriptor<T> InstanceWrap<T>::InstanceValue(
4056
+ Symbol name,
4057
+ Napi::Value value,
4058
+ napi_property_attributes attributes) {
4059
+ napi_property_descriptor desc = napi_property_descriptor();
4060
+ desc.name = name;
4061
+ desc.value = value;
4062
+ desc.attributes = attributes;
4063
+ return desc;
4064
+ }
4065
+
4066
+ template <typename T>
4067
+ inline napi_value InstanceWrap<T>::InstanceVoidMethodCallbackWrapper(
4068
+ napi_env env,
4069
+ napi_callback_info info) {
4070
+ return details::WrapCallback([&] {
4071
+ CallbackInfo callbackInfo(env, info);
4072
+ InstanceVoidMethodCallbackData* callbackData =
4073
+ reinterpret_cast<InstanceVoidMethodCallbackData*>(callbackInfo.Data());
4074
+ callbackInfo.SetData(callbackData->data);
4075
+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4076
+ auto cb = callbackData->callback;
4077
+ (instance->*cb)(callbackInfo);
4078
+ return nullptr;
4079
+ });
4080
+ }
4081
+
4082
+ template <typename T>
4083
+ inline napi_value InstanceWrap<T>::InstanceMethodCallbackWrapper(
4084
+ napi_env env,
4085
+ napi_callback_info info) {
4086
+ return details::WrapCallback([&] {
4087
+ CallbackInfo callbackInfo(env, info);
4088
+ InstanceMethodCallbackData* callbackData =
4089
+ reinterpret_cast<InstanceMethodCallbackData*>(callbackInfo.Data());
4090
+ callbackInfo.SetData(callbackData->data);
4091
+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4092
+ auto cb = callbackData->callback;
4093
+ return (instance->*cb)(callbackInfo);
4094
+ });
4095
+ }
4096
+
4097
+ template <typename T>
4098
+ inline napi_value InstanceWrap<T>::InstanceGetterCallbackWrapper(
4099
+ napi_env env,
4100
+ napi_callback_info info) {
4101
+ return details::WrapCallback([&] {
4102
+ CallbackInfo callbackInfo(env, info);
4103
+ InstanceAccessorCallbackData* callbackData =
4104
+ reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
4105
+ callbackInfo.SetData(callbackData->data);
4106
+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4107
+ auto cb = callbackData->getterCallback;
4108
+ return (instance->*cb)(callbackInfo);
4109
+ });
4110
+ }
4111
+
4112
+ template <typename T>
4113
+ inline napi_value InstanceWrap<T>::InstanceSetterCallbackWrapper(
4114
+ napi_env env,
4115
+ napi_callback_info info) {
4116
+ return details::WrapCallback([&] {
4117
+ CallbackInfo callbackInfo(env, info);
4118
+ InstanceAccessorCallbackData* callbackData =
4119
+ reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
4120
+ callbackInfo.SetData(callbackData->data);
4121
+ T* instance = T::Unwrap(callbackInfo.This().As<Object>());
4122
+ auto cb = callbackData->setterCallback;
4123
+ (instance->*cb)(callbackInfo, callbackInfo[0]);
4124
+ return nullptr;
4125
+ });
4126
+ }
4127
+
4128
+ template <typename T>
4129
+ template <typename InstanceWrap<T>::InstanceSetterCallback method>
4130
+ inline napi_value InstanceWrap<T>::WrappedMethod(
4131
+ napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
4132
+ return details::WrapCallback([&] {
4133
+ const CallbackInfo cbInfo(env, info);
4134
+ T* instance = T::Unwrap(cbInfo.This().As<Object>());
4135
+ (instance->*method)(cbInfo, cbInfo[0]);
4136
+ return nullptr;
4137
+ });
4138
+ }
4139
+
4140
+ ////////////////////////////////////////////////////////////////////////////////
4141
+ // ObjectWrap<T> class
4142
+ ////////////////////////////////////////////////////////////////////////////////
4143
+
4144
+ template <typename T>
4145
+ inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
4146
+ napi_env env = callbackInfo.Env();
4147
+ napi_value wrapper = callbackInfo.This();
4148
+ napi_status status;
4149
+ napi_ref ref;
4150
+ T* instance = static_cast<T*>(this);
4151
+ status = napi_wrap(env, wrapper, instance, FinalizeCallback, nullptr, &ref);
4152
+ NAPI_THROW_IF_FAILED_VOID(env, status);
4153
+
4154
+ Reference<Object>* instanceRef = instance;
4155
+ *instanceRef = Reference<Object>(env, ref);
4156
+ }
4157
+
4158
+ template <typename T>
4159
+ inline ObjectWrap<T>::~ObjectWrap() {
4160
+ // If the JS object still exists at this point, remove the finalizer added
4161
+ // through `napi_wrap()`.
4162
+ if (!IsEmpty()) {
4163
+ Object object = Value();
4164
+ // It is not valid to call `napi_remove_wrap()` with an empty `object`.
4165
+ // This happens e.g. during garbage collection.
4166
+ if (!object.IsEmpty() && _construction_failed) {
4167
+ napi_remove_wrap(Env(), object, nullptr);
4168
+ }
4169
+ }
4170
+ }
4171
+
4172
+ template<typename T>
4173
+ inline T* ObjectWrap<T>::Unwrap(Object wrapper) {
4174
+ void* unwrapped;
4175
+ napi_status status = napi_unwrap(wrapper.Env(), wrapper, &unwrapped);
4176
+ NAPI_THROW_IF_FAILED(wrapper.Env(), status, nullptr);
4177
+ return static_cast<T*>(unwrapped);
4178
+ }
4179
+
4180
+ template <typename T>
4181
+ inline Function
4182
+ ObjectWrap<T>::DefineClass(Napi::Env env,
4183
+ const char* utf8name,
4184
+ const size_t props_count,
4185
+ const napi_property_descriptor* descriptors,
4186
+ void* data) {
4187
+ napi_status status;
4188
+ std::vector<napi_property_descriptor> props(props_count);
4189
+
4190
+ // We copy the descriptors to a local array because before defining the class
4191
+ // we must replace static method property descriptors with value property
4192
+ // descriptors such that the value is a function-valued `napi_value` created
4193
+ // with `CreateFunction()`.
2913
4194
  //
2914
4195
  // This replacement could be made for instance methods as well, but V8 aborts
2915
4196
  // if we do that, because it expects methods defined on the prototype template
@@ -2919,19 +4200,19 @@ ObjectWrap<T>::DefineClass(Napi::Env env,
2919
4200
  napi_property_descriptor* prop = &props[index];
2920
4201
  if (prop->method == T::StaticMethodCallbackWrapper) {
2921
4202
  status = CreateFunction(env,
2922
- utf8name,
2923
- prop->method,
2924
- static_cast<StaticMethodCallbackData*>(prop->data),
4203
+ utf8name,
4204
+ prop->method,
4205
+ static_cast<StaticMethodCallbackData*>(prop->data),
2925
4206
  &(prop->value));
2926
4207
  NAPI_THROW_IF_FAILED(env, status, Function());
2927
4208
  prop->method = nullptr;
2928
4209
  prop->data = nullptr;
2929
4210
  } else if (prop->method == T::StaticVoidMethodCallbackWrapper) {
2930
4211
  status = CreateFunction(env,
2931
- utf8name,
2932
- prop->method,
2933
- static_cast<StaticVoidMethodCallbackData*>(prop->data),
2934
- &(prop->value));
4212
+ utf8name,
4213
+ prop->method,
4214
+ static_cast<StaticVoidMethodCallbackData*>(prop->data),
4215
+ &(prop->value));
2935
4216
  NAPI_THROW_IF_FAILED(env, status, Function());
2936
4217
  prop->method = nullptr;
2937
4218
  prop->data = nullptr;
@@ -2961,24 +4242,10 @@ ObjectWrap<T>::DefineClass(Napi::Env env,
2961
4242
  value,
2962
4243
  static_cast<StaticAccessorCallbackData*>(prop->data));
2963
4244
  NAPI_THROW_IF_FAILED(env, status, Function());
2964
- } else if (prop->getter == T::InstanceGetterCallbackWrapper ||
2965
- prop->setter == T::InstanceSetterCallbackWrapper) {
2966
- status = Napi::details::AttachData(env,
2967
- value,
2968
- static_cast<InstanceAccessorCallbackData*>(prop->data));
2969
- NAPI_THROW_IF_FAILED(env, status, Function());
2970
- } else if (prop->method != nullptr && !(prop->attributes & napi_static)) {
2971
- if (prop->method == T::InstanceVoidMethodCallbackWrapper) {
2972
- status = Napi::details::AttachData(env,
2973
- value,
2974
- static_cast<InstanceVoidMethodCallbackData*>(prop->data));
2975
- NAPI_THROW_IF_FAILED(env, status, Function());
2976
- } else if (prop->method == T::InstanceMethodCallbackWrapper) {
2977
- status = Napi::details::AttachData(env,
2978
- value,
2979
- static_cast<InstanceMethodCallbackData*>(prop->data));
2980
- NAPI_THROW_IF_FAILED(env, status, Function());
2981
- }
4245
+ } else {
4246
+ // InstanceWrap<T>::AttachPropData is responsible for attaching the data
4247
+ // of instance methods and accessors.
4248
+ T::AttachPropData(env, value, prop);
2982
4249
  }
2983
4250
  }
2984
4251
 
@@ -3076,144 +4343,128 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
3076
4343
  }
3077
4344
 
3078
4345
  template <typename T>
3079
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4346
+ template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
4347
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
3080
4348
  const char* utf8name,
3081
- StaticGetterCallback getter,
3082
- StaticSetterCallback setter,
3083
4349
  napi_property_attributes attributes,
3084
4350
  void* data) {
3085
- StaticAccessorCallbackData* callbackData =
3086
- new StaticAccessorCallbackData({ getter, setter, data });
3087
-
3088
4351
  napi_property_descriptor desc = napi_property_descriptor();
3089
4352
  desc.utf8name = utf8name;
3090
- desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
3091
- desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
3092
- desc.data = callbackData;
4353
+ desc.method = details::TemplatedVoidCallback<method>;
4354
+ desc.data = data;
3093
4355
  desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3094
4356
  return desc;
3095
4357
  }
3096
4358
 
3097
4359
  template <typename T>
3098
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4360
+ template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
4361
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
3099
4362
  Symbol name,
3100
- StaticGetterCallback getter,
3101
- StaticSetterCallback setter,
3102
4363
  napi_property_attributes attributes,
3103
4364
  void* data) {
3104
- StaticAccessorCallbackData* callbackData =
3105
- new StaticAccessorCallbackData({ getter, setter, data });
3106
-
3107
4365
  napi_property_descriptor desc = napi_property_descriptor();
3108
4366
  desc.name = name;
3109
- desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
3110
- desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
3111
- desc.data = callbackData;
4367
+ desc.method = details::TemplatedVoidCallback<method>;
4368
+ desc.data = data;
3112
4369
  desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3113
4370
  return desc;
3114
4371
  }
3115
4372
 
3116
4373
  template <typename T>
3117
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
4374
+ template <typename ObjectWrap<T>::StaticMethodCallback method>
4375
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
3118
4376
  const char* utf8name,
3119
- InstanceVoidMethodCallback method,
3120
4377
  napi_property_attributes attributes,
3121
4378
  void* data) {
3122
- InstanceVoidMethodCallbackData* callbackData =
3123
- new InstanceVoidMethodCallbackData({ method, data});
3124
-
3125
4379
  napi_property_descriptor desc = napi_property_descriptor();
3126
4380
  desc.utf8name = utf8name;
3127
- desc.method = T::InstanceVoidMethodCallbackWrapper;
3128
- desc.data = callbackData;
3129
- desc.attributes = attributes;
4381
+ desc.method = details::TemplatedCallback<method>;
4382
+ desc.data = data;
4383
+ desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3130
4384
  return desc;
3131
4385
  }
3132
4386
 
3133
4387
  template <typename T>
3134
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
3135
- const char* utf8name,
3136
- InstanceMethodCallback method,
4388
+ template <typename ObjectWrap<T>::StaticMethodCallback method>
4389
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
4390
+ Symbol name,
3137
4391
  napi_property_attributes attributes,
3138
4392
  void* data) {
3139
- InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
3140
-
3141
4393
  napi_property_descriptor desc = napi_property_descriptor();
3142
- desc.utf8name = utf8name;
3143
- desc.method = T::InstanceMethodCallbackWrapper;
3144
- desc.data = callbackData;
3145
- desc.attributes = attributes;
4394
+ desc.name = name;
4395
+ desc.method = details::TemplatedCallback<method>;
4396
+ desc.data = data;
4397
+ desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3146
4398
  return desc;
3147
4399
  }
3148
4400
 
3149
4401
  template <typename T>
3150
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
3151
- Symbol name,
3152
- InstanceVoidMethodCallback method,
4402
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
4403
+ const char* utf8name,
4404
+ StaticGetterCallback getter,
4405
+ StaticSetterCallback setter,
3153
4406
  napi_property_attributes attributes,
3154
4407
  void* data) {
3155
- InstanceVoidMethodCallbackData* callbackData =
3156
- new InstanceVoidMethodCallbackData({ method, data});
4408
+ StaticAccessorCallbackData* callbackData =
4409
+ new StaticAccessorCallbackData({ getter, setter, data });
3157
4410
 
3158
4411
  napi_property_descriptor desc = napi_property_descriptor();
3159
- desc.name = name;
3160
- desc.method = T::InstanceVoidMethodCallbackWrapper;
4412
+ desc.utf8name = utf8name;
4413
+ desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
4414
+ desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
3161
4415
  desc.data = callbackData;
3162
- desc.attributes = attributes;
4416
+ desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3163
4417
  return desc;
3164
4418
  }
3165
4419
 
3166
4420
  template <typename T>
3167
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
4421
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
3168
4422
  Symbol name,
3169
- InstanceMethodCallback method,
4423
+ StaticGetterCallback getter,
4424
+ StaticSetterCallback setter,
3170
4425
  napi_property_attributes attributes,
3171
4426
  void* data) {
3172
- InstanceMethodCallbackData* callbackData = new InstanceMethodCallbackData({ method, data });
4427
+ StaticAccessorCallbackData* callbackData =
4428
+ new StaticAccessorCallbackData({ getter, setter, data });
3173
4429
 
3174
4430
  napi_property_descriptor desc = napi_property_descriptor();
3175
4431
  desc.name = name;
3176
- desc.method = T::InstanceMethodCallbackWrapper;
4432
+ desc.getter = getter != nullptr ? T::StaticGetterCallbackWrapper : nullptr;
4433
+ desc.setter = setter != nullptr ? T::StaticSetterCallbackWrapper : nullptr;
3177
4434
  desc.data = callbackData;
3178
- desc.attributes = attributes;
4435
+ desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3179
4436
  return desc;
3180
4437
  }
3181
4438
 
3182
4439
  template <typename T>
3183
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
4440
+ template <typename ObjectWrap<T>::StaticGetterCallback getter,
4441
+ typename ObjectWrap<T>::StaticSetterCallback setter>
4442
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
3184
4443
  const char* utf8name,
3185
- InstanceGetterCallback getter,
3186
- InstanceSetterCallback setter,
3187
4444
  napi_property_attributes attributes,
3188
4445
  void* data) {
3189
- InstanceAccessorCallbackData* callbackData =
3190
- new InstanceAccessorCallbackData({ getter, setter, data });
3191
-
3192
4446
  napi_property_descriptor desc = napi_property_descriptor();
3193
4447
  desc.utf8name = utf8name;
3194
- desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
3195
- desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
3196
- desc.data = callbackData;
3197
- desc.attributes = attributes;
4448
+ desc.getter = details::TemplatedCallback<getter>;
4449
+ desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
4450
+ desc.data = data;
4451
+ desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3198
4452
  return desc;
3199
4453
  }
3200
4454
 
3201
4455
  template <typename T>
3202
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
4456
+ template <typename ObjectWrap<T>::StaticGetterCallback getter,
4457
+ typename ObjectWrap<T>::StaticSetterCallback setter>
4458
+ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
3203
4459
  Symbol name,
3204
- InstanceGetterCallback getter,
3205
- InstanceSetterCallback setter,
3206
4460
  napi_property_attributes attributes,
3207
4461
  void* data) {
3208
- InstanceAccessorCallbackData* callbackData =
3209
- new InstanceAccessorCallbackData({ getter, setter, data });
3210
-
3211
4462
  napi_property_descriptor desc = napi_property_descriptor();
3212
4463
  desc.name = name;
3213
- desc.getter = getter != nullptr ? T::InstanceGetterCallbackWrapper : nullptr;
3214
- desc.setter = setter != nullptr ? T::InstanceSetterCallbackWrapper : nullptr;
3215
- desc.data = callbackData;
3216
- desc.attributes = attributes;
4464
+ desc.getter = details::TemplatedCallback<getter>;
4465
+ desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
4466
+ desc.data = data;
4467
+ desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
3217
4468
  return desc;
3218
4469
  }
3219
4470
 
@@ -3238,28 +4489,16 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticValue(Symbol name,
3238
4489
  }
3239
4490
 
3240
4491
  template <typename T>
3241
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceValue(
3242
- const char* utf8name,
3243
- Napi::Value value,
3244
- napi_property_attributes attributes) {
3245
- napi_property_descriptor desc = napi_property_descriptor();
3246
- desc.utf8name = utf8name;
3247
- desc.value = value;
3248
- desc.attributes = attributes;
3249
- return desc;
4492
+ inline Value ObjectWrap<T>::OnCalledAsFunction(
4493
+ const Napi::CallbackInfo& callbackInfo) {
4494
+ NAPI_THROW(
4495
+ TypeError::New(callbackInfo.Env(),
4496
+ "Class constructors cannot be invoked without 'new'"),
4497
+ Napi::Value());
3250
4498
  }
3251
4499
 
3252
4500
  template <typename T>
3253
- inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceValue(
3254
- Symbol name,
3255
- Napi::Value value,
3256
- napi_property_attributes attributes) {
3257
- napi_property_descriptor desc = napi_property_descriptor();
3258
- desc.name = name;
3259
- desc.value = value;
3260
- desc.attributes = attributes;
3261
- return desc;
3262
- }
4501
+ inline void ObjectWrap<T>::Finalize(Napi::Env /*env*/) {}
3263
4502
 
3264
4503
  template <typename T>
3265
4504
  inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
@@ -3271,14 +4510,25 @@ inline napi_value ObjectWrap<T>::ConstructorCallbackWrapper(
3271
4510
 
3272
4511
  bool isConstructCall = (new_target != nullptr);
3273
4512
  if (!isConstructCall) {
3274
- napi_throw_type_error(env, nullptr, "Class constructors cannot be invoked without 'new'");
3275
- return nullptr;
4513
+ return details::WrapCallback(
4514
+ [&] { return T::OnCalledAsFunction(CallbackInfo(env, info)); });
3276
4515
  }
3277
4516
 
3278
- T* instance;
3279
4517
  napi_value wrapper = details::WrapCallback([&] {
3280
4518
  CallbackInfo callbackInfo(env, info);
3281
- instance = new T(callbackInfo);
4519
+ T* instance = new T(callbackInfo);
4520
+ #ifdef NAPI_CPP_EXCEPTIONS
4521
+ instance->_construction_failed = false;
4522
+ #else
4523
+ if (callbackInfo.Env().IsExceptionPending()) {
4524
+ // We need to clear the exception so that removing the wrap might work.
4525
+ Error e = callbackInfo.Env().GetAndClearPendingException();
4526
+ delete instance;
4527
+ e.ThrowAsJavaScriptException();
4528
+ } else {
4529
+ instance->_construction_failed = false;
4530
+ }
4531
+ # endif // NAPI_CPP_EXCEPTIONS
3282
4532
  return callbackInfo.This();
3283
4533
  });
3284
4534
 
@@ -3340,73 +4590,24 @@ inline napi_value ObjectWrap<T>::StaticSetterCallbackWrapper(
3340
4590
  }
3341
4591
 
3342
4592
  template <typename T>
3343
- inline napi_value ObjectWrap<T>::InstanceVoidMethodCallbackWrapper(
3344
- napi_env env,
3345
- napi_callback_info info) {
3346
- return details::WrapCallback([&] {
3347
- CallbackInfo callbackInfo(env, info);
3348
- InstanceVoidMethodCallbackData* callbackData =
3349
- reinterpret_cast<InstanceVoidMethodCallbackData*>(callbackInfo.Data());
3350
- callbackInfo.SetData(callbackData->data);
3351
- T* instance = Unwrap(callbackInfo.This().As<Object>());
3352
- auto cb = callbackData->callback;
3353
- (instance->*cb)(callbackInfo);
3354
- return nullptr;
3355
- });
3356
- }
3357
-
3358
- template <typename T>
3359
- inline napi_value ObjectWrap<T>::InstanceMethodCallbackWrapper(
3360
- napi_env env,
3361
- napi_callback_info info) {
3362
- return details::WrapCallback([&] {
3363
- CallbackInfo callbackInfo(env, info);
3364
- InstanceMethodCallbackData* callbackData =
3365
- reinterpret_cast<InstanceMethodCallbackData*>(callbackInfo.Data());
3366
- callbackInfo.SetData(callbackData->data);
3367
- T* instance = Unwrap(callbackInfo.This().As<Object>());
3368
- auto cb = callbackData->callback;
3369
- return (instance->*cb)(callbackInfo);
3370
- });
3371
- }
3372
-
3373
- template <typename T>
3374
- inline napi_value ObjectWrap<T>::InstanceGetterCallbackWrapper(
3375
- napi_env env,
3376
- napi_callback_info info) {
3377
- return details::WrapCallback([&] {
3378
- CallbackInfo callbackInfo(env, info);
3379
- InstanceAccessorCallbackData* callbackData =
3380
- reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
3381
- callbackInfo.SetData(callbackData->data);
3382
- T* instance = Unwrap(callbackInfo.This().As<Object>());
3383
- auto cb = callbackData->getterCallback;
3384
- return (instance->*cb)(callbackInfo);
3385
- });
4593
+ inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hint*/) {
4594
+ HandleScope scope(env);
4595
+ T* instance = static_cast<T*>(data);
4596
+ instance->Finalize(Napi::Env(env));
4597
+ delete instance;
3386
4598
  }
3387
4599
 
3388
4600
  template <typename T>
3389
- inline napi_value ObjectWrap<T>::InstanceSetterCallbackWrapper(
3390
- napi_env env,
3391
- napi_callback_info info) {
4601
+ template <typename ObjectWrap<T>::StaticSetterCallback method>
4602
+ inline napi_value ObjectWrap<T>::WrappedMethod(
4603
+ napi_env env, napi_callback_info info) NAPI_NOEXCEPT {
3392
4604
  return details::WrapCallback([&] {
3393
- CallbackInfo callbackInfo(env, info);
3394
- InstanceAccessorCallbackData* callbackData =
3395
- reinterpret_cast<InstanceAccessorCallbackData*>(callbackInfo.Data());
3396
- callbackInfo.SetData(callbackData->data);
3397
- T* instance = Unwrap(callbackInfo.This().As<Object>());
3398
- auto cb = callbackData->setterCallback;
3399
- (instance->*cb)(callbackInfo, callbackInfo[0]);
4605
+ const CallbackInfo cbInfo(env, info);
4606
+ method(cbInfo, cbInfo[0]);
3400
4607
  return nullptr;
3401
4608
  });
3402
4609
  }
3403
4610
 
3404
- template <typename T>
3405
- inline void ObjectWrap<T>::FinalizeCallback(napi_env /*env*/, void* data, void* /*hint*/) {
3406
- T* instance = reinterpret_cast<T*>(data);
3407
- delete instance;
3408
- }
3409
-
3410
4611
  ////////////////////////////////////////////////////////////////////////////////
3411
4612
  // HandleScope class
3412
4613
  ////////////////////////////////////////////////////////////////////////////////
@@ -3421,7 +4622,10 @@ inline HandleScope::HandleScope(Napi::Env env) : _env(env) {
3421
4622
  }
3422
4623
 
3423
4624
  inline HandleScope::~HandleScope() {
3424
- napi_close_handle_scope(_env, _scope);
4625
+ napi_status status = napi_close_handle_scope(_env, _scope);
4626
+ NAPI_FATAL_IF_FAILED(status,
4627
+ "HandleScope::~HandleScope",
4628
+ "napi_close_handle_scope");
3425
4629
  }
3426
4630
 
3427
4631
  inline HandleScope::operator napi_handle_scope() const {
@@ -3446,7 +4650,10 @@ inline EscapableHandleScope::EscapableHandleScope(Napi::Env env) : _env(env) {
3446
4650
  }
3447
4651
 
3448
4652
  inline EscapableHandleScope::~EscapableHandleScope() {
3449
- napi_close_escapable_handle_scope(_env, _scope);
4653
+ napi_status status = napi_close_escapable_handle_scope(_env, _scope);
4654
+ NAPI_FATAL_IF_FAILED(status,
4655
+ "EscapableHandleScope::~EscapableHandleScope",
4656
+ "napi_close_escapable_handle_scope");
3450
4657
  }
3451
4658
 
3452
4659
  inline EscapableHandleScope::operator napi_escapable_handle_scope() const {
@@ -3482,7 +4689,10 @@ inline CallbackScope::CallbackScope(napi_env env, napi_async_context context)
3482
4689
  }
3483
4690
 
3484
4691
  inline CallbackScope::~CallbackScope() {
3485
- napi_close_callback_scope(_env, _scope);
4692
+ napi_status status = napi_close_callback_scope(_env, _scope);
4693
+ NAPI_FATAL_IF_FAILED(status,
4694
+ "CallbackScope::~CallbackScope",
4695
+ "napi_close_callback_scope");
3486
4696
  }
3487
4697
 
3488
4698
  inline CallbackScope::operator napi_callback_scope() const {
@@ -3503,10 +4713,9 @@ inline AsyncContext::AsyncContext(napi_env env, const char* resource_name)
3503
4713
  }
3504
4714
 
3505
4715
  inline AsyncContext::AsyncContext(napi_env env,
3506
- const char* resource_name,
4716
+ const char* resource_name,
3507
4717
  const Object& resource)
3508
- : _env(env),
3509
- _context(nullptr) {
4718
+ : _env(env), _context(nullptr) {
3510
4719
  napi_value resource_id;
3511
4720
  napi_status status = napi_create_string_utf8(
3512
4721
  _env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
@@ -3542,6 +4751,10 @@ inline AsyncContext::operator napi_async_context() const {
3542
4751
  return _context;
3543
4752
  }
3544
4753
 
4754
+ inline Napi::Env AsyncContext::Env() const {
4755
+ return Napi::Env(_env);
4756
+ }
4757
+
3545
4758
  ////////////////////////////////////////////////////////////////////////////////
3546
4759
  // AsyncWorker class
3547
4760
  ////////////////////////////////////////////////////////////////////////////////
@@ -3591,8 +4804,8 @@ inline AsyncWorker::AsyncWorker(const Object& receiver,
3591
4804
  _env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
3592
4805
  NAPI_THROW_IF_FAILED_VOID(_env, status);
3593
4806
 
3594
- status = napi_create_async_work(_env, resource, resource_id, OnExecute,
3595
- OnWorkComplete, this, &_work);
4807
+ status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute,
4808
+ OnAsyncWorkComplete, this, &_work);
3596
4809
  NAPI_THROW_IF_FAILED_VOID(_env, status);
3597
4810
  }
3598
4811
 
@@ -3617,132 +4830,627 @@ inline AsyncWorker::AsyncWorker(Napi::Env env,
3617
4830
  _env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
3618
4831
  NAPI_THROW_IF_FAILED_VOID(_env, status);
3619
4832
 
3620
- status = napi_create_async_work(_env, resource, resource_id, OnExecute,
3621
- OnWorkComplete, this, &_work);
3622
- NAPI_THROW_IF_FAILED_VOID(_env, status);
4833
+ status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute,
4834
+ OnAsyncWorkComplete, this, &_work);
4835
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
4836
+ }
4837
+
4838
+ inline AsyncWorker::~AsyncWorker() {
4839
+ if (_work != nullptr) {
4840
+ napi_delete_async_work(_env, _work);
4841
+ _work = nullptr;
4842
+ }
4843
+ }
4844
+
4845
+ inline void AsyncWorker::Destroy() {
4846
+ delete this;
4847
+ }
4848
+
4849
+ inline AsyncWorker::AsyncWorker(AsyncWorker&& other) {
4850
+ _env = other._env;
4851
+ other._env = nullptr;
4852
+ _work = other._work;
4853
+ other._work = nullptr;
4854
+ _receiver = std::move(other._receiver);
4855
+ _callback = std::move(other._callback);
4856
+ _error = std::move(other._error);
4857
+ _suppress_destruct = other._suppress_destruct;
4858
+ }
4859
+
4860
+ inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) {
4861
+ _env = other._env;
4862
+ other._env = nullptr;
4863
+ _work = other._work;
4864
+ other._work = nullptr;
4865
+ _receiver = std::move(other._receiver);
4866
+ _callback = std::move(other._callback);
4867
+ _error = std::move(other._error);
4868
+ _suppress_destruct = other._suppress_destruct;
4869
+ return *this;
4870
+ }
4871
+
4872
+ inline AsyncWorker::operator napi_async_work() const {
4873
+ return _work;
4874
+ }
4875
+
4876
+ inline Napi::Env AsyncWorker::Env() const {
4877
+ return Napi::Env(_env);
4878
+ }
4879
+
4880
+ inline void AsyncWorker::Queue() {
4881
+ napi_status status = napi_queue_async_work(_env, _work);
4882
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
4883
+ }
4884
+
4885
+ inline void AsyncWorker::Cancel() {
4886
+ napi_status status = napi_cancel_async_work(_env, _work);
4887
+ NAPI_THROW_IF_FAILED_VOID(_env, status);
4888
+ }
4889
+
4890
+ inline ObjectReference& AsyncWorker::Receiver() {
4891
+ return _receiver;
4892
+ }
4893
+
4894
+ inline FunctionReference& AsyncWorker::Callback() {
4895
+ return _callback;
4896
+ }
4897
+
4898
+ inline void AsyncWorker::SuppressDestruct() {
4899
+ _suppress_destruct = true;
4900
+ }
4901
+
4902
+ inline void AsyncWorker::OnOK() {
4903
+ if (!_callback.IsEmpty()) {
4904
+ _callback.Call(_receiver.Value(), GetResult(_callback.Env()));
4905
+ }
4906
+ }
4907
+
4908
+ inline void AsyncWorker::OnError(const Error& e) {
4909
+ if (!_callback.IsEmpty()) {
4910
+ _callback.Call(_receiver.Value(), std::initializer_list<napi_value>{ e.Value() });
4911
+ }
4912
+ }
4913
+
4914
+ inline void AsyncWorker::SetError(const std::string& error) {
4915
+ _error = error;
4916
+ }
4917
+
4918
+ inline std::vector<napi_value> AsyncWorker::GetResult(Napi::Env /*env*/) {
4919
+ return {};
4920
+ }
4921
+ // The OnAsyncWorkExecute method receives an napi_env argument. However, do NOT
4922
+ // use it within this method, as it does not run on the JavaScript thread and
4923
+ // must not run any method that would cause JavaScript to run. In practice,
4924
+ // this means that almost any use of napi_env will be incorrect.
4925
+ inline void AsyncWorker::OnAsyncWorkExecute(napi_env env, void* asyncworker) {
4926
+ AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
4927
+ self->OnExecute(env);
4928
+ }
4929
+ // The OnExecute method receives an napi_env argument. However, do NOT
4930
+ // use it within this method, as it does not run on the JavaScript thread and
4931
+ // must not run any method that would cause JavaScript to run. In practice,
4932
+ // this means that almost any use of napi_env will be incorrect.
4933
+ inline void AsyncWorker::OnExecute(Napi::Env /*DO_NOT_USE*/) {
4934
+ #ifdef NAPI_CPP_EXCEPTIONS
4935
+ try {
4936
+ Execute();
4937
+ } catch (const std::exception& e) {
4938
+ SetError(e.what());
4939
+ }
4940
+ #else // NAPI_CPP_EXCEPTIONS
4941
+ Execute();
4942
+ #endif // NAPI_CPP_EXCEPTIONS
4943
+ }
4944
+
4945
+ inline void AsyncWorker::OnAsyncWorkComplete(napi_env env,
4946
+ napi_status status,
4947
+ void* asyncworker) {
4948
+ AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
4949
+ self->OnWorkComplete(env, status);
4950
+ }
4951
+ inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) {
4952
+ if (status != napi_cancelled) {
4953
+ HandleScope scope(_env);
4954
+ details::WrapCallback([&] {
4955
+ if (_error.size() == 0) {
4956
+ OnOK();
4957
+ }
4958
+ else {
4959
+ OnError(Error::New(_env, _error));
4960
+ }
4961
+ return nullptr;
4962
+ });
4963
+ }
4964
+ if (!_suppress_destruct) {
4965
+ Destroy();
4966
+ }
4967
+ }
4968
+
4969
+ #if (NAPI_VERSION > 3 && !defined(__wasm32__))
4970
+ ////////////////////////////////////////////////////////////////////////////////
4971
+ // TypedThreadSafeFunction<ContextType,DataType,CallJs> class
4972
+ ////////////////////////////////////////////////////////////////////////////////
4973
+
4974
+ // Starting with NAPI 5, the JavaScript function `func` parameter of
4975
+ // `napi_create_threadsafe_function` is optional.
4976
+ #if NAPI_VERSION > 4
4977
+ // static, with Callback [missing] Resource [missing] Finalizer [missing]
4978
+ template <typename ContextType,
4979
+ typename DataType,
4980
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
4981
+ template <typename ResourceString>
4982
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
4983
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
4984
+ napi_env env,
4985
+ ResourceString resourceName,
4986
+ size_t maxQueueSize,
4987
+ size_t initialThreadCount,
4988
+ ContextType* context) {
4989
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
4990
+
4991
+ napi_status status =
4992
+ napi_create_threadsafe_function(env,
4993
+ nullptr,
4994
+ nullptr,
4995
+ String::From(env, resourceName),
4996
+ maxQueueSize,
4997
+ initialThreadCount,
4998
+ nullptr,
4999
+ nullptr,
5000
+ context,
5001
+ CallJsInternal,
5002
+ &tsfn._tsfn);
5003
+ if (status != napi_ok) {
5004
+ NAPI_THROW_IF_FAILED(
5005
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5006
+ }
5007
+
5008
+ return tsfn;
5009
+ }
5010
+
5011
+ // static, with Callback [missing] Resource [passed] Finalizer [missing]
5012
+ template <typename ContextType,
5013
+ typename DataType,
5014
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5015
+ template <typename ResourceString>
5016
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5017
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5018
+ napi_env env,
5019
+ const Object& resource,
5020
+ ResourceString resourceName,
5021
+ size_t maxQueueSize,
5022
+ size_t initialThreadCount,
5023
+ ContextType* context) {
5024
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5025
+
5026
+ napi_status status =
5027
+ napi_create_threadsafe_function(env,
5028
+ nullptr,
5029
+ resource,
5030
+ String::From(env, resourceName),
5031
+ maxQueueSize,
5032
+ initialThreadCount,
5033
+ nullptr,
5034
+ nullptr,
5035
+ context,
5036
+ CallJsInternal,
5037
+ &tsfn._tsfn);
5038
+ if (status != napi_ok) {
5039
+ NAPI_THROW_IF_FAILED(
5040
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5041
+ }
5042
+
5043
+ return tsfn;
5044
+ }
5045
+
5046
+ // static, with Callback [missing] Resource [missing] Finalizer [passed]
5047
+ template <typename ContextType,
5048
+ typename DataType,
5049
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5050
+ template <typename ResourceString,
5051
+ typename Finalizer,
5052
+ typename FinalizerDataType>
5053
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5054
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5055
+ napi_env env,
5056
+ ResourceString resourceName,
5057
+ size_t maxQueueSize,
5058
+ size_t initialThreadCount,
5059
+ ContextType* context,
5060
+ Finalizer finalizeCallback,
5061
+ FinalizerDataType* data) {
5062
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5063
+
5064
+ auto* finalizeData = new details::
5065
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5066
+ {data, finalizeCallback});
5067
+ napi_status status = napi_create_threadsafe_function(
5068
+ env,
5069
+ nullptr,
5070
+ nullptr,
5071
+ String::From(env, resourceName),
5072
+ maxQueueSize,
5073
+ initialThreadCount,
5074
+ finalizeData,
5075
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5076
+ FinalizeFinalizeWrapperWithDataAndContext,
5077
+ context,
5078
+ CallJsInternal,
5079
+ &tsfn._tsfn);
5080
+ if (status != napi_ok) {
5081
+ delete finalizeData;
5082
+ NAPI_THROW_IF_FAILED(
5083
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5084
+ }
5085
+
5086
+ return tsfn;
5087
+ }
5088
+
5089
+ // static, with Callback [missing] Resource [passed] Finalizer [passed]
5090
+ template <typename ContextType,
5091
+ typename DataType,
5092
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5093
+ template <typename ResourceString,
5094
+ typename Finalizer,
5095
+ typename FinalizerDataType>
5096
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5097
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5098
+ napi_env env,
5099
+ const Object& resource,
5100
+ ResourceString resourceName,
5101
+ size_t maxQueueSize,
5102
+ size_t initialThreadCount,
5103
+ ContextType* context,
5104
+ Finalizer finalizeCallback,
5105
+ FinalizerDataType* data) {
5106
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5107
+
5108
+ auto* finalizeData = new details::
5109
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5110
+ {data, finalizeCallback});
5111
+ napi_status status = napi_create_threadsafe_function(
5112
+ env,
5113
+ nullptr,
5114
+ resource,
5115
+ String::From(env, resourceName),
5116
+ maxQueueSize,
5117
+ initialThreadCount,
5118
+ finalizeData,
5119
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5120
+ FinalizeFinalizeWrapperWithDataAndContext,
5121
+ context,
5122
+ CallJsInternal,
5123
+ &tsfn._tsfn);
5124
+ if (status != napi_ok) {
5125
+ delete finalizeData;
5126
+ NAPI_THROW_IF_FAILED(
5127
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5128
+ }
5129
+
5130
+ return tsfn;
5131
+ }
5132
+ #endif
5133
+
5134
+ // static, with Callback [passed] Resource [missing] Finalizer [missing]
5135
+ template <typename ContextType,
5136
+ typename DataType,
5137
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5138
+ template <typename ResourceString>
5139
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5140
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5141
+ napi_env env,
5142
+ const Function& callback,
5143
+ ResourceString resourceName,
5144
+ size_t maxQueueSize,
5145
+ size_t initialThreadCount,
5146
+ ContextType* context) {
5147
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5148
+
5149
+ napi_status status =
5150
+ napi_create_threadsafe_function(env,
5151
+ callback,
5152
+ nullptr,
5153
+ String::From(env, resourceName),
5154
+ maxQueueSize,
5155
+ initialThreadCount,
5156
+ nullptr,
5157
+ nullptr,
5158
+ context,
5159
+ CallJsInternal,
5160
+ &tsfn._tsfn);
5161
+ if (status != napi_ok) {
5162
+ NAPI_THROW_IF_FAILED(
5163
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5164
+ }
5165
+
5166
+ return tsfn;
3623
5167
  }
3624
5168
 
3625
- inline AsyncWorker::~AsyncWorker() {
3626
- if (_work != nullptr) {
3627
- napi_delete_async_work(_env, _work);
3628
- _work = nullptr;
5169
+ // static, with Callback [passed] Resource [passed] Finalizer [missing]
5170
+ template <typename ContextType,
5171
+ typename DataType,
5172
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5173
+ template <typename ResourceString>
5174
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5175
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5176
+ napi_env env,
5177
+ const Function& callback,
5178
+ const Object& resource,
5179
+ ResourceString resourceName,
5180
+ size_t maxQueueSize,
5181
+ size_t initialThreadCount,
5182
+ ContextType* context) {
5183
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5184
+
5185
+ napi_status status =
5186
+ napi_create_threadsafe_function(env,
5187
+ callback,
5188
+ resource,
5189
+ String::From(env, resourceName),
5190
+ maxQueueSize,
5191
+ initialThreadCount,
5192
+ nullptr,
5193
+ nullptr,
5194
+ context,
5195
+ CallJsInternal,
5196
+ &tsfn._tsfn);
5197
+ if (status != napi_ok) {
5198
+ NAPI_THROW_IF_FAILED(
5199
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
3629
5200
  }
3630
- }
3631
5201
 
3632
- inline void AsyncWorker::Destroy() {
3633
- delete this;
5202
+ return tsfn;
3634
5203
  }
3635
5204
 
3636
- inline AsyncWorker::AsyncWorker(AsyncWorker&& other) {
3637
- _env = other._env;
3638
- other._env = nullptr;
3639
- _work = other._work;
3640
- other._work = nullptr;
3641
- _receiver = std::move(other._receiver);
3642
- _callback = std::move(other._callback);
3643
- _error = std::move(other._error);
3644
- _suppress_destruct = other._suppress_destruct;
5205
+ // static, with Callback [passed] Resource [missing] Finalizer [passed]
5206
+ template <typename ContextType,
5207
+ typename DataType,
5208
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5209
+ template <typename ResourceString,
5210
+ typename Finalizer,
5211
+ typename FinalizerDataType>
5212
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5213
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5214
+ napi_env env,
5215
+ const Function& callback,
5216
+ ResourceString resourceName,
5217
+ size_t maxQueueSize,
5218
+ size_t initialThreadCount,
5219
+ ContextType* context,
5220
+ Finalizer finalizeCallback,
5221
+ FinalizerDataType* data) {
5222
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5223
+
5224
+ auto* finalizeData = new details::
5225
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5226
+ {data, finalizeCallback});
5227
+ napi_status status = napi_create_threadsafe_function(
5228
+ env,
5229
+ callback,
5230
+ nullptr,
5231
+ String::From(env, resourceName),
5232
+ maxQueueSize,
5233
+ initialThreadCount,
5234
+ finalizeData,
5235
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5236
+ FinalizeFinalizeWrapperWithDataAndContext,
5237
+ context,
5238
+ CallJsInternal,
5239
+ &tsfn._tsfn);
5240
+ if (status != napi_ok) {
5241
+ delete finalizeData;
5242
+ NAPI_THROW_IF_FAILED(
5243
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5244
+ }
5245
+
5246
+ return tsfn;
3645
5247
  }
3646
5248
 
3647
- inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) {
3648
- _env = other._env;
3649
- other._env = nullptr;
3650
- _work = other._work;
3651
- other._work = nullptr;
3652
- _receiver = std::move(other._receiver);
3653
- _callback = std::move(other._callback);
3654
- _error = std::move(other._error);
3655
- _suppress_destruct = other._suppress_destruct;
3656
- return *this;
5249
+ // static, with: Callback [passed] Resource [passed] Finalizer [passed]
5250
+ template <typename ContextType,
5251
+ typename DataType,
5252
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5253
+ template <typename CallbackType,
5254
+ typename ResourceString,
5255
+ typename Finalizer,
5256
+ typename FinalizerDataType>
5257
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>
5258
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::New(
5259
+ napi_env env,
5260
+ CallbackType callback,
5261
+ const Object& resource,
5262
+ ResourceString resourceName,
5263
+ size_t maxQueueSize,
5264
+ size_t initialThreadCount,
5265
+ ContextType* context,
5266
+ Finalizer finalizeCallback,
5267
+ FinalizerDataType* data) {
5268
+ TypedThreadSafeFunction<ContextType, DataType, CallJs> tsfn;
5269
+
5270
+ auto* finalizeData = new details::
5271
+ ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>(
5272
+ {data, finalizeCallback});
5273
+ napi_status status = napi_create_threadsafe_function(
5274
+ env,
5275
+ details::DefaultCallbackWrapper<
5276
+ CallbackType,
5277
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>>(env,
5278
+ callback),
5279
+ resource,
5280
+ String::From(env, resourceName),
5281
+ maxQueueSize,
5282
+ initialThreadCount,
5283
+ finalizeData,
5284
+ details::ThreadSafeFinalize<ContextType, Finalizer, FinalizerDataType>::
5285
+ FinalizeFinalizeWrapperWithDataAndContext,
5286
+ context,
5287
+ CallJsInternal,
5288
+ &tsfn._tsfn);
5289
+ if (status != napi_ok) {
5290
+ delete finalizeData;
5291
+ NAPI_THROW_IF_FAILED(
5292
+ env, status, TypedThreadSafeFunction<ContextType, DataType, CallJs>());
5293
+ }
5294
+
5295
+ return tsfn;
3657
5296
  }
3658
5297
 
3659
- inline AsyncWorker::operator napi_async_work() const {
3660
- return _work;
5298
+ template <typename ContextType,
5299
+ typename DataType,
5300
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5301
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
5302
+ TypedThreadSafeFunction()
5303
+ : _tsfn() {}
5304
+
5305
+ template <typename ContextType,
5306
+ typename DataType,
5307
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5308
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
5309
+ TypedThreadSafeFunction(napi_threadsafe_function tsfn)
5310
+ : _tsfn(tsfn) {}
5311
+
5312
+ template <typename ContextType,
5313
+ typename DataType,
5314
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5315
+ inline TypedThreadSafeFunction<ContextType, DataType, CallJs>::
5316
+ operator napi_threadsafe_function() const {
5317
+ return _tsfn;
5318
+ }
5319
+
5320
+ template <typename ContextType,
5321
+ typename DataType,
5322
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5323
+ inline napi_status
5324
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::BlockingCall(
5325
+ DataType* data) const {
5326
+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking);
5327
+ }
5328
+
5329
+ template <typename ContextType,
5330
+ typename DataType,
5331
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5332
+ inline napi_status
5333
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::NonBlockingCall(
5334
+ DataType* data) const {
5335
+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking);
5336
+ }
5337
+
5338
+ template <typename ContextType,
5339
+ typename DataType,
5340
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5341
+ inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Ref(
5342
+ napi_env env) const {
5343
+ if (_tsfn != nullptr) {
5344
+ napi_status status = napi_ref_threadsafe_function(env, _tsfn);
5345
+ NAPI_THROW_IF_FAILED_VOID(env, status);
5346
+ }
3661
5347
  }
3662
5348
 
3663
- inline Napi::Env AsyncWorker::Env() const {
3664
- return Napi::Env(_env);
5349
+ template <typename ContextType,
5350
+ typename DataType,
5351
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5352
+ inline void TypedThreadSafeFunction<ContextType, DataType, CallJs>::Unref(
5353
+ napi_env env) const {
5354
+ if (_tsfn != nullptr) {
5355
+ napi_status status = napi_unref_threadsafe_function(env, _tsfn);
5356
+ NAPI_THROW_IF_FAILED_VOID(env, status);
5357
+ }
3665
5358
  }
3666
5359
 
3667
- inline void AsyncWorker::Queue() {
3668
- napi_status status = napi_queue_async_work(_env, _work);
3669
- NAPI_THROW_IF_FAILED_VOID(_env, status);
5360
+ template <typename ContextType,
5361
+ typename DataType,
5362
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5363
+ inline napi_status
5364
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::Acquire() const {
5365
+ return napi_acquire_threadsafe_function(_tsfn);
3670
5366
  }
3671
5367
 
3672
- inline void AsyncWorker::Cancel() {
3673
- napi_status status = napi_cancel_async_work(_env, _work);
3674
- NAPI_THROW_IF_FAILED_VOID(_env, status);
5368
+ template <typename ContextType,
5369
+ typename DataType,
5370
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5371
+ inline napi_status
5372
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::Release() const {
5373
+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_release);
3675
5374
  }
3676
5375
 
3677
- inline ObjectReference& AsyncWorker::Receiver() {
3678
- return _receiver;
5376
+ template <typename ContextType,
5377
+ typename DataType,
5378
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5379
+ inline napi_status
5380
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::Abort() const {
5381
+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort);
3679
5382
  }
3680
5383
 
3681
- inline FunctionReference& AsyncWorker::Callback() {
3682
- return _callback;
5384
+ template <typename ContextType,
5385
+ typename DataType,
5386
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5387
+ inline ContextType*
5388
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::GetContext() const {
5389
+ void* context;
5390
+ napi_status status = napi_get_threadsafe_function_context(_tsfn, &context);
5391
+ NAPI_FATAL_IF_FAILED(status,
5392
+ "TypedThreadSafeFunction::GetContext",
5393
+ "napi_get_threadsafe_function_context");
5394
+ return static_cast<ContextType*>(context);
3683
5395
  }
3684
5396
 
3685
- inline void AsyncWorker::SuppressDestruct() {
3686
- _suppress_destruct = true;
5397
+ // static
5398
+ template <typename ContextType,
5399
+ typename DataType,
5400
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5401
+ void TypedThreadSafeFunction<ContextType, DataType, CallJs>::CallJsInternal(
5402
+ napi_env env, napi_value jsCallback, void* context, void* data) {
5403
+ details::CallJsWrapper<ContextType, DataType, decltype(CallJs), CallJs>(
5404
+ env, jsCallback, context, data);
3687
5405
  }
3688
5406
 
3689
- inline void AsyncWorker::OnOK() {
3690
- if (!_callback.IsEmpty()) {
3691
- _callback.Call(_receiver.Value(), GetResult(_callback.Env()));
3692
- }
5407
+ #if NAPI_VERSION == 4
5408
+ // static
5409
+ template <typename ContextType,
5410
+ typename DataType,
5411
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5412
+ Napi::Function
5413
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
5414
+ Napi::Env env) {
5415
+ return Napi::Function::New(env, [](const CallbackInfo& cb) {});
3693
5416
  }
3694
5417
 
3695
- inline void AsyncWorker::OnError(const Error& e) {
3696
- if (!_callback.IsEmpty()) {
3697
- _callback.Call(_receiver.Value(), std::initializer_list<napi_value>{ e.Value() });
5418
+ // static
5419
+ template <typename ContextType,
5420
+ typename DataType,
5421
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5422
+ Napi::Function
5423
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
5424
+ Napi::Env env, Napi::Function& callback) {
5425
+ if (callback.IsEmpty()) {
5426
+ return EmptyFunctionFactory(env);
3698
5427
  }
5428
+ return callback;
3699
5429
  }
3700
5430
 
3701
- inline void AsyncWorker::SetError(const std::string& error) {
3702
- _error = error;
5431
+ #else
5432
+ // static
5433
+ template <typename ContextType,
5434
+ typename DataType,
5435
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5436
+ std::nullptr_t
5437
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::EmptyFunctionFactory(
5438
+ Napi::Env /*env*/) {
5439
+ return nullptr;
3703
5440
  }
3704
5441
 
3705
- inline std::vector<napi_value> AsyncWorker::GetResult(Napi::Env /*env*/) {
3706
- return {};
3707
- }
3708
- // The OnExecute method receives an napi_env argument. However, do NOT
3709
- // use it within this method, as it does not run on the main thread and must
3710
- // not run any method that would cause JavaScript to run. In practice, this
3711
- // means that almost any use of napi_env will be incorrect.
3712
- inline void AsyncWorker::OnExecute(napi_env /*DO_NOT_USE*/, void* this_pointer) {
3713
- AsyncWorker* self = static_cast<AsyncWorker*>(this_pointer);
3714
- #ifdef NAPI_CPP_EXCEPTIONS
3715
- try {
3716
- self->Execute();
3717
- } catch (const std::exception& e) {
3718
- self->SetError(e.what());
3719
- }
3720
- #else // NAPI_CPP_EXCEPTIONS
3721
- self->Execute();
3722
- #endif // NAPI_CPP_EXCEPTIONS
5442
+ // static
5443
+ template <typename ContextType,
5444
+ typename DataType,
5445
+ void (*CallJs)(Napi::Env, Napi::Function, ContextType*, DataType*)>
5446
+ Napi::Function
5447
+ TypedThreadSafeFunction<ContextType, DataType, CallJs>::FunctionOrEmpty(
5448
+ Napi::Env /*env*/, Napi::Function& callback) {
5449
+ return callback;
3723
5450
  }
3724
5451
 
3725
- inline void AsyncWorker::OnWorkComplete(
3726
- napi_env /*env*/, napi_status status, void* this_pointer) {
3727
- AsyncWorker* self = static_cast<AsyncWorker*>(this_pointer);
3728
- if (status != napi_cancelled) {
3729
- HandleScope scope(self->_env);
3730
- details::WrapCallback([&] {
3731
- if (self->_error.size() == 0) {
3732
- self->OnOK();
3733
- }
3734
- else {
3735
- self->OnError(Error::New(self->_env, self->_error));
3736
- }
3737
- return nullptr;
3738
- });
3739
- }
3740
- if (!self->_suppress_destruct) {
3741
- self->Destroy();
3742
- }
3743
- }
5452
+ #endif
3744
5453
 
3745
- #if (NAPI_VERSION > 3)
3746
5454
  ////////////////////////////////////////////////////////////////////////////////
3747
5455
  // ThreadSafeFunction class
3748
5456
  ////////////////////////////////////////////////////////////////////////////////
@@ -3919,35 +5627,28 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
3919
5627
  }
3920
5628
 
3921
5629
  inline ThreadSafeFunction::ThreadSafeFunction()
3922
- : _tsfn(new napi_threadsafe_function(nullptr)) {
5630
+ : _tsfn() {
3923
5631
  }
3924
5632
 
3925
5633
  inline ThreadSafeFunction::ThreadSafeFunction(
3926
5634
  napi_threadsafe_function tsfn)
3927
- : _tsfn(new napi_threadsafe_function(tsfn)) {
5635
+ : _tsfn(tsfn) {
3928
5636
  }
3929
5637
 
3930
- inline ThreadSafeFunction::ThreadSafeFunction(ThreadSafeFunction&& other)
3931
- : _tsfn(std::move(other._tsfn)) {
3932
- other._tsfn.reset();
3933
- }
3934
-
3935
- inline ThreadSafeFunction& ThreadSafeFunction::operator =(
3936
- ThreadSafeFunction&& other) {
3937
- if (*_tsfn != nullptr) {
3938
- Error::Fatal("ThreadSafeFunction::operator =",
3939
- "You cannot assign a new TSFN because existing one is still alive.");
3940
- return *this;
3941
- }
3942
- _tsfn = std::move(other._tsfn);
3943
- other._tsfn.reset();
3944
- return *this;
5638
+ inline ThreadSafeFunction::operator napi_threadsafe_function() const {
5639
+ return _tsfn;
3945
5640
  }
3946
5641
 
3947
5642
  inline napi_status ThreadSafeFunction::BlockingCall() const {
3948
5643
  return CallInternal(nullptr, napi_tsfn_blocking);
3949
5644
  }
3950
5645
 
5646
+ template <>
5647
+ inline napi_status ThreadSafeFunction::BlockingCall(
5648
+ void* data) const {
5649
+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_blocking);
5650
+ }
5651
+
3951
5652
  template <typename Callback>
3952
5653
  inline napi_status ThreadSafeFunction::BlockingCall(
3953
5654
  Callback callback) const {
@@ -3967,6 +5668,12 @@ inline napi_status ThreadSafeFunction::NonBlockingCall() const {
3967
5668
  return CallInternal(nullptr, napi_tsfn_nonblocking);
3968
5669
  }
3969
5670
 
5671
+ template <>
5672
+ inline napi_status ThreadSafeFunction::NonBlockingCall(
5673
+ void* data) const {
5674
+ return napi_call_threadsafe_function(_tsfn, data, napi_tsfn_nonblocking);
5675
+ }
5676
+
3970
5677
  template <typename Callback>
3971
5678
  inline napi_status ThreadSafeFunction::NonBlockingCall(
3972
5679
  Callback callback) const {
@@ -3982,22 +5689,37 @@ inline napi_status ThreadSafeFunction::NonBlockingCall(
3982
5689
  return CallInternal(new CallbackWrapper(wrapper), napi_tsfn_nonblocking);
3983
5690
  }
3984
5691
 
5692
+ inline void ThreadSafeFunction::Ref(napi_env env) const {
5693
+ if (_tsfn != nullptr) {
5694
+ napi_status status = napi_ref_threadsafe_function(env, _tsfn);
5695
+ NAPI_THROW_IF_FAILED_VOID(env, status);
5696
+ }
5697
+ }
5698
+
5699
+ inline void ThreadSafeFunction::Unref(napi_env env) const {
5700
+ if (_tsfn != nullptr) {
5701
+ napi_status status = napi_unref_threadsafe_function(env, _tsfn);
5702
+ NAPI_THROW_IF_FAILED_VOID(env, status);
5703
+ }
5704
+ }
5705
+
3985
5706
  inline napi_status ThreadSafeFunction::Acquire() const {
3986
- return napi_acquire_threadsafe_function(*_tsfn);
5707
+ return napi_acquire_threadsafe_function(_tsfn);
3987
5708
  }
3988
5709
 
3989
- inline napi_status ThreadSafeFunction::Release() {
3990
- return napi_release_threadsafe_function(*_tsfn, napi_tsfn_release);
5710
+ inline napi_status ThreadSafeFunction::Release() const {
5711
+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_release);
3991
5712
  }
3992
5713
 
3993
- inline napi_status ThreadSafeFunction::Abort() {
3994
- return napi_release_threadsafe_function(*_tsfn, napi_tsfn_abort);
5714
+ inline napi_status ThreadSafeFunction::Abort() const {
5715
+ return napi_release_threadsafe_function(_tsfn, napi_tsfn_abort);
3995
5716
  }
3996
5717
 
3997
5718
  inline ThreadSafeFunction::ConvertibleContext
3998
5719
  ThreadSafeFunction::GetContext() const {
3999
5720
  void* context;
4000
- napi_get_threadsafe_function_context(*_tsfn, &context);
5721
+ napi_status status = napi_get_threadsafe_function_context(_tsfn, &context);
5722
+ NAPI_FATAL_IF_FAILED(status, "ThreadSafeFunction::GetContext", "napi_get_threadsafe_function_context");
4001
5723
  return ConvertibleContext({ context });
4002
5724
  }
4003
5725
 
@@ -4020,10 +5742,10 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
4020
5742
 
4021
5743
  ThreadSafeFunction tsfn;
4022
5744
  auto* finalizeData = new details::ThreadSafeFinalize<ContextType, Finalizer,
4023
- FinalizerDataType>({ data, finalizeCallback, tsfn._tsfn.get() });
5745
+ FinalizerDataType>({ data, finalizeCallback });
4024
5746
  napi_status status = napi_create_threadsafe_function(env, callback, resource,
4025
5747
  Value::From(env, resourceName), maxQueueSize, initialThreadCount,
4026
- finalizeData, wrapper, context, CallJS, tsfn._tsfn.get());
5748
+ finalizeData, wrapper, context, CallJS, &tsfn._tsfn);
4027
5749
  if (status != napi_ok) {
4028
5750
  delete finalizeData;
4029
5751
  NAPI_THROW_IF_FAILED(env, status, ThreadSafeFunction());
@@ -4036,7 +5758,7 @@ inline napi_status ThreadSafeFunction::CallInternal(
4036
5758
  CallbackWrapper* callbackWrapper,
4037
5759
  napi_threadsafe_function_call_mode mode) const {
4038
5760
  napi_status status = napi_call_threadsafe_function(
4039
- *_tsfn, callbackWrapper, mode);
5761
+ _tsfn, callbackWrapper, mode);
4040
5762
  if (status != napi_ok && callbackWrapper != nullptr) {
4041
5763
  delete callbackWrapper;
4042
5764
  }
@@ -4061,8 +5783,354 @@ inline void ThreadSafeFunction::CallJS(napi_env env,
4061
5783
  Function(env, jsCallback).Call({});
4062
5784
  }
4063
5785
  }
5786
+
5787
+ ////////////////////////////////////////////////////////////////////////////////
5788
+ // Async Progress Worker Base class
5789
+ ////////////////////////////////////////////////////////////////////////////////
5790
+ template <typename DataType>
5791
+ inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(const Object& receiver,
5792
+ const Function& callback,
5793
+ const char* resource_name,
5794
+ const Object& resource,
5795
+ size_t queue_size)
5796
+ : AsyncWorker(receiver, callback, resource_name, resource) {
5797
+ // Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures.
5798
+ _tsfn = ThreadSafeFunction::New(callback.Env(),
5799
+ callback,
5800
+ resource,
5801
+ resource_name,
5802
+ queue_size,
5803
+ /** initialThreadCount */ 1,
5804
+ /** context */ this,
5805
+ OnThreadSafeFunctionFinalize,
5806
+ /** finalizeData */ this);
5807
+ }
5808
+
5809
+ #if NAPI_VERSION > 4
5810
+ template <typename DataType>
5811
+ inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(Napi::Env env,
5812
+ const char* resource_name,
5813
+ const Object& resource,
5814
+ size_t queue_size)
5815
+ : AsyncWorker(env, resource_name, resource) {
5816
+ // TODO: Once the changes to make the callback optional for threadsafe
5817
+ // functions are available on all versions we can remove the dummy Function here.
5818
+ Function callback;
5819
+ // Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures.
5820
+ _tsfn = ThreadSafeFunction::New(env,
5821
+ callback,
5822
+ resource,
5823
+ resource_name,
5824
+ queue_size,
5825
+ /** initialThreadCount */ 1,
5826
+ /** context */ this,
5827
+ OnThreadSafeFunctionFinalize,
5828
+ /** finalizeData */ this);
5829
+ }
5830
+ #endif
5831
+
5832
+ template<typename DataType>
5833
+ inline AsyncProgressWorkerBase<DataType>::~AsyncProgressWorkerBase() {
5834
+ // Abort pending tsfn call.
5835
+ // Don't send progress events after we've already completed.
5836
+ // It's ok to call ThreadSafeFunction::Abort and ThreadSafeFunction::Release duplicated.
5837
+ _tsfn.Abort();
5838
+ }
5839
+
5840
+ template <typename DataType>
5841
+ inline void AsyncProgressWorkerBase<DataType>::OnAsyncWorkProgress(Napi::Env /* env */,
5842
+ Napi::Function /* jsCallback */,
5843
+ void* data) {
5844
+ ThreadSafeData* tsd = static_cast<ThreadSafeData*>(data);
5845
+ tsd->asyncprogressworker()->OnWorkProgress(tsd->data());
5846
+ delete tsd;
5847
+ }
5848
+
5849
+ template <typename DataType>
5850
+ inline napi_status AsyncProgressWorkerBase<DataType>::NonBlockingCall(DataType* data) {
5851
+ auto tsd = new AsyncProgressWorkerBase::ThreadSafeData(this, data);
5852
+ return _tsfn.NonBlockingCall(tsd, OnAsyncWorkProgress);
5853
+ }
5854
+
5855
+ template <typename DataType>
5856
+ inline void AsyncProgressWorkerBase<DataType>::OnWorkComplete(Napi::Env /* env */, napi_status status) {
5857
+ _work_completed = true;
5858
+ _complete_status = status;
5859
+ _tsfn.Release();
5860
+ }
5861
+
5862
+ template <typename DataType>
5863
+ inline void AsyncProgressWorkerBase<DataType>::OnThreadSafeFunctionFinalize(Napi::Env env, void* /* data */, AsyncProgressWorkerBase* context) {
5864
+ if (context->_work_completed) {
5865
+ context->AsyncWorker::OnWorkComplete(env, context->_complete_status);
5866
+ }
5867
+ }
5868
+
5869
+ ////////////////////////////////////////////////////////////////////////////////
5870
+ // Async Progress Worker class
5871
+ ////////////////////////////////////////////////////////////////////////////////
5872
+ template<class T>
5873
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback)
5874
+ : AsyncProgressWorker(callback, "generic") {
5875
+ }
5876
+
5877
+ template<class T>
5878
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback,
5879
+ const char* resource_name)
5880
+ : AsyncProgressWorker(callback, resource_name, Object::New(callback.Env())) {
5881
+ }
5882
+
5883
+ template<class T>
5884
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback,
5885
+ const char* resource_name,
5886
+ const Object& resource)
5887
+ : AsyncProgressWorker(Object::New(callback.Env()),
5888
+ callback,
5889
+ resource_name,
5890
+ resource) {
5891
+ }
5892
+
5893
+ template<class T>
5894
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
5895
+ const Function& callback)
5896
+ : AsyncProgressWorker(receiver, callback, "generic") {
5897
+ }
5898
+
5899
+ template<class T>
5900
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
5901
+ const Function& callback,
5902
+ const char* resource_name)
5903
+ : AsyncProgressWorker(receiver,
5904
+ callback,
5905
+ resource_name,
5906
+ Object::New(callback.Env())) {
5907
+ }
5908
+
5909
+ template<class T>
5910
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
5911
+ const Function& callback,
5912
+ const char* resource_name,
5913
+ const Object& resource)
5914
+ : AsyncProgressWorkerBase(receiver, callback, resource_name, resource),
5915
+ _asyncdata(nullptr),
5916
+ _asyncsize(0) {
5917
+ }
5918
+
5919
+ #if NAPI_VERSION > 4
5920
+ template<class T>
5921
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env)
5922
+ : AsyncProgressWorker(env, "generic") {
5923
+ }
5924
+
5925
+ template<class T>
5926
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
5927
+ const char* resource_name)
5928
+ : AsyncProgressWorker(env, resource_name, Object::New(env)) {
5929
+ }
5930
+
5931
+ template<class T>
5932
+ inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
5933
+ const char* resource_name,
5934
+ const Object& resource)
5935
+ : AsyncProgressWorkerBase(env, resource_name, resource),
5936
+ _asyncdata(nullptr),
5937
+ _asyncsize(0) {
5938
+ }
5939
+ #endif
5940
+
5941
+ template<class T>
5942
+ inline AsyncProgressWorker<T>::~AsyncProgressWorker() {
5943
+ {
5944
+ std::lock_guard<std::mutex> lock(this->_mutex);
5945
+ _asyncdata = nullptr;
5946
+ _asyncsize = 0;
5947
+ }
5948
+ }
5949
+
5950
+ template<class T>
5951
+ inline void AsyncProgressWorker<T>::Execute() {
5952
+ ExecutionProgress progress(this);
5953
+ Execute(progress);
5954
+ }
5955
+
5956
+ template<class T>
5957
+ inline void AsyncProgressWorker<T>::OnWorkProgress(void*) {
5958
+ T* data;
5959
+ size_t size;
5960
+ {
5961
+ std::lock_guard<std::mutex> lock(this->_mutex);
5962
+ data = this->_asyncdata;
5963
+ size = this->_asyncsize;
5964
+ this->_asyncdata = nullptr;
5965
+ this->_asyncsize = 0;
5966
+ }
5967
+
5968
+ /**
5969
+ * The callback of ThreadSafeFunction is not been invoked immediately on the
5970
+ * callback of uv_async_t (uv io poll), rather the callback of TSFN is
5971
+ * invoked on the right next uv idle callback. There are chances that during
5972
+ * the deferring the signal of uv_async_t is been sent again, i.e. potential
5973
+ * not coalesced two calls of the TSFN callback.
5974
+ */
5975
+ if (data == nullptr) {
5976
+ return;
5977
+ }
5978
+
5979
+ this->OnProgress(data, size);
5980
+ delete[] data;
5981
+ }
5982
+
5983
+ template<class T>
5984
+ inline void AsyncProgressWorker<T>::SendProgress_(const T* data, size_t count) {
5985
+ T* new_data = new T[count];
5986
+ std::copy(data, data + count, new_data);
5987
+
5988
+ T* old_data;
5989
+ {
5990
+ std::lock_guard<std::mutex> lock(this->_mutex);
5991
+ old_data = _asyncdata;
5992
+ _asyncdata = new_data;
5993
+ _asyncsize = count;
5994
+ }
5995
+ this->NonBlockingCall(nullptr);
5996
+
5997
+ delete[] old_data;
5998
+ }
5999
+
6000
+ template<class T>
6001
+ inline void AsyncProgressWorker<T>::Signal() const {
6002
+ this->NonBlockingCall(static_cast<T*>(nullptr));
6003
+ }
6004
+
6005
+ template<class T>
6006
+ inline void AsyncProgressWorker<T>::ExecutionProgress::Signal() const {
6007
+ _worker->Signal();
6008
+ }
6009
+
6010
+ template<class T>
6011
+ inline void AsyncProgressWorker<T>::ExecutionProgress::Send(const T* data, size_t count) const {
6012
+ _worker->SendProgress_(data, count);
6013
+ }
6014
+
6015
+ ////////////////////////////////////////////////////////////////////////////////
6016
+ // Async Progress Queue Worker class
6017
+ ////////////////////////////////////////////////////////////////////////////////
6018
+ template<class T>
6019
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback)
6020
+ : AsyncProgressQueueWorker(callback, "generic") {
6021
+ }
6022
+
6023
+ template<class T>
6024
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback,
6025
+ const char* resource_name)
6026
+ : AsyncProgressQueueWorker(callback, resource_name, Object::New(callback.Env())) {
6027
+ }
6028
+
6029
+ template<class T>
6030
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback,
6031
+ const char* resource_name,
6032
+ const Object& resource)
6033
+ : AsyncProgressQueueWorker(Object::New(callback.Env()),
6034
+ callback,
6035
+ resource_name,
6036
+ resource) {
6037
+ }
6038
+
6039
+ template<class T>
6040
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
6041
+ const Function& callback)
6042
+ : AsyncProgressQueueWorker(receiver, callback, "generic") {
6043
+ }
6044
+
6045
+ template<class T>
6046
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
6047
+ const Function& callback,
6048
+ const char* resource_name)
6049
+ : AsyncProgressQueueWorker(receiver,
6050
+ callback,
6051
+ resource_name,
6052
+ Object::New(callback.Env())) {
6053
+ }
6054
+
6055
+ template<class T>
6056
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
6057
+ const Function& callback,
6058
+ const char* resource_name,
6059
+ const Object& resource)
6060
+ : AsyncProgressWorkerBase<std::pair<T*, size_t>>(receiver, callback, resource_name, resource, /** unlimited queue size */0) {
6061
+ }
6062
+
6063
+ #if NAPI_VERSION > 4
6064
+ template<class T>
6065
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env)
6066
+ : AsyncProgressQueueWorker(env, "generic") {
6067
+ }
6068
+
6069
+ template<class T>
6070
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env,
6071
+ const char* resource_name)
6072
+ : AsyncProgressQueueWorker(env, resource_name, Object::New(env)) {
6073
+ }
6074
+
6075
+ template<class T>
6076
+ inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env,
6077
+ const char* resource_name,
6078
+ const Object& resource)
6079
+ : AsyncProgressWorkerBase<std::pair<T*, size_t>>(env, resource_name, resource, /** unlimited queue size */0) {
6080
+ }
4064
6081
  #endif
4065
6082
 
6083
+ template<class T>
6084
+ inline void AsyncProgressQueueWorker<T>::Execute() {
6085
+ ExecutionProgress progress(this);
6086
+ Execute(progress);
6087
+ }
6088
+
6089
+ template<class T>
6090
+ inline void AsyncProgressQueueWorker<T>::OnWorkProgress(std::pair<T*, size_t>* datapair) {
6091
+ if (datapair == nullptr) {
6092
+ return;
6093
+ }
6094
+
6095
+ T *data = datapair->first;
6096
+ size_t size = datapair->second;
6097
+
6098
+ this->OnProgress(data, size);
6099
+ delete datapair;
6100
+ delete[] data;
6101
+ }
6102
+
6103
+ template<class T>
6104
+ inline void AsyncProgressQueueWorker<T>::SendProgress_(const T* data, size_t count) {
6105
+ T* new_data = new T[count];
6106
+ std::copy(data, data + count, new_data);
6107
+
6108
+ auto pair = new std::pair<T*, size_t>(new_data, count);
6109
+ this->NonBlockingCall(pair);
6110
+ }
6111
+
6112
+ template<class T>
6113
+ inline void AsyncProgressQueueWorker<T>::Signal() const {
6114
+ this->NonBlockingCall(nullptr);
6115
+ }
6116
+
6117
+ template<class T>
6118
+ inline void AsyncProgressQueueWorker<T>::OnWorkComplete(Napi::Env env, napi_status status) {
6119
+ // Draining queued items in TSFN.
6120
+ AsyncProgressWorkerBase<std::pair<T*, size_t>>::OnWorkComplete(env, status);
6121
+ }
6122
+
6123
+ template<class T>
6124
+ inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Signal() const {
6125
+ _worker->Signal();
6126
+ }
6127
+
6128
+ template<class T>
6129
+ inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Send(const T* data, size_t count) const {
6130
+ _worker->SendProgress_(data, count);
6131
+ }
6132
+ #endif // NAPI_VERSION > 3 && !defined(__wasm32__)
6133
+
4066
6134
  ////////////////////////////////////////////////////////////////////////////////
4067
6135
  // Memory Management class
4068
6136
  ////////////////////////////////////////////////////////////////////////////////
@@ -4092,6 +6160,100 @@ inline const napi_node_version* VersionManagement::GetNodeVersion(Env env) {
4092
6160
  return result;
4093
6161
  }
4094
6162
 
6163
+ #if NAPI_VERSION > 5
6164
+ ////////////////////////////////////////////////////////////////////////////////
6165
+ // Addon<T> class
6166
+ ////////////////////////////////////////////////////////////////////////////////
6167
+
6168
+ template <typename T>
6169
+ inline Object Addon<T>::Init(Env env, Object exports) {
6170
+ T* addon = new T(env, exports);
6171
+ env.SetInstanceData(addon);
6172
+ return addon->entry_point_;
6173
+ }
6174
+
6175
+ template <typename T>
6176
+ inline T* Addon<T>::Unwrap(Object wrapper) {
6177
+ return wrapper.Env().GetInstanceData<T>();
6178
+ }
6179
+
6180
+ template <typename T>
6181
+ inline void
6182
+ Addon<T>::DefineAddon(Object exports,
6183
+ const std::initializer_list<AddonProp>& props) {
6184
+ DefineProperties(exports, props);
6185
+ entry_point_ = exports;
6186
+ }
6187
+
6188
+ template <typename T>
6189
+ inline Napi::Object
6190
+ Addon<T>::DefineProperties(Object object,
6191
+ const std::initializer_list<AddonProp>& props) {
6192
+ const napi_property_descriptor* properties =
6193
+ reinterpret_cast<const napi_property_descriptor*>(props.begin());
6194
+ size_t size = props.size();
6195
+ napi_status status = napi_define_properties(object.Env(),
6196
+ object,
6197
+ size,
6198
+ properties);
6199
+ NAPI_THROW_IF_FAILED(object.Env(), status, object);
6200
+ for (size_t idx = 0; idx < size; idx++)
6201
+ T::AttachPropData(object.Env(), object, &properties[idx]);
6202
+ return object;
6203
+ }
6204
+ #endif // NAPI_VERSION > 5
6205
+
6206
+ #if NAPI_VERSION > 2
6207
+ template <typename Hook, typename Arg>
6208
+ Env::CleanupHook<Hook, Arg> Env::AddCleanupHook(Hook hook, Arg* arg) {
6209
+ return CleanupHook<Hook, Arg>(*this, hook, arg);
6210
+ }
6211
+
6212
+ template <typename Hook>
6213
+ Env::CleanupHook<Hook> Env::AddCleanupHook(Hook hook) {
6214
+ return CleanupHook<Hook>(*this, hook);
6215
+ }
6216
+
6217
+ template <typename Hook, typename Arg>
6218
+ Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook)
6219
+ : wrapper(Env::CleanupHook<Hook, Arg>::Wrapper) {
6220
+ data = new CleanupData{std::move(hook), nullptr};
6221
+ napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
6222
+ if (status != napi_ok) {
6223
+ delete data;
6224
+ data = nullptr;
6225
+ }
6226
+ }
6227
+
6228
+ template <typename Hook, typename Arg>
6229
+ Env::CleanupHook<Hook, Arg>::CleanupHook(Napi::Env env, Hook hook, Arg* arg)
6230
+ : wrapper(Env::CleanupHook<Hook, Arg>::WrapperWithArg) {
6231
+ data = new CleanupData{std::move(hook), arg};
6232
+ napi_status status = napi_add_env_cleanup_hook(env, wrapper, data);
6233
+ if (status != napi_ok) {
6234
+ delete data;
6235
+ data = nullptr;
6236
+ }
6237
+ }
6238
+
6239
+ template <class Hook, class Arg>
6240
+ bool Env::CleanupHook<Hook, Arg>::Remove(Env env) {
6241
+ napi_status status = napi_remove_env_cleanup_hook(env, wrapper, data);
6242
+ delete data;
6243
+ data = nullptr;
6244
+ return status == napi_ok;
6245
+ }
6246
+
6247
+ template <class Hook, class Arg>
6248
+ bool Env::CleanupHook<Hook, Arg>::IsEmpty() const {
6249
+ return data == nullptr;
6250
+ }
6251
+ #endif // NAPI_VERSION > 2
6252
+
6253
+ #ifdef NAPI_CPP_CUSTOM_NAMESPACE
6254
+ } // namespace NAPI_CPP_CUSTOM_NAMESPACE
6255
+ #endif
6256
+
4095
6257
  } // namespace Napi
4096
6258
 
4097
6259
  #endif // SRC_NAPI_INL_H_