@pkcprotocol/pkc-js 0.0.11

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 (843) hide show
  1. package/LICENSE +339 -0
  2. package/README.md +1663 -0
  3. package/dist/browser/challenges.d.ts +1 -0
  4. package/dist/browser/challenges.js +2 -0
  5. package/dist/browser/challenges.js.map +1 -0
  6. package/dist/browser/clients/base-client-manager.d.ts +126 -0
  7. package/dist/browser/clients/base-client-manager.js +673 -0
  8. package/dist/browser/clients/base-client-manager.js.map +1 -0
  9. package/dist/browser/clients/name-resolver-client.d.ts +8 -0
  10. package/dist/browser/clients/name-resolver-client.js +10 -0
  11. package/dist/browser/clients/name-resolver-client.js.map +1 -0
  12. package/dist/browser/clients/pkc-typed-emitter.d.ts +9 -0
  13. package/dist/browser/clients/pkc-typed-emitter.js +52 -0
  14. package/dist/browser/clients/pkc-typed-emitter.js.map +1 -0
  15. package/dist/browser/clients/rpc-client/decode-rpc-response-util.d.ts +8 -0
  16. package/dist/browser/clients/rpc-client/decode-rpc-response-util.js +53 -0
  17. package/dist/browser/clients/rpc-client/decode-rpc-response-util.js.map +1 -0
  18. package/dist/browser/clients/rpc-client/pkc-rpc-client.d.ts +68 -0
  19. package/dist/browser/clients/rpc-client/pkc-rpc-client.js +404 -0
  20. package/dist/browser/clients/rpc-client/pkc-rpc-client.js.map +1 -0
  21. package/dist/browser/clients/rpc-client/rpc-schema-util.d.ts +147 -0
  22. package/dist/browser/clients/rpc-client/rpc-schema-util.js +11 -0
  23. package/dist/browser/clients/rpc-client/rpc-schema-util.js.map +1 -0
  24. package/dist/browser/clients/rpc-client/schema.d.ts +433 -0
  25. package/dist/browser/clients/rpc-client/schema.js +49 -0
  26. package/dist/browser/clients/rpc-client/schema.js.map +1 -0
  27. package/dist/browser/clients/rpc-client/types.d.ts +8 -0
  28. package/dist/browser/clients/rpc-client/types.js +2 -0
  29. package/dist/browser/clients/rpc-client/types.js.map +1 -0
  30. package/dist/browser/community/community-client-manager.d.ts +60 -0
  31. package/dist/browser/community/community-client-manager.js +717 -0
  32. package/dist/browser/community/community-client-manager.js.map +1 -0
  33. package/dist/browser/community/community-clients.d.ts +18 -0
  34. package/dist/browser/community/community-clients.js +12 -0
  35. package/dist/browser/community/community-clients.js.map +1 -0
  36. package/dist/browser/community/community-wire.d.ts +20 -0
  37. package/dist/browser/community/community-wire.js +38 -0
  38. package/dist/browser/community/community-wire.js.map +1 -0
  39. package/dist/browser/community/remote-community.d.ts +110 -0
  40. package/dist/browser/community/remote-community.js +555 -0
  41. package/dist/browser/community/remote-community.js.map +1 -0
  42. package/dist/browser/community/rpc-local-community.d.ts +41 -0
  43. package/dist/browser/community/rpc-local-community.js +289 -0
  44. package/dist/browser/community/rpc-local-community.js.map +1 -0
  45. package/dist/browser/community/rpc-remote-community.d.ts +18 -0
  46. package/dist/browser/community/rpc-remote-community.js +286 -0
  47. package/dist/browser/community/rpc-remote-community.js.map +1 -0
  48. package/dist/browser/community/schema.d.ts +4217 -0
  49. package/dist/browser/community/schema.js +289 -0
  50. package/dist/browser/community/schema.js.map +1 -0
  51. package/dist/browser/community/types.d.ts +135 -0
  52. package/dist/browser/community/types.js +2 -0
  53. package/dist/browser/community/types.js.map +1 -0
  54. package/dist/browser/constants.d.ts +6 -0
  55. package/dist/browser/constants.js +9 -0
  56. package/dist/browser/constants.js.map +1 -0
  57. package/dist/browser/decorator-util.d.ts +1 -0
  58. package/dist/browser/decorator-util.js +35 -0
  59. package/dist/browser/decorator-util.js.map +1 -0
  60. package/dist/browser/errors.d.ts +343 -0
  61. package/dist/browser/errors.js +358 -0
  62. package/dist/browser/errors.js.map +1 -0
  63. package/dist/browser/general-util/limited-set.d.ts +15 -0
  64. package/dist/browser/general-util/limited-set.js +66 -0
  65. package/dist/browser/general-util/limited-set.js.map +1 -0
  66. package/dist/browser/generated-version.d.ts +1 -0
  67. package/dist/browser/generated-version.js +3 -0
  68. package/dist/browser/generated-version.js.map +1 -0
  69. package/dist/browser/generic-state-client.d.ts +6 -0
  70. package/dist/browser/generic-state-client.js +11 -0
  71. package/dist/browser/generic-state-client.js.map +1 -0
  72. package/dist/browser/helia/helia-for-pkc.d.ts +3 -0
  73. package/dist/browser/helia/helia-for-pkc.js +255 -0
  74. package/dist/browser/helia/helia-for-pkc.js.map +1 -0
  75. package/dist/browser/helia/ipns-over-pubsub-with-fetch.d.ts +36 -0
  76. package/dist/browser/helia/ipns-over-pubsub-with-fetch.js +229 -0
  77. package/dist/browser/helia/ipns-over-pubsub-with-fetch.js.map +1 -0
  78. package/dist/browser/helia/libp2pjsClient.d.ts +27 -0
  79. package/dist/browser/helia/libp2pjsClient.js +15 -0
  80. package/dist/browser/helia/libp2pjsClient.js.map +1 -0
  81. package/dist/browser/helia/types.d.ts +19 -0
  82. package/dist/browser/helia/types.js +2 -0
  83. package/dist/browser/helia/types.js.map +1 -0
  84. package/dist/browser/helia/util.d.ts +13 -0
  85. package/dist/browser/helia/util.js +98 -0
  86. package/dist/browser/helia/util.js.map +1 -0
  87. package/dist/browser/index.d.ts +244 -0
  88. package/dist/browser/index.js +36 -0
  89. package/dist/browser/index.js.map +1 -0
  90. package/dist/browser/logger.d.ts +12 -0
  91. package/dist/browser/logger.js +11 -0
  92. package/dist/browser/logger.js.map +1 -0
  93. package/dist/browser/pages/pages-client-manager.d.ts +159 -0
  94. package/dist/browser/pages/pages-client-manager.js +334 -0
  95. package/dist/browser/pages/pages-client-manager.js.map +1 -0
  96. package/dist/browser/pages/pages-clients.d.ts +11 -0
  97. package/dist/browser/pages/pages-clients.js +10 -0
  98. package/dist/browser/pages/pages-clients.js.map +1 -0
  99. package/dist/browser/pages/pages.d.ts +107 -0
  100. package/dist/browser/pages/pages.js +262 -0
  101. package/dist/browser/pages/pages.js.map +1 -0
  102. package/dist/browser/pages/schema-util.d.ts +3 -0
  103. package/dist/browser/pages/schema-util.js +3 -0
  104. package/dist/browser/pages/schema-util.js.map +1 -0
  105. package/dist/browser/pages/schema.d.ts +719 -0
  106. package/dist/browser/pages/schema.js +32 -0
  107. package/dist/browser/pages/schema.js.map +1 -0
  108. package/dist/browser/pages/types.d.ts +44 -0
  109. package/dist/browser/pages/types.js +2 -0
  110. package/dist/browser/pages/types.js.map +1 -0
  111. package/dist/browser/pages/util.d.ts +56 -0
  112. package/dist/browser/pages/util.js +446 -0
  113. package/dist/browser/pages/util.js.map +1 -0
  114. package/dist/browser/pkc/pkc-client-manager.d.ts +44 -0
  115. package/dist/browser/pkc/pkc-client-manager.js +156 -0
  116. package/dist/browser/pkc/pkc-client-manager.js.map +1 -0
  117. package/dist/browser/pkc/pkc-clients.d.ts +11 -0
  118. package/dist/browser/pkc/pkc-clients.js +8 -0
  119. package/dist/browser/pkc/pkc-clients.js.map +1 -0
  120. package/dist/browser/pkc/pkc-with-rpc-client.d.ts +19 -0
  121. package/dist/browser/pkc/pkc-with-rpc-client.js +128 -0
  122. package/dist/browser/pkc/pkc-with-rpc-client.js.map +1 -0
  123. package/dist/browser/pkc/pkc.d.ts +137 -0
  124. package/dist/browser/pkc/pkc.js +888 -0
  125. package/dist/browser/pkc/pkc.js.map +1 -0
  126. package/dist/browser/pkc/tracked-instance-registry-util.d.ts +44 -0
  127. package/dist/browser/pkc/tracked-instance-registry-util.js +106 -0
  128. package/dist/browser/pkc/tracked-instance-registry-util.js.map +1 -0
  129. package/dist/browser/pkc/tracked-instance-registry.d.ts +18 -0
  130. package/dist/browser/pkc/tracked-instance-registry.js +134 -0
  131. package/dist/browser/pkc/tracked-instance-registry.js.map +1 -0
  132. package/dist/browser/pkc-error.d.ts +65 -0
  133. package/dist/browser/pkc-error.js +137 -0
  134. package/dist/browser/pkc-error.js.map +1 -0
  135. package/dist/browser/publications/comment/comment-client-manager.d.ts +86 -0
  136. package/dist/browser/publications/comment/comment-client-manager.js +908 -0
  137. package/dist/browser/publications/comment/comment-client-manager.js.map +1 -0
  138. package/dist/browser/publications/comment/comment-clients.d.ts +19 -0
  139. package/dist/browser/publications/comment/comment-clients.js +12 -0
  140. package/dist/browser/publications/comment/comment-clients.js.map +1 -0
  141. package/dist/browser/publications/comment/comment-util.d.ts +10 -0
  142. package/dist/browser/publications/comment/comment-util.js +202 -0
  143. package/dist/browser/publications/comment/comment-util.js.map +1 -0
  144. package/dist/browser/publications/comment/comment.d.ts +147 -0
  145. package/dist/browser/publications/comment/comment.js +1044 -0
  146. package/dist/browser/publications/comment/comment.js.map +1 -0
  147. package/dist/browser/publications/comment/schema.d.ts +1237 -0
  148. package/dist/browser/publications/comment/schema.js +184 -0
  149. package/dist/browser/publications/comment/schema.js.map +1 -0
  150. package/dist/browser/publications/comment/types.d.ts +100 -0
  151. package/dist/browser/publications/comment/types.js +2 -0
  152. package/dist/browser/publications/comment/types.js.map +1 -0
  153. package/dist/browser/publications/comment-edit/comment-edit.d.ts +41 -0
  154. package/dist/browser/publications/comment-edit/comment-edit.js +63 -0
  155. package/dist/browser/publications/comment-edit/comment-edit.js.map +1 -0
  156. package/dist/browser/publications/comment-edit/schema.d.ts +295 -0
  157. package/dist/browser/publications/comment-edit/schema.js +55 -0
  158. package/dist/browser/publications/comment-edit/schema.js.map +1 -0
  159. package/dist/browser/publications/comment-edit/types.d.ts +25 -0
  160. package/dist/browser/publications/comment-edit/types.js +2 -0
  161. package/dist/browser/publications/comment-edit/types.js.map +1 -0
  162. package/dist/browser/publications/comment-moderation/comment-moderation.d.ts +36 -0
  163. package/dist/browser/publications/comment-moderation/comment-moderation.js +53 -0
  164. package/dist/browser/publications/comment-moderation/comment-moderation.js.map +1 -0
  165. package/dist/browser/publications/comment-moderation/schema.d.ts +315 -0
  166. package/dist/browser/publications/comment-moderation/schema.js +62 -0
  167. package/dist/browser/publications/comment-moderation/schema.js.map +1 -0
  168. package/dist/browser/publications/comment-moderation/types.d.ts +22 -0
  169. package/dist/browser/publications/comment-moderation/types.js +2 -0
  170. package/dist/browser/publications/comment-moderation/types.js.map +1 -0
  171. package/dist/browser/publications/community-edit/community-edit.d.ts +35 -0
  172. package/dist/browser/publications/community-edit/community-edit.js +50 -0
  173. package/dist/browser/publications/community-edit/community-edit.js.map +1 -0
  174. package/dist/browser/publications/community-edit/schema.d.ts +467 -0
  175. package/dist/browser/publications/community-edit/schema.js +36 -0
  176. package/dist/browser/publications/community-edit/schema.js.map +1 -0
  177. package/dist/browser/publications/community-edit/types.d.ts +19 -0
  178. package/dist/browser/publications/community-edit/types.js +2 -0
  179. package/dist/browser/publications/community-edit/types.js.map +1 -0
  180. package/dist/browser/publications/publication-author.d.ts +22 -0
  181. package/dist/browser/publications/publication-author.js +66 -0
  182. package/dist/browser/publications/publication-author.js.map +1 -0
  183. package/dist/browser/publications/publication-client-manager.d.ts +62 -0
  184. package/dist/browser/publications/publication-client-manager.js +257 -0
  185. package/dist/browser/publications/publication-client-manager.js.map +1 -0
  186. package/dist/browser/publications/publication-clients.d.ts +19 -0
  187. package/dist/browser/publications/publication-clients.js +12 -0
  188. package/dist/browser/publications/publication-clients.js.map +1 -0
  189. package/dist/browser/publications/publication-community.d.ts +55 -0
  190. package/dist/browser/publications/publication-community.js +87 -0
  191. package/dist/browser/publications/publication-community.js.map +1 -0
  192. package/dist/browser/publications/publication.d.ts +120 -0
  193. package/dist/browser/publications/publication.js +950 -0
  194. package/dist/browser/publications/publication.js.map +1 -0
  195. package/dist/browser/publications/types.d.ts +26 -0
  196. package/dist/browser/publications/types.js +2 -0
  197. package/dist/browser/publications/types.js.map +1 -0
  198. package/dist/browser/publications/vote/schema.d.ts +150 -0
  199. package/dist/browser/publications/vote/schema.js +44 -0
  200. package/dist/browser/publications/vote/schema.js.map +1 -0
  201. package/dist/browser/publications/vote/types.d.ts +21 -0
  202. package/dist/browser/publications/vote/types.js +2 -0
  203. package/dist/browser/publications/vote/types.js.map +1 -0
  204. package/dist/browser/publications/vote/vote.d.ts +36 -0
  205. package/dist/browser/publications/vote/vote.js +49 -0
  206. package/dist/browser/publications/vote/vote.js.map +1 -0
  207. package/dist/browser/pubsub-messages/schema.d.ts +964 -0
  208. package/dist/browser/pubsub-messages/schema.js +98 -0
  209. package/dist/browser/pubsub-messages/schema.js.map +1 -0
  210. package/dist/browser/pubsub-messages/types.d.ts +81 -0
  211. package/dist/browser/pubsub-messages/types.js +2 -0
  212. package/dist/browser/pubsub-messages/types.js.map +1 -0
  213. package/dist/browser/rpc/src/index.d.ts +483 -0
  214. package/dist/browser/rpc/src/index.js +1267 -0
  215. package/dist/browser/rpc/src/index.js.map +1 -0
  216. package/dist/browser/rpc/src/json-rpc-util.d.ts +1 -0
  217. package/dist/browser/rpc/src/json-rpc-util.js +19 -0
  218. package/dist/browser/rpc/src/json-rpc-util.js.map +1 -0
  219. package/dist/browser/rpc/src/lib/pkc-js/index.d.ts +132 -0
  220. package/dist/browser/rpc/src/lib/pkc-js/index.js +29 -0
  221. package/dist/browser/rpc/src/lib/pkc-js/index.js.map +1 -0
  222. package/dist/browser/rpc/src/lib/pkc-js/pkc-js-mock.d.ts +1 -0
  223. package/dist/browser/rpc/src/lib/pkc-js/pkc-js-mock.js +472 -0
  224. package/dist/browser/rpc/src/lib/pkc-js/pkc-js-mock.js.map +1 -0
  225. package/dist/browser/rpc/src/schema.d.ts +843 -0
  226. package/dist/browser/rpc/src/schema.js +28 -0
  227. package/dist/browser/rpc/src/schema.js.map +1 -0
  228. package/dist/browser/rpc/src/types.d.ts +24 -0
  229. package/dist/browser/rpc/src/types.js +2 -0
  230. package/dist/browser/rpc/src/types.js.map +1 -0
  231. package/dist/browser/rpc/src/utils.d.ts +7 -0
  232. package/dist/browser/rpc/src/utils.js +58 -0
  233. package/dist/browser/rpc/src/utils.js.map +1 -0
  234. package/dist/browser/runtime/browser/community/challenges/index.d.ts +6 -0
  235. package/dist/browser/runtime/browser/community/challenges/index.js +7 -0
  236. package/dist/browser/runtime/browser/community/challenges/index.js.map +1 -0
  237. package/dist/browser/runtime/browser/community/local-community.d.ts +3 -0
  238. package/dist/browser/runtime/browser/community/local-community.js +6 -0
  239. package/dist/browser/runtime/browser/community/local-community.js.map +1 -0
  240. package/dist/browser/runtime/browser/db-handler.d.ts +4 -0
  241. package/dist/browser/runtime/browser/db-handler.js +8 -0
  242. package/dist/browser/runtime/browser/db-handler.js.map +1 -0
  243. package/dist/browser/runtime/browser/localforage-lru.d.ts +15 -0
  244. package/dist/browser/runtime/browser/localforage-lru.js +140 -0
  245. package/dist/browser/runtime/browser/localforage-lru.js.map +1 -0
  246. package/dist/browser/runtime/browser/lru-storage.d.ts +14 -0
  247. package/dist/browser/runtime/browser/lru-storage.js +34 -0
  248. package/dist/browser/runtime/browser/lru-storage.js.map +1 -0
  249. package/dist/browser/runtime/browser/native-functions.d.ts +3 -0
  250. package/dist/browser/runtime/browser/native-functions.js +6 -0
  251. package/dist/browser/runtime/browser/native-functions.js.map +1 -0
  252. package/dist/browser/runtime/browser/polyfill.d.ts +3 -0
  253. package/dist/browser/runtime/browser/polyfill.js +37 -0
  254. package/dist/browser/runtime/browser/polyfill.js.map +1 -0
  255. package/dist/browser/runtime/browser/setup-kubo-address-rewriter-and-http-router.d.ts +1 -0
  256. package/dist/browser/runtime/browser/setup-kubo-address-rewriter-and-http-router.js +4 -0
  257. package/dist/browser/runtime/browser/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
  258. package/dist/browser/runtime/browser/storage.d.ts +13 -0
  259. package/dist/browser/runtime/browser/storage.js +37 -0
  260. package/dist/browser/runtime/browser/storage.js.map +1 -0
  261. package/dist/browser/runtime/browser/util.d.ts +14 -0
  262. package/dist/browser/runtime/browser/util.js +61 -0
  263. package/dist/browser/runtime/browser/util.js.map +1 -0
  264. package/dist/browser/runtime/node/address-rewriter-db.d.ts +31 -0
  265. package/dist/browser/runtime/node/address-rewriter-db.js +156 -0
  266. package/dist/browser/runtime/node/address-rewriter-db.js.map +1 -0
  267. package/dist/browser/runtime/node/addresses-rewriter-proxy-server.d.ts +45 -0
  268. package/dist/browser/runtime/node/addresses-rewriter-proxy-server.js +493 -0
  269. package/dist/browser/runtime/node/addresses-rewriter-proxy-server.js.map +1 -0
  270. package/dist/browser/runtime/node/community/challenges/exclude/exclude.d.ts +8 -0
  271. package/dist/browser/runtime/node/community/challenges/exclude/exclude.js +280 -0
  272. package/dist/browser/runtime/node/community/challenges/exclude/exclude.js.map +1 -0
  273. package/dist/browser/runtime/node/community/challenges/exclude/index.d.ts +3 -0
  274. package/dist/browser/runtime/node/community/challenges/exclude/index.js +4 -0
  275. package/dist/browser/runtime/node/community/challenges/exclude/index.js.map +1 -0
  276. package/dist/browser/runtime/node/community/challenges/exclude/rate-limiter.d.ts +5 -0
  277. package/dist/browser/runtime/node/community/challenges/exclude/rate-limiter.js +127 -0
  278. package/dist/browser/runtime/node/community/challenges/exclude/rate-limiter.js.map +1 -0
  279. package/dist/browser/runtime/node/community/challenges/exclude/utils.d.ts +13 -0
  280. package/dist/browser/runtime/node/community/challenges/exclude/utils.js +52 -0
  281. package/dist/browser/runtime/node/community/challenges/exclude/utils.js.map +1 -0
  282. package/dist/browser/runtime/node/community/challenges/index.d.ts +32 -0
  283. package/dist/browser/runtime/node/community/challenges/index.js +307 -0
  284. package/dist/browser/runtime/node/community/challenges/index.js.map +1 -0
  285. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/blacklist.d.ts +5 -0
  286. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/blacklist.js +118 -0
  287. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/blacklist.js.map +1 -0
  288. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/fail.d.ts +5 -0
  289. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/fail.js +26 -0
  290. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/fail.js.map +1 -0
  291. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/publication-match.d.ts +5 -0
  292. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/publication-match.js +135 -0
  293. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/publication-match.js.map +1 -0
  294. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/question.d.ts +5 -0
  295. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/question.js +66 -0
  296. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/question.js.map +1 -0
  297. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/text-math.d.ts +5 -0
  298. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/text-math.js +61 -0
  299. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/text-math.js.map +1 -0
  300. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/whitelist.d.ts +5 -0
  301. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/whitelist.js +118 -0
  302. package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/whitelist.js.map +1 -0
  303. package/dist/browser/runtime/node/community/db-handler-types.d.ts +19 -0
  304. package/dist/browser/runtime/node/community/db-handler-types.js +2 -0
  305. package/dist/browser/runtime/node/community/db-handler-types.js.map +1 -0
  306. package/dist/browser/runtime/node/community/db-handler.d.ts +226 -0
  307. package/dist/browser/runtime/node/community/db-handler.js +2462 -0
  308. package/dist/browser/runtime/node/community/db-handler.js.map +1 -0
  309. package/dist/browser/runtime/node/community/db-row-parser.d.ts +19 -0
  310. package/dist/browser/runtime/node/community/db-row-parser.js +40 -0
  311. package/dist/browser/runtime/node/community/db-row-parser.js.map +1 -0
  312. package/dist/browser/runtime/node/community/keyv-better-sqlite3.d.ts +68 -0
  313. package/dist/browser/runtime/node/community/keyv-better-sqlite3.js +251 -0
  314. package/dist/browser/runtime/node/community/keyv-better-sqlite3.js.map +1 -0
  315. package/dist/browser/runtime/node/community/local-community.d.ts +129 -0
  316. package/dist/browser/runtime/node/community/local-community.js +2978 -0
  317. package/dist/browser/runtime/node/community/local-community.js.map +1 -0
  318. package/dist/browser/runtime/node/community/page-generator.d.ts +433 -0
  319. package/dist/browser/runtime/node/community/page-generator.js +441 -0
  320. package/dist/browser/runtime/node/community/page-generator.js.map +1 -0
  321. package/dist/browser/runtime/node/lru-storage.d.ts +14 -0
  322. package/dist/browser/runtime/node/lru-storage.js +40 -0
  323. package/dist/browser/runtime/node/lru-storage.js.map +1 -0
  324. package/dist/browser/runtime/node/native-functions.d.ts +3 -0
  325. package/dist/browser/runtime/node/native-functions.js +7 -0
  326. package/dist/browser/runtime/node/native-functions.js.map +1 -0
  327. package/dist/browser/runtime/node/polyfill.d.ts +3 -0
  328. package/dist/browser/runtime/node/polyfill.js +20 -0
  329. package/dist/browser/runtime/node/polyfill.js.map +1 -0
  330. package/dist/browser/runtime/node/setup-kubo-address-rewriter-and-http-router.d.ts +4 -0
  331. package/dist/browser/runtime/node/setup-kubo-address-rewriter-and-http-router.js +240 -0
  332. package/dist/browser/runtime/node/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
  333. package/dist/browser/runtime/node/sqlite-lru-cache.d.ts +52 -0
  334. package/dist/browser/runtime/node/sqlite-lru-cache.js +127 -0
  335. package/dist/browser/runtime/node/sqlite-lru-cache.js.map +1 -0
  336. package/dist/browser/runtime/node/storage.d.ts +14 -0
  337. package/dist/browser/runtime/node/storage.js +52 -0
  338. package/dist/browser/runtime/node/storage.js.map +1 -0
  339. package/dist/browser/runtime/node/test/helpers/hanging-runner.d.ts +1 -0
  340. package/dist/browser/runtime/node/test/helpers/hanging-runner.js +157 -0
  341. package/dist/browser/runtime/node/test/helpers/hanging-runner.js.map +1 -0
  342. package/dist/browser/runtime/node/test/helpers/run-hanging-node.d.ts +7 -0
  343. package/dist/browser/runtime/node/test/helpers/run-hanging-node.js +68 -0
  344. package/dist/browser/runtime/node/test/helpers/run-hanging-node.js.map +1 -0
  345. package/dist/browser/runtime/node/test/mock-http-router.d.ts +54 -0
  346. package/dist/browser/runtime/node/test/mock-http-router.js +397 -0
  347. package/dist/browser/runtime/node/test/mock-http-router.js.map +1 -0
  348. package/dist/browser/runtime/node/util.d.ts +43 -0
  349. package/dist/browser/runtime/node/util.js +384 -0
  350. package/dist/browser/runtime/node/util.js.map +1 -0
  351. package/dist/browser/schema/schema-util.d.ts +2751 -0
  352. package/dist/browser/schema/schema-util.js +562 -0
  353. package/dist/browser/schema/schema-util.js.map +1 -0
  354. package/dist/browser/schema/schema.d.ts +237 -0
  355. package/dist/browser/schema/schema.js +128 -0
  356. package/dist/browser/schema/schema.js.map +1 -0
  357. package/dist/browser/schema.d.ts +1142 -0
  358. package/dist/browser/schema.js +104 -0
  359. package/dist/browser/schema.js.map +1 -0
  360. package/dist/browser/signer/constants.d.ts +2 -0
  361. package/dist/browser/signer/constants.js +3 -0
  362. package/dist/browser/signer/constants.js.map +1 -0
  363. package/dist/browser/signer/encryption.d.ts +21 -0
  364. package/dist/browser/signer/encryption.js +122 -0
  365. package/dist/browser/signer/encryption.js.map +1 -0
  366. package/dist/browser/signer/index.d.ts +21 -0
  367. package/dist/browser/signer/index.js +49 -0
  368. package/dist/browser/signer/index.js.map +1 -0
  369. package/dist/browser/signer/signatures.d.ts +200 -0
  370. package/dist/browser/signer/signatures.js +594 -0
  371. package/dist/browser/signer/signatures.js.map +1 -0
  372. package/dist/browser/signer/types.d.ts +20 -0
  373. package/dist/browser/signer/types.js +2 -0
  374. package/dist/browser/signer/types.js.map +1 -0
  375. package/dist/browser/signer/util.d.ts +14 -0
  376. package/dist/browser/signer/util.js +156 -0
  377. package/dist/browser/signer/util.js.map +1 -0
  378. package/dist/browser/stats.d.ts +15 -0
  379. package/dist/browser/stats.js +64 -0
  380. package/dist/browser/stats.js.map +1 -0
  381. package/dist/browser/test/mock-ipfs-client.d.ts +34 -0
  382. package/dist/browser/test/mock-ipfs-client.js +208 -0
  383. package/dist/browser/test/mock-ipfs-client.js.map +1 -0
  384. package/dist/browser/test/node/hanging-test/scenarios/comment-publish-pending.scenario.d.ts +8 -0
  385. package/dist/browser/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js +21 -0
  386. package/dist/browser/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js.map +1 -0
  387. package/dist/browser/test/node/hanging-test/scenarios/comment-publish.scenario.d.ts +8 -0
  388. package/dist/browser/test/node/hanging-test/scenarios/comment-publish.scenario.js +19 -0
  389. package/dist/browser/test/node/hanging-test/scenarios/comment-publish.scenario.js.map +1 -0
  390. package/dist/browser/test/node/hanging-test/scenarios/comment-update.scenario.d.ts +8 -0
  391. package/dist/browser/test/node/hanging-test/scenarios/comment-update.scenario.js +22 -0
  392. package/dist/browser/test/node/hanging-test/scenarios/comment-update.scenario.js.map +1 -0
  393. package/dist/browser/test/node/hanging-test/scenarios/community-start.scenario.d.ts +8 -0
  394. package/dist/browser/test/node/hanging-test/scenarios/community-start.scenario.js +23 -0
  395. package/dist/browser/test/node/hanging-test/scenarios/community-start.scenario.js.map +1 -0
  396. package/dist/browser/test/node/hanging-test/scenarios/community-update.scenario.d.ts +8 -0
  397. package/dist/browser/test/node/hanging-test/scenarios/community-update.scenario.js +21 -0
  398. package/dist/browser/test/node/hanging-test/scenarios/community-update.scenario.js.map +1 -0
  399. package/dist/browser/test/node/hanging-test/scenarios/destroy-only.scenario.d.ts +7 -0
  400. package/dist/browser/test/node/hanging-test/scenarios/destroy-only.scenario.js +15 -0
  401. package/dist/browser/test/node/hanging-test/scenarios/destroy-only.scenario.js.map +1 -0
  402. package/dist/browser/test/node/hanging-test/scenarios/hanging-test-util.d.ts +30 -0
  403. package/dist/browser/test/node/hanging-test/scenarios/hanging-test-util.js +46 -0
  404. package/dist/browser/test/node/hanging-test/scenarios/hanging-test-util.js.map +1 -0
  405. package/dist/browser/test/test-util.d.ts +1019 -0
  406. package/dist/browser/test/test-util.js +1886 -0
  407. package/dist/browser/test/test-util.js.map +1 -0
  408. package/dist/browser/types.d.ts +165 -0
  409. package/dist/browser/types.js +2 -0
  410. package/dist/browser/types.js.map +1 -0
  411. package/dist/browser/util/inflight-fetch-manager.d.ts +11 -0
  412. package/dist/browser/util/inflight-fetch-manager.js +41 -0
  413. package/dist/browser/util/inflight-fetch-manager.js.map +1 -0
  414. package/dist/browser/util.d.ts +120 -0
  415. package/dist/browser/util.js +816 -0
  416. package/dist/browser/util.js.map +1 -0
  417. package/dist/browser/version.d.ts +7 -0
  418. package/dist/browser/version.js +12 -0
  419. package/dist/browser/version.js.map +1 -0
  420. package/dist/browser/zod-error-map.d.ts +1 -0
  421. package/dist/browser/zod-error-map.js +10 -0
  422. package/dist/browser/zod-error-map.js.map +1 -0
  423. package/dist/node/challenges.d.ts +1 -0
  424. package/dist/node/challenges.js +2 -0
  425. package/dist/node/challenges.js.map +1 -0
  426. package/dist/node/clients/base-client-manager.d.ts +126 -0
  427. package/dist/node/clients/base-client-manager.js +673 -0
  428. package/dist/node/clients/base-client-manager.js.map +1 -0
  429. package/dist/node/clients/name-resolver-client.d.ts +8 -0
  430. package/dist/node/clients/name-resolver-client.js +10 -0
  431. package/dist/node/clients/name-resolver-client.js.map +1 -0
  432. package/dist/node/clients/pkc-typed-emitter.d.ts +9 -0
  433. package/dist/node/clients/pkc-typed-emitter.js +52 -0
  434. package/dist/node/clients/pkc-typed-emitter.js.map +1 -0
  435. package/dist/node/clients/rpc-client/decode-rpc-response-util.d.ts +8 -0
  436. package/dist/node/clients/rpc-client/decode-rpc-response-util.js +53 -0
  437. package/dist/node/clients/rpc-client/decode-rpc-response-util.js.map +1 -0
  438. package/dist/node/clients/rpc-client/pkc-rpc-client.d.ts +68 -0
  439. package/dist/node/clients/rpc-client/pkc-rpc-client.js +404 -0
  440. package/dist/node/clients/rpc-client/pkc-rpc-client.js.map +1 -0
  441. package/dist/node/clients/rpc-client/rpc-schema-util.d.ts +147 -0
  442. package/dist/node/clients/rpc-client/rpc-schema-util.js +11 -0
  443. package/dist/node/clients/rpc-client/rpc-schema-util.js.map +1 -0
  444. package/dist/node/clients/rpc-client/schema.d.ts +433 -0
  445. package/dist/node/clients/rpc-client/schema.js +49 -0
  446. package/dist/node/clients/rpc-client/schema.js.map +1 -0
  447. package/dist/node/clients/rpc-client/types.d.ts +8 -0
  448. package/dist/node/clients/rpc-client/types.js +2 -0
  449. package/dist/node/clients/rpc-client/types.js.map +1 -0
  450. package/dist/node/community/community-client-manager.d.ts +60 -0
  451. package/dist/node/community/community-client-manager.js +717 -0
  452. package/dist/node/community/community-client-manager.js.map +1 -0
  453. package/dist/node/community/community-clients.d.ts +18 -0
  454. package/dist/node/community/community-clients.js +12 -0
  455. package/dist/node/community/community-clients.js.map +1 -0
  456. package/dist/node/community/community-wire.d.ts +20 -0
  457. package/dist/node/community/community-wire.js +38 -0
  458. package/dist/node/community/community-wire.js.map +1 -0
  459. package/dist/node/community/remote-community.d.ts +110 -0
  460. package/dist/node/community/remote-community.js +555 -0
  461. package/dist/node/community/remote-community.js.map +1 -0
  462. package/dist/node/community/rpc-local-community.d.ts +41 -0
  463. package/dist/node/community/rpc-local-community.js +289 -0
  464. package/dist/node/community/rpc-local-community.js.map +1 -0
  465. package/dist/node/community/rpc-remote-community.d.ts +18 -0
  466. package/dist/node/community/rpc-remote-community.js +286 -0
  467. package/dist/node/community/rpc-remote-community.js.map +1 -0
  468. package/dist/node/community/schema.d.ts +4217 -0
  469. package/dist/node/community/schema.js +289 -0
  470. package/dist/node/community/schema.js.map +1 -0
  471. package/dist/node/community/types.d.ts +135 -0
  472. package/dist/node/community/types.js +2 -0
  473. package/dist/node/community/types.js.map +1 -0
  474. package/dist/node/constants.d.ts +6 -0
  475. package/dist/node/constants.js +9 -0
  476. package/dist/node/constants.js.map +1 -0
  477. package/dist/node/decorator-util.d.ts +1 -0
  478. package/dist/node/decorator-util.js +35 -0
  479. package/dist/node/decorator-util.js.map +1 -0
  480. package/dist/node/errors.d.ts +343 -0
  481. package/dist/node/errors.js +358 -0
  482. package/dist/node/errors.js.map +1 -0
  483. package/dist/node/general-util/limited-set.d.ts +15 -0
  484. package/dist/node/general-util/limited-set.js +66 -0
  485. package/dist/node/general-util/limited-set.js.map +1 -0
  486. package/dist/node/generated-version.d.ts +1 -0
  487. package/dist/node/generated-version.js +3 -0
  488. package/dist/node/generated-version.js.map +1 -0
  489. package/dist/node/generic-state-client.d.ts +6 -0
  490. package/dist/node/generic-state-client.js +11 -0
  491. package/dist/node/generic-state-client.js.map +1 -0
  492. package/dist/node/helia/helia-for-pkc.d.ts +3 -0
  493. package/dist/node/helia/helia-for-pkc.js +255 -0
  494. package/dist/node/helia/helia-for-pkc.js.map +1 -0
  495. package/dist/node/helia/ipns-over-pubsub-with-fetch.d.ts +36 -0
  496. package/dist/node/helia/ipns-over-pubsub-with-fetch.js +229 -0
  497. package/dist/node/helia/ipns-over-pubsub-with-fetch.js.map +1 -0
  498. package/dist/node/helia/libp2pjsClient.d.ts +27 -0
  499. package/dist/node/helia/libp2pjsClient.js +15 -0
  500. package/dist/node/helia/libp2pjsClient.js.map +1 -0
  501. package/dist/node/helia/types.d.ts +19 -0
  502. package/dist/node/helia/types.js +2 -0
  503. package/dist/node/helia/types.js.map +1 -0
  504. package/dist/node/helia/util.d.ts +13 -0
  505. package/dist/node/helia/util.js +98 -0
  506. package/dist/node/helia/util.js.map +1 -0
  507. package/dist/node/index.d.ts +244 -0
  508. package/dist/node/index.js +36 -0
  509. package/dist/node/index.js.map +1 -0
  510. package/dist/node/logger.d.ts +12 -0
  511. package/dist/node/logger.js +11 -0
  512. package/dist/node/logger.js.map +1 -0
  513. package/dist/node/pages/pages-client-manager.d.ts +159 -0
  514. package/dist/node/pages/pages-client-manager.js +334 -0
  515. package/dist/node/pages/pages-client-manager.js.map +1 -0
  516. package/dist/node/pages/pages-clients.d.ts +11 -0
  517. package/dist/node/pages/pages-clients.js +10 -0
  518. package/dist/node/pages/pages-clients.js.map +1 -0
  519. package/dist/node/pages/pages.d.ts +107 -0
  520. package/dist/node/pages/pages.js +262 -0
  521. package/dist/node/pages/pages.js.map +1 -0
  522. package/dist/node/pages/schema-util.d.ts +3 -0
  523. package/dist/node/pages/schema-util.js +3 -0
  524. package/dist/node/pages/schema-util.js.map +1 -0
  525. package/dist/node/pages/schema.d.ts +719 -0
  526. package/dist/node/pages/schema.js +32 -0
  527. package/dist/node/pages/schema.js.map +1 -0
  528. package/dist/node/pages/types.d.ts +44 -0
  529. package/dist/node/pages/types.js +2 -0
  530. package/dist/node/pages/types.js.map +1 -0
  531. package/dist/node/pages/util.d.ts +56 -0
  532. package/dist/node/pages/util.js +446 -0
  533. package/dist/node/pages/util.js.map +1 -0
  534. package/dist/node/pkc/pkc-client-manager.d.ts +44 -0
  535. package/dist/node/pkc/pkc-client-manager.js +156 -0
  536. package/dist/node/pkc/pkc-client-manager.js.map +1 -0
  537. package/dist/node/pkc/pkc-clients.d.ts +11 -0
  538. package/dist/node/pkc/pkc-clients.js +8 -0
  539. package/dist/node/pkc/pkc-clients.js.map +1 -0
  540. package/dist/node/pkc/pkc-with-rpc-client.d.ts +19 -0
  541. package/dist/node/pkc/pkc-with-rpc-client.js +128 -0
  542. package/dist/node/pkc/pkc-with-rpc-client.js.map +1 -0
  543. package/dist/node/pkc/pkc.d.ts +137 -0
  544. package/dist/node/pkc/pkc.js +888 -0
  545. package/dist/node/pkc/pkc.js.map +1 -0
  546. package/dist/node/pkc/tracked-instance-registry-util.d.ts +44 -0
  547. package/dist/node/pkc/tracked-instance-registry-util.js +106 -0
  548. package/dist/node/pkc/tracked-instance-registry-util.js.map +1 -0
  549. package/dist/node/pkc/tracked-instance-registry.d.ts +18 -0
  550. package/dist/node/pkc/tracked-instance-registry.js +134 -0
  551. package/dist/node/pkc/tracked-instance-registry.js.map +1 -0
  552. package/dist/node/pkc-error.d.ts +65 -0
  553. package/dist/node/pkc-error.js +137 -0
  554. package/dist/node/pkc-error.js.map +1 -0
  555. package/dist/node/publications/comment/comment-client-manager.d.ts +86 -0
  556. package/dist/node/publications/comment/comment-client-manager.js +908 -0
  557. package/dist/node/publications/comment/comment-client-manager.js.map +1 -0
  558. package/dist/node/publications/comment/comment-clients.d.ts +19 -0
  559. package/dist/node/publications/comment/comment-clients.js +12 -0
  560. package/dist/node/publications/comment/comment-clients.js.map +1 -0
  561. package/dist/node/publications/comment/comment-util.d.ts +10 -0
  562. package/dist/node/publications/comment/comment-util.js +202 -0
  563. package/dist/node/publications/comment/comment-util.js.map +1 -0
  564. package/dist/node/publications/comment/comment.d.ts +147 -0
  565. package/dist/node/publications/comment/comment.js +1044 -0
  566. package/dist/node/publications/comment/comment.js.map +1 -0
  567. package/dist/node/publications/comment/schema.d.ts +1237 -0
  568. package/dist/node/publications/comment/schema.js +184 -0
  569. package/dist/node/publications/comment/schema.js.map +1 -0
  570. package/dist/node/publications/comment/types.d.ts +100 -0
  571. package/dist/node/publications/comment/types.js +2 -0
  572. package/dist/node/publications/comment/types.js.map +1 -0
  573. package/dist/node/publications/comment-edit/comment-edit.d.ts +41 -0
  574. package/dist/node/publications/comment-edit/comment-edit.js +63 -0
  575. package/dist/node/publications/comment-edit/comment-edit.js.map +1 -0
  576. package/dist/node/publications/comment-edit/schema.d.ts +295 -0
  577. package/dist/node/publications/comment-edit/schema.js +55 -0
  578. package/dist/node/publications/comment-edit/schema.js.map +1 -0
  579. package/dist/node/publications/comment-edit/types.d.ts +25 -0
  580. package/dist/node/publications/comment-edit/types.js +2 -0
  581. package/dist/node/publications/comment-edit/types.js.map +1 -0
  582. package/dist/node/publications/comment-moderation/comment-moderation.d.ts +36 -0
  583. package/dist/node/publications/comment-moderation/comment-moderation.js +53 -0
  584. package/dist/node/publications/comment-moderation/comment-moderation.js.map +1 -0
  585. package/dist/node/publications/comment-moderation/schema.d.ts +315 -0
  586. package/dist/node/publications/comment-moderation/schema.js +62 -0
  587. package/dist/node/publications/comment-moderation/schema.js.map +1 -0
  588. package/dist/node/publications/comment-moderation/types.d.ts +22 -0
  589. package/dist/node/publications/comment-moderation/types.js +2 -0
  590. package/dist/node/publications/comment-moderation/types.js.map +1 -0
  591. package/dist/node/publications/community-edit/community-edit.d.ts +35 -0
  592. package/dist/node/publications/community-edit/community-edit.js +50 -0
  593. package/dist/node/publications/community-edit/community-edit.js.map +1 -0
  594. package/dist/node/publications/community-edit/schema.d.ts +467 -0
  595. package/dist/node/publications/community-edit/schema.js +36 -0
  596. package/dist/node/publications/community-edit/schema.js.map +1 -0
  597. package/dist/node/publications/community-edit/types.d.ts +19 -0
  598. package/dist/node/publications/community-edit/types.js +2 -0
  599. package/dist/node/publications/community-edit/types.js.map +1 -0
  600. package/dist/node/publications/publication-author.d.ts +22 -0
  601. package/dist/node/publications/publication-author.js +66 -0
  602. package/dist/node/publications/publication-author.js.map +1 -0
  603. package/dist/node/publications/publication-client-manager.d.ts +62 -0
  604. package/dist/node/publications/publication-client-manager.js +257 -0
  605. package/dist/node/publications/publication-client-manager.js.map +1 -0
  606. package/dist/node/publications/publication-clients.d.ts +19 -0
  607. package/dist/node/publications/publication-clients.js +12 -0
  608. package/dist/node/publications/publication-clients.js.map +1 -0
  609. package/dist/node/publications/publication-community.d.ts +55 -0
  610. package/dist/node/publications/publication-community.js +87 -0
  611. package/dist/node/publications/publication-community.js.map +1 -0
  612. package/dist/node/publications/publication.d.ts +120 -0
  613. package/dist/node/publications/publication.js +950 -0
  614. package/dist/node/publications/publication.js.map +1 -0
  615. package/dist/node/publications/types.d.ts +26 -0
  616. package/dist/node/publications/types.js +2 -0
  617. package/dist/node/publications/types.js.map +1 -0
  618. package/dist/node/publications/vote/schema.d.ts +150 -0
  619. package/dist/node/publications/vote/schema.js +44 -0
  620. package/dist/node/publications/vote/schema.js.map +1 -0
  621. package/dist/node/publications/vote/types.d.ts +21 -0
  622. package/dist/node/publications/vote/types.js +2 -0
  623. package/dist/node/publications/vote/types.js.map +1 -0
  624. package/dist/node/publications/vote/vote.d.ts +36 -0
  625. package/dist/node/publications/vote/vote.js +49 -0
  626. package/dist/node/publications/vote/vote.js.map +1 -0
  627. package/dist/node/pubsub-messages/schema.d.ts +964 -0
  628. package/dist/node/pubsub-messages/schema.js +98 -0
  629. package/dist/node/pubsub-messages/schema.js.map +1 -0
  630. package/dist/node/pubsub-messages/types.d.ts +81 -0
  631. package/dist/node/pubsub-messages/types.js +2 -0
  632. package/dist/node/pubsub-messages/types.js.map +1 -0
  633. package/dist/node/rpc/src/index.d.ts +483 -0
  634. package/dist/node/rpc/src/index.js +1267 -0
  635. package/dist/node/rpc/src/index.js.map +1 -0
  636. package/dist/node/rpc/src/json-rpc-util.d.ts +1 -0
  637. package/dist/node/rpc/src/json-rpc-util.js +19 -0
  638. package/dist/node/rpc/src/json-rpc-util.js.map +1 -0
  639. package/dist/node/rpc/src/lib/pkc-js/index.d.ts +132 -0
  640. package/dist/node/rpc/src/lib/pkc-js/index.js +29 -0
  641. package/dist/node/rpc/src/lib/pkc-js/index.js.map +1 -0
  642. package/dist/node/rpc/src/lib/pkc-js/pkc-js-mock.d.ts +1 -0
  643. package/dist/node/rpc/src/lib/pkc-js/pkc-js-mock.js +472 -0
  644. package/dist/node/rpc/src/lib/pkc-js/pkc-js-mock.js.map +1 -0
  645. package/dist/node/rpc/src/schema.d.ts +843 -0
  646. package/dist/node/rpc/src/schema.js +28 -0
  647. package/dist/node/rpc/src/schema.js.map +1 -0
  648. package/dist/node/rpc/src/types.d.ts +24 -0
  649. package/dist/node/rpc/src/types.js +2 -0
  650. package/dist/node/rpc/src/types.js.map +1 -0
  651. package/dist/node/rpc/src/utils.d.ts +7 -0
  652. package/dist/node/rpc/src/utils.js +58 -0
  653. package/dist/node/rpc/src/utils.js.map +1 -0
  654. package/dist/node/runtime/browser/community/challenges/index.d.ts +6 -0
  655. package/dist/node/runtime/browser/community/challenges/index.js +7 -0
  656. package/dist/node/runtime/browser/community/challenges/index.js.map +1 -0
  657. package/dist/node/runtime/browser/community/local-community.d.ts +3 -0
  658. package/dist/node/runtime/browser/community/local-community.js +6 -0
  659. package/dist/node/runtime/browser/community/local-community.js.map +1 -0
  660. package/dist/node/runtime/browser/db-handler.d.ts +4 -0
  661. package/dist/node/runtime/browser/db-handler.js +8 -0
  662. package/dist/node/runtime/browser/db-handler.js.map +1 -0
  663. package/dist/node/runtime/browser/localforage-lru.d.ts +15 -0
  664. package/dist/node/runtime/browser/localforage-lru.js +140 -0
  665. package/dist/node/runtime/browser/localforage-lru.js.map +1 -0
  666. package/dist/node/runtime/browser/lru-storage.d.ts +14 -0
  667. package/dist/node/runtime/browser/lru-storage.js +34 -0
  668. package/dist/node/runtime/browser/lru-storage.js.map +1 -0
  669. package/dist/node/runtime/browser/native-functions.d.ts +3 -0
  670. package/dist/node/runtime/browser/native-functions.js +6 -0
  671. package/dist/node/runtime/browser/native-functions.js.map +1 -0
  672. package/dist/node/runtime/browser/polyfill.d.ts +3 -0
  673. package/dist/node/runtime/browser/polyfill.js +37 -0
  674. package/dist/node/runtime/browser/polyfill.js.map +1 -0
  675. package/dist/node/runtime/browser/setup-kubo-address-rewriter-and-http-router.d.ts +1 -0
  676. package/dist/node/runtime/browser/setup-kubo-address-rewriter-and-http-router.js +4 -0
  677. package/dist/node/runtime/browser/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
  678. package/dist/node/runtime/browser/storage.d.ts +13 -0
  679. package/dist/node/runtime/browser/storage.js +37 -0
  680. package/dist/node/runtime/browser/storage.js.map +1 -0
  681. package/dist/node/runtime/browser/util.d.ts +14 -0
  682. package/dist/node/runtime/browser/util.js +61 -0
  683. package/dist/node/runtime/browser/util.js.map +1 -0
  684. package/dist/node/runtime/node/address-rewriter-db.d.ts +31 -0
  685. package/dist/node/runtime/node/address-rewriter-db.js +156 -0
  686. package/dist/node/runtime/node/address-rewriter-db.js.map +1 -0
  687. package/dist/node/runtime/node/addresses-rewriter-proxy-server.d.ts +45 -0
  688. package/dist/node/runtime/node/addresses-rewriter-proxy-server.js +493 -0
  689. package/dist/node/runtime/node/addresses-rewriter-proxy-server.js.map +1 -0
  690. package/dist/node/runtime/node/community/challenges/exclude/exclude.d.ts +8 -0
  691. package/dist/node/runtime/node/community/challenges/exclude/exclude.js +280 -0
  692. package/dist/node/runtime/node/community/challenges/exclude/exclude.js.map +1 -0
  693. package/dist/node/runtime/node/community/challenges/exclude/index.d.ts +3 -0
  694. package/dist/node/runtime/node/community/challenges/exclude/index.js +4 -0
  695. package/dist/node/runtime/node/community/challenges/exclude/index.js.map +1 -0
  696. package/dist/node/runtime/node/community/challenges/exclude/rate-limiter.d.ts +5 -0
  697. package/dist/node/runtime/node/community/challenges/exclude/rate-limiter.js +127 -0
  698. package/dist/node/runtime/node/community/challenges/exclude/rate-limiter.js.map +1 -0
  699. package/dist/node/runtime/node/community/challenges/exclude/utils.d.ts +13 -0
  700. package/dist/node/runtime/node/community/challenges/exclude/utils.js +52 -0
  701. package/dist/node/runtime/node/community/challenges/exclude/utils.js.map +1 -0
  702. package/dist/node/runtime/node/community/challenges/index.d.ts +32 -0
  703. package/dist/node/runtime/node/community/challenges/index.js +307 -0
  704. package/dist/node/runtime/node/community/challenges/index.js.map +1 -0
  705. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/blacklist.d.ts +5 -0
  706. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/blacklist.js +118 -0
  707. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/blacklist.js.map +1 -0
  708. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/fail.d.ts +5 -0
  709. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/fail.js +26 -0
  710. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/fail.js.map +1 -0
  711. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/publication-match.d.ts +5 -0
  712. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/publication-match.js +135 -0
  713. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/publication-match.js.map +1 -0
  714. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/question.d.ts +5 -0
  715. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/question.js +66 -0
  716. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/question.js.map +1 -0
  717. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/text-math.d.ts +5 -0
  718. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/text-math.js +61 -0
  719. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/text-math.js.map +1 -0
  720. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/whitelist.d.ts +5 -0
  721. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/whitelist.js +118 -0
  722. package/dist/node/runtime/node/community/challenges/pkc-js-challenges/whitelist.js.map +1 -0
  723. package/dist/node/runtime/node/community/db-handler-types.d.ts +19 -0
  724. package/dist/node/runtime/node/community/db-handler-types.js +2 -0
  725. package/dist/node/runtime/node/community/db-handler-types.js.map +1 -0
  726. package/dist/node/runtime/node/community/db-handler.d.ts +226 -0
  727. package/dist/node/runtime/node/community/db-handler.js +2462 -0
  728. package/dist/node/runtime/node/community/db-handler.js.map +1 -0
  729. package/dist/node/runtime/node/community/db-row-parser.d.ts +19 -0
  730. package/dist/node/runtime/node/community/db-row-parser.js +40 -0
  731. package/dist/node/runtime/node/community/db-row-parser.js.map +1 -0
  732. package/dist/node/runtime/node/community/keyv-better-sqlite3.d.ts +68 -0
  733. package/dist/node/runtime/node/community/keyv-better-sqlite3.js +251 -0
  734. package/dist/node/runtime/node/community/keyv-better-sqlite3.js.map +1 -0
  735. package/dist/node/runtime/node/community/local-community.d.ts +129 -0
  736. package/dist/node/runtime/node/community/local-community.js +2978 -0
  737. package/dist/node/runtime/node/community/local-community.js.map +1 -0
  738. package/dist/node/runtime/node/community/page-generator.d.ts +433 -0
  739. package/dist/node/runtime/node/community/page-generator.js +441 -0
  740. package/dist/node/runtime/node/community/page-generator.js.map +1 -0
  741. package/dist/node/runtime/node/lru-storage.d.ts +14 -0
  742. package/dist/node/runtime/node/lru-storage.js +40 -0
  743. package/dist/node/runtime/node/lru-storage.js.map +1 -0
  744. package/dist/node/runtime/node/native-functions.d.ts +3 -0
  745. package/dist/node/runtime/node/native-functions.js +7 -0
  746. package/dist/node/runtime/node/native-functions.js.map +1 -0
  747. package/dist/node/runtime/node/polyfill.d.ts +3 -0
  748. package/dist/node/runtime/node/polyfill.js +20 -0
  749. package/dist/node/runtime/node/polyfill.js.map +1 -0
  750. package/dist/node/runtime/node/setup-kubo-address-rewriter-and-http-router.d.ts +4 -0
  751. package/dist/node/runtime/node/setup-kubo-address-rewriter-and-http-router.js +240 -0
  752. package/dist/node/runtime/node/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
  753. package/dist/node/runtime/node/sqlite-lru-cache.d.ts +52 -0
  754. package/dist/node/runtime/node/sqlite-lru-cache.js +127 -0
  755. package/dist/node/runtime/node/sqlite-lru-cache.js.map +1 -0
  756. package/dist/node/runtime/node/storage.d.ts +14 -0
  757. package/dist/node/runtime/node/storage.js +52 -0
  758. package/dist/node/runtime/node/storage.js.map +1 -0
  759. package/dist/node/runtime/node/test/helpers/hanging-runner.d.ts +1 -0
  760. package/dist/node/runtime/node/test/helpers/hanging-runner.js +157 -0
  761. package/dist/node/runtime/node/test/helpers/hanging-runner.js.map +1 -0
  762. package/dist/node/runtime/node/test/helpers/run-hanging-node.d.ts +7 -0
  763. package/dist/node/runtime/node/test/helpers/run-hanging-node.js +68 -0
  764. package/dist/node/runtime/node/test/helpers/run-hanging-node.js.map +1 -0
  765. package/dist/node/runtime/node/test/mock-http-router.d.ts +54 -0
  766. package/dist/node/runtime/node/test/mock-http-router.js +397 -0
  767. package/dist/node/runtime/node/test/mock-http-router.js.map +1 -0
  768. package/dist/node/runtime/node/util.d.ts +43 -0
  769. package/dist/node/runtime/node/util.js +384 -0
  770. package/dist/node/runtime/node/util.js.map +1 -0
  771. package/dist/node/schema/schema-util.d.ts +2751 -0
  772. package/dist/node/schema/schema-util.js +562 -0
  773. package/dist/node/schema/schema-util.js.map +1 -0
  774. package/dist/node/schema/schema.d.ts +237 -0
  775. package/dist/node/schema/schema.js +128 -0
  776. package/dist/node/schema/schema.js.map +1 -0
  777. package/dist/node/schema.d.ts +1142 -0
  778. package/dist/node/schema.js +104 -0
  779. package/dist/node/schema.js.map +1 -0
  780. package/dist/node/signer/constants.d.ts +2 -0
  781. package/dist/node/signer/constants.js +3 -0
  782. package/dist/node/signer/constants.js.map +1 -0
  783. package/dist/node/signer/encryption.d.ts +21 -0
  784. package/dist/node/signer/encryption.js +122 -0
  785. package/dist/node/signer/encryption.js.map +1 -0
  786. package/dist/node/signer/index.d.ts +21 -0
  787. package/dist/node/signer/index.js +49 -0
  788. package/dist/node/signer/index.js.map +1 -0
  789. package/dist/node/signer/signatures.d.ts +200 -0
  790. package/dist/node/signer/signatures.js +594 -0
  791. package/dist/node/signer/signatures.js.map +1 -0
  792. package/dist/node/signer/types.d.ts +20 -0
  793. package/dist/node/signer/types.js +2 -0
  794. package/dist/node/signer/types.js.map +1 -0
  795. package/dist/node/signer/util.d.ts +14 -0
  796. package/dist/node/signer/util.js +156 -0
  797. package/dist/node/signer/util.js.map +1 -0
  798. package/dist/node/stats.d.ts +15 -0
  799. package/dist/node/stats.js +64 -0
  800. package/dist/node/stats.js.map +1 -0
  801. package/dist/node/test/mock-ipfs-client.d.ts +34 -0
  802. package/dist/node/test/mock-ipfs-client.js +208 -0
  803. package/dist/node/test/mock-ipfs-client.js.map +1 -0
  804. package/dist/node/test/node/hanging-test/scenarios/comment-publish-pending.scenario.d.ts +8 -0
  805. package/dist/node/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js +21 -0
  806. package/dist/node/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js.map +1 -0
  807. package/dist/node/test/node/hanging-test/scenarios/comment-publish.scenario.d.ts +8 -0
  808. package/dist/node/test/node/hanging-test/scenarios/comment-publish.scenario.js +19 -0
  809. package/dist/node/test/node/hanging-test/scenarios/comment-publish.scenario.js.map +1 -0
  810. package/dist/node/test/node/hanging-test/scenarios/comment-update.scenario.d.ts +8 -0
  811. package/dist/node/test/node/hanging-test/scenarios/comment-update.scenario.js +22 -0
  812. package/dist/node/test/node/hanging-test/scenarios/comment-update.scenario.js.map +1 -0
  813. package/dist/node/test/node/hanging-test/scenarios/community-start.scenario.d.ts +8 -0
  814. package/dist/node/test/node/hanging-test/scenarios/community-start.scenario.js +23 -0
  815. package/dist/node/test/node/hanging-test/scenarios/community-start.scenario.js.map +1 -0
  816. package/dist/node/test/node/hanging-test/scenarios/community-update.scenario.d.ts +8 -0
  817. package/dist/node/test/node/hanging-test/scenarios/community-update.scenario.js +21 -0
  818. package/dist/node/test/node/hanging-test/scenarios/community-update.scenario.js.map +1 -0
  819. package/dist/node/test/node/hanging-test/scenarios/destroy-only.scenario.d.ts +7 -0
  820. package/dist/node/test/node/hanging-test/scenarios/destroy-only.scenario.js +15 -0
  821. package/dist/node/test/node/hanging-test/scenarios/destroy-only.scenario.js.map +1 -0
  822. package/dist/node/test/node/hanging-test/scenarios/hanging-test-util.d.ts +30 -0
  823. package/dist/node/test/node/hanging-test/scenarios/hanging-test-util.js +46 -0
  824. package/dist/node/test/node/hanging-test/scenarios/hanging-test-util.js.map +1 -0
  825. package/dist/node/test/test-util.d.ts +1019 -0
  826. package/dist/node/test/test-util.js +1886 -0
  827. package/dist/node/test/test-util.js.map +1 -0
  828. package/dist/node/types.d.ts +165 -0
  829. package/dist/node/types.js +2 -0
  830. package/dist/node/types.js.map +1 -0
  831. package/dist/node/util/inflight-fetch-manager.d.ts +11 -0
  832. package/dist/node/util/inflight-fetch-manager.js +41 -0
  833. package/dist/node/util/inflight-fetch-manager.js.map +1 -0
  834. package/dist/node/util.d.ts +120 -0
  835. package/dist/node/util.js +816 -0
  836. package/dist/node/util.js.map +1 -0
  837. package/dist/node/version.d.ts +7 -0
  838. package/dist/node/version.js +12 -0
  839. package/dist/node/version.js.map +1 -0
  840. package/dist/node/zod-error-map.d.ts +1 -0
  841. package/dist/node/zod-error-map.js +10 -0
  842. package/dist/node/zod-error-map.js.map +1 -0
  843. package/package.json +212 -0
@@ -0,0 +1,1886 @@
1
+ import PKCIndex from "../index.js";
2
+ import { calculateStringSizeSameAsIpfsAddCidV0, removeUndefinedValuesRecursively, retryKuboIpfsAdd, timestamp } from "../util.js";
3
+ import { getCommunityAddressFromRecord } from "../publications/publication-community.js";
4
+ import assert from "assert";
5
+ import { stringify as deterministicStringify } from "safe-stable-stringify";
6
+ import { v4 as uuidv4 } from "uuid";
7
+ import { createMockPubsubClient } from "./mock-ipfs-client.js";
8
+ import Logger from "../logger.js";
9
+ import * as remeda from "remeda";
10
+ import { LocalCommunity } from "../runtime/browser/community/local-community.js";
11
+ import { findUpdatingComment, findUpdatingCommunity } from "../pkc/tracked-instance-registry-util.js";
12
+ import pTimeout from "p-timeout";
13
+ import { signComment, _signJson, signCommentEdit, cleanUpBeforePublishing, _signPubsubMsg, signChallengeVerification, signCommunity } from "../signer/signatures.js";
14
+ import { findCommentInHierarchicalPageIpfsRecursively, findCommentInPageInstance, mapPageIpfsCommentToPageJsonComment, TIMEFRAMES_TO_SECONDS } from "../pages/util.js";
15
+ import { importSignerIntoKuboNode } from "../runtime/browser/util.js";
16
+ import { getIpfsKeyFromPrivateKey, getPKCAddressFromPublicKeySync } from "../signer/util.js";
17
+ import { Buffer } from "buffer";
18
+ import { encryptEd25519AesGcm, encryptEd25519AesGcmPublicKeyBuffer } from "../signer/encryption.js";
19
+ import env from "../version.js";
20
+ import { PKCError } from "../pkc-error.js";
21
+ import last from "it-last";
22
+ import { buildRuntimeAuthor } from "../publications/publication-author.js";
23
+ const defaultMockResolverRecords = new Map([
24
+ ["plebbit.eth", "12D3KooWNMYPSuNadceoKsJ6oUQcxGcfiAsHNpVTt1RQ1zSrKKpo"],
25
+ ["plebbit.bso", "12D3KooWNMYPSuNadceoKsJ6oUQcxGcfiAsHNpVTt1RQ1zSrKKpo"],
26
+ ["rpc-edit-test.eth", "12D3KooWMZPQsQdYtrakc4D1XtzGXwN1X3DBnAobcCjcPYYXTB6o"],
27
+ ["rpc-edit-test.bso", "12D3KooWMZPQsQdYtrakc4D1XtzGXwN1X3DBnAobcCjcPYYXTB6o"],
28
+ // Resolves to signers[0] — used by key migration tests where record is signed by a different key
29
+ ["migration-test.bso", "12D3KooWN5rLmRJ8fWMwTtkDN7w2RgPPGRM4mtWTnfbjpi1Sh7zR"],
30
+ ["migrating.bso", "12D3KooWN5rLmRJ8fWMwTtkDN7w2RgPPGRM4mtWTnfbjpi1Sh7zR"],
31
+ // Resolves to signers[3] but record has name "plebbit.bso" — used by name mismatch rejection test
32
+ ["wrong-name.bso", "12D3KooWNMYPSuNadceoKsJ6oUQcxGcfiAsHNpVTt1RQ1zSrKKpo"],
33
+ // Resolves to signers[4] — used by resolver tests where client signs with signers[6] but server resolves to a different key
34
+ ["testgibbreish.bso", "12D3KooWJrsheZoiATwG4Z6EJpNqo1v11wpHLcnMECqa4mneZiho"]
35
+ ]);
36
+ function getMockResolverRecord(records, name) {
37
+ if (records instanceof Map)
38
+ return { found: records.has(name), value: records.get(name) };
39
+ if (records && Object.prototype.hasOwnProperty.call(records, name))
40
+ return { found: true, value: records[name] };
41
+ return { found: false, value: undefined };
42
+ }
43
+ export function createMockNameResolver({ records, includeDefaultRecords = false, key = "mock-resolver", provider = "mock", canResolve, resolveFunction } = {}) {
44
+ return {
45
+ key,
46
+ canResolve: canResolve || (() => true),
47
+ resolve: resolveFunction ||
48
+ (async ({ name }) => {
49
+ console.log(`Attempting to mock resolve address (${name})`);
50
+ const record = getMockResolverRecord(records, name);
51
+ if (record.found)
52
+ return record.value ? { publicKey: record.value } : undefined;
53
+ const defaultRecord = includeDefaultRecords ? getMockResolverRecord(defaultMockResolverRecords, name) : undefined;
54
+ if (defaultRecord?.found)
55
+ return defaultRecord.value ? { publicKey: defaultRecord.value } : undefined;
56
+ return undefined;
57
+ }),
58
+ provider
59
+ };
60
+ }
61
+ export function createPendingApprovalChallenge(overrides = {}) {
62
+ const { options, exclude, ...rest } = overrides;
63
+ return {
64
+ ...rest,
65
+ name: rest.name ?? "question",
66
+ options: {
67
+ question: "Pending approval password?",
68
+ answer: "pending",
69
+ ...(options ?? {})
70
+ },
71
+ pendingApproval: rest.pendingApproval ?? true,
72
+ exclude: exclude ?? [{ role: ["moderator"] }]
73
+ };
74
+ }
75
+ function generateRandomTimestamp(parentTimestamp) {
76
+ const [lowerLimit, upperLimit] = [typeof parentTimestamp === "number" && parentTimestamp > 2 ? parentTimestamp : 2, timestamp()];
77
+ let randomTimestamp = -1;
78
+ while (randomTimestamp === -1) {
79
+ const randomTimeframeIndex = (remeda.keys.strict(TIMEFRAMES_TO_SECONDS).length * Math.random()) << 0;
80
+ const tempTimestamp = lowerLimit + Object.values(TIMEFRAMES_TO_SECONDS)[randomTimeframeIndex];
81
+ if (tempTimestamp >= lowerLimit && tempTimestamp <= upperLimit)
82
+ randomTimestamp = tempTimestamp;
83
+ }
84
+ return randomTimestamp;
85
+ }
86
+ export async function generateMockPost({ communityAddress, pkc, randomTimestamp = false, postProps = {} }) {
87
+ const postTimestamp = (randomTimestamp && generateRandomTimestamp()) || timestamp();
88
+ const postStartTestTime = Date.now() / 1000 + Math.random();
89
+ const signer = postProps?.signer || (await pkc.createSigner());
90
+ const baseProps = {
91
+ communityAddress,
92
+ author: { displayName: `Mock Author - ${postStartTestTime}` },
93
+ title: `Mock Post - ${postStartTestTime}`,
94
+ content: `Mock content - ${postStartTestTime}`,
95
+ signer,
96
+ timestamp: postTimestamp
97
+ };
98
+ const finalPostProps = remeda.mergeDeep(baseProps, postProps);
99
+ const post = await pkc.createComment(finalPostProps);
100
+ return post;
101
+ }
102
+ // TODO rework this
103
+ export async function generateMockComment(parentPostOrComment, pkc, randomTimestamp = false, commentProps = {}) {
104
+ const commentTimestamp = (randomTimestamp && generateRandomTimestamp(parentPostOrComment.timestamp)) || timestamp();
105
+ const commentTime = Date.now() / 1000 + Math.random();
106
+ const signer = commentProps?.signer || (await pkc.createSigner());
107
+ const comment = await pkc.createComment({
108
+ author: { displayName: `Mock Author - ${commentTime}` },
109
+ signer: signer,
110
+ content: `Mock comment - ${commentTime}`,
111
+ parentCid: parentPostOrComment.cid,
112
+ postCid: parentPostOrComment.postCid,
113
+ communityAddress: getCommunityAddressFromRecord(parentPostOrComment),
114
+ timestamp: commentTimestamp,
115
+ ...commentProps
116
+ });
117
+ return comment;
118
+ }
119
+ export async function generateMockVote(parentPostOrComment, vote, pkc, signer) {
120
+ const voteTime = Date.now() / 1000;
121
+ const commentCid = parentPostOrComment.cid;
122
+ if (typeof commentCid !== "string")
123
+ throw Error(`generateMockVote: commentCid (${commentCid}) is not a valid CID`);
124
+ signer = signer || (await pkc.createSigner());
125
+ const voteObj = await pkc.createVote({
126
+ author: { displayName: `Mock Author - ${voteTime}` },
127
+ signer: signer,
128
+ commentCid,
129
+ vote,
130
+ communityAddress: getCommunityAddressFromRecord(parentPostOrComment)
131
+ });
132
+ return voteObj;
133
+ }
134
+ export async function loadAllPages(pageCid, pagesInstance) {
135
+ if (!pageCid)
136
+ throw Error("Can't load all pages with undefined pageCid");
137
+ let sortedCommentsPage = await pagesInstance.getPage({ cid: pageCid });
138
+ let sortedComments = sortedCommentsPage.comments;
139
+ while (sortedCommentsPage.nextCid) {
140
+ sortedCommentsPage = await pagesInstance.getPage({ cid: sortedCommentsPage.nextCid });
141
+ sortedComments = sortedComments.concat(sortedCommentsPage.comments);
142
+ }
143
+ return sortedComments;
144
+ }
145
+ export async function loadAllPagesBySortName(pageSortName, pagesInstance) {
146
+ if (!pageSortName)
147
+ throw Error("Can't load all pages with undefined pageSortName");
148
+ if (Object.keys(pagesInstance.pageCids).length === 0 && pagesInstance.pages && pagesInstance.pages[pageSortName])
149
+ return pagesInstance.pages[pageSortName].comments;
150
+ let sortedCommentsPage = (pagesInstance.pages && pagesInstance.pages[pageSortName]) ||
151
+ (await pagesInstance.getPage({ cid: pagesInstance.pageCids[pageSortName] }));
152
+ let sortedComments = sortedCommentsPage.comments;
153
+ while (sortedCommentsPage.nextCid) {
154
+ sortedCommentsPage = await pagesInstance.getPage({ cid: sortedCommentsPage.nextCid });
155
+ //@ts-expect-error
156
+ sortedComments = sortedComments.concat(sortedCommentsPage.comments);
157
+ }
158
+ return sortedComments;
159
+ }
160
+ export async function loadAllUniquePostsUnderCommunity(community) {
161
+ if (Object.keys(community.posts.pageCids).length === 0 && Object.keys(community.posts.pages).length === 0)
162
+ return [];
163
+ const allCommentsInPreloadedPages = Object.keys(community.posts.pageCids).length === 0 && Object.keys(community.posts.pages).length > 0;
164
+ if (allCommentsInPreloadedPages) {
165
+ const allComments = community.posts.pages.hot?.comments;
166
+ if (!allComments)
167
+ throw Error("No comments found under community.posts.pages.hot");
168
+ return allComments;
169
+ }
170
+ else {
171
+ // we have multiple pages, need to load all pages and merge them
172
+ return loadAllPages(community.posts.pageCids.new, community.posts);
173
+ }
174
+ }
175
+ export async function loadAllUniqueCommentsUnderCommentInstance(comment) {
176
+ if (Object.keys(comment.replies.pageCids).length === 0 && Object.keys(comment.replies.pages).length === 0)
177
+ throw Error("Comment replies instance has no comments under it");
178
+ const allCommentsInPreloadedPages = Object.keys(comment.replies.pageCids).length === 0 && Object.keys(comment.replies.pages).length > 0;
179
+ if (allCommentsInPreloadedPages) {
180
+ const allComments = comment.replies.pages.best?.comments;
181
+ if (!allComments)
182
+ throw Error("No comments found under comment.replies.pages.best");
183
+ return allComments;
184
+ }
185
+ else {
186
+ // we have multiple pages, need to load all pages and merge them
187
+ return loadAllPages(comment.replies.pageCids.new, comment.replies);
188
+ }
189
+ }
190
+ async function _mockCommunityPKC(signer, pkcOptions) {
191
+ const pkc = await mockPKC({ ...pkcOptions, pubsubKuboRpcClientsOptions: ["http://localhost:15002/api/v0"] }, true);
192
+ return pkc;
193
+ }
194
+ async function _startMathCliCommunity(signer, pkc) {
195
+ const community = await pkc.createCommunity({ signer });
196
+ await community.edit({ settings: { challenges: [{ name: "question", options: { question: "1+1=?", answer: "2" } }] } });
197
+ await community.start();
198
+ return community;
199
+ }
200
+ async function _startEnsCommunity(signers, pkc) {
201
+ const signer = await pkc.createSigner(signers[3]);
202
+ const community = (await createSubWithNoChallenge({ signer }, pkc));
203
+ await community.edit({
204
+ roles: {
205
+ [signers[1].address]: { role: "owner" },
206
+ [signers[2].address]: { role: "admin" },
207
+ [signers[3].address]: { role: "moderator" }
208
+ }
209
+ });
210
+ await community.start();
211
+ await community.edit({ address: "plebbit.bso" });
212
+ assert.equal(community.address, "plebbit.bso");
213
+ return community;
214
+ }
215
+ async function _publishPosts(communityAddress, numOfPosts, pkc) {
216
+ return Promise.all(new Array(numOfPosts).fill(null).map(() => publishRandomPost({ communityAddress, pkc })));
217
+ }
218
+ async function _publishReplies(parentComment, numOfReplies, pkc) {
219
+ return Promise.all(new Array(numOfReplies).fill(null).map(() => publishRandomReply({ parentComment, pkc })));
220
+ }
221
+ async function _publishVotesOnOneComment(comment, votesPerCommentToPublish, pkc) {
222
+ return Promise.all(new Array(votesPerCommentToPublish).fill(null).map(() => publishVote({
223
+ commentCid: comment.cid,
224
+ communityAddress: comment.communityAddress,
225
+ vote: Math.random() > 0.5 ? 1 : -1,
226
+ pkc
227
+ })));
228
+ }
229
+ async function _publishVotes(comments, votesPerCommentToPublish, pkc) {
230
+ const votes = remeda.flattenDeep(await Promise.all(comments.map((comment) => _publishVotesOnOneComment(comment, votesPerCommentToPublish, pkc))));
231
+ assert.equal(votes.length, votesPerCommentToPublish * comments.length);
232
+ console.log(`${votes.length} votes for ${comments.length} ${comments[0].depth === 0 ? "posts" : "replies"} have been published`);
233
+ return votes;
234
+ }
235
+ async function _populateCommunity(community, props) {
236
+ await community.edit({
237
+ roles: {
238
+ [props.signers[1].address]: { role: "owner" },
239
+ [props.signers[2].address]: { role: "admin" },
240
+ [props.signers[3].address]: { role: "moderator" }
241
+ }
242
+ });
243
+ if (props.numOfPostsToPublish === 0)
244
+ return;
245
+ await new Promise((resolve) => community.once("update", resolve));
246
+ const posts = await _publishPosts(community.address, props.numOfPostsToPublish, community._pkc); // If no comment[] is provided, we publish posts
247
+ console.log(`Have successfully published ${posts.length} posts`);
248
+ const replies = await _publishReplies(posts[0], props.numOfCommentsToPublish, community._pkc);
249
+ console.log(`Have sucessfully published ${replies.length} replies`);
250
+ const postVotes = await _publishVotes(posts, props.votesPerCommentToPublish, community._pkc);
251
+ console.log(`Have sucessfully published ${postVotes.length} votes on ${posts.length} posts`);
252
+ const repliesVotes = await _publishVotes(replies, props.votesPerCommentToPublish, community._pkc);
253
+ console.log(`Have successfully published ${repliesVotes.length} votes on ${replies.length} replies`);
254
+ }
255
+ export async function startOnlineCommunity() {
256
+ const onlinePKC = await createOnlinePKC();
257
+ const onlineCommunity = await onlinePKC.createCommunity(); // Will create a new community that is on the ipfs network
258
+ await onlineCommunity.edit({ settings: { challenges: [{ name: "question", options: { question: "1+1=?", answer: "2" } }] } });
259
+ await onlineCommunity.start();
260
+ await new Promise((resolve) => onlineCommunity.once("update", resolve));
261
+ console.log("Online community is online on address", onlineCommunity.address);
262
+ return onlineCommunity;
263
+ }
264
+ export async function startCommunities(props) {
265
+ const pkc = await _mockCommunityPKC(props.signers, {
266
+ ...remeda.pick(props, ["noData", "dataPath"]),
267
+ publishInterval: 1000,
268
+ updateInterval: 1000
269
+ });
270
+ const mainCommunity = (await createSubWithNoChallenge({ signer: props.signers[0] }, pkc)); // most publications will be on this community
271
+ // Enable flair features and set allowed flairs for flair tests
272
+ await mainCommunity.edit({
273
+ features: { postFlairs: true },
274
+ flairs: {
275
+ post: [{ text: "Author Flair" }, { text: "Discussion" }, { text: "Updated" }, { text: "Important", backgroundColor: "#ff0000" }]
276
+ }
277
+ });
278
+ await mainCommunity.start();
279
+ const mathSub = await _startMathCliCommunity(props.signers[1], pkc);
280
+ const ensSub = await _startEnsCommunity(props.signers, pkc);
281
+ console.time("populate");
282
+ await _populateCommunity(mainCommunity, props);
283
+ console.timeEnd("populate");
284
+ let onlineSub;
285
+ if (props.startOnlineSub)
286
+ onlineSub = await startOnlineCommunity();
287
+ console.log("All communities and ipfs nodes have been started. You are ready to run the tests");
288
+ const subWithNoResponse = (await createSubWithNoChallenge({ signer: props.signers[4] }, pkc));
289
+ await subWithNoResponse.start();
290
+ await new Promise((resolve) => subWithNoResponse.once("update", resolve));
291
+ await subWithNoResponse.stop();
292
+ const pkcNoMockedSub = await mockPKC({ kuboRpcClientsOptions: ["http://localhost:15002/api/v0"], pubsubKuboRpcClientsOptions: ["http://localhost:15002/api/v0"] }, false, true, true);
293
+ const mathCliSubWithNoMockedPubsub = await _startMathCliCommunity(props.signers[5], pkcNoMockedSub);
294
+ await new Promise((resolve) => mathCliSubWithNoMockedPubsub.once("update", resolve));
295
+ const subForPurge = (await createSubWithNoChallenge({ signer: props.signers[6] }, pkc));
296
+ await subForPurge.edit({
297
+ roles: {
298
+ [props.signers[1].address]: { role: "owner" },
299
+ [props.signers[2].address]: { role: "admin" },
300
+ [props.signers[3].address]: { role: "moderator" }
301
+ }
302
+ });
303
+ await subForPurge.start();
304
+ await new Promise((resolve) => subForPurge.once("update", resolve));
305
+ const subForRemove = (await createSubWithNoChallenge({ signer: props.signers[7] }, pkc));
306
+ await subForRemove.edit({
307
+ roles: {
308
+ [props.signers[1].address]: { role: "owner" },
309
+ [props.signers[2].address]: { role: "admin" },
310
+ [props.signers[3].address]: { role: "moderator" }
311
+ }
312
+ });
313
+ await subForRemove.start();
314
+ await new Promise((resolve) => subForRemove.once("update", resolve));
315
+ const subForDelete = (await createSubWithNoChallenge({ signer: props.signers[8] }, pkc));
316
+ await subForDelete.edit({
317
+ roles: {
318
+ [props.signers[1].address]: { role: "owner" },
319
+ [props.signers[2].address]: { role: "admin" },
320
+ [props.signers[3].address]: { role: "moderator" }
321
+ }
322
+ });
323
+ await subForDelete.start();
324
+ await new Promise((resolve) => subForDelete.once("update", resolve));
325
+ const subForChainProviders = (await createSubWithNoChallenge({ signer: props.signers[9] }, pkc));
326
+ await subForChainProviders.start();
327
+ await new Promise((resolve) => subForChainProviders.once("update", resolve));
328
+ const subForEditContent = (await createSubWithNoChallenge({ signer: props.signers[10] }, pkc));
329
+ await subForEditContent.edit({
330
+ roles: {
331
+ [props.signers[1].address]: { role: "owner" },
332
+ [props.signers[2].address]: { role: "admin" },
333
+ [props.signers[3].address]: { role: "moderator" }
334
+ }
335
+ });
336
+ await subForEditContent.start();
337
+ await new Promise((resolve) => subForEditContent.once("update", resolve));
338
+ const subForLocked = (await createSubWithNoChallenge({ signer: props.signers[11] }, pkc));
339
+ await subForLocked.edit({
340
+ roles: {
341
+ [props.signers[1].address]: { role: "owner" },
342
+ [props.signers[2].address]: { role: "admin" },
343
+ [props.signers[3].address]: { role: "moderator" }
344
+ }
345
+ });
346
+ await subForLocked.start();
347
+ await new Promise((resolve) => subForLocked.once("update", resolve));
348
+ return {
349
+ onlineSub: onlineSub,
350
+ mathSub: mathSub,
351
+ ensSub: ensSub,
352
+ mainSub: mainCommunity,
353
+ NoPubsubResponseSub: subWithNoResponse,
354
+ mathCliSubWithNoMockedPubsub: mathCliSubWithNoMockedPubsub,
355
+ subForPurge: subForPurge,
356
+ subForRemove: subForRemove,
357
+ subForDelete: subForDelete,
358
+ subForChainProviders: subForChainProviders,
359
+ subForEditContent: subForEditContent,
360
+ subForLocked: subForLocked
361
+ };
362
+ }
363
+ export async function fetchTestServerSubs() {
364
+ const res = await fetch("http://localhost:14953");
365
+ const resWithType = await res.json();
366
+ return resWithType;
367
+ }
368
+ export function mockDefaultOptionsForNodeAndBrowserTests() {
369
+ const shouldUseRPC = isRpcFlagOn();
370
+ if (shouldUseRPC)
371
+ return { pkcRpcClientsOptions: ["ws://localhost:39652"], httpRoutersOptions: [] };
372
+ else
373
+ return {
374
+ kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
375
+ pubsubKuboRpcClientsOptions: [
376
+ `http://localhost:15002/api/v0`,
377
+ `http://localhost:42234/api/v0`,
378
+ `http://localhost:42254/api/v0`
379
+ ],
380
+ httpRoutersOptions: []
381
+ };
382
+ }
383
+ export async function mockPKCV2({ pkcOptions, forceMockPubsub, stubStorage, mockResolve, remotePKC } = {}) {
384
+ if (remotePKC)
385
+ pkcOptions = { dataPath: undefined, ...pkcOptions };
386
+ const pkc = await mockPKC(pkcOptions, forceMockPubsub, stubStorage, mockResolve);
387
+ return pkc;
388
+ }
389
+ export async function mockPKC(pkcOptions, forceMockPubsub = false, stubStorage = true, mockResolve = true) {
390
+ const log = Logger("pkc-js:test-util:mockPKC");
391
+ if (pkcOptions?.pkcRpcClientsOptions && pkcOptions?.kuboRpcClientsOptions)
392
+ throw Error("Can't have both kubo and RPC config. Is this a mistake?");
393
+ if (pkcOptions?.pkcRpcClientsOptions && pkcOptions?.libp2pJsClientsOptions)
394
+ throw Error("Can't have both libp2p and RPC config. Is this a mistake?");
395
+ const mockNameResolvers = mockResolve ? [createMockNameResolver({ includeDefaultRecords: true })] : undefined;
396
+ const pkc = await PKCIndex({
397
+ ...mockDefaultOptionsForNodeAndBrowserTests(),
398
+ resolveAuthorNames: true,
399
+ publishInterval: 1000,
400
+ validatePages: false,
401
+ updateInterval: 500,
402
+ nameResolvers: mockNameResolvers,
403
+ ...pkcOptions
404
+ });
405
+ if (stubStorage) {
406
+ pkc._storage.getItem = async () => undefined;
407
+ pkc._storage.setItem = async () => undefined;
408
+ }
409
+ // TODO should have multiple pubsub providers here to emulate a real browser/mobile environment
410
+ if (!pkcOptions?.pubsubKuboRpcClientsOptions || forceMockPubsub)
411
+ for (const pubsubUrl of remeda.keys.strict(pkc.clients.pubsubKuboRpcClients)) {
412
+ const mockClient = createMockPubsubClient();
413
+ pkc.clients.pubsubKuboRpcClients[pubsubUrl]._client = mockClient;
414
+ pkc.clients.pubsubKuboRpcClients[pubsubUrl].destroy = mockClient.destroy.bind(mockClient);
415
+ }
416
+ pkc.on("error", (e) => {
417
+ log.error("PKC error", e);
418
+ });
419
+ return pkc;
420
+ }
421
+ // name should be changed to mockBrowserPKC
422
+ export async function mockRemotePKC(opts) {
423
+ // Mock browser environment
424
+ const pkc = await mockPKCV2({ ...opts, pkcOptions: { dataPath: undefined, ...opts?.pkcOptions } });
425
+ pkc._canCreateNewLocalCommunity = () => false;
426
+ return pkc;
427
+ }
428
+ export async function createOnlinePKC(pkcOptions) {
429
+ const pkc = await PKCIndex({
430
+ kuboRpcClientsOptions: ["http://localhost:15003/api/v0"],
431
+ pubsubKuboRpcClientsOptions: ["http://localhost:15003/api/v0"],
432
+ ...pkcOptions
433
+ }); // use online ipfs node
434
+ return pkc;
435
+ }
436
+ export async function mockPKCNoDataPathWithOnlyKuboClient(opts) {
437
+ const pkc = await mockPKCV2({
438
+ ...opts,
439
+ pkcOptions: {
440
+ kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
441
+ pkcRpcClientsOptions: undefined,
442
+ dataPath: undefined,
443
+ ...opts?.pkcOptions
444
+ }
445
+ });
446
+ return pkc;
447
+ }
448
+ export async function mockPKCNoDataPathWithOnlyKuboClientNoAdd(opts) {
449
+ const pkc = await mockPKCV2({
450
+ ...opts,
451
+ pkcOptions: {
452
+ kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
453
+ pkcRpcClientsOptions: undefined,
454
+ dataPath: undefined,
455
+ ...opts?.pkcOptions
456
+ }
457
+ });
458
+ Object.values(pkc.clients.kuboRpcClients)[0]._client.add = () => {
459
+ throw Error("Add is not supported");
460
+ };
461
+ return pkc;
462
+ }
463
+ export async function mockRpcServerPKC(pkcOptions) {
464
+ const pkc = await mockPKCV2({
465
+ pkcOptions: {
466
+ kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
467
+ ...pkcOptions,
468
+ pkcRpcClientsOptions: undefined
469
+ },
470
+ mockResolve: true,
471
+ forceMockPubsub: true,
472
+ remotePKC: false,
473
+ stubStorage: true // we want storage to force new resolve-community-address states
474
+ });
475
+ pkc.removeAllListeners("error"); // for rpc server, we want to test the error handling
476
+ return pkc;
477
+ }
478
+ export async function mockRpcRemotePKC(opts) {
479
+ if (!isRpcFlagOn())
480
+ throw Error("This function should only be used when the rpc flag is on");
481
+ // This instance will connect to an rpc server that has no local subs
482
+ const pkc = await mockPKCV2({
483
+ ...opts,
484
+ pkcOptions: {
485
+ pkcRpcClientsOptions: ["ws://localhost:39653"],
486
+ dataPath: undefined,
487
+ ...opts?.pkcOptions
488
+ }
489
+ });
490
+ return pkc;
491
+ }
492
+ export async function mockRPCLocalPKC(pkcOptions) {
493
+ if (!isRpcFlagOn())
494
+ throw Error("This function should only be used when the rpc flag is on");
495
+ // This instance will connect to an rpc server that local subs
496
+ return mockPKC({ pkcRpcClientsOptions: ["ws://localhost:39652"], ...pkcOptions });
497
+ }
498
+ export async function mockGatewayPKC(opts) {
499
+ // Keep only pubsub and gateway
500
+ const pkc = await mockPKCV2({
501
+ ...opts,
502
+ pkcOptions: {
503
+ ipfsGatewayUrls: ["http://localhost:18080"],
504
+ pkcRpcClientsOptions: undefined,
505
+ kuboRpcClientsOptions: undefined,
506
+ pubsubKuboRpcClientsOptions: undefined,
507
+ libp2pJsClientsOptions: undefined,
508
+ ...opts?.pkcOptions
509
+ },
510
+ remotePKC: true
511
+ });
512
+ return pkc;
513
+ }
514
+ export async function publishRandomReply({ parentComment, pkc, commentProps }) {
515
+ const reply = await generateMockComment(parentComment, pkc, false, {
516
+ content: `Content ${uuidv4()}`,
517
+ ...commentProps
518
+ });
519
+ await publishWithExpectedResult({ publication: reply, expectedChallengeSuccess: true });
520
+ return reply;
521
+ }
522
+ export async function publishRandomPost({ communityAddress, pkc, postProps }) {
523
+ const post = await generateMockPost({
524
+ communityAddress,
525
+ pkc,
526
+ postProps: {
527
+ content: `Random post Content ${uuidv4()}`,
528
+ title: `Random post Title ${uuidv4()}`,
529
+ ...postProps
530
+ }
531
+ });
532
+ await publishWithExpectedResult({ publication: post, expectedChallengeSuccess: true });
533
+ return post;
534
+ }
535
+ export async function publishVote({ commentCid, communityAddress, vote, pkc, voteProps }) {
536
+ const voteObj = await pkc.createVote({
537
+ commentCid,
538
+ vote,
539
+ communityAddress,
540
+ signer: voteProps?.signer || (await pkc.createSigner()),
541
+ ...voteProps
542
+ });
543
+ await publishWithExpectedResult({ publication: voteObj, expectedChallengeSuccess: true });
544
+ return voteObj;
545
+ }
546
+ async function _publishWithExpectedResultOnce({ publication, expectedChallengeSuccess, expectedReason }) {
547
+ const emittedErrors = [];
548
+ const timeoutMs = 60000;
549
+ const summarizePublication = () => removeUndefinedValuesRecursively({
550
+ type: publication.constructor?.name,
551
+ cid: publication.cid,
552
+ parentCid: publication.parentCid,
553
+ communityAddress: publication.communityAddress,
554
+ signerAddress: publication.signer?.address,
555
+ commentModeration: publication.commentModeration
556
+ ? remeda.pick(publication.commentModeration, ["approved", "reason", "spoiler", "nsfw", "pinned", "removed"])
557
+ : undefined
558
+ });
559
+ publication.on("error", (err) => emittedErrors.push(err));
560
+ let cleanupChallengeVerificationListener;
561
+ const challengeVerificationPromise = new Promise((resolve, reject) => {
562
+ const challengeVerificationListener = (verificationMsg) => {
563
+ if (verificationMsg.challengeSuccess !== expectedChallengeSuccess) {
564
+ const msg = `Expected challengeSuccess to be (${expectedChallengeSuccess}) and got (${verificationMsg.challengeSuccess}). Reason (${verificationMsg.reason}): ${JSON.stringify(remeda.omit(verificationMsg, ["encrypted", "signature", "challengeRequestId"]))}`;
565
+ reject(msg);
566
+ }
567
+ else if (expectedReason && expectedReason !== verificationMsg.reason) {
568
+ const msg = `Expected reason to be (${expectedReason}) and got (${verificationMsg.reason}): ${JSON.stringify(remeda.omit(verificationMsg, ["encrypted", "signature", "challengeRequestId"]))}`;
569
+ reject(msg);
570
+ }
571
+ else
572
+ resolve(1);
573
+ };
574
+ publication.on("challengeverification", challengeVerificationListener);
575
+ cleanupChallengeVerificationListener = () => {
576
+ if (typeof publication.off === "function")
577
+ publication.off("challengeverification", challengeVerificationListener);
578
+ else
579
+ publication.removeListener("challengeverification", challengeVerificationListener);
580
+ };
581
+ });
582
+ const error = new Error("Publication did not receive response");
583
+ //@ts-expect-error
584
+ error.details = {
585
+ publication: summarizePublication(),
586
+ expectedChallengeSuccess,
587
+ expectedReason,
588
+ waitTime: timeoutMs,
589
+ emittedErrorsOnPublicationInstance: emittedErrors
590
+ };
591
+ const validateResponsePromise = pTimeout(challengeVerificationPromise, {
592
+ milliseconds: timeoutMs,
593
+ message: error
594
+ });
595
+ await publication.publish();
596
+ try {
597
+ await validateResponsePromise;
598
+ }
599
+ catch (error) {
600
+ throw error;
601
+ }
602
+ finally {
603
+ cleanupChallengeVerificationListener?.();
604
+ }
605
+ }
606
+ const retriableSubLoadingCodes = new Set([
607
+ "ERR_FAILED_TO_FETCH_IPFS_CID_VIA_IPFS_P2P",
608
+ "ERR_GET_COMMUNITY_TIMED_OUT",
609
+ "ERR_FAILED_TO_FETCH_COMMUNITY_FROM_GATEWAYS"
610
+ ]);
611
+ export async function publishWithExpectedResult({ publication, expectedChallengeSuccess, expectedReason }) {
612
+ const maxAttempts = 3;
613
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
614
+ try {
615
+ await _publishWithExpectedResultOnce({ publication, expectedChallengeSuccess, expectedReason });
616
+ return;
617
+ }
618
+ catch (error) {
619
+ const isRetriable = error instanceof PKCError && retriableSubLoadingCodes.has(error.code);
620
+ if (!isRetriable || attempt === maxAttempts)
621
+ throw error;
622
+ console.log(`publishWithExpectedResult: retrying (attempt ${attempt + 1}/${maxAttempts}) after retriable error: ${error.code}`);
623
+ }
624
+ }
625
+ }
626
+ export async function iterateThroughPageCidToFindComment(commentCid, pageCid, pages) {
627
+ if (!commentCid)
628
+ throw Error("Can't find comment with undefined commentCid");
629
+ if (!pageCid)
630
+ throw Error("Can't find comment with undefined pageCid");
631
+ let currentPageCid = remeda.clone(pageCid);
632
+ while (currentPageCid) {
633
+ const loadedPage = (await pages.getPage({ cid: currentPageCid }));
634
+ const commentInPage = loadedPage.comments.find((c) => c.cid === commentCid);
635
+ if (commentInPage)
636
+ return commentInPage;
637
+ currentPageCid = loadedPage.nextCid;
638
+ }
639
+ return undefined;
640
+ }
641
+ export async function findCommentInCommunityInstancePagesPreloadedAndPageCids(opts) {
642
+ // TODO need to handle, what if the comment is nested deep down the community.posts tree and doesn't appear in preloaded page
643
+ // code below doesn't handle it
644
+ const { community, comment } = opts;
645
+ if (!community)
646
+ throw Error("Failed to provide opts.community");
647
+ if (!comment)
648
+ throw Error("Failed to provde opts.comment");
649
+ if (Object.keys(community.posts.pageCids).length === 0 && Object.keys(community.posts.pages).length > 0) {
650
+ // it's a single preloaded page
651
+ const loadedAllHotPagesComments = (await loadAllPagesBySortName(Object.keys(community.posts.pages)[0], community.posts));
652
+ const pageIpfs = {
653
+ comments: loadedAllHotPagesComments.map((c) => c.raw)
654
+ };
655
+ const postInPage = findCommentInHierarchicalPageIpfsRecursively(pageIpfs, comment.cid);
656
+ if (postInPage)
657
+ return mapPageIpfsCommentToPageJsonComment(postInPage);
658
+ else
659
+ return undefined;
660
+ }
661
+ else if (Object.keys(community.posts?.pageCids).length > 0) {
662
+ const postsNewPageCid = community.posts.pageCids.new;
663
+ const postInPageCid = await iterateThroughPageCidToFindComment(comment.cid, postsNewPageCid, community.posts);
664
+ return postInPageCid;
665
+ }
666
+ else
667
+ return undefined;
668
+ }
669
+ export async function findReplyInParentCommentPagesInstancePreloadedAndPageCids(opts) {
670
+ const { parentComment, reply } = opts;
671
+ const log = Logger("pkc-js:test-util:waitTillReplyInParentPagesInstance");
672
+ if (reply?.parentCid !== parentComment?.cid)
673
+ throw Error("You need to provide a reply that's direct child of parentComment");
674
+ log("waiting for reply", reply.cid, "in parent comment", parentComment.cid, "replyCount of parent comment", parentComment.replyCount);
675
+ // Handle intermediate state where both pageCids and pages are empty
676
+ // This happens during early update events before CommentUpdate with replies is received
677
+ if (Object.keys(parentComment.replies.pageCids).length === 0 && Object.keys(parentComment.replies.pages).length === 0) {
678
+ // No pages loaded yet - this is a valid intermediate state, not an error
679
+ return undefined;
680
+ }
681
+ if (Object.keys(parentComment.replies.pageCids).length === 0 && Object.keys(parentComment.replies.pages).length > 0) {
682
+ // it's a single preloaded page
683
+ const loadedAllBestPagesComments = (await loadAllPagesBySortName(Object.keys(parentComment.replies.pages)[0], parentComment.replies));
684
+ const pageIpfs = {
685
+ comments: loadedAllBestPagesComments.map((c) => c.raw)
686
+ };
687
+ const replyInPage = findCommentInHierarchicalPageIpfsRecursively(pageIpfs, reply.cid);
688
+ if (replyInPage)
689
+ return mapPageIpfsCommentToPageJsonComment(replyInPage);
690
+ else
691
+ return undefined;
692
+ }
693
+ else {
694
+ if (!("new" in parentComment.replies.pageCids)) {
695
+ console.error("no new page", "parentComment.replies.pageCids", parentComment.replies.pageCids);
696
+ return undefined;
697
+ }
698
+ const commentNewPageCid = parentComment.replies.pageCids.new;
699
+ const replyInPage = await iterateThroughPageCidToFindComment(reply.cid, commentNewPageCid, parentComment.replies);
700
+ return replyInPage;
701
+ }
702
+ }
703
+ export async function waitTillPostInCommunityInstancePages(post, community) {
704
+ if (community.state === "stopped")
705
+ await community.update();
706
+ await resolveWhenConditionIsTrue({
707
+ toUpdate: community,
708
+ predicate: async () => Boolean(await findCommentInCommunityInstancePagesPreloadedAndPageCids({ comment: post, community }))
709
+ });
710
+ }
711
+ export async function waitTillPostInCommunityPages(post, pkc) {
712
+ const community = await pkc.createCommunity({ address: post.communityAddress });
713
+ await waitTillPostInCommunityInstancePages(post, community);
714
+ await community.stop();
715
+ }
716
+ export async function iterateThroughPagesToFindCommentInParentPagesInstance(commentCid, pages) {
717
+ const preloadedPage = Object.keys(pages.pages)[0];
718
+ const commentInPage = findCommentInPageInstance(pages, commentCid);
719
+ if (commentInPage)
720
+ return mapPageIpfsCommentToPageJsonComment(commentInPage);
721
+ if (pages.pages[preloadedPage]?.nextCid || pages.pageCids.new) {
722
+ // means we have multiple pages
723
+ return iterateThroughPageCidToFindComment(commentCid, pages.pageCids.new, pages);
724
+ }
725
+ else
726
+ return undefined;
727
+ }
728
+ export async function waitTillReplyInParentPagesInstance(reply, parentComment) {
729
+ if (parentComment.state === "stopped")
730
+ throw Error("Parent comment is stopped, can't wait for reply in parent pages");
731
+ if (!reply.cid)
732
+ throw Error("reply.cid need to be defined so we can find it in parent pages");
733
+ await resolveWhenConditionIsTrue({
734
+ toUpdate: parentComment,
735
+ predicate: async () => Boolean(await findReplyInParentCommentPagesInstancePreloadedAndPageCids({ reply, parentComment }))
736
+ });
737
+ }
738
+ export async function waitTillReplyInParentPages(reply, pkc) {
739
+ const parentComment = await pkc.createComment({ cid: reply.parentCid });
740
+ await parentComment.update();
741
+ await waitTillReplyInParentPagesInstance(reply, parentComment);
742
+ await parentComment.stop();
743
+ }
744
+ export async function createSubWithNoChallenge(props, pkc) {
745
+ const community = await pkc.createCommunity(props);
746
+ await community.edit({ settings: { challenges: [] } }); // No challenge
747
+ return community;
748
+ }
749
+ export async function generatePostToAnswerMathQuestion(props, pkc) {
750
+ const mockPost = await generateMockPost({ communityAddress: props.communityAddress, pkc, postProps: props });
751
+ mockPost.removeAllListeners("challenge");
752
+ mockPost.once("challenge", (challengeMessage) => {
753
+ mockPost.publishChallengeAnswers(["2"]);
754
+ });
755
+ return mockPost;
756
+ }
757
+ export function isRpcFlagOn() {
758
+ const isPartOfProcessEnv = globalThis?.["process"]?.env?.["USE_RPC"] === "1";
759
+ // const isPartOfKarmaArgs = globalThis?.["__karma__"]?.config?.config?.["USE_RPC"] === "1";
760
+ return isPartOfProcessEnv;
761
+ }
762
+ export function isRunningInBrowser() {
763
+ const hasWindow = typeof globalThis["window"] !== "undefined";
764
+ const hasDocument = typeof globalThis["window"]?.["document"] !== "undefined";
765
+ const isNodeProcess = typeof globalThis["process"] !== "undefined" && Boolean(globalThis["process"]?.versions?.node);
766
+ const isJsDom = typeof globalThis["navigator"]?.userAgent === "string" && globalThis["navigator"].userAgent.includes("jsdom");
767
+ return hasWindow && hasDocument && !isNodeProcess && !isJsDom;
768
+ }
769
+ export async function resolveWhenConditionIsTrue(options) {
770
+ if (!options) {
771
+ throw Error("resolveWhenConditionIsTrue requires an options object");
772
+ }
773
+ const { toUpdate, predicate, eventName = "update" } = options;
774
+ if (!toUpdate) {
775
+ throw Error("resolveWhenConditionIsTrue options.toUpdate is required");
776
+ }
777
+ if (typeof predicate !== "function") {
778
+ throw Error("resolveWhenConditionIsTrue options.predicate must be a function");
779
+ }
780
+ const normalizedEventName = eventName || "update";
781
+ await new Promise((resolve, reject) => {
782
+ const listener = async () => {
783
+ try {
784
+ const conditionStatus = await predicate();
785
+ if (conditionStatus) {
786
+ toUpdate.removeListener(normalizedEventName, listener);
787
+ resolve();
788
+ }
789
+ }
790
+ catch (error) {
791
+ toUpdate.removeListener(normalizedEventName, listener);
792
+ reject(error);
793
+ }
794
+ };
795
+ toUpdate.on(normalizedEventName, listener);
796
+ listener(); // initial check — no await, errors flow through reject()
797
+ });
798
+ }
799
+ export async function disableValidationOfSignatureBeforePublishing(publication) {
800
+ //@ts-expect-error
801
+ publication._validateSignatureHook = async () => { };
802
+ }
803
+ export async function overrideCommentInstancePropsAndSign(comment, props) {
804
+ if (!comment.signer)
805
+ throw Error("Need comment.signer to overwrite the signature");
806
+ // If deferred signing hasn't populated pubsubMessageToPublish yet,
807
+ // modify the unsigned options so publish() will sign with the overridden props
808
+ const unsignedOpts = comment.raw.unsignedPublicationOptions;
809
+ if (!comment.raw.pubsubMessageToPublish && unsignedOpts) {
810
+ for (const optionKey of remeda.keys.strict(props)) {
811
+ //@ts-expect-error
812
+ comment[optionKey] = unsignedOpts[optionKey] = props[optionKey];
813
+ }
814
+ disableValidationOfSignatureBeforePublishing(comment);
815
+ return;
816
+ }
817
+ const pubsubPublication = remeda.clone(comment.raw.pubsubMessageToPublish);
818
+ for (const optionKey of remeda.keys.strict(props)) {
819
+ //@ts-expect-error
820
+ comment[optionKey] = pubsubPublication[optionKey] = props[optionKey];
821
+ }
822
+ comment.signature = pubsubPublication.signature = await signComment({
823
+ comment: removeUndefinedValuesRecursively({
824
+ ...pubsubPublication,
825
+ signer: comment.signer,
826
+ communityAddress: comment.communityAddress
827
+ }),
828
+ pkc: comment._pkc
829
+ });
830
+ comment.raw.pubsubMessageToPublish = pubsubPublication;
831
+ disableValidationOfSignatureBeforePublishing(comment);
832
+ }
833
+ export async function overrideCommentEditInstancePropsAndSign(commentEdit, props) {
834
+ if (!commentEdit.signer)
835
+ throw Error("Need commentEdit.signer to overwrite the signature");
836
+ //@ts-expect-error
837
+ for (const optionKey of Object.keys(props))
838
+ commentEdit[optionKey] = props[optionKey];
839
+ commentEdit.signature = await signCommentEdit({
840
+ edit: removeUndefinedValuesRecursively({
841
+ ...commentEdit.raw.pubsubMessageToPublish,
842
+ signer: commentEdit.signer,
843
+ communityAddress: commentEdit.communityAddress
844
+ }),
845
+ pkc: commentEdit._pkc
846
+ });
847
+ disableValidationOfSignatureBeforePublishing(commentEdit);
848
+ }
849
+ export async function ensurePublicationIsSigned(publication, community) {
850
+ if (!publication.raw.pubsubMessageToPublish) {
851
+ publication._community = {
852
+ address: community.address,
853
+ publicKey: community.signer?.address ?? community.address,
854
+ name: community.name,
855
+ encryption: community.encryption,
856
+ pubsubTopic: community.pubsubTopic
857
+ };
858
+ await publication._signPublicationWithCommunityFields();
859
+ }
860
+ }
861
+ export async function setExtraPropOnCommentAndSign(comment, extraProps, includeExtraPropInSignedPropertyNames) {
862
+ const log = Logger("pkc-js:test-util:setExtraPropOnVoteAndSign");
863
+ // With deferred signing, the publication may not be signed yet
864
+ if (!comment.raw.pubsubMessageToPublish) {
865
+ await comment._initCommunity();
866
+ await comment._signPublicationWithCommunityFields();
867
+ }
868
+ const publicationWithExtraProp = { ...comment.raw.pubsubMessageToPublish, ...extraProps };
869
+ if (includeExtraPropInSignedPropertyNames)
870
+ publicationWithExtraProp.signature = await _signJson([...comment.signature.signedPropertyNames, ...remeda.keys.strict(extraProps)], cleanUpBeforePublishing(publicationWithExtraProp), comment.signer, log);
871
+ comment.raw.pubsubMessageToPublish = publicationWithExtraProp;
872
+ disableValidationOfSignatureBeforePublishing(comment);
873
+ Object.assign(comment, publicationWithExtraProp, {
874
+ author: buildRuntimeAuthor({
875
+ author: publicationWithExtraProp.author,
876
+ signaturePublicKey: publicationWithExtraProp.signature.publicKey
877
+ })
878
+ });
879
+ }
880
+ export async function setExtraPropOnVoteAndSign(vote, extraProps, includeExtraPropInSignedPropertyNames) {
881
+ const log = Logger("pkc-js:test-util:setExtraPropOnVoteAndSign");
882
+ // With deferred signing, the publication may not be signed yet
883
+ if (!vote.raw.pubsubMessageToPublish) {
884
+ await vote._initCommunity();
885
+ await vote._signPublicationWithCommunityFields();
886
+ }
887
+ const publicationWithExtraProp = { ...vote.raw.pubsubMessageToPublish, ...extraProps };
888
+ if (includeExtraPropInSignedPropertyNames)
889
+ publicationWithExtraProp.signature = await _signJson([...vote.signature.signedPropertyNames, ...Object.keys(extraProps)], cleanUpBeforePublishing(publicationWithExtraProp), vote.signer, log);
890
+ vote.raw.pubsubMessageToPublish = publicationWithExtraProp;
891
+ disableValidationOfSignatureBeforePublishing(vote);
892
+ Object.assign(vote, publicationWithExtraProp, {
893
+ author: buildRuntimeAuthor({
894
+ author: publicationWithExtraProp.author,
895
+ signaturePublicKey: publicationWithExtraProp.signature.publicKey
896
+ })
897
+ });
898
+ }
899
+ export async function setExtraPropOnCommentEditAndSign(commentEdit, extraProps, includeExtraPropInSignedPropertyNames) {
900
+ const log = Logger("pkc-js:test-util:setExtraPropOnCommentEditAndSign");
901
+ // With deferred signing, the publication may not be signed yet
902
+ if (!commentEdit.raw.pubsubMessageToPublish) {
903
+ await commentEdit._initCommunity();
904
+ await commentEdit._signPublicationWithCommunityFields();
905
+ }
906
+ const publicationWithExtraProp = { ...commentEdit.raw.pubsubMessageToPublish, ...extraProps };
907
+ if (includeExtraPropInSignedPropertyNames)
908
+ publicationWithExtraProp.signature = await _signJson([...commentEdit.signature.signedPropertyNames, ...Object.keys(extraProps)], cleanUpBeforePublishing(publicationWithExtraProp), commentEdit.signer, log);
909
+ commentEdit.raw.pubsubMessageToPublish = publicationWithExtraProp;
910
+ disableValidationOfSignatureBeforePublishing(commentEdit);
911
+ Object.assign(commentEdit, publicationWithExtraProp, {
912
+ author: buildRuntimeAuthor({
913
+ author: publicationWithExtraProp.author,
914
+ signaturePublicKey: publicationWithExtraProp.signature.publicKey
915
+ })
916
+ });
917
+ }
918
+ export async function setExtraPropOnCommentModerationAndSign(commentModeration, extraProps, includeExtraPropInSignedPropertyNames) {
919
+ const log = Logger("pkc-js:test-util:setExtraPropOnCommentModerationAndSign");
920
+ if (!commentModeration.raw.pubsubMessageToPublish) {
921
+ await commentModeration._initCommunity();
922
+ await commentModeration._signPublicationWithCommunityFields();
923
+ }
924
+ const newPubsubPublicationWithExtraProp = (remeda.mergeDeep(commentModeration.raw.pubsubMessageToPublish, extraProps));
925
+ if (includeExtraPropInSignedPropertyNames)
926
+ newPubsubPublicationWithExtraProp.signature = await _signJson([...commentModeration.signature.signedPropertyNames, ...Object.keys(extraProps)], cleanUpBeforePublishing(newPubsubPublicationWithExtraProp), commentModeration.signer, log);
927
+ commentModeration.raw.pubsubMessageToPublish = newPubsubPublicationWithExtraProp;
928
+ disableValidationOfSignatureBeforePublishing(commentModeration);
929
+ Object.assign(commentModeration, newPubsubPublicationWithExtraProp, {
930
+ author: buildRuntimeAuthor({
931
+ author: newPubsubPublicationWithExtraProp.author,
932
+ signaturePublicKey: newPubsubPublicationWithExtraProp.signature.publicKey
933
+ })
934
+ });
935
+ }
936
+ export async function setExtraPropOnChallengeRequestAndSign({ publication, extraProps, includeExtraPropsInRequestSignedPropertyNames }) {
937
+ const log = Logger("pkc-js:test-util:setExtraPropOnChallengeRequestAndSign");
938
+ //@ts-expect-error
939
+ publication._signAndValidateChallengeRequestBeforePublishing = async (requestWithoutSignature, signer) => {
940
+ const signedPropertyNames = Object.keys(requestWithoutSignature);
941
+ if (includeExtraPropsInRequestSignedPropertyNames)
942
+ signedPropertyNames.push(...Object.keys(extraProps));
943
+ const requestWithExtraProps = { ...requestWithoutSignature, ...extraProps };
944
+ const signature = await _signPubsubMsg({ signedPropertyNames, msg: requestWithExtraProps, signer, log });
945
+ return { ...requestWithExtraProps, signature };
946
+ };
947
+ }
948
+ export async function publishChallengeAnswerMessageWithExtraProps({ publication, challengeAnswers, extraProps, includeExtraPropsInChallengeSignedPropertyNames }) {
949
+ // we're crafting a challenge answer from scratch here
950
+ const log = Logger("pkc-js:test-util:setExtraPropsOnChallengeAnswerMessageAndSign");
951
+ const signer = Object.values(publication._challengeExchanges)[0].signer;
952
+ if (!signer)
953
+ throw Error("Signer is undefined for this challenge exchange");
954
+ const encryptedChallengeAnswers = await encryptEd25519AesGcm(JSON.stringify({ challengeAnswers }), signer.privateKey, publication._community.encryption.publicKey);
955
+ const toSignAnswer = cleanUpBeforePublishing({
956
+ type: "CHALLENGEANSWER",
957
+ challengeRequestId: Object.values(publication._challengeExchanges)[0].challengeRequest.challengeRequestId,
958
+ encrypted: encryptedChallengeAnswers,
959
+ userAgent: publication._pkc.userAgent,
960
+ protocolVersion: env.PROTOCOL_VERSION,
961
+ timestamp: timestamp()
962
+ });
963
+ const signedPropertyNames = remeda.keys.strict(toSignAnswer);
964
+ //@ts-expect-error
965
+ if (includeExtraPropsInChallengeSignedPropertyNames)
966
+ signedPropertyNames.push(...Object.keys(extraProps));
967
+ Object.assign(toSignAnswer, extraProps);
968
+ const signature = await _signPubsubMsg({ signedPropertyNames, msg: toSignAnswer, signer, log });
969
+ await publishOverPubsub(publication._community.pubsubTopic, { ...toSignAnswer, signature });
970
+ }
971
+ export async function publishChallengeMessageWithExtraProps({ publication, pubsubSigner, extraProps, includeExtraPropsInChallengeSignedPropertyNames }) {
972
+ const log = Logger("pkc-js:test-util:publishChallengeMessageWithExtraProps");
973
+ const encryptedChallenges = await encryptEd25519AesGcmPublicKeyBuffer(deterministicStringify({ challenges: [] }), pubsubSigner.privateKey, Object.values(publication._challengeExchanges)[0].challengeRequest.signature.publicKey);
974
+ const toSignChallenge = cleanUpBeforePublishing({
975
+ type: "CHALLENGE",
976
+ challengeRequestId: Object.values(publication._challengeExchanges)[0].challengeRequest.challengeRequestId,
977
+ encrypted: encryptedChallenges,
978
+ userAgent: publication._pkc.userAgent,
979
+ protocolVersion: env.PROTOCOL_VERSION,
980
+ timestamp: timestamp()
981
+ });
982
+ const signedPropertyNames = remeda.keys.strict(toSignChallenge);
983
+ //@ts-expect-error
984
+ if (includeExtraPropsInChallengeSignedPropertyNames)
985
+ signedPropertyNames.push(...Object.keys(extraProps));
986
+ Object.assign(toSignChallenge, extraProps);
987
+ const signature = await _signPubsubMsg({
988
+ signedPropertyNames: signedPropertyNames,
989
+ msg: toSignChallenge,
990
+ signer: pubsubSigner,
991
+ log
992
+ });
993
+ await publishOverPubsub(pubsubSigner.address, { ...toSignChallenge, signature });
994
+ }
995
+ export async function publishChallengeVerificationMessageWithExtraProps({ publication, pubsubSigner, extraProps, includeExtraPropsInChallengeSignedPropertyNames }) {
996
+ const log = Logger("pkc-js:test-util:publishChallengeVerificationMessageWithExtraProps");
997
+ const toSignChallengeVerification = cleanUpBeforePublishing({
998
+ type: "CHALLENGEVERIFICATION",
999
+ challengeRequestId: Object.values(publication._challengeExchanges)[0].challengeRequest.challengeRequestId,
1000
+ challengeSuccess: false,
1001
+ reason: "Random reason",
1002
+ userAgent: publication._pkc.userAgent,
1003
+ protocolVersion: env.PROTOCOL_VERSION,
1004
+ timestamp: timestamp()
1005
+ });
1006
+ const signedPropertyNames = remeda.keys.strict(toSignChallengeVerification);
1007
+ //@ts-expect-error
1008
+ if (includeExtraPropsInChallengeSignedPropertyNames)
1009
+ signedPropertyNames.push(...Object.keys(extraProps));
1010
+ Object.assign(toSignChallengeVerification, extraProps);
1011
+ const signature = await _signPubsubMsg({
1012
+ signedPropertyNames: signedPropertyNames,
1013
+ msg: toSignChallengeVerification,
1014
+ signer: pubsubSigner,
1015
+ log
1016
+ });
1017
+ await publishOverPubsub(pubsubSigner.address, { ...toSignChallengeVerification, signature });
1018
+ }
1019
+ export async function publishChallengeVerificationMessageWithEncryption(publication, pubsubSigner, toEncrypt, verificationProps) {
1020
+ const log = Logger("pkc-js:test-util:publishChallengeVerificationMessageWithExtraProps");
1021
+ const challengeRequest = Object.values(publication._challengeExchanges)[0].challengeRequest;
1022
+ const toSignChallengeVerification = cleanUpBeforePublishing({
1023
+ type: "CHALLENGEVERIFICATION",
1024
+ challengeRequestId: challengeRequest.challengeRequestId,
1025
+ challengeSuccess: true,
1026
+ userAgent: publication._pkc.userAgent,
1027
+ protocolVersion: env.PROTOCOL_VERSION,
1028
+ timestamp: timestamp(),
1029
+ ...verificationProps
1030
+ });
1031
+ const publicKey = Buffer.from(challengeRequest.signature.publicKey).toString("base64");
1032
+ const encrypted = await encryptEd25519AesGcm(JSON.stringify(toEncrypt), pubsubSigner.privateKey, publicKey);
1033
+ toSignChallengeVerification.encrypted = encrypted;
1034
+ const signature = await signChallengeVerification({ challengeVerification: toSignChallengeVerification, signer: pubsubSigner });
1035
+ await publishOverPubsub(pubsubSigner.address, { ...toSignChallengeVerification, signature });
1036
+ }
1037
+ export async function addStringToIpfs(content) {
1038
+ const pkc = await mockPKCNoDataPathWithOnlyKuboClient();
1039
+ const ipfsClient = pkc._clientsManager.getDefaultKuboRpcClient();
1040
+ const cid = (await retryKuboIpfsAdd({ content, ipfsClient: ipfsClient._client, log: Logger("pkc-js:test-util:addStringToIpfs") })).path;
1041
+ await pkc.destroy();
1042
+ return cid;
1043
+ }
1044
+ export async function publishOverPubsub(pubsubTopic, jsonToPublish) {
1045
+ const pkc = await mockPKCNoDataPathWithOnlyKuboClient();
1046
+ await pkc._clientsManager.pubsubPublish(pubsubTopic, jsonToPublish);
1047
+ await pkc.destroy();
1048
+ }
1049
+ export async function mockPKCWithHeliaConfig(opts) {
1050
+ const key = "Helia config default for testing(remote)" + String(opts?.forceMockPubsub ? "" : Math.random());
1051
+ const forceMockPubsub = typeof opts?.forceMockPubsub === "boolean" ? opts.forceMockPubsub : true;
1052
+ const heliaPKC = await mockPKCV2({
1053
+ forceMockPubsub,
1054
+ ...opts,
1055
+ pkcOptions: {
1056
+ libp2pJsClientsOptions: [{ key, libp2pOptions: { connectionGater: { denyDialMultiaddr: async () => false } } }],
1057
+ pubsubKuboRpcClientsOptions: [],
1058
+ kuboRpcClientsOptions: [],
1059
+ pkcRpcClientsOptions: undefined,
1060
+ httpRoutersOptions: ["http://localhost:20001"], // this http router transmits the addresses of kubo node of test-server.js
1061
+ dataPath: undefined,
1062
+ ...opts?.pkcOptions
1063
+ }
1064
+ });
1065
+ if (forceMockPubsub) {
1066
+ const mockedPubsubClient = createMockPubsubClient();
1067
+ const heliaLibp2pJsClient = heliaPKC.clients.libp2pJsClients[Object.keys(heliaPKC.clients.libp2pJsClients)[0]];
1068
+ heliaLibp2pJsClient.heliaWithKuboRpcClientFunctions.pubsub = mockedPubsubClient.pubsub; // that should work for publishing/subscribing
1069
+ const originalStop = heliaLibp2pJsClient._helia.stop.bind(heliaLibp2pJsClient._helia);
1070
+ heliaLibp2pJsClient._helia.stop = async () => {
1071
+ await originalStop();
1072
+ await mockedPubsubClient.destroy();
1073
+ };
1074
+ }
1075
+ return heliaPKC;
1076
+ }
1077
+ const testConfigCodeToPKCInstanceWithHumanName = {
1078
+ "remote-kubo-rpc": {
1079
+ pkcInstancePromise: (args) => mockPKCNoDataPathWithOnlyKuboClient(args),
1080
+ name: "Kubo Node with no datapath (remote)",
1081
+ testConfigCode: "remote-kubo-rpc"
1082
+ },
1083
+ "remote-ipfs-gateway": {
1084
+ pkcInstancePromise: (args) => mockGatewayPKC(args),
1085
+ name: "IPFS Gateway",
1086
+ testConfigCode: "remote-ipfs-gateway"
1087
+ },
1088
+ "remote-pkc-rpc": {
1089
+ pkcInstancePromise: (args) => mockRpcRemotePKC(args),
1090
+ name: "PKC RPC Remote",
1091
+ testConfigCode: "remote-pkc-rpc"
1092
+ },
1093
+ "local-kubo-rpc": {
1094
+ pkcInstancePromise: (args) => mockPKCV2({
1095
+ ...args,
1096
+ pkcOptions: {
1097
+ ...args?.pkcOptions,
1098
+ pkcRpcClientsOptions: undefined,
1099
+ kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
1100
+ pubsubKuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
1101
+ ipfsGatewayUrls: undefined
1102
+ }
1103
+ }),
1104
+ name: "Kubo node with datapath (local)",
1105
+ testConfigCode: "local-kubo-rpc"
1106
+ },
1107
+ "remote-libp2pjs": {
1108
+ pkcInstancePromise: (args) => mockPKCWithHeliaConfig(args),
1109
+ name: "Libp2pJS client with no datapath (remote)",
1110
+ testConfigCode: "remote-libp2pjs"
1111
+ }
1112
+ };
1113
+ let pkcConfigs = [];
1114
+ export function setPKCConfigs(configs) {
1115
+ if (configs.length === 0)
1116
+ throw Error("No configs were provided");
1117
+ // Make sure each config exists in the mapper
1118
+ for (const config of configs)
1119
+ if (!testConfigCodeToPKCInstanceWithHumanName[config])
1120
+ throw new Error(`Config "${config}" does not exist in the mapper. Available configs are: ${Object.keys(testConfigCodeToPKCInstanceWithHumanName)}`);
1121
+ pkcConfigs = configs.map((config) => testConfigCodeToPKCInstanceWithHumanName[config]);
1122
+ if (globalThis.window) {
1123
+ globalThis.window.addEventListener("uncaughtException", (err) => {
1124
+ console.error("uncaughtException", JSON.stringify(err, ["message", "arguments", "type", "name"]));
1125
+ });
1126
+ globalThis.window.addEventListener("unhandledrejection", (err) => {
1127
+ console.error("unhandledRejection", JSON.stringify(err, ["message", "arguments", "type", "name"]));
1128
+ });
1129
+ }
1130
+ else if (process) {
1131
+ process.setMaxListeners(100);
1132
+ process.on("uncaughtException", (...err) => {
1133
+ console.error("uncaughtException", ...err);
1134
+ });
1135
+ process.on("unhandledRejection", (...err) => {
1136
+ console.error("unhandledRejection", ...err);
1137
+ });
1138
+ }
1139
+ }
1140
+ export function getAvailablePKCConfigsToTestAgainst(opts) {
1141
+ if (opts?.includeAllPossibleConfigOnEnv) {
1142
+ // if node, ["local-kubo-rpc", "remote-kubo-rpc", "remote-ipfs-gateway"], also 'remote-pkc-rpc' if isRpcFlagOn()
1143
+ // if browser, ["remote-kubo-rpc", "remote-ipfs-gateway"]
1144
+ // NOTE: "remote-libp2pjs" is temporarily disabled due to stability issues
1145
+ const isBrowser = isRunningInBrowser();
1146
+ const pkcConfigCodes = isBrowser
1147
+ ? ["remote-kubo-rpc", "remote-ipfs-gateway"]
1148
+ : ["local-kubo-rpc", "remote-kubo-rpc", "remote-ipfs-gateway"];
1149
+ if (!isBrowser && isRpcFlagOn())
1150
+ pkcConfigCodes.push("remote-pkc-rpc");
1151
+ const availableConfigs = remeda.pick(testConfigCodeToPKCInstanceWithHumanName, pkcConfigCodes);
1152
+ if (opts.includeOnlyTheseTests?.length) {
1153
+ return Object.values(remeda.pick(availableConfigs, opts.includeOnlyTheseTests));
1154
+ }
1155
+ return Object.values(availableConfigs);
1156
+ }
1157
+ // Check if configs are passed via environment variable
1158
+ const pkcConfigsFromEnv = process?.env?.PKC_CONFIGS;
1159
+ if (pkcConfigsFromEnv) {
1160
+ const configs = pkcConfigsFromEnv.split(",");
1161
+ // Set the configs if they're coming from the environment variable
1162
+ setPKCConfigs(configs);
1163
+ }
1164
+ //@ts-expect-error
1165
+ const pkcConfigsFromWindow = globalThis["window"]?.["PKC_CONFIGS"];
1166
+ if (pkcConfigsFromWindow) {
1167
+ const configs = pkcConfigsFromWindow.split(",");
1168
+ // Set the configs if they're coming from the environment variable
1169
+ setPKCConfigs(configs);
1170
+ }
1171
+ if (pkcConfigs.length === 0)
1172
+ throw Error("No remote pkc configs set, " + pkcConfigsFromEnv + " " + pkcConfigsFromWindow);
1173
+ if (opts?.includeOnlyTheseTests) {
1174
+ opts.includeOnlyTheseTests.forEach((config) => {
1175
+ if (!testConfigCodeToPKCInstanceWithHumanName[config])
1176
+ throw new Error(`Config "${config}" does not exist in the mapper. Available configs are: ${pkcConfigs.map((c) => c.name).join(", ")}`);
1177
+ });
1178
+ const filteredKeys = remeda.keys
1179
+ .strict(testConfigCodeToPKCInstanceWithHumanName)
1180
+ .filter((config) => opts.includeOnlyTheseTests.includes(config) &&
1181
+ pkcConfigs.find((c) => c.name === testConfigCodeToPKCInstanceWithHumanName[config].name));
1182
+ const configs = filteredKeys.map((config) => testConfigCodeToPKCInstanceWithHumanName[config]);
1183
+ return configs;
1184
+ }
1185
+ return pkcConfigs;
1186
+ }
1187
+ export async function createNewIpns() {
1188
+ const pkc = await mockPKCNoDataPathWithOnlyKuboClient({});
1189
+ const ipfsClient = pkc._clientsManager.getDefaultKuboRpcClient();
1190
+ const signer = await pkc.createSigner();
1191
+ signer.ipfsKey = new Uint8Array(await getIpfsKeyFromPrivateKey(signer.privateKey));
1192
+ await importSignerIntoKuboNode(signer.address, signer.ipfsKey, {
1193
+ url: pkc.kuboRpcClientsOptions[0].url.toString(),
1194
+ headers: pkc.kuboRpcClientsOptions[0].headers
1195
+ });
1196
+ const publishToIpns = async (content) => {
1197
+ const cid = await addStringToIpfs(content);
1198
+ await ipfsClient._client.name.publish(cid, {
1199
+ key: signer.address,
1200
+ allowOffline: true
1201
+ });
1202
+ // Verify the IPNS record is resolvable before returning
1203
+ // This ensures Kubo's cache is properly synced for RPC tests
1204
+ const resolvedCid = await last(ipfsClient._client.name.resolve(signer.address, {
1205
+ nocache: false, // Allow cache to be used
1206
+ timeout: 5000 // 5 second timeout for verification
1207
+ }));
1208
+ if (!resolvedCid) {
1209
+ throw new Error(`Failed to verify IPNS resolution for ${signer.address}`);
1210
+ }
1211
+ };
1212
+ return {
1213
+ signer,
1214
+ publishToIpns,
1215
+ pkc
1216
+ };
1217
+ }
1218
+ async function getTemplateCommunityRecord(pkc) {
1219
+ const community = await pkc.createCommunity({ address: "12D3KooWANwdyPERMQaCgiMnTT1t3Lr4XLFbK1z4ptFVhW2ozg1z" });
1220
+ await community.update();
1221
+ await resolveWhenConditionIsTrue({ toUpdate: community, predicate: async () => typeof community.updatedAt === "number" });
1222
+ const result = community.raw.communityIpfs;
1223
+ await community.stop();
1224
+ return result;
1225
+ }
1226
+ export async function publishCommunityRecordWithExtraProp(opts) {
1227
+ const ipnsObj = await createNewIpns();
1228
+ const communityRecord = JSON.parse(JSON.stringify(await getTemplateCommunityRecord(ipnsObj.pkc)));
1229
+ communityRecord.pubsubTopic = ipnsObj.signer.address;
1230
+ delete communityRecord.posts;
1231
+ if (opts?.extraProps)
1232
+ Object.assign(communityRecord, opts.extraProps);
1233
+ const signedPropertyNames = communityRecord.signature.signedPropertyNames;
1234
+ if (opts?.includeExtraPropInSignedPropertyNames)
1235
+ signedPropertyNames.push("extraProp");
1236
+ communityRecord.signature = await _signJson(signedPropertyNames, communityRecord, ipnsObj.signer, Logger("pkc-js:test-util:publishCommunityRecordWithExtraProp"));
1237
+ await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
1238
+ return { communityRecord, ipnsObj };
1239
+ }
1240
+ export async function createMockedCommunityIpns(communityOpts) {
1241
+ const ipnsObj = await createNewIpns();
1242
+ const communityAddress = ipnsObj.signer.address;
1243
+ const communityRecord = {
1244
+ ...(await getTemplateCommunityRecord(ipnsObj.pkc)),
1245
+ posts: undefined,
1246
+ pubsubTopic: communityAddress,
1247
+ ...communityOpts
1248
+ }; // default community, will be using its props
1249
+ if (!communityRecord.posts)
1250
+ delete communityRecord.posts;
1251
+ communityRecord.signature = await signCommunity({ community: communityRecord, signer: ipnsObj.signer });
1252
+ await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
1253
+ await ipnsObj.pkc.destroy();
1254
+ return { communityRecord, communityAddress, ipnsObj };
1255
+ }
1256
+ export async function createStaticCommunityRecordForComment(opts) {
1257
+ const { pkc, commentOptions = {}, invalidateCommunitySignature = false } = opts || {};
1258
+ if (commentOptions.parentCid && !commentOptions.postCid)
1259
+ throw Error("postCid must be provided when parentCid is supplied for a reply");
1260
+ const ipnsObj = await createNewIpns();
1261
+ const communityAddress = ipnsObj.signer.address;
1262
+ const commentPKC = pkc || (await mockPKCNoDataPathWithOnlyKuboClient());
1263
+ const shouldDestroyCommentPKC = !pkc;
1264
+ try {
1265
+ const communityRecord = {
1266
+ ...(await getTemplateCommunityRecord(ipnsObj.pkc)),
1267
+ posts: undefined,
1268
+ pubsubTopic: communityAddress
1269
+ };
1270
+ if (!communityRecord.posts)
1271
+ delete communityRecord.posts;
1272
+ // Always publish a valid record first so the IPNS key is established for gateway discovery
1273
+ communityRecord.signature = await signCommunity({ community: communityRecord, signer: ipnsObj.signer });
1274
+ await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
1275
+ const commentToPublish = await commentPKC.createComment({
1276
+ ...commentOptions,
1277
+ signer: commentOptions.signer || (await commentPKC.createSigner()),
1278
+ communityAddress: communityAddress,
1279
+ title: commentOptions.title ?? `Mock Post - ${Date.now()}`,
1280
+ content: commentOptions.content ?? `Mock content - ${Date.now()}`
1281
+ });
1282
+ const depth = typeof commentOptions.depth === "number" ? commentOptions.depth : commentOptions.parentCid ? 1 : 0;
1283
+ if (!commentToPublish.raw.pubsubMessageToPublish) {
1284
+ // Directly set _community from in-memory data to avoid fetching from the gateway.
1285
+ // This prevents caching the valid community record in dedicatedPKC's memory,
1286
+ // which would otherwise cause the subsequent update() to get the cached valid record
1287
+ // instead of fetching the (possibly invalid) record from the gateway.
1288
+ commentToPublish["_community"] = {
1289
+ address: communityAddress,
1290
+ publicKey: getPKCAddressFromPublicKeySync(communityRecord.signature.publicKey),
1291
+ encryption: communityRecord.encryption,
1292
+ pubsubTopic: communityRecord.pubsubTopic
1293
+ };
1294
+ await commentToPublish._signPublicationWithCommunityFields();
1295
+ }
1296
+ const commentIpfs = { ...commentToPublish.raw.pubsubMessageToPublish, depth };
1297
+ if (commentOptions.parentCid) {
1298
+ commentIpfs.parentCid = commentOptions.parentCid;
1299
+ commentIpfs.postCid = commentOptions.postCid;
1300
+ }
1301
+ const commentCid = await addStringToIpfs(JSON.stringify(commentIpfs));
1302
+ // Optionally re-publish with invalid signature after comment is already created
1303
+ if (invalidateCommunitySignature) {
1304
+ communityRecord.updatedAt = (communityRecord.updatedAt || timestamp()) + 1234;
1305
+ await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
1306
+ }
1307
+ return { commentCid, communityAddress: communityAddress };
1308
+ }
1309
+ finally {
1310
+ await ipnsObj.pkc.destroy();
1311
+ if (shouldDestroyCommentPKC)
1312
+ await commentPKC.destroy();
1313
+ }
1314
+ }
1315
+ function _stripNameResolvedFromPages(pagesContainer) {
1316
+ if (!pagesContainer?.pages)
1317
+ return;
1318
+ for (const page of Object.values(pagesContainer.pages)) {
1319
+ if (!page || !page.comments)
1320
+ continue;
1321
+ for (const c of page.comments) {
1322
+ if (c?.author)
1323
+ delete c.author.nameResolved;
1324
+ }
1325
+ }
1326
+ }
1327
+ export function jsonifyCommunityAndRemoveInternalProps(community) {
1328
+ const jsonfied = JSON.parse(JSON.stringify(community));
1329
+ delete jsonfied["posts"]["clients"];
1330
+ delete jsonfied["modQueue"]["clients"];
1331
+ delete jsonfied["raw"]["runtimeFieldsFromRpc"];
1332
+ delete jsonfied["raw"]["localCommunity"];
1333
+ // Normalize old raw key to new key for backward compat comparison
1334
+ if (jsonfied["raw"]["subplebbitIpfs"] && !jsonfied["raw"]["communityIpfs"]) {
1335
+ jsonfied["raw"]["communityIpfs"] = jsonfied["raw"]["subplebbitIpfs"];
1336
+ delete jsonfied["raw"]["subplebbitIpfs"];
1337
+ }
1338
+ _stripNameResolvedFromPages(jsonfied["posts"]);
1339
+ _stripNameResolvedFromPages(jsonfied["modQueue"]);
1340
+ return remeda.omit(jsonfied, ["startedState", "started", "signer", "settings", "editable", "clients", "updatingState", "state"]);
1341
+ }
1342
+ export function jsonifyLocalCommunityWithNoInternalProps(community) {
1343
+ const localJson = JSON.parse(JSON.stringify(community));
1344
+ //@ts-expect-error
1345
+ delete localJson["posts"]["clients"];
1346
+ return remeda.omit(localJson, ["startedState", "started", "clients", "state", "updatingState"]);
1347
+ }
1348
+ export function jsonifyCommentAndRemoveInstanceProps(comment) {
1349
+ const jsonfied = cleanUpBeforePublishing(JSON.parse(JSON.stringify(comment)));
1350
+ if ("replies" in jsonfied)
1351
+ delete jsonfied["replies"]["clients"];
1352
+ if ("replies" in jsonfied && remeda.isEmpty(jsonfied.replies))
1353
+ delete jsonfied["replies"];
1354
+ // nameResolved is runtime-only — strip it like jsonifyCommunityAndRemoveInternalProps does
1355
+ if (jsonfied.author?.nameResolved !== undefined)
1356
+ delete jsonfied.author.nameResolved;
1357
+ _stripNameResolvedFromPages(jsonfied["replies"]);
1358
+ return remeda.omit(jsonfied, ["clients", "state", "updatingState", "state", "publishingState", "raw"]);
1359
+ }
1360
+ export async function waitUntilPKCCommunitiesIncludeSubAddress(pkc, subAddress) {
1361
+ return pkc._awaitCommunitiesToIncludeCommunity(subAddress);
1362
+ }
1363
+ export function isPKCFetchingUsingGateways(pkc) {
1364
+ return (!pkc._pkcRpcClient && Object.keys(pkc.clients.kuboRpcClients).length === 0 && Object.keys(pkc.clients.libp2pJsClients).length === 0);
1365
+ }
1366
+ export function mockRpcServerForTests(pkcWs) {
1367
+ const functionsToBind = [
1368
+ "_createCommentModerationInstanceFromPublishCommentModerationParams",
1369
+ "_createCommentEditInstanceFromPublishCommentEditParams",
1370
+ "_createVoteInstanceFromPublishVoteParams",
1371
+ "_createCommentInstanceFromPublishCommentParams",
1372
+ "_createCommunityEditInstanceFromPublishCommunityEditParams"
1373
+ ];
1374
+ // disable validation of signature before publishing
1375
+ // reduce threshold for publishing
1376
+ for (const funcBind of functionsToBind) {
1377
+ const originalFunc = pkcWs[funcBind].bind(pkcWs);
1378
+ pkcWs[funcBind] = async (...args) => {
1379
+ const pubInstance = await originalFunc(...args);
1380
+ disableValidationOfSignatureBeforePublishing(pubInstance);
1381
+ pubInstance._publishToDifferentProviderThresholdSeconds = 5;
1382
+ pubInstance._setProviderFailureThresholdSeconds = 10;
1383
+ return pubInstance;
1384
+ };
1385
+ }
1386
+ }
1387
+ export function disablePreloadPagesOnSub({ community }) {
1388
+ if (!(community instanceof LocalCommunity))
1389
+ throw Error("You need to provide LocalCommunity instance");
1390
+ //@ts-expect-error
1391
+ const pageGenerator = community._pageGenerator;
1392
+ const originalCommunityPostsFunc = pageGenerator.generateCommunityPosts.bind(pageGenerator);
1393
+ const originalPostRepliesFunc = pageGenerator.generatePostPages.bind(pageGenerator);
1394
+ const originalReplyRepliesFunc = pageGenerator.generateReplyPages.bind(pageGenerator);
1395
+ const originalChunkComments = pageGenerator._chunkComments.bind(pageGenerator);
1396
+ pageGenerator.generateCommunityPosts = async (preloadedPageSortName, preloadedPageSize) => {
1397
+ return originalCommunityPostsFunc(preloadedPageSortName, preloadedPageSize); // should force community to publish to pageCids
1398
+ };
1399
+ pageGenerator.generatePostPages = async (comment, preloadedPageSortName, preloadedPageSize) => {
1400
+ return originalPostRepliesFunc(comment, preloadedPageSortName, preloadedPageSize); // should force community to publish to pageCids
1401
+ };
1402
+ pageGenerator.generateReplyPages = async (comment, preloadedPageSortName, preloadedPageSize) => {
1403
+ return originalReplyRepliesFunc(comment, preloadedPageSortName, preloadedPageSize);
1404
+ };
1405
+ //@ts-expect-error
1406
+ pageGenerator._chunkComments = async (opts) => {
1407
+ const res = await originalChunkComments(opts);
1408
+ return [[], ...res];
1409
+ };
1410
+ const cleanup = () => {
1411
+ pageGenerator.generateCommunityPosts = originalCommunityPostsFunc;
1412
+ pageGenerator.generatePostPages = originalPostRepliesFunc;
1413
+ pageGenerator.generateReplyPages = originalReplyRepliesFunc;
1414
+ pageGenerator._chunkComments = originalChunkComments;
1415
+ };
1416
+ return { cleanup };
1417
+ }
1418
+ export function mockPostToReturnSpecificCommentUpdate(commentToBeMocked, commentUpdateRecordString) {
1419
+ const updatingPostComment = findUpdatingComment(commentToBeMocked._pkc, { cid: commentToBeMocked.cid });
1420
+ if (!updatingPostComment)
1421
+ throw Error("Post should be updating before starting to mock");
1422
+ if (commentToBeMocked._pkc._pkcRpcClient)
1423
+ throw Error("Can't mock Post to return specific CommentUpdate record when pkc is using RPC");
1424
+ delete updatingPostComment.updatedAt;
1425
+ delete updatingPostComment.raw.commentUpdate;
1426
+ //@ts-expect-error
1427
+ delete updatingPostComment._communityForUpdating?.community?.updateCid;
1428
+ //@ts-expect-error
1429
+ if (updatingPostComment._communityForUpdating?.community?._clientsManager?._updateCidsAlreadyLoaded)
1430
+ //@ts-expect-error
1431
+ updatingPostComment._communityForUpdating.community._clientsManager._updateCidsAlreadyLoaded = new Set();
1432
+ mockCommentToNotUsePagesForUpdates(commentToBeMocked);
1433
+ if (isPKCFetchingUsingGateways(updatingPostComment._pkc)) {
1434
+ const originalFetch = updatingPostComment._clientsManager.fetchFromMultipleGateways.bind(updatingPostComment._clientsManager);
1435
+ updatingPostComment._clientsManager.fetchFromMultipleGateways = async (...args) => {
1436
+ const commentUpdateCid = await addStringToIpfs(commentUpdateRecordString);
1437
+ if (args[0].recordPKCType === "comment-update")
1438
+ return originalFetch({
1439
+ ...args[0],
1440
+ root: commentUpdateCid,
1441
+ path: undefined
1442
+ });
1443
+ else
1444
+ return originalFetch(...args);
1445
+ };
1446
+ }
1447
+ else {
1448
+ // we're using kubo/helia
1449
+ const originalFetch = updatingPostComment._clientsManager._fetchCidP2P.bind(updatingPostComment._clientsManager);
1450
+ //@ts-expect-error
1451
+ updatingPostComment._clientsManager._fetchCidP2P = (...args) => {
1452
+ if (args[0].endsWith("/update")) {
1453
+ return commentUpdateRecordString;
1454
+ }
1455
+ else
1456
+ return originalFetch(...args);
1457
+ };
1458
+ }
1459
+ }
1460
+ export function mockPostToFailToLoadFromPostUpdates(postToBeMocked) {
1461
+ const updatingPostComment = findUpdatingComment(postToBeMocked._pkc, { cid: postToBeMocked.cid });
1462
+ if (!updatingPostComment)
1463
+ throw Error("Post should be updating before starting to mock");
1464
+ if (postToBeMocked._pkc._pkcRpcClient)
1465
+ throw Error("Can't mock Post to to fail loading post from postUpdates when pkc is using RPC");
1466
+ mockCommentToNotUsePagesForUpdates(postToBeMocked);
1467
+ updatingPostComment._clientsManager._fetchPostCommentUpdateIpfsP2P =
1468
+ updatingPostComment._clientsManager._fetchPostCommentUpdateFromGateways = async () => {
1469
+ throw new PKCError("ERR_FAILED_TO_FETCH_COMMENT_UPDATE_FROM_ALL_POST_UPDATES_RANGES");
1470
+ };
1471
+ }
1472
+ export function mockPostToHaveCommunityWithNoPostUpdates(postToBeMocked) {
1473
+ const updatingPostComment = findUpdatingComment(postToBeMocked._pkc, { cid: postToBeMocked.cid });
1474
+ if (!updatingPostComment)
1475
+ throw Error("Post should be updating before starting to mock");
1476
+ if (postToBeMocked._pkc._pkcRpcClient)
1477
+ throw Error("Can't mock Post to to fail loading post from postUpdates when pkc is using RPC");
1478
+ mockCommentToNotUsePagesForUpdates(postToBeMocked);
1479
+ const originalCommunityUpdateHandle = updatingPostComment._clientsManager.handleUpdateEventFromCommunity.bind(updatingPostComment._clientsManager);
1480
+ updatingPostComment._clientsManager.handleUpdateEventFromCommunity = (community) => {
1481
+ delete community.postUpdates;
1482
+ delete community.raw.communityIpfs.postUpdates;
1483
+ return originalCommunityUpdateHandle(community);
1484
+ };
1485
+ }
1486
+ export async function createCommentUpdateWithInvalidSignature(commentCid) {
1487
+ const pkc = await mockPKCNoDataPathWithOnlyKuboClient({});
1488
+ const comment = await pkc.getComment({ cid: commentCid });
1489
+ await comment.update();
1490
+ await resolveWhenConditionIsTrue({ toUpdate: comment, predicate: async () => typeof comment.updatedAt === "number" });
1491
+ const invalidCommentUpdateJson = comment.raw.commentUpdate;
1492
+ await comment.stop();
1493
+ invalidCommentUpdateJson.updatedAt += 1234; // Invalidate CommentUpdate signature
1494
+ return invalidCommentUpdateJson;
1495
+ }
1496
+ export function mockPKCToTimeoutFetchingCid(pkc) {
1497
+ const originalFetch = pkc._clientsManager._fetchCidP2P;
1498
+ const restoreFns = [];
1499
+ for (const ipfsClient of Object.values(pkc.clients.kuboRpcClients)) {
1500
+ const originalCat = ipfsClient._client.cat;
1501
+ ipfsClient._client.cat = async function* (ipfsPath, options) {
1502
+ await new Promise((resolve) => setTimeout(resolve, pkc._timeouts["community-ipfs"] * 2));
1503
+ return undefined;
1504
+ };
1505
+ restoreFns.push(() => {
1506
+ ipfsClient._client.cat = originalCat;
1507
+ });
1508
+ }
1509
+ for (const libp2pJsClient of Object.values(pkc.clients.libp2pJsClients)) {
1510
+ const originalCat = libp2pJsClient.heliaWithKuboRpcClientFunctions.cat;
1511
+ libp2pJsClient.heliaWithKuboRpcClientFunctions.cat = async function* (ipfsPath, options) {
1512
+ await new Promise((resolve) => setTimeout(resolve, pkc._timeouts["community-ipfs"] * 2));
1513
+ return undefined;
1514
+ };
1515
+ restoreFns.push(() => {
1516
+ libp2pJsClient.heliaWithKuboRpcClientFunctions.cat = originalCat;
1517
+ });
1518
+ }
1519
+ // TODO mock for gateway
1520
+ // pkc._clientsManager._fetchCidP2P = async (...args) => {
1521
+ // await new Promise((resolve) => setTimeout(resolve, pkc._timeouts["community-ipfs"] * 2));
1522
+ // return undefined;
1523
+ // };
1524
+ return {
1525
+ cleanUp: () => {
1526
+ pkc._clientsManager._fetchCidP2P = originalFetch;
1527
+ for (const restore of restoreFns)
1528
+ restore();
1529
+ }
1530
+ };
1531
+ }
1532
+ export function mockCommentToNotUsePagesForUpdates(comment) {
1533
+ const updatingComment = findUpdatingComment(comment._pkc, { cid: comment.cid });
1534
+ if (!updatingComment)
1535
+ throw Error("Comment should be updating before starting to mock");
1536
+ if (comment._pkc._pkcRpcClient)
1537
+ throw Error("Can't mock comment _findCommentInPagesOfUpdatingCommentsCommunity with pkc rpc clients");
1538
+ delete updatingComment.raw.commentUpdate;
1539
+ delete updatingComment.updatedAt;
1540
+ updatingComment._clientsManager._findCommentInPagesOfUpdatingCommentsOrCommunity = () => undefined;
1541
+ }
1542
+ const FORCE_COMMUNITY_MIN_POST_CONTENT_BYTES = 30 * 1024;
1543
+ function ensureLocalCommunityForForcedChunking(community) {
1544
+ if (!community)
1545
+ throw Error("Local community instance is required to force reply pages to use page cids");
1546
+ if (!(community instanceof LocalCommunity))
1547
+ throw Error("Forcing reply page chunking is only supported when using a LocalCommunity");
1548
+ }
1549
+ export async function forceLocalSubPagesToAlwaysGenerateMultipleChunks({ community, parentComment, forcedPreloadedPageSizeBytes = 1, parentCommentReplyProps, communityPostsCommentProps }) {
1550
+ if (!parentComment) {
1551
+ await forceCommunityToGenerateAllPostsPages(community, communityPostsCommentProps);
1552
+ return { cleanup: () => { } };
1553
+ }
1554
+ ensureLocalCommunityForForcedChunking(community);
1555
+ const parentCid = parentComment.cid;
1556
+ if (!parentCid)
1557
+ throw Error("parent comment cid is required to force chunking to multiple pages");
1558
+ const localCommunity = community;
1559
+ const communityWithGenerator = localCommunity;
1560
+ const pageGenerator = communityWithGenerator["_pageGenerator"];
1561
+ if (!pageGenerator)
1562
+ throw Error("Local community page generator is not initialized");
1563
+ const isPost = parentComment.depth === 0;
1564
+ const originalGenerateReplyPages = pageGenerator.generateReplyPages;
1565
+ const originalGeneratePostPages = pageGenerator.generatePostPages;
1566
+ if (isPost) {
1567
+ if (typeof originalGeneratePostPages !== "function")
1568
+ throw Error("Page generator post pages function is not available");
1569
+ pageGenerator.generatePostPages = (async (comment, preloadedReplyPageSortName, preloadedPageSizeBytes) => {
1570
+ const shouldForce = comment?.cid === parentCid;
1571
+ const effectivePageSizeBytes = shouldForce
1572
+ ? Math.min(preloadedPageSizeBytes, forcedPreloadedPageSizeBytes)
1573
+ : preloadedPageSizeBytes;
1574
+ return originalGeneratePostPages.call(pageGenerator, comment, preloadedReplyPageSortName, effectivePageSizeBytes);
1575
+ });
1576
+ }
1577
+ else {
1578
+ if (typeof originalGenerateReplyPages !== "function")
1579
+ throw Error("Page generator reply pages function is not available");
1580
+ pageGenerator.generateReplyPages = (async (comment, preloadedReplyPageSortName, preloadedPageSizeBytes) => {
1581
+ const shouldForce = comment?.cid === parentCid;
1582
+ const effectivePageSizeBytes = shouldForce
1583
+ ? Math.min(preloadedPageSizeBytes, forcedPreloadedPageSizeBytes)
1584
+ : preloadedPageSizeBytes;
1585
+ return originalGenerateReplyPages.call(pageGenerator, comment, preloadedReplyPageSortName, effectivePageSizeBytes);
1586
+ });
1587
+ }
1588
+ const cleanup = () => {
1589
+ if (isPost && originalGeneratePostPages)
1590
+ pageGenerator.generatePostPages = originalGeneratePostPages;
1591
+ if (!isPost && originalGenerateReplyPages)
1592
+ pageGenerator.generateReplyPages = originalGenerateReplyPages;
1593
+ };
1594
+ try {
1595
+ if (Object.keys(parentComment.replies.pageCids).length === 0)
1596
+ await ensureParentCommentHasPageCidsForChunking(parentComment, {
1597
+ commentProps: parentCommentReplyProps,
1598
+ publishWithPKC: localCommunity._pkc
1599
+ });
1600
+ }
1601
+ catch (err) {
1602
+ cleanup();
1603
+ throw err;
1604
+ }
1605
+ return { cleanup };
1606
+ }
1607
+ async function ensureParentCommentHasPageCidsForChunking(parentComment, options) {
1608
+ if (!parentComment?.cid)
1609
+ throw Error("parent comment cid should be defined before ensuring page cids");
1610
+ const hasPageCids = () => Object.keys(parentComment.replies.pageCids).length > 0;
1611
+ if (hasPageCids())
1612
+ return;
1613
+ const { commentProps, publishWithPKC } = options ?? {};
1614
+ const MAX_REPLIES_TO_PUBLISH = 5;
1615
+ for (let i = 0; i < MAX_REPLIES_TO_PUBLISH && !hasPageCids(); i++) {
1616
+ const replyProps = {
1617
+ ...commentProps,
1618
+ content: commentProps?.content ?? `force pagination reply ${i} ${Date.now()}`
1619
+ };
1620
+ const publishingPKC = publishWithPKC ?? parentComment._pkc;
1621
+ await publishRandomReply({
1622
+ parentComment: parentComment,
1623
+ pkc: publishingPKC,
1624
+ commentProps: replyProps
1625
+ });
1626
+ await parentComment.update();
1627
+ await resolveWhenConditionIsTrue({
1628
+ toUpdate: parentComment,
1629
+ predicate: async () => hasPageCids()
1630
+ });
1631
+ }
1632
+ if (!hasPageCids())
1633
+ throw Error(`Failed to force parent comment ${parentComment.cid} to have replies.pageCids`);
1634
+ }
1635
+ export async function findOrPublishCommentWithDepth({ depth, community, pkc }) {
1636
+ const pkcWithDefault = pkc || community._pkc;
1637
+ let commentFromPreloadedPages;
1638
+ if (community.posts.pages.hot) {
1639
+ processAllCommentsRecursively(community.posts.pages.hot.comments, (comment) => {
1640
+ if (comment.depth === depth) {
1641
+ commentFromPreloadedPages = comment;
1642
+ }
1643
+ });
1644
+ }
1645
+ if (commentFromPreloadedPages)
1646
+ return pkcWithDefault.createComment(commentFromPreloadedPages);
1647
+ let curComment;
1648
+ let closestCommentFromHot;
1649
+ if (community.posts.pages.hot) {
1650
+ let maxDepthFound = -1;
1651
+ processAllCommentsRecursively(community.posts.pages.hot.comments, (comment) => {
1652
+ const commentDepth = comment.depth ?? 0;
1653
+ if (commentDepth <= depth && commentDepth > maxDepthFound) {
1654
+ maxDepthFound = commentDepth;
1655
+ closestCommentFromHot = comment;
1656
+ }
1657
+ });
1658
+ }
1659
+ if (closestCommentFromHot) {
1660
+ curComment = await pkcWithDefault.createComment(closestCommentFromHot);
1661
+ }
1662
+ else {
1663
+ curComment = await publishRandomPost({ communityAddress: community.address, pkc: pkcWithDefault });
1664
+ }
1665
+ if (curComment.depth === depth)
1666
+ return curComment;
1667
+ while (curComment.depth < depth) {
1668
+ curComment = await publishRandomReply({ parentComment: curComment, pkc: pkcWithDefault });
1669
+ if (curComment.depth === depth)
1670
+ return curComment;
1671
+ }
1672
+ throw Error("Failed to find or publish comment with depth");
1673
+ }
1674
+ export async function findOrPublishCommentWithDepthWithHttpServerShortcut({ depth, community, pkc }) {
1675
+ const pkcWithDefault = pkc || community._pkc;
1676
+ const queryUrl = `http://localhost:14953/find-comment-with-depth?subAddress=${community.address}&commentDepth=${depth}`;
1677
+ const commentWithSameDepthOrClosest = await (await fetch(queryUrl)).json();
1678
+ if (commentWithSameDepthOrClosest.depth === depth) {
1679
+ return pkcWithDefault.createComment(commentWithSameDepthOrClosest);
1680
+ }
1681
+ let curComment = await publishRandomReply({ parentComment: commentWithSameDepthOrClosest, pkc: pkcWithDefault });
1682
+ while (curComment.depth < depth) {
1683
+ curComment = await publishRandomReply({ parentComment: curComment, pkc: pkcWithDefault });
1684
+ if (curComment.depth === depth)
1685
+ return curComment;
1686
+ }
1687
+ throw Error("Failed to find or publish comment with depth");
1688
+ }
1689
+ export async function publishCommentWithDepth({ depth, community }) {
1690
+ if (depth === 0) {
1691
+ return publishRandomPost({ communityAddress: community.address, pkc: community._pkc });
1692
+ }
1693
+ else {
1694
+ const parentComment = await publishCommentWithDepth({ depth: depth - 1, community });
1695
+ let curComment = await publishRandomReply({
1696
+ parentComment: parentComment,
1697
+ pkc: community._pkc
1698
+ });
1699
+ if (curComment.depth === depth)
1700
+ return curComment;
1701
+ while (curComment.depth < depth) {
1702
+ curComment = await publishRandomReply({ parentComment: curComment, pkc: community._pkc });
1703
+ if (curComment.depth === depth)
1704
+ return curComment;
1705
+ }
1706
+ throw Error("Failed to publish comment with depth");
1707
+ }
1708
+ }
1709
+ export async function getCommentWithCommentUpdateProps({ cid, pkc }) {
1710
+ const comment = await pkc.createComment({ cid });
1711
+ await comment.update();
1712
+ await resolveWhenConditionIsTrue({ toUpdate: comment, predicate: async () => Boolean(comment.updatedAt) });
1713
+ return comment;
1714
+ }
1715
+ export async function publishCommentToModQueue({ community, pkc, parentComment, commentProps }) {
1716
+ if (!commentProps?.challengeRequest?.challengeAnswers)
1717
+ throw Error("You need to challengeRequest.challengeAnswers to pass the challenge and get to pending approval");
1718
+ const remotePKC = pkc || (await mockGatewayPKC({ forceMockPubsub: true, remotePKC: true })); // this pkc is not connected to kubo rpc client of community
1719
+ const pendingComment = parentComment
1720
+ ? await generateMockComment(parentComment, remotePKC, false, {
1721
+ content: "Pending reply" + " " + Math.random(),
1722
+ ...commentProps
1723
+ })
1724
+ : await generateMockPost({
1725
+ communityAddress: community.address,
1726
+ pkc: remotePKC,
1727
+ postProps: {
1728
+ content: "Pending post" + " " + Math.random(),
1729
+ ...commentProps
1730
+ }
1731
+ });
1732
+ pendingComment.once("challenge", async () => {
1733
+ throw Error("Should not received challenge with challengeRequest props");
1734
+ });
1735
+ const challengeVerificationPromise = new Promise((resolve) => pendingComment.once("challengeverification", resolve));
1736
+ await publishWithExpectedResult({ publication: pendingComment, expectedChallengeSuccess: true }); // a pending approval is technically challengeSucess = true
1737
+ if (!pendingComment.pendingApproval)
1738
+ throw Error("The comment did not go to pending approval");
1739
+ return { comment: pendingComment, challengeVerification: await challengeVerificationPromise };
1740
+ }
1741
+ export async function publishToModQueueWithDepth({ community, depth, pkc, modCommentProps, commentProps }) {
1742
+ if (!commentProps?.challengeRequest?.challengeAnswers)
1743
+ throw Error("You need to challengeRequest.challengeAnswers to pass the challenge and get to pending approval");
1744
+ if (depth === 0)
1745
+ return publishCommentToModQueue({ community, pkc, commentProps });
1746
+ else {
1747
+ // we assume mod can publish comments without mod queue
1748
+ const remotePKC = pkc || community._pkc;
1749
+ const commentsPublishedByMod = [
1750
+ await publishRandomPost({ communityAddress: community.address, pkc: remotePKC, postProps: modCommentProps })
1751
+ ];
1752
+ for (let i = 1; i < depth; i++) {
1753
+ commentsPublishedByMod.push(await publishRandomReply({
1754
+ parentComment: commentsPublishedByMod[i - 1],
1755
+ pkc: remotePKC,
1756
+ commentProps: modCommentProps
1757
+ }));
1758
+ }
1759
+ // we have created a tree of comments and now we can publish the pending comment underneath it
1760
+ const pendingReply = await generateMockComment(commentsPublishedByMod[commentsPublishedByMod.length - 1], remotePKC, false, {
1761
+ content: "Pending reply" + " " + Math.random(),
1762
+ ...commentProps
1763
+ });
1764
+ pendingReply.once("challenge", () => {
1765
+ throw Error("Should not received challenge with challengeRequest props");
1766
+ });
1767
+ const challengeVerificationPromise = new Promise((resolve) => pendingReply.once("challengeverification", resolve));
1768
+ await publishWithExpectedResult({ publication: pendingReply, expectedChallengeSuccess: true }); // a pending approval is technically challengeSucess = true
1769
+ if (!pendingReply.pendingApproval)
1770
+ throw Error("The reply did not go to pending approval");
1771
+ return { comment: pendingReply, challengeVerification: await challengeVerificationPromise };
1772
+ }
1773
+ }
1774
+ // This may not be needed
1775
+ export async function forceCommunityToGenerateAllPostsPages(community, commentProps) {
1776
+ // max comment size is 40kb = 40000
1777
+ const rawCommunityRecord = community.raw.communityIpfs;
1778
+ if (!rawCommunityRecord)
1779
+ throw Error("Community should be updating before forcing to generate all pages");
1780
+ community.setMaxListeners(100);
1781
+ if (Object.keys(community.posts.pageCids).length > 0)
1782
+ return;
1783
+ const curRecordSize = await calculateStringSizeSameAsIpfsAddCidV0(JSON.stringify(rawCommunityRecord));
1784
+ const maxCommentSize = 30000;
1785
+ const defaultContent = "x".repeat(FORCE_COMMUNITY_MIN_POST_CONTENT_BYTES); // 30kb
1786
+ const paddedContent = typeof commentProps?.content === "string"
1787
+ ? commentProps.content.padEnd(FORCE_COMMUNITY_MIN_POST_CONTENT_BYTES, "x")
1788
+ : defaultContent;
1789
+ const estimatedCommentSize = Math.max(maxCommentSize, Buffer.byteLength(paddedContent, "utf8"));
1790
+ const adjustedCommentProps = { ...commentProps, content: paddedContent };
1791
+ const numOfCommentsToPublish = Math.round((1024 * 1024 - curRecordSize) / estimatedCommentSize) + 1;
1792
+ let lastPublishedPost = await publishRandomPost({
1793
+ communityAddress: community.address,
1794
+ pkc: community._pkc,
1795
+ postProps: adjustedCommentProps
1796
+ });
1797
+ await Promise.all(new Array(numOfCommentsToPublish).fill(null).map(async () => {
1798
+ const post = await publishRandomPost({
1799
+ communityAddress: community.address,
1800
+ pkc: community._pkc,
1801
+ postProps: adjustedCommentProps
1802
+ });
1803
+ lastPublishedPost = post;
1804
+ }));
1805
+ await waitTillPostInCommunityPages(lastPublishedPost, community._pkc);
1806
+ const newCommunity = await community._pkc.createCommunity({ address: community.address });
1807
+ await newCommunity.update();
1808
+ await resolveWhenConditionIsTrue({ toUpdate: newCommunity, predicate: async () => typeof newCommunity.updatedAt === "number" });
1809
+ if (Object.keys(newCommunity.posts.pageCids).length === 0)
1810
+ throw Error("Failed to force the community to load all pages");
1811
+ await newCommunity.stop();
1812
+ }
1813
+ export function mockReplyToUseParentPagesForUpdates(reply) {
1814
+ const updatingComment = findUpdatingComment(reply._pkc, { cid: reply.cid });
1815
+ if (!updatingComment)
1816
+ throw Error("Reply should be updating before starting to mock");
1817
+ if (updatingComment.depth === 0)
1818
+ throw Error("Should not call this function on a post");
1819
+ delete updatingComment.raw.commentUpdate;
1820
+ delete updatingComment.updatedAt;
1821
+ mockCommentToNotUsePagesForUpdates(reply);
1822
+ const originalFunc = updatingComment._clientsManager.handleUpdateEventFromPostToFetchReplyCommentUpdate.bind(updatingComment._clientsManager);
1823
+ updatingComment._clientsManager.handleUpdateEventFromPostToFetchReplyCommentUpdate = (postInstance) => {
1824
+ // this should stop pkc-js from assuming the post replies is a single preloaded page
1825
+ const updatingCommunityInstance = findUpdatingCommunity(reply._pkc, { address: postInstance.communityAddress });
1826
+ const updatingParentInstance = findUpdatingComment(reply._pkc, { cid: reply.parentCid });
1827
+ if (postInstance.replies.pages)
1828
+ Object.keys(postInstance.replies.pages).forEach((preloadedPageKey) => {
1829
+ if (postInstance.replies.pages[preloadedPageKey]?.comments)
1830
+ postInstance.replies.pages[preloadedPageKey].comments = [];
1831
+ });
1832
+ if (updatingCommunityInstance?.posts.pages)
1833
+ Object.keys(updatingCommunityInstance.posts.pages).forEach((preloadedPageKey) => {
1834
+ if (updatingCommunityInstance.posts.pages[preloadedPageKey]?.comments)
1835
+ updatingCommunityInstance.posts.pages[preloadedPageKey].comments = [];
1836
+ });
1837
+ if (updatingParentInstance?.replies?.pages)
1838
+ Object.keys(updatingParentInstance.replies.pages).forEach((preloadedPageKey) => {
1839
+ if (updatingParentInstance.replies.pages[preloadedPageKey]?.comments)
1840
+ updatingParentInstance.replies.pages[preloadedPageKey].comments = [];
1841
+ });
1842
+ return originalFunc(postInstance);
1843
+ };
1844
+ }
1845
+ export function mockUpdatingCommentResolvingAuthor(comment, mockFunction) {
1846
+ const updatingComment = findUpdatingComment(comment._pkc, { cid: comment.cid });
1847
+ if (!updatingComment)
1848
+ throw Error("Comment should be updating before starting to mock");
1849
+ if (comment._pkc._pkcRpcClient)
1850
+ throw Error("Can't mock cache with pkc rpc clients");
1851
+ updatingComment._clientsManager.resolveAuthorNameIfNeeded = mockFunction;
1852
+ }
1853
+ export async function getRandomPostCidFromSub(communityAddress, pkc) {
1854
+ const community = await pkc.createCommunity({ address: communityAddress });
1855
+ await community.update();
1856
+ await resolveWhenConditionIsTrue({ toUpdate: community, predicate: async () => typeof community.updatedAt === "number" });
1857
+ const lastPostCid = community.lastPostCid;
1858
+ await community.stop();
1859
+ if (!lastPostCid)
1860
+ throw Error("Community should have a last post cid");
1861
+ return lastPostCid;
1862
+ }
1863
+ const skipFunction = (_) => { };
1864
+ skipFunction.skip = () => { };
1865
+ //@ts-expect-error
1866
+ export const describeSkipIfRpc = globalThis["describe"]?.runIf(!isRpcFlagOn());
1867
+ //@ts-expect-error
1868
+ export const describeIfRpc = globalThis["describe"]?.runIf(isRpcFlagOn());
1869
+ //@ts-expect-error
1870
+ export const itSkipIfRpc = globalThis["it"]?.runIf(!isRpcFlagOn());
1871
+ //@ts-expect-error
1872
+ export const itIfRpc = globalThis["it"]?.runIf(isRpcFlagOn());
1873
+ export function mockNameResolvers({ pkc, resolveFunction }) {
1874
+ if (pkc._pkcRpcClient)
1875
+ throw Error("Can't mock name resolvers with pkc rpc clients");
1876
+ pkc.nameResolvers = [createMockNameResolver({ resolveFunction: (opts) => resolveFunction(opts) })];
1877
+ }
1878
+ export function processAllCommentsRecursively(comments, processor) {
1879
+ if (!comments || comments.length === 0)
1880
+ return;
1881
+ comments.forEach((comment) => processor(comment));
1882
+ for (const comment of comments)
1883
+ if (comment.replies?.pages?.best?.comments)
1884
+ processAllCommentsRecursively(comment.replies.pages.best.comments, processor);
1885
+ }
1886
+ //# sourceMappingURL=test-util.js.map