@pezkuwi/api 16.5.6 → 16.5.8

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 (379) hide show
  1. package/build/LICENSE +201 -0
  2. package/build/README.md +100 -0
  3. package/build/augment.d.ts +1 -0
  4. package/build/augment.js +1 -0
  5. package/build/base/Decorate.d.ts +143 -0
  6. package/build/base/Decorate.js +752 -0
  7. package/build/base/Events.d.ts +67 -0
  8. package/build/base/Events.js +78 -0
  9. package/build/base/Getters.d.ts +163 -0
  10. package/build/base/Getters.js +207 -0
  11. package/build/base/Init.d.ts +44 -0
  12. package/build/base/Init.js +400 -0
  13. package/build/base/find.d.ts +3 -0
  14. package/build/base/find.js +7 -0
  15. package/build/base/index.d.ts +47 -0
  16. package/build/base/index.js +57 -0
  17. package/build/base/types.d.ts +15 -0
  18. package/build/base/types.js +1 -0
  19. package/build/bundle-pezkuwi-api.js +26247 -0
  20. package/build/bundle.d.ts +7 -0
  21. package/build/bundle.js +7 -0
  22. package/build/cjs/augment.d.ts +1 -0
  23. package/build/cjs/augment.js +3 -0
  24. package/build/cjs/base/Decorate.d.ts +143 -0
  25. package/build/cjs/base/Decorate.js +756 -0
  26. package/build/cjs/base/Events.d.ts +67 -0
  27. package/build/cjs/base/Events.js +82 -0
  28. package/build/cjs/base/Getters.d.ts +163 -0
  29. package/build/cjs/base/Getters.js +211 -0
  30. package/build/cjs/base/Init.d.ts +44 -0
  31. package/build/cjs/base/Init.js +404 -0
  32. package/build/cjs/base/find.d.ts +3 -0
  33. package/build/cjs/base/find.js +11 -0
  34. package/build/cjs/base/index.d.ts +47 -0
  35. package/build/cjs/base/index.js +61 -0
  36. package/build/cjs/base/types.d.ts +15 -0
  37. package/build/cjs/base/types.js +2 -0
  38. package/build/cjs/bundle.d.ts +7 -0
  39. package/build/cjs/bundle.js +17 -0
  40. package/build/cjs/index.d.ts +2 -0
  41. package/build/cjs/index.js +5 -0
  42. package/build/cjs/package.json +3 -0
  43. package/build/cjs/packageDetect.d.ts +1 -0
  44. package/build/cjs/packageDetect.js +10 -0
  45. package/build/cjs/packageInfo.d.ts +6 -0
  46. package/build/cjs/packageInfo.js +4 -0
  47. package/build/cjs/promise/Api.d.ts +158 -0
  48. package/build/cjs/promise/Api.js +195 -0
  49. package/build/cjs/promise/Combinator.d.ts +12 -0
  50. package/build/cjs/promise/Combinator.js +72 -0
  51. package/build/cjs/promise/decorateMethod.d.ts +14 -0
  52. package/build/cjs/promise/decorateMethod.js +75 -0
  53. package/build/cjs/promise/index.d.ts +2 -0
  54. package/build/cjs/promise/index.js +7 -0
  55. package/build/cjs/promise/types.d.ts +5 -0
  56. package/build/cjs/promise/types.js +2 -0
  57. package/build/cjs/rx/Api.d.ts +155 -0
  58. package/build/cjs/rx/Api.js +173 -0
  59. package/build/cjs/rx/decorateMethod.d.ts +3 -0
  60. package/build/cjs/rx/decorateMethod.js +6 -0
  61. package/build/cjs/rx/index.d.ts +2 -0
  62. package/build/cjs/rx/index.js +7 -0
  63. package/build/cjs/submittable/Result.d.ts +31 -0
  64. package/build/cjs/submittable/Result.js +84 -0
  65. package/build/cjs/submittable/createClass.d.ts +12 -0
  66. package/build/cjs/submittable/createClass.js +277 -0
  67. package/build/cjs/submittable/createSubmittable.d.ts +8 -0
  68. package/build/cjs/submittable/createSubmittable.js +8 -0
  69. package/build/cjs/submittable/index.d.ts +2 -0
  70. package/build/cjs/submittable/index.js +7 -0
  71. package/build/cjs/submittable/types.d.ts +1 -0
  72. package/build/cjs/submittable/types.js +2 -0
  73. package/build/cjs/types/calls.d.ts +1 -0
  74. package/build/cjs/types/calls.js +4 -0
  75. package/build/cjs/types/consts.d.ts +1 -0
  76. package/build/cjs/types/consts.js +4 -0
  77. package/build/cjs/types/errors.d.ts +1 -0
  78. package/build/cjs/types/errors.js +4 -0
  79. package/build/cjs/types/events.d.ts +1 -0
  80. package/build/cjs/types/events.js +4 -0
  81. package/build/cjs/types/index.d.ts +114 -0
  82. package/build/cjs/types/index.js +13 -0
  83. package/build/cjs/types/storage.d.ts +1 -0
  84. package/build/cjs/types/storage.js +4 -0
  85. package/build/cjs/types/submittable.d.ts +1 -0
  86. package/build/cjs/types/submittable.js +4 -0
  87. package/build/cjs/util/augmentObject.d.ts +9 -0
  88. package/build/cjs/util/augmentObject.js +84 -0
  89. package/build/cjs/util/decorate.d.ts +16 -0
  90. package/build/cjs/util/decorate.js +17 -0
  91. package/build/cjs/util/filterEvents.d.ts +6 -0
  92. package/build/cjs/util/filterEvents.js +25 -0
  93. package/build/cjs/util/index.d.ts +4 -0
  94. package/build/cjs/util/index.js +11 -0
  95. package/build/cjs/util/isKeyringPair.d.ts +3 -0
  96. package/build/cjs/util/isKeyringPair.js +7 -0
  97. package/build/cjs/util/logging.d.ts +1 -0
  98. package/build/cjs/util/logging.js +5 -0
  99. package/build/cjs/util/validate.d.ts +3 -0
  100. package/build/cjs/util/validate.js +26 -0
  101. package/build/index.d.ts +2 -0
  102. package/build/index.js +2 -0
  103. package/build/package.json +612 -0
  104. package/build/packageDetect.d.ts +1 -0
  105. package/build/packageDetect.js +8 -0
  106. package/build/packageInfo.d.ts +6 -0
  107. package/build/packageInfo.js +1 -0
  108. package/build/promise/Api.d.ts +158 -0
  109. package/build/promise/Api.js +191 -0
  110. package/build/promise/Combinator.d.ts +12 -0
  111. package/build/promise/Combinator.js +68 -0
  112. package/build/promise/decorateMethod.d.ts +14 -0
  113. package/build/promise/decorateMethod.js +71 -0
  114. package/build/promise/index.d.ts +2 -0
  115. package/build/promise/index.js +2 -0
  116. package/build/promise/types.d.ts +5 -0
  117. package/build/promise/types.js +1 -0
  118. package/build/rx/Api.d.ts +155 -0
  119. package/build/rx/Api.js +169 -0
  120. package/build/rx/decorateMethod.d.ts +3 -0
  121. package/build/rx/decorateMethod.js +3 -0
  122. package/build/rx/index.d.ts +2 -0
  123. package/build/rx/index.js +2 -0
  124. package/build/submittable/Result.d.ts +31 -0
  125. package/build/submittable/Result.js +80 -0
  126. package/build/submittable/createClass.d.ts +12 -0
  127. package/build/submittable/createClass.js +274 -0
  128. package/build/submittable/createSubmittable.d.ts +8 -0
  129. package/build/submittable/createSubmittable.js +5 -0
  130. package/build/submittable/index.d.ts +2 -0
  131. package/build/submittable/index.js +2 -0
  132. package/build/submittable/types.d.ts +1 -0
  133. package/build/submittable/types.js +1 -0
  134. package/build/types/calls.d.ts +1 -0
  135. package/build/types/calls.js +1 -0
  136. package/build/types/consts.d.ts +1 -0
  137. package/build/types/consts.js +1 -0
  138. package/build/types/errors.d.ts +1 -0
  139. package/build/types/errors.js +1 -0
  140. package/build/types/events.d.ts +1 -0
  141. package/build/types/events.js +1 -0
  142. package/build/types/index.d.ts +114 -0
  143. package/build/types/index.js +8 -0
  144. package/build/types/storage.d.ts +1 -0
  145. package/build/types/storage.js +1 -0
  146. package/build/types/submittable.d.ts +1 -0
  147. package/build/types/submittable.js +1 -0
  148. package/build/util/augmentObject.d.ts +9 -0
  149. package/build/util/augmentObject.js +81 -0
  150. package/build/util/decorate.d.ts +16 -0
  151. package/build/util/decorate.js +14 -0
  152. package/build/util/filterEvents.d.ts +6 -0
  153. package/build/util/filterEvents.js +22 -0
  154. package/build/util/index.d.ts +4 -0
  155. package/build/util/index.js +4 -0
  156. package/build/util/isKeyringPair.d.ts +3 -0
  157. package/build/util/isKeyringPair.js +4 -0
  158. package/build/util/logging.d.ts +1 -0
  159. package/build/util/logging.js +2 -0
  160. package/build/util/validate.d.ts +3 -0
  161. package/build/util/validate.js +23 -0
  162. package/build-deno/README.md +95 -0
  163. package/build-deno/augment.ts +2 -0
  164. package/build-deno/base/Decorate.ts +1100 -0
  165. package/build-deno/base/Events.ts +89 -0
  166. package/build-deno/base/Getters.ts +243 -0
  167. package/build-deno/base/Init.ts +523 -0
  168. package/build-deno/base/find.ts +12 -0
  169. package/build-deno/base/index.ts +83 -0
  170. package/build-deno/base/types.ts +17 -0
  171. package/build-deno/bundle.ts +11 -0
  172. package/build-deno/checkTypes.manual.ts +320 -0
  173. package/build-deno/index.ts +4 -0
  174. package/build-deno/mod.ts +2 -0
  175. package/build-deno/packageDetect.ts +12 -0
  176. package/build-deno/packageInfo.ts +3 -0
  177. package/build-deno/promise/Api.ts +212 -0
  178. package/build-deno/promise/Combinator.ts +89 -0
  179. package/build-deno/promise/decorateMethod.ts +111 -0
  180. package/build-deno/promise/index.ts +3 -0
  181. package/build-deno/promise/types.ts +7 -0
  182. package/build-deno/rx/Api.ts +184 -0
  183. package/build-deno/rx/decorateMethod.ts +7 -0
  184. package/build-deno/rx/index.ts +3 -0
  185. package/build-deno/submittable/Result.ts +109 -0
  186. package/build-deno/submittable/createClass.ts +436 -0
  187. package/build-deno/submittable/createSubmittable.ts +17 -0
  188. package/build-deno/submittable/index.ts +3 -0
  189. package/build-deno/submittable/types.ts +2 -0
  190. package/build-deno/test/SingleAccountSigner.ts +51 -0
  191. package/build-deno/test/index.ts +3 -0
  192. package/build-deno/test/logEvents.ts +21 -0
  193. package/build-deno/types/calls.ts +2 -0
  194. package/build-deno/types/consts.ts +2 -0
  195. package/build-deno/types/errors.ts +2 -0
  196. package/build-deno/types/events.ts +2 -0
  197. package/build-deno/types/index.ts +124 -0
  198. package/build-deno/types/storage.ts +2 -0
  199. package/build-deno/types/submittable.ts +2 -0
  200. package/build-deno/util/augmentObject.ts +109 -0
  201. package/build-deno/util/decorate.ts +38 -0
  202. package/build-deno/util/filterEvents.ts +32 -0
  203. package/build-deno/util/index.ts +6 -0
  204. package/build-deno/util/isKeyringPair.ts +9 -0
  205. package/build-deno/util/logging.ts +4 -0
  206. package/build-deno/util/validate.ts +32 -0
  207. package/build-tsc/augment.d.ts +1 -0
  208. package/build-tsc/base/Decorate.d.ts +143 -0
  209. package/build-tsc/base/Events.d.ts +67 -0
  210. package/build-tsc/base/Getters.d.ts +163 -0
  211. package/build-tsc/base/Init.d.ts +44 -0
  212. package/build-tsc/base/find.d.ts +3 -0
  213. package/build-tsc/base/index.d.ts +47 -0
  214. package/build-tsc/base/types.d.ts +15 -0
  215. package/build-tsc/bundle.d.ts +7 -0
  216. package/build-tsc/index.d.ts +2 -0
  217. package/build-tsc/packageDetect.d.ts +1 -0
  218. package/build-tsc/packageInfo.d.ts +6 -0
  219. package/build-tsc/promise/Api.d.ts +158 -0
  220. package/build-tsc/promise/Combinator.d.ts +12 -0
  221. package/build-tsc/promise/decorateMethod.d.ts +14 -0
  222. package/build-tsc/promise/index.d.ts +2 -0
  223. package/build-tsc/promise/types.d.ts +5 -0
  224. package/build-tsc/rx/Api.d.ts +155 -0
  225. package/build-tsc/rx/decorateMethod.d.ts +3 -0
  226. package/build-tsc/rx/index.d.ts +2 -0
  227. package/build-tsc/submittable/Result.d.ts +31 -0
  228. package/build-tsc/submittable/createClass.d.ts +12 -0
  229. package/build-tsc/submittable/createSubmittable.d.ts +8 -0
  230. package/build-tsc/submittable/index.d.ts +2 -0
  231. package/build-tsc/submittable/types.d.ts +1 -0
  232. package/build-tsc/types/calls.d.ts +1 -0
  233. package/build-tsc/types/consts.d.ts +1 -0
  234. package/build-tsc/types/errors.d.ts +1 -0
  235. package/build-tsc/types/events.d.ts +1 -0
  236. package/build-tsc/types/index.d.ts +114 -0
  237. package/build-tsc/types/storage.d.ts +1 -0
  238. package/build-tsc/types/submittable.d.ts +1 -0
  239. package/build-tsc/util/augmentObject.d.ts +9 -0
  240. package/build-tsc/util/decorate.d.ts +16 -0
  241. package/build-tsc/util/filterEvents.d.ts +6 -0
  242. package/build-tsc/util/index.d.ts +4 -0
  243. package/build-tsc/util/isKeyringPair.d.ts +3 -0
  244. package/build-tsc/util/logging.d.ts +1 -0
  245. package/build-tsc/util/validate.d.ts +3 -0
  246. package/build-tsc-cjs/augment.js +3 -0
  247. package/build-tsc-cjs/base/Decorate.js +756 -0
  248. package/build-tsc-cjs/base/Events.js +82 -0
  249. package/build-tsc-cjs/base/Getters.js +211 -0
  250. package/build-tsc-cjs/base/Init.js +404 -0
  251. package/build-tsc-cjs/base/find.js +11 -0
  252. package/build-tsc-cjs/base/index.js +61 -0
  253. package/build-tsc-cjs/base/types.js +2 -0
  254. package/build-tsc-cjs/bundle.js +17 -0
  255. package/build-tsc-cjs/index.js +5 -0
  256. package/build-tsc-cjs/packageDetect.js +10 -0
  257. package/build-tsc-cjs/packageInfo.js +4 -0
  258. package/build-tsc-cjs/promise/Api.js +195 -0
  259. package/build-tsc-cjs/promise/Combinator.js +72 -0
  260. package/build-tsc-cjs/promise/decorateMethod.js +75 -0
  261. package/build-tsc-cjs/promise/index.js +7 -0
  262. package/build-tsc-cjs/promise/types.js +2 -0
  263. package/build-tsc-cjs/rx/Api.js +173 -0
  264. package/build-tsc-cjs/rx/decorateMethod.js +6 -0
  265. package/build-tsc-cjs/rx/index.js +7 -0
  266. package/build-tsc-cjs/submittable/Result.js +84 -0
  267. package/build-tsc-cjs/submittable/createClass.js +277 -0
  268. package/build-tsc-cjs/submittable/createSubmittable.js +8 -0
  269. package/build-tsc-cjs/submittable/index.js +7 -0
  270. package/build-tsc-cjs/submittable/types.js +2 -0
  271. package/build-tsc-cjs/types/calls.js +4 -0
  272. package/build-tsc-cjs/types/consts.js +4 -0
  273. package/build-tsc-cjs/types/errors.js +4 -0
  274. package/build-tsc-cjs/types/events.js +4 -0
  275. package/build-tsc-cjs/types/index.js +13 -0
  276. package/build-tsc-cjs/types/storage.js +4 -0
  277. package/build-tsc-cjs/types/submittable.js +4 -0
  278. package/build-tsc-cjs/util/augmentObject.js +84 -0
  279. package/build-tsc-cjs/util/decorate.js +17 -0
  280. package/build-tsc-cjs/util/filterEvents.js +25 -0
  281. package/build-tsc-cjs/util/index.js +11 -0
  282. package/build-tsc-cjs/util/isKeyringPair.js +7 -0
  283. package/build-tsc-cjs/util/logging.js +5 -0
  284. package/build-tsc-cjs/util/validate.js +26 -0
  285. package/build-tsc-esm/augment.js +1 -0
  286. package/build-tsc-esm/base/Decorate.js +752 -0
  287. package/build-tsc-esm/base/Events.js +78 -0
  288. package/build-tsc-esm/base/Getters.js +207 -0
  289. package/build-tsc-esm/base/Init.js +400 -0
  290. package/build-tsc-esm/base/find.js +7 -0
  291. package/build-tsc-esm/base/index.js +57 -0
  292. package/build-tsc-esm/base/types.js +1 -0
  293. package/build-tsc-esm/bundle.js +7 -0
  294. package/build-tsc-esm/index.js +2 -0
  295. package/build-tsc-esm/packageDetect.js +8 -0
  296. package/build-tsc-esm/packageInfo.js +1 -0
  297. package/build-tsc-esm/promise/Api.js +191 -0
  298. package/build-tsc-esm/promise/Combinator.js +68 -0
  299. package/build-tsc-esm/promise/decorateMethod.js +71 -0
  300. package/build-tsc-esm/promise/index.js +2 -0
  301. package/build-tsc-esm/promise/types.js +1 -0
  302. package/build-tsc-esm/rx/Api.js +169 -0
  303. package/build-tsc-esm/rx/decorateMethod.js +3 -0
  304. package/build-tsc-esm/rx/index.js +2 -0
  305. package/build-tsc-esm/submittable/Result.js +80 -0
  306. package/build-tsc-esm/submittable/createClass.js +274 -0
  307. package/build-tsc-esm/submittable/createSubmittable.js +5 -0
  308. package/build-tsc-esm/submittable/index.js +2 -0
  309. package/build-tsc-esm/submittable/types.js +1 -0
  310. package/build-tsc-esm/types/calls.js +1 -0
  311. package/build-tsc-esm/types/consts.js +1 -0
  312. package/build-tsc-esm/types/errors.js +1 -0
  313. package/build-tsc-esm/types/events.js +1 -0
  314. package/build-tsc-esm/types/index.js +8 -0
  315. package/build-tsc-esm/types/storage.js +1 -0
  316. package/build-tsc-esm/types/submittable.js +1 -0
  317. package/build-tsc-esm/util/augmentObject.js +81 -0
  318. package/build-tsc-esm/util/decorate.js +14 -0
  319. package/build-tsc-esm/util/filterEvents.js +22 -0
  320. package/build-tsc-esm/util/index.js +4 -0
  321. package/build-tsc-esm/util/isKeyringPair.js +4 -0
  322. package/build-tsc-esm/util/logging.js +2 -0
  323. package/build-tsc-esm/util/validate.js +23 -0
  324. package/bundle-pezkuwi-api.js +26240 -26231
  325. package/cjs/packageInfo.js +1 -1
  326. package/package.json +12 -12
  327. package/packageInfo.js +1 -1
  328. package/src/augment.ts +4 -0
  329. package/src/base/Decorate.ts +1103 -0
  330. package/src/base/Events.ts +91 -0
  331. package/src/base/Getters.ts +245 -0
  332. package/src/base/Init.ts +525 -0
  333. package/src/base/find.ts +14 -0
  334. package/src/base/index.ts +85 -0
  335. package/src/base/types.ts +19 -0
  336. package/src/bundle.ts +16 -0
  337. package/src/checkTypes.manual.ts +323 -0
  338. package/src/index.ts +6 -0
  339. package/src/mod.ts +4 -0
  340. package/src/packageDetect.ts +16 -0
  341. package/src/packageInfo.ts +6 -0
  342. package/src/promise/Api.ts +214 -0
  343. package/src/promise/Combinator.ts +91 -0
  344. package/src/promise/Combinators.spec.ts +109 -0
  345. package/src/promise/decorateMethod.ts +118 -0
  346. package/src/promise/index.spec.ts +167 -0
  347. package/src/promise/index.ts +5 -0
  348. package/src/promise/types.ts +9 -0
  349. package/src/rx/Api.ts +186 -0
  350. package/src/rx/decorateMethod.ts +9 -0
  351. package/src/rx/index.ts +5 -0
  352. package/src/submittable/Result.ts +111 -0
  353. package/src/submittable/createClass.ts +438 -0
  354. package/src/submittable/createSubmittable.ts +19 -0
  355. package/src/submittable/index.ts +5 -0
  356. package/src/submittable/types.ts +4 -0
  357. package/src/test/SingleAccountSigner.ts +53 -0
  358. package/src/test/index.ts +5 -0
  359. package/src/test/logEvents.ts +24 -0
  360. package/src/types/calls.ts +4 -0
  361. package/src/types/consts.ts +4 -0
  362. package/src/types/errors.ts +4 -0
  363. package/src/types/events.ts +4 -0
  364. package/src/types/index.ts +137 -0
  365. package/src/types/storage.ts +4 -0
  366. package/src/types/submittable.ts +4 -0
  367. package/src/util/augmentObject.spec.ts +54 -0
  368. package/src/util/augmentObject.ts +112 -0
  369. package/src/util/decorate.ts +43 -0
  370. package/src/util/filterEvents.ts +34 -0
  371. package/src/util/index.ts +10 -0
  372. package/src/util/isKeyringPair.ts +11 -0
  373. package/src/util/logging.ts +6 -0
  374. package/src/util/validate.spec.ts +72 -0
  375. package/src/util/validate.ts +36 -0
  376. package/tsconfig.build.json +25 -0
  377. package/tsconfig.build.tsbuildinfo +1 -0
  378. package/tsconfig.spec.json +26 -0
  379. package/tsconfig.spec.tsbuildinfo +1 -0
@@ -0,0 +1,109 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
+
6
+ import type { UnsubscribePromise } from '../types/index.js';
7
+
8
+ import { Combinator } from './Combinator.js';
9
+
10
+ describe('Combinator', (): void => {
11
+ let fns: ((value: any) => void)[] = [];
12
+
13
+ // eslint-disable-next-line @typescript-eslint/require-await
14
+ const storeFn = async (cb: (value: any) => void): UnsubscribePromise => {
15
+ fns.push(cb);
16
+
17
+ return (): void => undefined;
18
+ };
19
+
20
+ beforeEach((): void => {
21
+ fns = [];
22
+ });
23
+
24
+ it('triggers on all values', async (): Promise<void> => {
25
+ await new Promise<boolean>((resolve) => {
26
+ let count = 0;
27
+ const combinator = new Combinator(
28
+ [storeFn],
29
+ (value: any[]): void => {
30
+ expect(value[0]).toEqual(`test${count}`);
31
+
32
+ count++;
33
+
34
+ if (count === 3) {
35
+ resolve(true);
36
+ }
37
+ }
38
+ );
39
+
40
+ fns[0]('test0');
41
+ fns[0]('test1');
42
+ fns[0]('test2');
43
+
44
+ expect(combinator).toBeDefined();
45
+ });
46
+ });
47
+
48
+ it('combines values from 2 sources, firing when it has all results', async (): Promise<void> => {
49
+ await new Promise<boolean>((resolve) => {
50
+ const combinator = new Combinator(
51
+ [storeFn, storeFn],
52
+ (value: any[]): void => {
53
+ expect(value).toEqual(['test0', 'test1']);
54
+
55
+ resolve(true);
56
+ }
57
+ );
58
+
59
+ fns[0]('test0');
60
+ fns[1]('test1');
61
+
62
+ expect(combinator).toBeDefined();
63
+ });
64
+ });
65
+
66
+ it('combines values from 2 sources, allowing multiple updates', async (): Promise<void> => {
67
+ await new Promise<boolean>((resolve) => {
68
+ let count = 0;
69
+ const combinator = new Combinator(
70
+ [storeFn, storeFn],
71
+ (value: any[]): void => {
72
+ expect(value).toEqual(
73
+ count === 0
74
+ ? ['test0', 'test1']
75
+ : ['test2', 'test1']);
76
+
77
+ count++;
78
+
79
+ if (count === 2) {
80
+ resolve(true);
81
+ }
82
+ }
83
+ );
84
+
85
+ fns[0]('test0');
86
+ fns[1]('test1');
87
+ fns[0]('test2');
88
+
89
+ expect(combinator).toBeDefined();
90
+ });
91
+ });
92
+
93
+ // eslint-disable-next-line jest/expect-expect
94
+ it('unsubscribes as required', async (): Promise<void> => {
95
+ await new Promise<void>((resolve) => {
96
+ // eslint-disable-next-line @typescript-eslint/require-await
97
+ const mocker = () => Promise.resolve(resolve);
98
+ const combinator = new Combinator([
99
+ mocker,
100
+ // eslint-disable-next-line @typescript-eslint/require-await
101
+ async (): UnsubscribePromise => (): void => undefined
102
+ ], (_: any[]): void => {
103
+ // ignore
104
+ });
105
+
106
+ combinator.unsubscribe();
107
+ });
108
+ });
109
+ });
@@ -0,0 +1,118 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Observable, Subscription } from 'rxjs';
5
+ import type { Callback, Codec } from '@pezkuwi/types/types';
6
+ import type { DecorateFn, DecorateMethodOptions, ObsInnerType, StorageEntryPromiseOverloads, UnsubscribePromise, VoidFn } from '../types/index.js';
7
+
8
+ import { catchError, EMPTY, tap } from 'rxjs';
9
+
10
+ import { isFunction, nextTick } from '@pezkuwi/util';
11
+
12
+ interface Tracker<T> {
13
+ reject: (value: Error) => Observable<never>;
14
+ resolve: (value: T) => void;
15
+ }
16
+
17
+ type CodecReturnType<T extends (...args: unknown[]) => Observable<Codec>> =
18
+ T extends (...args: any) => infer R
19
+ ? R extends Observable<Codec>
20
+ ? ObsInnerType<R>
21
+ : never
22
+ : never;
23
+
24
+ // a Promise completion tracker, wrapping an isComplete variable that ensures
25
+ // that the promise only resolves once
26
+ export function promiseTracker<T> (resolve: (value: T) => void, reject: (value: Error) => void): Tracker<T> {
27
+ let isCompleted = false;
28
+
29
+ return {
30
+ reject: (error: Error): Observable<never> => {
31
+ if (!isCompleted) {
32
+ isCompleted = true;
33
+
34
+ reject(error);
35
+ }
36
+
37
+ return EMPTY;
38
+ },
39
+ resolve: (value: T): void => {
40
+ if (!isCompleted) {
41
+ isCompleted = true;
42
+
43
+ resolve(value);
44
+ }
45
+ }
46
+ };
47
+ }
48
+
49
+ // extract the arguments and callback params from a value array possibly containing a callback
50
+ function extractArgs (args: unknown[], needsCallback: boolean): [unknown[], Callback<Codec> | undefined] {
51
+ const actualArgs = args.slice();
52
+
53
+ // If the last arg is a function, we pop it, put it into callback.
54
+ // actualArgs will then hold the actual arguments to be passed to `method`
55
+ const callback = (args.length && isFunction(args[args.length - 1]))
56
+ ? actualArgs.pop() as Callback<Codec>
57
+ : undefined;
58
+
59
+ // When we need a subscription, ensure that a valid callback is actually passed
60
+ if (needsCallback && !isFunction(callback)) {
61
+ throw new Error('Expected a callback to be passed with subscriptions');
62
+ }
63
+
64
+ return [actualArgs, callback];
65
+ }
66
+
67
+ // Decorate a call for a single-shot result - retrieve and then immediate unsubscribe
68
+ function decorateCall<M extends DecorateFn<CodecReturnType<M>>> (method: M, args: unknown[]): Promise<CodecReturnType<M>> {
69
+ return new Promise((resolve, reject): void => {
70
+ // single result tracker - either reject with Error or resolve with Codec result
71
+ const tracker = promiseTracker(resolve, reject);
72
+
73
+ // encoding errors reject immediately, any result unsubscribes and resolves
74
+ const subscription: Subscription = method(...args)
75
+ .pipe(
76
+ catchError((error: Error) => tracker.reject(error))
77
+ )
78
+ .subscribe((result): void => {
79
+ tracker.resolve(result);
80
+
81
+ nextTick(() => subscription.unsubscribe());
82
+ });
83
+ });
84
+ }
85
+
86
+ // Decorate a subscription where we have a result callback specified
87
+ function decorateSubscribe<M extends DecorateFn<CodecReturnType<M>>> (method: M, args: unknown[], resultCb: Callback<Codec>): UnsubscribePromise {
88
+ return new Promise<VoidFn>((resolve, reject): void => {
89
+ // either reject with error or resolve with unsubscribe callback
90
+ const tracker = promiseTracker(resolve, reject);
91
+
92
+ // errors reject immediately, the first result resolves with an unsubscribe promise, all results via callback
93
+ const subscription: Subscription = method(...args)
94
+ .pipe(
95
+ catchError((error: Error) => tracker.reject(error)),
96
+ tap(() => tracker.resolve(() => subscription.unsubscribe()))
97
+ )
98
+ .subscribe((result): void => {
99
+ // queue result (back of queue to clear current)
100
+ nextTick(() => resultCb(result));
101
+ });
102
+ });
103
+ }
104
+
105
+ /**
106
+ * @description Decorate method for ApiPromise, where the results are converted to the Promise equivalent
107
+ */
108
+ export function toPromiseMethod<M extends DecorateFn<CodecReturnType<M>>> (method: M, options?: DecorateMethodOptions): StorageEntryPromiseOverloads {
109
+ const needsCallback = !!(options?.methodName && options.methodName.includes('subscribe'));
110
+
111
+ return function (...args: unknown[]): Promise<CodecReturnType<M>> | UnsubscribePromise {
112
+ const [actualArgs, resultCb] = extractArgs(args, needsCallback);
113
+
114
+ return resultCb
115
+ ? decorateSubscribe(method, actualArgs, resultCb)
116
+ : decorateCall((options?.overrideNoSub as M) || method, actualArgs);
117
+ } as StorageEntryPromiseOverloads;
118
+ }
@@ -0,0 +1,167 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /// <reference types="@pezkuwi/dev-test/globals.d.ts" />
5
+
6
+ import type { HexString } from '@pezkuwi/util/types';
7
+ import type { SubmittableExtrinsic } from '../types/index.js';
8
+
9
+ import { createPair } from '@pezkuwi/keyring/pair';
10
+ import { createTestKeyring } from '@pezkuwi/keyring/testing';
11
+ import { MockProvider } from '@pezkuwi/rpc-provider/mock';
12
+ import { TypeRegistry } from '@pezkuwi/types';
13
+ import { hexToU8a } from '@pezkuwi/util';
14
+
15
+ import { SingleAccountSigner } from '../test/index.js';
16
+ import { ApiPromise } from './index.js';
17
+
18
+ const TRANSFER_SIG = '0xbb861f9c905d860d303101dfd23a6042251721ca65fb1a58e317d628f08484767a3604afeaede64a4116d08daae3c285ea2ea97c8b6c7b3548e90df327c4e60c';
19
+
20
+ describe('ApiPromise', (): void => {
21
+ const registry = new TypeRegistry();
22
+ const keyring = createTestKeyring({ type: 'ed25519' });
23
+ const aliceEd = keyring.addPair(
24
+ createPair({ toSS58: keyring.encodeAddress, type: 'ed25519' }, {
25
+ publicKey: hexToU8a('0x88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee'),
26
+ secretKey: hexToU8a('0xabf8e5bdbe30c65656c0a3cbd181ff8a56294a69dfedd27982aace4a7690911588dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee')
27
+ })
28
+ );
29
+ let provider: MockProvider;
30
+
31
+ async function createTransfer (): Promise<{ api: ApiPromise; transfer: SubmittableExtrinsic<'promise'> }> {
32
+ provider.subscriptions.state_subscribeStorage.lastValue = {
33
+ changes: [
34
+ [
35
+ '0x26aa394eea5630e07c48ae0c9558cef79c2f82b23e5fd031fb54c292794b4cc4d560eb8d00e57357cf76492334e43bb2ecaa9f28df6a8c4426d7b6090f7ad3c9',
36
+ '0x00'
37
+ ]
38
+ ]
39
+ };
40
+
41
+ const signer = new SingleAccountSigner(registry, aliceEd);
42
+ const api = await ApiPromise.create({ provider, registry, signer, throwOnConnect: true });
43
+ const transfer = api.tx.balances.transferAllowDeath(keyring.getPair('0xe659a7a1628cdd93febc04a4e0646ea20e9f5f0ce097d9a05290d4a9e054df4e').address, 321564789876512345n);
44
+
45
+ return { api, transfer: await transfer.signAsync(aliceEd.address, {}) };
46
+ }
47
+
48
+ beforeEach((): void => {
49
+ provider = new MockProvider(registry);
50
+ });
51
+
52
+ afterEach(async () => {
53
+ await provider.disconnect();
54
+ });
55
+
56
+ describe('initialization', (): void => {
57
+ it('Create API instance with metadata map and makes the runtime, rpc, state & extrinsics available', async (): Promise<void> => {
58
+ const rpcData = await provider.send<HexString>('state_getMetadata', []);
59
+ const genesisHash = registry.createType('Hash', await provider.send('chain_getBlockHash', [])).toHex();
60
+ const specVersion = 0;
61
+ const api = await ApiPromise.create({ metadata: { [`${genesisHash}-${specVersion}`]: rpcData }, provider, registry, throwOnConnect: true });
62
+
63
+ expect(api.genesisHash).toBeDefined();
64
+ expect(api.runtimeMetadata).toBeDefined();
65
+ expect(api.runtimeVersion).toBeDefined();
66
+ expect(api.rpc).toBeDefined();
67
+ expect(api.query).toBeDefined();
68
+ expect(api.tx).toBeDefined();
69
+ expect(api.derive).toBeDefined();
70
+
71
+ await api.disconnect();
72
+ });
73
+
74
+ it('Create API instance without metadata and makes the runtime, rpc, state & extrinsics available', async (): Promise<void> => {
75
+ const metadata = {};
76
+ const api = await ApiPromise.create({ metadata, provider, registry, throwOnConnect: true });
77
+
78
+ expect(api.genesisHash).toBeDefined();
79
+ expect(api.runtimeMetadata).toBeDefined();
80
+ expect(api.runtimeVersion).toBeDefined();
81
+ expect(api.rpc).toBeDefined();
82
+ expect(api.query).toBeDefined();
83
+ expect(api.tx).toBeDefined();
84
+ expect(api.derive).toBeDefined();
85
+
86
+ await api.disconnect();
87
+ });
88
+
89
+ // eslint-disable-next-line jest/expect-expect
90
+ it('Create API instance will error on failure to await ready', async (): Promise<void> => {
91
+ class ErrorApiPromise extends ApiPromise {
92
+ constructor () {
93
+ super({ provider });
94
+ }
95
+
96
+ protected override _loadMeta (): Promise<boolean> {
97
+ throw new Error('Simulate failure to load meta');
98
+ }
99
+ }
100
+
101
+ try {
102
+ const api = await ErrorApiPromise.create({ provider, throwOnConnect: true });
103
+
104
+ await api.disconnect();
105
+
106
+ throw new Error('Expected an error but none occurred.');
107
+ } catch {
108
+ // Pass
109
+ }
110
+ });
111
+ });
112
+
113
+ describe('api.sign', (): void => {
114
+ const ADDR = '5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TTpu';
115
+ const TEST = { data: '0x0102030405060708090a0b0c0d0e0f112233445566778899aabbccddeeff' };
116
+ const SIG = '0x659effefbbe5ab4d7136ebb5084b959eb424e32b862307371be4721ac2c46334245af4f1476c36c5e5aff04396c2fdd2ce561ec90382821d4aa071b559b1db0f';
117
+
118
+ it('signs data using a specified keyring', async (): Promise<void> => {
119
+ const api = await ApiPromise.create({ provider, registry, throwOnConnect: true });
120
+ const sig = await api.sign(aliceEd, TEST);
121
+
122
+ expect(sig).toEqual(SIG);
123
+
124
+ await api.disconnect();
125
+ });
126
+
127
+ it('signs data using an external signer', async (): Promise<void> => {
128
+ const api = await ApiPromise.create({ provider, registry, signer: new SingleAccountSigner(registry, aliceEd), throwOnConnect: true });
129
+ const sig = await api.sign(ADDR, TEST);
130
+
131
+ expect(sig).toEqual(SIG);
132
+
133
+ await api.disconnect();
134
+ });
135
+ });
136
+
137
+ describe('decorator.signAsync', (): void => {
138
+ it('signs a transfer using an external signer', async (): Promise<void> => {
139
+ const { api, transfer } = await createTransfer();
140
+
141
+ expect(transfer.signature.toHex()).toEqual(TRANSFER_SIG);
142
+
143
+ await api.disconnect();
144
+ });
145
+ });
146
+
147
+ describe('api.tx(...)', (): void => {
148
+ it('allows construction from existing extrinsic', async (): Promise<void> => {
149
+ const { api, transfer } = await createTransfer();
150
+
151
+ expect(api.tx(transfer.toHex()).signature.toHex()).toEqual(TRANSFER_SIG);
152
+ expect(api.tx(transfer).signature.toHex()).toEqual(TRANSFER_SIG);
153
+
154
+ await api.disconnect();
155
+ });
156
+ });
157
+
158
+ describe('api.rpc(...)', (): void => {
159
+ it('allows sending rpc call', async (): Promise<void> => {
160
+ const { api } = await createTransfer();
161
+
162
+ expect(await api.rpc('dev_echo', 'hello', 'world')).toEqual(['hello', 'world']);
163
+
164
+ await api.disconnect();
165
+ });
166
+ });
167
+ });
@@ -0,0 +1,5 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { ApiPromise } from './Api.js';
5
+ export { toPromiseMethod } from './decorateMethod.js';
@@ -0,0 +1,9 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { SubmittableExtrinsic as SubmittableExtrinsicBase } from '../submittable/types.js';
5
+ import type { QueryableStorageEntry as QueryableStorageEntryBase, SubmittableExtrinsicFunction as SubmittableExtrinsicFunctionBase } from '../types/index.js';
6
+
7
+ export type QueryableStorageEntry = QueryableStorageEntryBase<'promise'>;
8
+ export type SubmittableExtrinsic = SubmittableExtrinsicBase<'promise'>;
9
+ export type SubmittableExtrinsicFunction = SubmittableExtrinsicFunctionBase<'promise'>;
package/src/rx/Api.ts ADDED
@@ -0,0 +1,186 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Observable } from 'rxjs';
5
+ import type { ApiOptions } from '../types/index.js';
6
+
7
+ import { from } from 'rxjs';
8
+
9
+ import { objectSpread } from '@pezkuwi/util';
10
+
11
+ import { ApiBase } from '../base/index.js';
12
+ import { toRxMethod } from './decorateMethod.js';
13
+
14
+ /**
15
+ * # @pezkuwi/api/rx
16
+ *
17
+ * ## Overview
18
+ *
19
+ * @name ApiRx
20
+ *
21
+ * @description
22
+ * ApiRx is a powerful RxJS Observable wrapper around the RPC and interfaces on the Pezkuwi network. As a full Observable API, all interface calls return RxJS Observables, including the static `.create(...)`. In the same fashion and subscription-based methods return long-running Observables that update with the latest values.
23
+ *
24
+ * The API is well suited to real-time applications where the latest state is needed, unlocking the subscription-based features of Pezkuwi (and Bizinikiwi) clients. Some familiarity with RxJS is a requirement to use the API, however just understanding `.subscribe` and `.pipe` on Observables will unlock full-scale use thereof.
25
+ *
26
+ * @see [[ApiPromise]]
27
+ *
28
+ * ## Usage
29
+ *
30
+ * Making rpc calls -
31
+ * <BR>
32
+ *
33
+ * ```javascript
34
+ * import ApiRx from '@pezkuwi/api/rx';
35
+ *
36
+ * // initialize via Promise & static create
37
+ * const api = await ApiRx.create().toPromise();
38
+ *
39
+ * // make a call to retrieve the current network head
40
+ * api.rpc.chain.subscribeNewHeads().subscribe((header) => {
41
+ * console.log(`Chain is at #${header.number}`);
42
+ * });
43
+ * ```
44
+ * <BR>
45
+ *
46
+ * Subscribing to chain state -
47
+ * <BR>
48
+ *
49
+ * ```javascript
50
+ * import { combineLatest, pairwise, switchMap } from 'rxjs';
51
+ * import { ApiRx, WsProvider } from '@pezkuwi/api';
52
+ *
53
+ *
54
+ * // initialize a provider with a specific endpoint
55
+ * const provider = new WsProvider('wss://example.com:9944')
56
+ *
57
+ * // initialize via isReady & new with specific provider
58
+ * new ApiRx({ provider })
59
+ * .isReady
60
+ * .pipe(
61
+ * switchMap((api) =>
62
+ * combineLatest([
63
+ * api.query.timestamp.blockPeriod(),
64
+ * api.query.timestamp.now().pipe(pairwise())
65
+ * ])
66
+ * )
67
+ * )
68
+ * .subscribe(([blockPeriod, timestamp]) => {
69
+ * const elapsed = timestamp[1].toNumber() - timestamp[0].toNumber();
70
+ * console.log(`timestamp ${timestamp[1]} \nelapsed ${elapsed} \n(${blockPeriod}s target)`);
71
+ * });
72
+ * ```
73
+ * <BR>
74
+ *
75
+ * Submitting a transaction -
76
+ * <BR>
77
+ *
78
+ * ```javascript
79
+ * import { first, switchMap } from 'rxjs';
80
+ * import ApiRx from '@pezkuwi/api/rx';
81
+ *
82
+ * // import the test keyring (already has dev keys for Alice, Bob, Charlie, Eve & Ferdie)
83
+ * import testingPairs from '@pezkuwi/keyring/testingPairs';
84
+ * const keyring = testingPairs();
85
+ *
86
+ * // get api via Promise
87
+ * const api = await ApiRx.create().toPromise();
88
+ *
89
+ * // retrieve nonce for the account
90
+ * api.query.system
91
+ * .account(keyring.alice.address)
92
+ * .pipe(
93
+ * first(),
94
+ * // pipe nonce into transfer
95
+ * switchMap(([nonce]) =>
96
+ * api.tx.balances
97
+ * // create transfer
98
+ * .transferAllowDeath(keyring.bob.address, 12345)
99
+ * // sign the transaction
100
+ * .sign(keyring.alice, { nonce })
101
+ * // send the transaction
102
+ * .send()
103
+ * )
104
+ * )
105
+ * // subscribe to overall result
106
+ * .subscribe(({ status }) => {
107
+ * if (status.isInBlock) {
108
+ * console.log('Completed at block hash', status.asFinalized.toHex());
109
+ * }
110
+ * });
111
+ * ```
112
+ */
113
+ export class ApiRx extends ApiBase<'rxjs'> {
114
+ #isReadyRx: Observable<ApiRx>;
115
+
116
+ /**
117
+ * @description Create an instance of the ApiRx class
118
+ * @param options Options to create an instance. Can be either [[ApiOptions]] or [[WsProvider]]
119
+ * @example
120
+ * <BR>
121
+ *
122
+ * ```javascript
123
+ * import { switchMap } from 'rxjs';
124
+ * import Api from '@pezkuwi/api/rx';
125
+ *
126
+ * new Api().isReady
127
+ * .pipe(
128
+ * switchMap((api) =>
129
+ * api.rpc.chain.subscribeNewHeads()
130
+ * ))
131
+ * .subscribe((header) => {
132
+ * console.log(`new block #${header.number.toNumber()}`);
133
+ * });
134
+ * ```
135
+ */
136
+ constructor (options?: ApiOptions) {
137
+ super(options, 'rxjs', toRxMethod);
138
+
139
+ this.#isReadyRx = from<Promise<ApiRx>>(
140
+ // You can create an observable from an event, however my mind groks this form better
141
+ new Promise((resolve): void => {
142
+ super.on('ready', () => resolve(this));
143
+ })
144
+ );
145
+ }
146
+
147
+ /**
148
+ * @description Creates an ApiRx instance using the supplied provider. Returns an Observable containing the actual Api instance.
149
+ * @param options options that is passed to the class constructor. Can be either [[ApiOptions]] or [[WsProvider]]
150
+ * @example
151
+ * <BR>
152
+ *
153
+ * ```javascript
154
+ * import { switchMap } from 'rxjs';
155
+ * import Api from '@pezkuwi/api/rx';
156
+ *
157
+ * Api.create()
158
+ * .pipe(
159
+ * switchMap((api) =>
160
+ * api.rpc.chain.subscribeNewHeads()
161
+ * ))
162
+ * .subscribe((header) => {
163
+ * console.log(`new block #${header.number.toNumber()}`);
164
+ * });
165
+ * ```
166
+ */
167
+ public static create (options?: ApiOptions): Observable<ApiRx> {
168
+ return new ApiRx(options).isReady;
169
+ }
170
+
171
+ /**
172
+ * @description Observable that returns the first time we are connected and loaded
173
+ */
174
+ public get isReady (): Observable<ApiRx> {
175
+ return this.#isReadyRx;
176
+ }
177
+
178
+ /**
179
+ * @description Returns a clone of this ApiRx instance (new underlying provider connection)
180
+ */
181
+ public clone (): ApiRx {
182
+ return new ApiRx(
183
+ objectSpread({}, this._options, { source: this })
184
+ );
185
+ }
186
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { Codec } from '@pezkuwi/types/types';
5
+ import type { DecorateFn } from '../types/index.js';
6
+
7
+ export function toRxMethod <M extends DecorateFn<Codec>> (method: M): M {
8
+ return method;
9
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright 2017-2025 @pezkuwi/api authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { ApiRx } from './Api.js';
5
+ export { toRxMethod } from './decorateMethod.js';