@bitsocial/bitsocial-react-hooks 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +1365 -0
  3. package/dist/hooks/accounts/accounts.d.ts +64 -0
  4. package/dist/hooks/accounts/accounts.d.ts.map +1 -0
  5. package/dist/hooks/accounts/accounts.js +706 -0
  6. package/dist/hooks/accounts/accounts.js.map +1 -0
  7. package/dist/hooks/accounts/index.d.ts +2 -0
  8. package/dist/hooks/accounts/index.d.ts.map +1 -0
  9. package/dist/hooks/accounts/index.js +2 -0
  10. package/dist/hooks/accounts/index.js.map +1 -0
  11. package/dist/hooks/accounts/utils.d.ts +6 -0
  12. package/dist/hooks/accounts/utils.d.ts.map +1 -0
  13. package/dist/hooks/accounts/utils.js +226 -0
  14. package/dist/hooks/accounts/utils.js.map +1 -0
  15. package/dist/hooks/actions/actions.d.ts +19 -0
  16. package/dist/hooks/actions/actions.d.ts.map +1 -0
  17. package/dist/hooks/actions/actions.js +552 -0
  18. package/dist/hooks/actions/actions.js.map +1 -0
  19. package/dist/hooks/actions/index.d.ts +2 -0
  20. package/dist/hooks/actions/index.d.ts.map +1 -0
  21. package/dist/hooks/actions/index.js +2 -0
  22. package/dist/hooks/actions/index.js.map +1 -0
  23. package/dist/hooks/authors/author-avatars.d.ts +28 -0
  24. package/dist/hooks/authors/author-avatars.d.ts.map +1 -0
  25. package/dist/hooks/authors/author-avatars.js +191 -0
  26. package/dist/hooks/authors/author-avatars.js.map +1 -0
  27. package/dist/hooks/authors/authors.d.ts +37 -0
  28. package/dist/hooks/authors/authors.d.ts.map +1 -0
  29. package/dist/hooks/authors/authors.js +509 -0
  30. package/dist/hooks/authors/authors.js.map +1 -0
  31. package/dist/hooks/authors/index.d.ts +2 -0
  32. package/dist/hooks/authors/index.d.ts.map +1 -0
  33. package/dist/hooks/authors/index.js +2 -0
  34. package/dist/hooks/authors/index.js.map +1 -0
  35. package/dist/hooks/authors/utils.d.ts +4 -0
  36. package/dist/hooks/authors/utils.d.ts.map +1 -0
  37. package/dist/hooks/authors/utils.js +21 -0
  38. package/dist/hooks/authors/utils.js.map +1 -0
  39. package/dist/hooks/comments.d.ts +17 -0
  40. package/dist/hooks/comments.d.ts.map +1 -0
  41. package/dist/hooks/comments.js +351 -0
  42. package/dist/hooks/comments.js.map +1 -0
  43. package/dist/hooks/communities.d.ts +31 -0
  44. package/dist/hooks/communities.d.ts.map +1 -0
  45. package/dist/hooks/communities.js +389 -0
  46. package/dist/hooks/communities.js.map +1 -0
  47. package/dist/hooks/feeds/feeds.d.ts +18 -0
  48. package/dist/hooks/feeds/feeds.d.ts.map +1 -0
  49. package/dist/hooks/feeds/feeds.js +315 -0
  50. package/dist/hooks/feeds/feeds.js.map +1 -0
  51. package/dist/hooks/feeds/index.d.ts +2 -0
  52. package/dist/hooks/feeds/index.d.ts.map +1 -0
  53. package/dist/hooks/feeds/index.js +2 -0
  54. package/dist/hooks/feeds/index.js.map +1 -0
  55. package/dist/hooks/pkc-rpc.d.ts +7 -0
  56. package/dist/hooks/pkc-rpc.d.ts.map +1 -0
  57. package/dist/hooks/pkc-rpc.js +88 -0
  58. package/dist/hooks/pkc-rpc.js.map +1 -0
  59. package/dist/hooks/replies.d.ts +5 -0
  60. package/dist/hooks/replies.d.ts.map +1 -0
  61. package/dist/hooks/replies.js +155 -0
  62. package/dist/hooks/replies.js.map +1 -0
  63. package/dist/hooks/states.d.ts +15 -0
  64. package/dist/hooks/states.d.ts.map +1 -0
  65. package/dist/hooks/states.js +213 -0
  66. package/dist/hooks/states.js.map +1 -0
  67. package/dist/hooks/utils/use-interval.d.ts +3 -0
  68. package/dist/hooks/utils/use-interval.d.ts.map +1 -0
  69. package/dist/hooks/utils/use-interval.js +36 -0
  70. package/dist/hooks/utils/use-interval.js.map +1 -0
  71. package/dist/hooks/utils/use-previous.d.ts +1 -0
  72. package/dist/hooks/utils/use-previous.js +10 -0
  73. package/dist/index.d.ts +82 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +128 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/lib/chain/chain.d.ts +36 -0
  78. package/dist/lib/chain/chain.d.ts.map +1 -0
  79. package/dist/lib/chain/chain.js +195 -0
  80. package/dist/lib/chain/chain.js.map +1 -0
  81. package/dist/lib/chain/index.d.ts +4 -0
  82. package/dist/lib/chain/index.d.ts.map +1 -0
  83. package/dist/lib/chain/index.js +4 -0
  84. package/dist/lib/chain/index.js.map +1 -0
  85. package/dist/lib/community-address.d.ts +6 -0
  86. package/dist/lib/community-address.d.ts.map +1 -0
  87. package/dist/lib/community-address.js +26 -0
  88. package/dist/lib/community-address.js.map +1 -0
  89. package/dist/lib/community-ref.d.ts +23 -0
  90. package/dist/lib/community-ref.d.ts.map +1 -0
  91. package/dist/lib/community-ref.js +113 -0
  92. package/dist/lib/community-ref.js.map +1 -0
  93. package/dist/lib/debug-utils.d.ts +9 -0
  94. package/dist/lib/debug-utils.d.ts.map +1 -0
  95. package/dist/lib/debug-utils.js +21 -0
  96. package/dist/lib/debug-utils.js.map +1 -0
  97. package/dist/lib/feed-sort-type.d.ts +2 -0
  98. package/dist/lib/feed-sort-type.d.ts.map +1 -0
  99. package/dist/lib/feed-sort-type.js +22 -0
  100. package/dist/lib/feed-sort-type.js.map +1 -0
  101. package/dist/lib/localforage-lru/index.d.ts +3 -0
  102. package/dist/lib/localforage-lru/index.d.ts.map +1 -0
  103. package/dist/lib/localforage-lru/index.js +46 -0
  104. package/dist/lib/localforage-lru/index.js.map +1 -0
  105. package/dist/lib/localforage-lru/localforage-lru.d.ts +6 -0
  106. package/dist/lib/localforage-lru/localforage-lru.d.ts.map +1 -0
  107. package/dist/lib/localforage-lru/localforage-lru.js +182 -0
  108. package/dist/lib/localforage-lru/localforage-lru.js.map +1 -0
  109. package/dist/lib/pkc-compat.d.ts +25 -0
  110. package/dist/lib/pkc-compat.d.ts.map +1 -0
  111. package/dist/lib/pkc-compat.js +131 -0
  112. package/dist/lib/pkc-compat.js.map +1 -0
  113. package/dist/lib/pkc-js/fixtures/markdown-example.d.ts +3 -0
  114. package/dist/lib/pkc-js/fixtures/markdown-example.d.ts.map +1 -0
  115. package/dist/lib/pkc-js/fixtures/markdown-example.js +280 -0
  116. package/dist/lib/pkc-js/fixtures/markdown-example.js.map +1 -0
  117. package/dist/lib/pkc-js/index.d.ts +11 -0
  118. package/dist/lib/pkc-js/index.d.ts.map +1 -0
  119. package/dist/lib/pkc-js/index.js +85 -0
  120. package/dist/lib/pkc-js/index.js.map +1 -0
  121. package/dist/lib/pkc-js/pkc-js-mock-content.d.ts +3 -0
  122. package/dist/lib/pkc-js/pkc-js-mock-content.d.ts.map +1 -0
  123. package/dist/lib/pkc-js/pkc-js-mock-content.js +1235 -0
  124. package/dist/lib/pkc-js/pkc-js-mock-content.js.map +1 -0
  125. package/dist/lib/pkc-js/pkc-js-mock.d.ts +137 -0
  126. package/dist/lib/pkc-js/pkc-js-mock.d.ts.map +1 -0
  127. package/dist/lib/pkc-js/pkc-js-mock.js +644 -0
  128. package/dist/lib/pkc-js/pkc-js-mock.js.map +1 -0
  129. package/dist/lib/polyfill.d.ts +3 -0
  130. package/dist/lib/polyfill.d.ts.map +1 -0
  131. package/dist/lib/polyfill.js +14 -0
  132. package/dist/lib/polyfill.js.map +1 -0
  133. package/dist/lib/protocol-compat.d.ts +14 -0
  134. package/dist/lib/protocol-compat.d.ts.map +1 -0
  135. package/dist/lib/protocol-compat.js +67 -0
  136. package/dist/lib/protocol-compat.js.map +1 -0
  137. package/dist/lib/test-utils.d.ts +29 -0
  138. package/dist/lib/test-utils.d.ts.map +1 -0
  139. package/dist/lib/test-utils.js +184 -0
  140. package/dist/lib/test-utils.js.map +1 -0
  141. package/dist/lib/utils/comment-moderation.d.ts +4 -0
  142. package/dist/lib/utils/comment-moderation.d.ts.map +1 -0
  143. package/dist/lib/utils/comment-moderation.js +56 -0
  144. package/dist/lib/utils/comment-moderation.js.map +1 -0
  145. package/dist/lib/utils/index.d.ts +4 -0
  146. package/dist/lib/utils/index.d.ts.map +1 -0
  147. package/dist/lib/utils/index.js +4 -0
  148. package/dist/lib/utils/index.js.map +1 -0
  149. package/dist/lib/utils/utils.d.ts +23 -0
  150. package/dist/lib/utils/utils.d.ts.map +1 -0
  151. package/dist/lib/utils/utils.js +375 -0
  152. package/dist/lib/utils/utils.js.map +1 -0
  153. package/dist/lib/validator.d.ts +30 -0
  154. package/dist/lib/validator.d.ts.map +1 -0
  155. package/dist/lib/validator.js +307 -0
  156. package/dist/lib/validator.js.map +1 -0
  157. package/dist/stores/accounts/account-generator.d.ts +51 -0
  158. package/dist/stores/accounts/account-generator.d.ts.map +1 -0
  159. package/dist/stores/accounts/account-generator.js +160 -0
  160. package/dist/stores/accounts/account-generator.js.map +1 -0
  161. package/dist/stores/accounts/accounts-actions-internal.d.ts +8 -0
  162. package/dist/stores/accounts/accounts-actions-internal.d.ts.map +1 -0
  163. package/dist/stores/accounts/accounts-actions-internal.js +403 -0
  164. package/dist/stores/accounts/accounts-actions-internal.js.map +1 -0
  165. package/dist/stores/accounts/accounts-actions.d.ts +46 -0
  166. package/dist/stores/accounts/accounts-actions.d.ts.map +1 -0
  167. package/dist/stores/accounts/accounts-actions.js +1341 -0
  168. package/dist/stores/accounts/accounts-actions.js.map +1 -0
  169. package/dist/stores/accounts/accounts-database.d.ts +34 -0
  170. package/dist/stores/accounts/accounts-database.d.ts.map +1 -0
  171. package/dist/stores/accounts/accounts-database.js +685 -0
  172. package/dist/stores/accounts/accounts-database.js.map +1 -0
  173. package/dist/stores/accounts/accounts-store.d.ts +32 -0
  174. package/dist/stores/accounts/accounts-store.d.ts.map +1 -0
  175. package/dist/stores/accounts/accounts-store.js +169 -0
  176. package/dist/stores/accounts/accounts-store.js.map +1 -0
  177. package/dist/stores/accounts/index.d.ts +4 -0
  178. package/dist/stores/accounts/index.d.ts.map +1 -0
  179. package/dist/stores/accounts/index.js +4 -0
  180. package/dist/stores/accounts/index.js.map +1 -0
  181. package/dist/stores/accounts/utils.d.ts +49 -0
  182. package/dist/stores/accounts/utils.d.ts.map +1 -0
  183. package/dist/stores/accounts/utils.js +419 -0
  184. package/dist/stores/accounts/utils.js.map +1 -0
  185. package/dist/stores/authors-comments/authors-comments-store.d.ts +37 -0
  186. package/dist/stores/authors-comments/authors-comments-store.d.ts.map +1 -0
  187. package/dist/stores/authors-comments/authors-comments-store.js +338 -0
  188. package/dist/stores/authors-comments/authors-comments-store.js.map +1 -0
  189. package/dist/stores/authors-comments/index.d.ts +4 -0
  190. package/dist/stores/authors-comments/index.d.ts.map +1 -0
  191. package/dist/stores/authors-comments/index.js +4 -0
  192. package/dist/stores/authors-comments/index.js.map +1 -0
  193. package/dist/stores/authors-comments/utils.d.ts +14 -0
  194. package/dist/stores/authors-comments/utils.d.ts.map +1 -0
  195. package/dist/stores/authors-comments/utils.js +81 -0
  196. package/dist/stores/authors-comments/utils.js.map +1 -0
  197. package/dist/stores/comments/comments-store.d.ts +19 -0
  198. package/dist/stores/comments/comments-store.d.ts.map +1 -0
  199. package/dist/stores/comments/comments-store.js +385 -0
  200. package/dist/stores/comments/comments-store.js.map +1 -0
  201. package/dist/stores/comments/index.d.ts +4 -0
  202. package/dist/stores/comments/index.d.ts.map +1 -0
  203. package/dist/stores/comments/index.js +4 -0
  204. package/dist/stores/comments/index.js.map +1 -0
  205. package/dist/stores/communities/communities-store.d.ts +17 -0
  206. package/dist/stores/communities/communities-store.d.ts.map +1 -0
  207. package/dist/stores/communities/communities-store.js +304 -0
  208. package/dist/stores/communities/communities-store.js.map +1 -0
  209. package/dist/stores/communities/index.d.ts +4 -0
  210. package/dist/stores/communities/index.d.ts.map +1 -0
  211. package/dist/stores/communities/index.js +4 -0
  212. package/dist/stores/communities/index.js.map +1 -0
  213. package/dist/stores/communities-pages/communities-pages-store.d.ts +23 -0
  214. package/dist/stores/communities-pages/communities-pages-store.d.ts.map +1 -0
  215. package/dist/stores/communities-pages/communities-pages-store.js +316 -0
  216. package/dist/stores/communities-pages/communities-pages-store.js.map +1 -0
  217. package/dist/stores/communities-pages/index.d.ts +4 -0
  218. package/dist/stores/communities-pages/index.d.ts.map +1 -0
  219. package/dist/stores/communities-pages/index.js +4 -0
  220. package/dist/stores/communities-pages/index.js.map +1 -0
  221. package/dist/stores/feeds/feed-sorter.d.ts +5 -0
  222. package/dist/stores/feeds/feed-sorter.d.ts.map +1 -0
  223. package/dist/stores/feeds/feed-sorter.js +135 -0
  224. package/dist/stores/feeds/feed-sorter.js.map +1 -0
  225. package/dist/stores/feeds/feeds-store.d.ts +25 -0
  226. package/dist/stores/feeds/feeds-store.d.ts.map +1 -0
  227. package/dist/stores/feeds/feeds-store.js +459 -0
  228. package/dist/stores/feeds/feeds-store.js.map +1 -0
  229. package/dist/stores/feeds/index.d.ts +4 -0
  230. package/dist/stores/feeds/index.d.ts.map +1 -0
  231. package/dist/stores/feeds/index.js +4 -0
  232. package/dist/stores/feeds/index.js.map +1 -0
  233. package/dist/stores/feeds/utils.d.ts +43 -0
  234. package/dist/stores/feeds/utils.d.ts.map +1 -0
  235. package/dist/stores/feeds/utils.js +736 -0
  236. package/dist/stores/feeds/utils.js.map +1 -0
  237. package/dist/stores/replies/index.d.ts +4 -0
  238. package/dist/stores/replies/index.d.ts.map +1 -0
  239. package/dist/stores/replies/index.js +4 -0
  240. package/dist/stores/replies/index.js.map +1 -0
  241. package/dist/stores/replies/replies-comments-store.d.ts +8 -0
  242. package/dist/stores/replies/replies-comments-store.d.ts.map +1 -0
  243. package/dist/stores/replies/replies-comments-store.js +23 -0
  244. package/dist/stores/replies/replies-comments-store.js.map +1 -0
  245. package/dist/stores/replies/replies-store.d.ts +29 -0
  246. package/dist/stores/replies/replies-store.d.ts.map +1 -0
  247. package/dist/stores/replies/replies-store.js +413 -0
  248. package/dist/stores/replies/replies-store.js.map +1 -0
  249. package/dist/stores/replies/utils.d.ts +25 -0
  250. package/dist/stores/replies/utils.d.ts.map +1 -0
  251. package/dist/stores/replies/utils.js +549 -0
  252. package/dist/stores/replies/utils.js.map +1 -0
  253. package/dist/stores/replies-pages/index.d.ts +4 -0
  254. package/dist/stores/replies-pages/index.d.ts.map +1 -0
  255. package/dist/stores/replies-pages/index.js +4 -0
  256. package/dist/stores/replies-pages/index.js.map +1 -0
  257. package/dist/stores/replies-pages/replies-pages-store.d.ts +20 -0
  258. package/dist/stores/replies-pages/replies-pages-store.d.ts.map +1 -0
  259. package/dist/stores/replies-pages/replies-pages-store.js +270 -0
  260. package/dist/stores/replies-pages/replies-pages-store.js.map +1 -0
  261. package/dist/stores/replies-pages/utils.d.ts +3 -0
  262. package/dist/stores/replies-pages/utils.d.ts.map +1 -0
  263. package/dist/stores/replies-pages/utils.js +43 -0
  264. package/dist/stores/replies-pages/utils.js.map +1 -0
  265. package/dist/types.d.ts +638 -0
  266. package/dist/types.d.ts.map +1 -0
  267. package/dist/types.js +3 -0
  268. package/dist/types.js.map +1 -0
  269. package/package.json +160 -0
@@ -0,0 +1,1341 @@
1
+ // public accounts actions that are called by the user
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ import accountsStore, { listeners } from "./accounts-store.js";
12
+ import communitiesStore from "../communities/index.js";
13
+ import accountsDatabase from "./accounts-database.js";
14
+ import accountGenerator from "./account-generator.js";
15
+ import Logger from "@pkcprotocol/pkc-logger";
16
+ import validator from "../../lib/validator.js";
17
+ import chain from "../../lib/chain/index.js";
18
+ import assert from "assert";
19
+ const log = Logger("bitsocial-react-hooks:accounts:stores");
20
+ import * as accountsActionsInternal from "./accounts-actions-internal.js";
21
+ import { backfillPublicationCommunityAddress, createPkcCommunityEdit, getPkcCommunityAddresses, normalizeCommunityEditOptionsForPkc, normalizePublicationOptionsForStore, normalizePublicationOptionsForPkc, } from "../../lib/pkc-compat.js";
22
+ import { getAccountCommentsIndex, getAccountCommunities, getCommentCidsToAccountsComments, getAccountEditPropertySummary, fetchCommentLinkDimensions, getAccountCommentDepth, addShortAddressesToAccountComment, sanitizeAccountCommentForState, sanitizeStoredAccountComment, } from "./utils.js";
23
+ import isEqual from "lodash.isequal";
24
+ import { v4 as uuid } from "uuid";
25
+ import utils from "../../lib/utils/index.js";
26
+ // Active publish-session tracking for pending comments (Task 3)
27
+ const activePublishSessions = new Map();
28
+ const abandonedPublishSessionIds = new Set();
29
+ const getClientsSnapshotForState = (clients) => {
30
+ if (!clients || typeof clients !== "object") {
31
+ return undefined;
32
+ }
33
+ if (typeof clients.on === "function" || "state" in clients) {
34
+ return { state: clients.state };
35
+ }
36
+ const snapshot = {};
37
+ for (const key in clients) {
38
+ const childSnapshot = getClientsSnapshotForState(clients[key]);
39
+ if (childSnapshot !== undefined) {
40
+ snapshot[key] = childSnapshot;
41
+ }
42
+ }
43
+ return Object.keys(snapshot).length > 0 ? snapshot : undefined;
44
+ };
45
+ const syncCommentClientsSnapshot = (publishSessionId, accountId, publication) => {
46
+ const session = getPublishSession(publishSessionId);
47
+ if ((session === null || session === void 0 ? void 0 : session.currentIndex) === undefined) {
48
+ return;
49
+ }
50
+ const snapshot = getClientsSnapshotForState(publication === null || publication === void 0 ? void 0 : publication.clients);
51
+ accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, accountId, session.currentIndex, (ac, acc) => {
52
+ const updatedAccountComment = Object.assign({}, acc);
53
+ if (snapshot === undefined) {
54
+ delete updatedAccountComment.clients;
55
+ }
56
+ else {
57
+ updatedAccountComment.clients = snapshot;
58
+ }
59
+ ac[session.currentIndex] = updatedAccountComment;
60
+ }));
61
+ };
62
+ const accountOwnsCommunityLocally = (account, communityAddress) => {
63
+ var _a, _b, _c, _d, _e, _f, _g;
64
+ const localCommunityAddresses = getPkcCommunityAddresses(account.pkc);
65
+ if (localCommunityAddresses.includes(communityAddress)) {
66
+ return true;
67
+ }
68
+ const storedCommunity = communitiesStore.getState().communities[communityAddress];
69
+ if (((_b = (_a = storedCommunity === null || storedCommunity === void 0 ? void 0 : storedCommunity.roles) === null || _a === void 0 ? void 0 : _a[account.author.address]) === null || _b === void 0 ? void 0 : _b.role) === "owner") {
70
+ return true;
71
+ }
72
+ if (((_c = storedCommunity === null || storedCommunity === void 0 ? void 0 : storedCommunity.signer) === null || _c === void 0 ? void 0 : _c.address) &&
73
+ storedCommunity.signer.address === ((_d = account.signer) === null || _d === void 0 ? void 0 : _d.address)) {
74
+ return true;
75
+ }
76
+ return ((_g = (_f = (_e = account.communities) === null || _e === void 0 ? void 0 : _e[communityAddress]) === null || _f === void 0 ? void 0 : _f.role) === null || _g === void 0 ? void 0 : _g.role) === "owner";
77
+ };
78
+ const createPublishSession = (accountId, index) => {
79
+ const sessionId = uuid();
80
+ activePublishSessions.set(sessionId, {
81
+ accountId,
82
+ originalIndex: index,
83
+ currentIndex: index,
84
+ });
85
+ return sessionId;
86
+ };
87
+ const updatePublishSessionComment = (sessionId, comment) => {
88
+ const session = activePublishSessions.get(sessionId);
89
+ if (!session) {
90
+ return;
91
+ }
92
+ activePublishSessions.set(sessionId, Object.assign(Object.assign({}, session), { comment }));
93
+ };
94
+ const abandonAndStopPublishSession = (accountId, index) => {
95
+ var _a, _b;
96
+ const session = getPublishSessionByCurrentIndex(accountId, index);
97
+ if (!session)
98
+ return;
99
+ abandonedPublishSessionIds.add(session.sessionId);
100
+ try {
101
+ const stop = (_b = (_a = session.comment) === null || _a === void 0 ? void 0 : _a.stop) === null || _b === void 0 ? void 0 : _b.bind(session.comment);
102
+ if (typeof stop === "function")
103
+ stop();
104
+ }
105
+ catch (e) {
106
+ log.error("comment.stop() error during abandon", { accountId, index, error: e });
107
+ }
108
+ activePublishSessions.delete(session.sessionId);
109
+ };
110
+ const isPublishSessionAbandoned = (sessionId) => abandonedPublishSessionIds.has(sessionId);
111
+ const getPublishSession = (sessionId) => activePublishSessions.get(sessionId);
112
+ /** Returns state update or {} when accountComment not yet in state (no-op). Exported for coverage. */
113
+ export const maybeUpdateAccountComment = (accountsComments, accountId, index, updater) => {
114
+ const accountComments = [...(accountsComments[accountId] || [])];
115
+ const accountComment = accountComments[index];
116
+ if (!accountComment)
117
+ return {};
118
+ updater(accountComments, accountComment);
119
+ return { accountsComments: Object.assign(Object.assign({}, accountsComments), { [accountId]: accountComments }) };
120
+ };
121
+ const getPublishSessionByCurrentIndex = (accountId, index) => {
122
+ for (const [key, session] of activePublishSessions) {
123
+ if (session.accountId === accountId && session.currentIndex === index) {
124
+ return Object.assign({ sessionId: key }, session);
125
+ }
126
+ }
127
+ return undefined;
128
+ };
129
+ const shiftPublishSessionIndicesAfterDelete = (accountId, deletedIndex) => {
130
+ for (const session of activePublishSessions.values()) {
131
+ if (session.accountId === accountId && session.currentIndex > deletedIndex) {
132
+ session.currentIndex -= 1;
133
+ }
134
+ }
135
+ };
136
+ const cleanupPublishSessionOnTerminal = (sessionId) => {
137
+ activePublishSessions.delete(sessionId);
138
+ abandonedPublishSessionIds.delete(sessionId);
139
+ };
140
+ export const doesStoredAccountEditMatch = (storedAccountEdit, targetStoredAccountEdit) => (storedAccountEdit === null || storedAccountEdit === void 0 ? void 0 : storedAccountEdit.clientId) && (targetStoredAccountEdit === null || targetStoredAccountEdit === void 0 ? void 0 : targetStoredAccountEdit.clientId)
141
+ ? storedAccountEdit.clientId === targetStoredAccountEdit.clientId
142
+ : isEqual(storedAccountEdit, targetStoredAccountEdit);
143
+ export const sanitizeStoredAccountEdit = (storedAccountEdit) => {
144
+ const sanitizedStoredAccountEdit = Object.assign({}, storedAccountEdit);
145
+ delete sanitizedStoredAccountEdit.signer;
146
+ delete sanitizedStoredAccountEdit.author;
147
+ return sanitizedStoredAccountEdit;
148
+ };
149
+ const accountEditNonPropertyNames = new Set([
150
+ "author",
151
+ "signer",
152
+ "clientId",
153
+ "commentCid",
154
+ "communityAddress",
155
+ "communityAddress",
156
+ "communityEdit",
157
+ "communityEdit",
158
+ "timestamp",
159
+ ]);
160
+ const normalizeStoredAccountEditForSummary = (storedAccountEdit) => {
161
+ var _a;
162
+ const normalizedEdit = storedAccountEdit.commentModeration
163
+ ? Object.assign(Object.assign(Object.assign({}, storedAccountEdit), storedAccountEdit.commentModeration), { commentModeration: undefined }) : Object.assign({}, storedAccountEdit);
164
+ const communityEdit = (_a = normalizedEdit.communityEdit) !== null && _a !== void 0 ? _a : normalizedEdit.communityEdit;
165
+ if (communityEdit && typeof communityEdit === "object") {
166
+ Object.assign(normalizedEdit, communityEdit);
167
+ }
168
+ delete normalizedEdit.communityEdit;
169
+ delete normalizedEdit.communityEdit;
170
+ return normalizedEdit;
171
+ };
172
+ const getStoredAccountEditTarget = (storedAccountEdit) => storedAccountEdit.commentCid ||
173
+ storedAccountEdit.communityAddress ||
174
+ storedAccountEdit.communityAddress;
175
+ export const addStoredAccountEditSummaryToState = (accountsEditsSummaries, accountId, storedAccountEdit) => {
176
+ var _a;
177
+ const editTarget = getStoredAccountEditTarget(storedAccountEdit);
178
+ if (!editTarget) {
179
+ return { accountsEditsSummaries };
180
+ }
181
+ const accountEditsSummary = accountsEditsSummaries[accountId] || {};
182
+ const targetSummary = accountEditsSummary[editTarget] || {};
183
+ const nextSummary = Object.assign({}, targetSummary);
184
+ const normalizedEdit = normalizeStoredAccountEditForSummary(storedAccountEdit);
185
+ for (const propertyName in normalizedEdit) {
186
+ if (normalizedEdit[propertyName] === undefined ||
187
+ accountEditNonPropertyNames.has(propertyName)) {
188
+ continue;
189
+ }
190
+ const previousTimestamp = ((_a = nextSummary[propertyName]) === null || _a === void 0 ? void 0 : _a.timestamp) || 0;
191
+ if ((normalizedEdit.timestamp || 0) >= previousTimestamp) {
192
+ nextSummary[propertyName] = {
193
+ timestamp: normalizedEdit.timestamp,
194
+ value: normalizedEdit[propertyName],
195
+ };
196
+ }
197
+ }
198
+ return {
199
+ accountsEditsSummaries: Object.assign(Object.assign({}, accountsEditsSummaries), { [accountId]: Object.assign(Object.assign({}, accountEditsSummary), { [editTarget]: nextSummary }) }),
200
+ };
201
+ };
202
+ export const removeStoredAccountEditSummaryFromState = (accountsEditsSummaries, accountsEdits, accountId, storedAccountEdit) => {
203
+ var _a;
204
+ const editTarget = getStoredAccountEditTarget(storedAccountEdit);
205
+ if (!editTarget) {
206
+ return { accountsEditsSummaries };
207
+ }
208
+ let deletedEdit = false;
209
+ const editsForTarget = (((_a = accountsEdits[accountId]) === null || _a === void 0 ? void 0 : _a[editTarget]) || []).filter((storedEdit) => {
210
+ if (!deletedEdit && doesStoredAccountEditMatch(storedEdit, storedAccountEdit)) {
211
+ deletedEdit = true;
212
+ return false;
213
+ }
214
+ return true;
215
+ });
216
+ const nextTargetSummary = getAccountEditPropertySummary(editsForTarget);
217
+ const nextAccountSummary = Object.assign({}, (accountsEditsSummaries[accountId] || {}));
218
+ if (Object.keys(nextTargetSummary).length > 0) {
219
+ nextAccountSummary[editTarget] = nextTargetSummary;
220
+ }
221
+ else {
222
+ delete nextAccountSummary[editTarget];
223
+ }
224
+ return {
225
+ accountsEditsSummaries: Object.assign(Object.assign({}, accountsEditsSummaries), { [accountId]: nextAccountSummary }),
226
+ };
227
+ };
228
+ export const hasTerminalChallengeVerificationError = (challengeVerification) => {
229
+ const challengeErrors = challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.challengeErrors;
230
+ const hasChallengeErrors = Array.isArray(challengeErrors)
231
+ ? challengeErrors.length > 0
232
+ : challengeErrors && typeof challengeErrors === "object"
233
+ ? Object.keys(challengeErrors).length > 0
234
+ : Boolean(challengeErrors);
235
+ return (!(challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.challengeSuccess) &&
236
+ (hasChallengeErrors || Boolean(challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.reason)));
237
+ };
238
+ export const addStoredAccountEditToState = (accountsEdits, accountId, storedAccountEdit) => {
239
+ const accountEdits = accountsEdits[accountId] || {};
240
+ const editTarget = getStoredAccountEditTarget(storedAccountEdit);
241
+ if (!editTarget) {
242
+ return { accountsEdits };
243
+ }
244
+ const commentEdits = accountEdits[editTarget] || [];
245
+ return {
246
+ accountsEdits: Object.assign(Object.assign({}, accountsEdits), { [accountId]: Object.assign(Object.assign({}, accountEdits), { [editTarget]: [...commentEdits, storedAccountEdit] }) }),
247
+ };
248
+ };
249
+ export const removeStoredAccountEditFromState = (accountsEdits, accountId, storedAccountEdit) => {
250
+ const accountEdits = accountsEdits[accountId] || {};
251
+ const editTarget = getStoredAccountEditTarget(storedAccountEdit);
252
+ if (!editTarget) {
253
+ return { accountsEdits };
254
+ }
255
+ const commentEdits = accountEdits[editTarget] || [];
256
+ let deletedEdit = false;
257
+ const nextCommentEdits = commentEdits.filter((commentEdit) => {
258
+ if (!deletedEdit && doesStoredAccountEditMatch(commentEdit, storedAccountEdit)) {
259
+ deletedEdit = true;
260
+ return false;
261
+ }
262
+ return true;
263
+ });
264
+ const nextAccountEdits = nextCommentEdits.length > 0
265
+ ? Object.assign(Object.assign({}, accountEdits), { [editTarget]: nextCommentEdits }) : Object.fromEntries(Object.entries(accountEdits).filter(([target]) => target !== editTarget));
266
+ return {
267
+ accountsEdits: Object.assign(Object.assign({}, accountsEdits), { [accountId]: nextAccountEdits }),
268
+ };
269
+ };
270
+ const addNewAccountToDatabaseAndState = (newAccount) => __awaiter(void 0, void 0, void 0, function* () {
271
+ // add to database first to init the account
272
+ yield accountsDatabase.addAccount(newAccount);
273
+ // use database data for these because it's easier
274
+ const [newAccountIds, newAccountNamesToAccountIds] = yield Promise.all([
275
+ accountsDatabase.accountsMetadataDatabase.getItem("accountIds"),
276
+ accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
277
+ ]);
278
+ // set the new state
279
+ const { accounts, accountsComments, accountsCommentsIndexes, accountsVotes, accountsEdits, accountsEditsSummaries, accountsEditsLoaded, accountsCommentsReplies, } = accountsStore.getState();
280
+ const newAccounts = Object.assign(Object.assign({}, accounts), { [newAccount.id]: newAccount });
281
+ const newState = {
282
+ accounts: newAccounts,
283
+ accountIds: newAccountIds,
284
+ accountNamesToAccountIds: newAccountNamesToAccountIds,
285
+ accountsComments: Object.assign(Object.assign({}, accountsComments), { [newAccount.id]: [] }),
286
+ accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [newAccount.id]: getAccountCommentsIndex([]) }),
287
+ accountsVotes: Object.assign(Object.assign({}, accountsVotes), { [newAccount.id]: {} }),
288
+ accountsEdits: Object.assign(Object.assign({}, accountsEdits), { [newAccount.id]: {} }),
289
+ accountsEditsSummaries: Object.assign(Object.assign({}, accountsEditsSummaries), { [newAccount.id]: {} }),
290
+ accountsEditsLoaded: Object.assign(Object.assign({}, accountsEditsLoaded), { [newAccount.id]: false }),
291
+ accountsCommentsReplies: Object.assign(Object.assign({}, accountsCommentsReplies), { [newAccount.id]: {} }),
292
+ };
293
+ // if there is only 1 account, make it active
294
+ // otherwise stay on the same active account
295
+ if (newAccountIds.length === 1) {
296
+ newState.activeAccountId = newAccount.id;
297
+ }
298
+ accountsStore.setState(newState);
299
+ });
300
+ export const createAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
301
+ const newAccount = yield accountGenerator.generateDefaultAccount();
302
+ if (accountName) {
303
+ newAccount.name = accountName;
304
+ }
305
+ yield addNewAccountToDatabaseAndState(newAccount);
306
+ log("accountsActions.createAccount", { accountName, account: newAccount });
307
+ });
308
+ export const deleteAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
309
+ const { accounts, accountNamesToAccountIds, activeAccountId, accountsComments, accountsCommentsIndexes, accountsVotes, accountsEdits, accountsEditsSummaries, accountsEditsLoaded, } = accountsStore.getState();
310
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
311
+ let account = accounts[activeAccountId];
312
+ if (accountName) {
313
+ const accountId = accountNamesToAccountIds[accountName];
314
+ account = accounts[accountId];
315
+ }
316
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.deleteAccount account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
317
+ yield accountsDatabase.removeAccount(account);
318
+ const newAccounts = Object.assign({}, accounts);
319
+ delete newAccounts[account.id];
320
+ const [newAccountIds, newActiveAccountId, newAccountNamesToAccountIds] = yield Promise.all([
321
+ accountsDatabase.accountsMetadataDatabase.getItem("accountIds"),
322
+ accountsDatabase.accountsMetadataDatabase.getItem("activeAccountId"),
323
+ accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
324
+ ]);
325
+ const newAccountsComments = Object.assign({}, accountsComments);
326
+ delete newAccountsComments[account.id];
327
+ const newAccountsCommentsIndexes = Object.assign({}, accountsCommentsIndexes);
328
+ delete newAccountsCommentsIndexes[account.id];
329
+ const newCommentCidsToAccountsComments = getCommentCidsToAccountsComments(newAccountsComments);
330
+ const newAccountsVotes = Object.assign({}, accountsVotes);
331
+ delete newAccountsVotes[account.id];
332
+ const newAccountsEdits = Object.assign({}, accountsEdits);
333
+ delete newAccountsEdits[account.id];
334
+ const newAccountsEditsSummaries = Object.assign({}, accountsEditsSummaries);
335
+ delete newAccountsEditsSummaries[account.id];
336
+ const newAccountsEditsLoaded = Object.assign({}, accountsEditsLoaded);
337
+ delete newAccountsEditsLoaded[account.id];
338
+ accountsStore.setState({
339
+ accounts: newAccounts,
340
+ accountIds: newAccountIds,
341
+ activeAccountId: newActiveAccountId,
342
+ accountNamesToAccountIds: newAccountNamesToAccountIds,
343
+ accountsComments: newAccountsComments,
344
+ accountsCommentsIndexes: newAccountsCommentsIndexes,
345
+ commentCidsToAccountsComments: newCommentCidsToAccountsComments,
346
+ accountsVotes: newAccountsVotes,
347
+ accountsEdits: newAccountsEdits,
348
+ accountsEditsSummaries: newAccountsEditsSummaries,
349
+ accountsEditsLoaded: newAccountsEditsLoaded,
350
+ });
351
+ });
352
+ export const setActiveAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
353
+ const { accountNamesToAccountIds } = accountsStore.getState();
354
+ assert(accountNamesToAccountIds, `can't use accountsStore.accountActions before initialized`);
355
+ validator.validateAccountsActionsSetActiveAccountArguments(accountName);
356
+ const accountId = accountNamesToAccountIds[accountName];
357
+ yield accountsDatabase.accountsMetadataDatabase.setItem("activeAccountId", accountId);
358
+ log("accountsActions.setActiveAccount", { accountName, accountId });
359
+ accountsStore.setState({ activeAccountId: accountId });
360
+ });
361
+ export const setAccount = (account) => __awaiter(void 0, void 0, void 0, function* () {
362
+ var _a;
363
+ const { accounts } = accountsStore.getState();
364
+ validator.validateAccountsActionsSetAccountArguments(account);
365
+ assert(accounts === null || accounts === void 0 ? void 0 : accounts[account.id], `cannot set account with account.id '${account.id}' id does not exist in database`);
366
+ // if author.address has changed, add new community roles of author.address found in communities store
367
+ // TODO: add test to check if roles get added
368
+ if (account.author.address !== accounts[account.id].author.address) {
369
+ const communities = getAccountCommunities(account, communitiesStore.getState().communities);
370
+ account = Object.assign(Object.assign({}, account), { communities });
371
+ // wallet.signature changes if author.address changes
372
+ if ((_a = account.author.wallets) === null || _a === void 0 ? void 0 : _a.eth) {
373
+ const pkcSignerWalletWithNewAuthorAddress = yield chain.getEthWalletFromPkcPrivateKey(account.signer.privateKey, account.author.address);
374
+ // wallet is using pkc signer, redo signature with new author.address
375
+ if (account.author.wallets.eth.address === (pkcSignerWalletWithNewAuthorAddress === null || pkcSignerWalletWithNewAuthorAddress === void 0 ? void 0 : pkcSignerWalletWithNewAuthorAddress.address)) {
376
+ account.author.wallets = Object.assign(Object.assign({}, account.author.wallets), { eth: pkcSignerWalletWithNewAuthorAddress });
377
+ }
378
+ }
379
+ }
380
+ // use this function to serialize and update all databases
381
+ yield accountsDatabase.addAccount(account);
382
+ const [newAccount, newAccountNamesToAccountIds] = yield Promise.all([
383
+ // use this function to deserialize
384
+ accountsDatabase.getAccount(account.id),
385
+ accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
386
+ ]);
387
+ const newAccounts = Object.assign(Object.assign({}, accounts), { [newAccount.id]: newAccount });
388
+ log("accountsActions.setAccount", { account: newAccount });
389
+ accountsStore.setState({
390
+ accounts: newAccounts,
391
+ accountNamesToAccountIds: newAccountNamesToAccountIds,
392
+ });
393
+ });
394
+ export const setAccountsOrder = (newOrderedAccountNames) => __awaiter(void 0, void 0, void 0, function* () {
395
+ const { accounts, accountNamesToAccountIds } = accountsStore.getState();
396
+ assert(accounts && accountNamesToAccountIds, `can't use accountsStore.accountActions before initialized`);
397
+ const accountIds = [];
398
+ const accountNames = [];
399
+ for (const accountName of newOrderedAccountNames) {
400
+ const accountId = accountNamesToAccountIds[accountName];
401
+ accountIds.push(accountId);
402
+ accountNames.push(accounts[accountId].name);
403
+ }
404
+ validator.validateAccountsActionsSetAccountsOrderArguments(newOrderedAccountNames, accountNames);
405
+ log("accountsActions.setAccountsOrder", {
406
+ previousAccountNames: accountNames,
407
+ newAccountNames: newOrderedAccountNames,
408
+ });
409
+ yield accountsDatabase.accountsMetadataDatabase.setItem("accountIds", accountIds);
410
+ accountsStore.setState({ accountIds });
411
+ });
412
+ export const importAccount = (serializedAccount) => __awaiter(void 0, void 0, void 0, function* () {
413
+ var _a, _b;
414
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
415
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
416
+ let imported;
417
+ try {
418
+ imported = JSON.parse(serializedAccount);
419
+ }
420
+ catch (e) { }
421
+ assert((imported === null || imported === void 0 ? void 0 : imported.account) && ((_a = imported === null || imported === void 0 ? void 0 : imported.account) === null || _a === void 0 ? void 0 : _a.id) && ((_b = imported === null || imported === void 0 ? void 0 : imported.account) === null || _b === void 0 ? void 0 : _b.name), `accountsActions.importAccount failed JSON.stringify json serializedAccount '${serializedAccount}'`);
422
+ // add community roles already in communities store to imported account
423
+ // TODO: add test to check if roles get added
424
+ const communities = getAccountCommunities(imported.account, communitiesStore.getState().communities);
425
+ // if imported.account.name already exists, add ' 2', don't overwrite
426
+ if (accountNamesToAccountIds[imported.account.name]) {
427
+ imported.account.name += " 2";
428
+ }
429
+ // generate new account
430
+ const generatedAccount = yield accountGenerator.generateDefaultAccount();
431
+ // use generatedAccount to init properties like .pkc and .id on a new account
432
+ // overwrite account.id to avoid duplicate ids
433
+ const newAccount = Object.assign(Object.assign(Object.assign({}, generatedAccount), imported.account), { communities, id: generatedAccount.id });
434
+ // add account to database
435
+ yield accountsDatabase.addAccount(newAccount);
436
+ // add account comments, votes, edits to database
437
+ for (const accountComment of imported.accountComments || []) {
438
+ yield accountsDatabase.addAccountComment(newAccount.id, accountComment);
439
+ }
440
+ for (const accountVote of imported.accountVotes || []) {
441
+ yield accountsDatabase.addAccountVote(newAccount.id, accountVote);
442
+ }
443
+ for (const accountEdit of imported.accountEdits || []) {
444
+ yield accountsDatabase.addAccountEdit(newAccount.id, accountEdit);
445
+ }
446
+ // set new state
447
+ // get new state data from database because it's easier
448
+ const [accountComments, accountVotes, accountEditsSummary, accountIds, newAccountNamesToAccountIds,] = yield Promise.all([
449
+ accountsDatabase.getAccountComments(newAccount.id),
450
+ accountsDatabase.getAccountVotes(newAccount.id),
451
+ accountsDatabase.getAccountEditsSummary(newAccount.id),
452
+ accountsDatabase.accountsMetadataDatabase.getItem("accountIds"),
453
+ accountsDatabase.accountsMetadataDatabase.getItem("accountNamesToAccountIds"),
454
+ ]);
455
+ accountsStore.setState((state) => ({
456
+ accounts: Object.assign(Object.assign({}, state.accounts), { [newAccount.id]: newAccount }),
457
+ accountIds,
458
+ accountNamesToAccountIds: newAccountNamesToAccountIds,
459
+ accountsComments: Object.assign(Object.assign({}, state.accountsComments), { [newAccount.id]: accountComments }),
460
+ accountsCommentsIndexes: Object.assign(Object.assign({}, state.accountsCommentsIndexes), { [newAccount.id]: getAccountCommentsIndex(accountComments) }),
461
+ commentCidsToAccountsComments: getCommentCidsToAccountsComments(Object.assign(Object.assign({}, state.accountsComments), { [newAccount.id]: accountComments })),
462
+ accountsVotes: Object.assign(Object.assign({}, state.accountsVotes), { [newAccount.id]: accountVotes }),
463
+ accountsEdits: Object.assign(Object.assign({}, state.accountsEdits), { [newAccount.id]: {} }),
464
+ accountsEditsSummaries: Object.assign(Object.assign({}, state.accountsEditsSummaries), { [newAccount.id]: accountEditsSummary }),
465
+ accountsEditsLoaded: Object.assign(Object.assign({}, state.accountsEditsLoaded), { [newAccount.id]: false }),
466
+ // don't import/export replies to own comments, those are just cached and can be refetched
467
+ accountsCommentsReplies: Object.assign(Object.assign({}, state.accountsCommentsReplies), { [newAccount.id]: {} }),
468
+ }));
469
+ log("accountsActions.importAccount", {
470
+ account: newAccount,
471
+ accountComments,
472
+ accountVotes,
473
+ accountEditsSummary,
474
+ });
475
+ // start looking for updates for all accounts comments in database
476
+ for (const accountComment of accountComments) {
477
+ accountsStore
478
+ .getState()
479
+ .accountsActionsInternal.startUpdatingAccountCommentOnCommentUpdateEvents(accountComment, newAccount, accountComment.index)
480
+ .catch((error) => log.error("accountsActions.importAccount startUpdatingAccountCommentOnCommentUpdateEvents error", {
481
+ accountComment,
482
+ accountCommentIndex: accountComment.index,
483
+ importedAccount: newAccount,
484
+ error,
485
+ }));
486
+ }
487
+ // TODO: add options to only import private key, account settings, or include all account comments/votes history
488
+ });
489
+ export const exportAccount = (accountName) => __awaiter(void 0, void 0, void 0, function* () {
490
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
491
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
492
+ let account = accounts[activeAccountId];
493
+ if (accountName) {
494
+ const accountId = accountNamesToAccountIds[accountName];
495
+ account = accounts[accountId];
496
+ }
497
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.exportAccount account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
498
+ const exportedAccountJson = yield accountsDatabase.getExportedAccountJson(account.id);
499
+ log("accountsActions.exportAccount", { exportedAccountJson });
500
+ return exportedAccountJson;
501
+ });
502
+ export const subscribe = (communityAddress, accountName) => __awaiter(void 0, void 0, void 0, function* () {
503
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
504
+ assert(communityAddress && typeof communityAddress === "string", `accountsActions.subscribe invalid communityAddress '${communityAddress}'`);
505
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
506
+ let account = accounts[activeAccountId];
507
+ if (accountName) {
508
+ const accountId = accountNamesToAccountIds[accountName];
509
+ account = accounts[accountId];
510
+ }
511
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.subscribe account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
512
+ let subscriptions = account.subscriptions || [];
513
+ if (subscriptions.includes(communityAddress)) {
514
+ throw Error(`account '${account.id}' already subscribed to '${communityAddress}'`);
515
+ }
516
+ subscriptions = [...subscriptions, communityAddress];
517
+ const updatedAccount = Object.assign(Object.assign({}, account), { subscriptions });
518
+ // update account in db async for instant feedback speed
519
+ accountsDatabase.addAccount(updatedAccount);
520
+ const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
521
+ log("accountsActions.subscribe", { account: updatedAccount, accountName, communityAddress });
522
+ accountsStore.setState({ accounts: updatedAccounts });
523
+ });
524
+ export const unsubscribe = (communityAddress, accountName) => __awaiter(void 0, void 0, void 0, function* () {
525
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
526
+ assert(communityAddress && typeof communityAddress === "string", `accountsActions.unsubscribe invalid communityAddress '${communityAddress}'`);
527
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
528
+ let account = accounts[activeAccountId];
529
+ if (accountName) {
530
+ const accountId = accountNamesToAccountIds[accountName];
531
+ account = accounts[accountId];
532
+ }
533
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.unsubscribe account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
534
+ let subscriptions = account.subscriptions || [];
535
+ if (!subscriptions.includes(communityAddress)) {
536
+ throw Error(`account '${account.id}' already unsubscribed from '${communityAddress}'`);
537
+ }
538
+ // remove communityAddress
539
+ subscriptions = subscriptions.filter((address) => address !== communityAddress);
540
+ const updatedAccount = Object.assign(Object.assign({}, account), { subscriptions });
541
+ // update account in db async for instant feedback speed
542
+ accountsDatabase.addAccount(updatedAccount);
543
+ const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
544
+ log("accountsActions.unsubscribe", { account: updatedAccount, accountName, communityAddress });
545
+ accountsStore.setState({ accounts: updatedAccounts });
546
+ });
547
+ export const blockAddress = (address, accountName) => __awaiter(void 0, void 0, void 0, function* () {
548
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
549
+ assert(address && typeof address === "string", `accountsActions.blockAddress invalid address '${address}'`);
550
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
551
+ let account = accounts[activeAccountId];
552
+ if (accountName) {
553
+ const accountId = accountNamesToAccountIds[accountName];
554
+ account = accounts[accountId];
555
+ }
556
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.blockAddress account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
557
+ const blockedAddresses = Object.assign({}, account.blockedAddresses);
558
+ if (blockedAddresses[address] === true) {
559
+ throw Error(`account '${account.id}' already blocked address '${address}'`);
560
+ }
561
+ blockedAddresses[address] = true;
562
+ const updatedAccount = Object.assign(Object.assign({}, account), { blockedAddresses });
563
+ // update account in db async for instant feedback speed
564
+ accountsDatabase.addAccount(updatedAccount);
565
+ const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
566
+ log("accountsActions.blockAddress", { account: updatedAccount, accountName, address });
567
+ accountsStore.setState({ accounts: updatedAccounts });
568
+ });
569
+ export const unblockAddress = (address, accountName) => __awaiter(void 0, void 0, void 0, function* () {
570
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
571
+ assert(address && typeof address === "string", `accountsActions.unblockAddress invalid address '${address}'`);
572
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
573
+ let account = accounts[activeAccountId];
574
+ if (accountName) {
575
+ const accountId = accountNamesToAccountIds[accountName];
576
+ account = accounts[accountId];
577
+ }
578
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.unblockAddress account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
579
+ const blockedAddresses = Object.assign({}, account.blockedAddresses);
580
+ if (!blockedAddresses[address]) {
581
+ throw Error(`account '${account.id}' already unblocked address '${address}'`);
582
+ }
583
+ delete blockedAddresses[address];
584
+ const updatedAccount = Object.assign(Object.assign({}, account), { blockedAddresses });
585
+ // update account in db async for instant feedback speed
586
+ accountsDatabase.addAccount(updatedAccount);
587
+ const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
588
+ log("accountsActions.unblockAddress", { account: updatedAccount, accountName, address });
589
+ accountsStore.setState({ accounts: updatedAccounts });
590
+ });
591
+ export const blockCid = (cid, accountName) => __awaiter(void 0, void 0, void 0, function* () {
592
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
593
+ assert(cid && typeof cid === "string", `accountsActions.blockCid invalid cid '${cid}'`);
594
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
595
+ let account = accounts[activeAccountId];
596
+ if (accountName) {
597
+ const accountId = accountNamesToAccountIds[accountName];
598
+ account = accounts[accountId];
599
+ }
600
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.blockCid account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
601
+ const blockedCids = Object.assign({}, account.blockedCids);
602
+ if (blockedCids[cid] === true) {
603
+ throw Error(`account '${account.id}' already blocked cid '${cid}'`);
604
+ }
605
+ blockedCids[cid] = true;
606
+ const updatedAccount = Object.assign(Object.assign({}, account), { blockedCids });
607
+ // update account in db async for instant feedback speed
608
+ accountsDatabase.addAccount(updatedAccount);
609
+ const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
610
+ log("accountsActions.blockCid", { account: updatedAccount, accountName, cid });
611
+ accountsStore.setState({ accounts: updatedAccounts });
612
+ });
613
+ export const unblockCid = (cid, accountName) => __awaiter(void 0, void 0, void 0, function* () {
614
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
615
+ assert(cid && typeof cid === "string", `accountsActions.unblockCid invalid cid '${cid}'`);
616
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
617
+ let account = accounts[activeAccountId];
618
+ if (accountName) {
619
+ const accountId = accountNamesToAccountIds[accountName];
620
+ account = accounts[accountId];
621
+ }
622
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.unblockCid account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist, activeAccountId '${activeAccountId}' accountName '${accountName}'`);
623
+ const blockedCids = Object.assign({}, account.blockedCids);
624
+ if (!blockedCids[cid]) {
625
+ throw Error(`account '${account.id}' already unblocked cid '${cid}'`);
626
+ }
627
+ delete blockedCids[cid];
628
+ const updatedAccount = Object.assign(Object.assign({}, account), { blockedCids });
629
+ // update account in db async for instant feedback speed
630
+ accountsDatabase.addAccount(updatedAccount);
631
+ const updatedAccounts = Object.assign(Object.assign({}, accounts), { [updatedAccount.id]: updatedAccount });
632
+ log("accountsActions.unblockCid", { account: updatedAccount, accountName, cid });
633
+ accountsStore.setState({ accounts: updatedAccounts });
634
+ });
635
+ export const publishComment = (publishCommentOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
636
+ var _a, _b, _c;
637
+ const { accounts, accountsComments, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
638
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
639
+ let account = accounts[activeAccountId];
640
+ if (accountName) {
641
+ const accountId = accountNamesToAccountIds[accountName];
642
+ account = accounts[accountId];
643
+ }
644
+ validator.validateAccountsActionsPublishCommentArguments({
645
+ publishCommentOptions,
646
+ accountName,
647
+ account,
648
+ });
649
+ // find author.previousCommentCid if any
650
+ const accountCommentsWithCids = accountsComments[account.id]
651
+ .filter((comment) => comment.cid)
652
+ // author can change his address, his previousCommentCid becomes invalid
653
+ .filter((comment) => { var _a, _b; return ((_a = comment.author) === null || _a === void 0 ? void 0 : _a.address) === ((_b = account.author) === null || _b === void 0 ? void 0 : _b.address); });
654
+ const previousCommentCid = (_a = accountCommentsWithCids[accountCommentsWithCids.length - 1]) === null || _a === void 0 ? void 0 : _a.cid;
655
+ const author = Object.assign({}, account.author);
656
+ if (previousCommentCid) {
657
+ author.previousCommentCid = previousCommentCid;
658
+ }
659
+ let createCommentOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author, signer: account.signer }, publishCommentOptions));
660
+ delete createCommentOptions.onChallenge;
661
+ delete createCommentOptions.onChallengeVerification;
662
+ delete createCommentOptions.onError;
663
+ delete createCommentOptions.onPublishingStateChange;
664
+ delete createCommentOptions._onPendingCommentIndex;
665
+ const storedCreateCommentOptions = normalizePublicationOptionsForStore(createCommentOptions);
666
+ // make sure the options dont throw
667
+ yield account.pkc.createComment(createCommentOptions);
668
+ // try to get comment depth needed for custom depth flat account replies
669
+ const depth = getAccountCommentDepth(createCommentOptions);
670
+ // set fetching link dimensions state
671
+ let fetchingLinkDimensionsStates;
672
+ if (publishCommentOptions.link) {
673
+ (_b = publishCommentOptions.onPublishingStateChange) === null || _b === void 0 ? void 0 : _b.call(publishCommentOptions, "fetching-link-dimensions");
674
+ fetchingLinkDimensionsStates = {
675
+ state: "publishing",
676
+ publishingState: "fetching-link-dimensions",
677
+ };
678
+ }
679
+ // save comment to db
680
+ let accountCommentIndex = accountsComments[account.id].length;
681
+ const publishSessionId = createPublishSession(account.id, accountCommentIndex);
682
+ let savedOnce = false;
683
+ const saveCreatedAccountComment = (accountComment) => __awaiter(void 0, void 0, void 0, function* () {
684
+ var _a;
685
+ if (isPublishSessionAbandoned(publishSessionId)) {
686
+ return;
687
+ }
688
+ const isUpdate = savedOnce;
689
+ const session = getPublishSession(publishSessionId);
690
+ const currentIndex = (_a = session === null || session === void 0 ? void 0 : session.currentIndex) !== null && _a !== void 0 ? _a : accountCommentIndex;
691
+ const persistedAccountComment = addShortAddressesToAccountComment(sanitizeStoredAccountComment(accountComment));
692
+ const liveAccountComment = addShortAddressesToAccountComment(sanitizeAccountCommentForState(accountComment));
693
+ const liveAccountComments = accountsStore.getState().accountsComments[account.id] || [];
694
+ if (isUpdate && !liveAccountComments[currentIndex]) {
695
+ return;
696
+ }
697
+ yield accountsDatabase.addAccountComment(account.id, persistedAccountComment, isUpdate ? currentIndex : undefined);
698
+ savedOnce = true;
699
+ accountsStore.setState(({ accountsComments, accountsCommentsIndexes }) => {
700
+ const accountComments = [...accountsComments[account.id]];
701
+ if (isUpdate && !accountComments[currentIndex]) {
702
+ return {};
703
+ }
704
+ accountComments[currentIndex] = Object.assign(Object.assign({}, liveAccountComment), { index: currentIndex, accountId: account.id });
705
+ return {
706
+ accountsComments: Object.assign(Object.assign({}, accountsComments), { [account.id]: accountComments }),
707
+ accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [account.id]: getAccountCommentsIndex(accountComments) }),
708
+ };
709
+ });
710
+ });
711
+ let createdAccountComment = Object.assign(Object.assign({}, storedCreateCommentOptions), { depth, index: accountCommentIndex, accountId: account.id });
712
+ createdAccountComment = addShortAddressesToAccountComment(sanitizeAccountCommentForState(createdAccountComment));
713
+ yield saveCreatedAccountComment(createdAccountComment);
714
+ (_c = publishCommentOptions._onPendingCommentIndex) === null || _c === void 0 ? void 0 : _c.call(publishCommentOptions, accountCommentIndex, createdAccountComment);
715
+ let comment;
716
+ (() => __awaiter(void 0, void 0, void 0, function* () {
717
+ // fetch comment.link dimensions
718
+ if (publishCommentOptions.link) {
719
+ const commentLinkDimensions = yield fetchCommentLinkDimensions(publishCommentOptions.link);
720
+ createCommentOptions = Object.assign(Object.assign({}, createCommentOptions), commentLinkDimensions);
721
+ // save dimensions to db
722
+ createdAccountComment = Object.assign(Object.assign({}, createdAccountComment), commentLinkDimensions);
723
+ yield saveCreatedAccountComment(createdAccountComment);
724
+ }
725
+ if (isPublishSessionAbandoned(publishSessionId)) {
726
+ return;
727
+ }
728
+ comment = backfillPublicationCommunityAddress(yield account.pkc.createComment(createCommentOptions), createCommentOptions);
729
+ syncCommentClientsSnapshot(publishSessionId, account.id, comment);
730
+ publishAndRetryFailedChallengeVerification();
731
+ log("accountsActions.publishComment", { createCommentOptions });
732
+ }))();
733
+ let lastChallenge;
734
+ let lastReportedPublishError;
735
+ const normalizePublishError = (error) => error instanceof Error ? error : new Error(String(error));
736
+ const getActiveSessionForComment = (activeComment) => {
737
+ const session = getPublishSession(publishSessionId);
738
+ if (!session ||
739
+ isPublishSessionAbandoned(publishSessionId) ||
740
+ session.comment !== activeComment) {
741
+ return undefined;
742
+ }
743
+ return session;
744
+ };
745
+ const queueCleanupFailedPublishSession = (activeComment) => {
746
+ if (!getActiveSessionForComment(activeComment))
747
+ return;
748
+ queueMicrotask(() => {
749
+ if (getActiveSessionForComment(activeComment)) {
750
+ cleanupPublishSessionOnTerminal(publishSessionId);
751
+ }
752
+ });
753
+ };
754
+ const recordPublishCommentError = (rawError, activeComment) => {
755
+ const error = normalizePublishError(rawError);
756
+ if (lastReportedPublishError === error) {
757
+ return error;
758
+ }
759
+ lastReportedPublishError = error;
760
+ const session = getActiveSessionForComment(activeComment);
761
+ if (!session)
762
+ return error;
763
+ const currentIndex = session.currentIndex;
764
+ accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
765
+ const previousErrors = Array.isArray(acc.errors) ? acc.errors : [];
766
+ const errors = previousErrors[previousErrors.length - 1] === error
767
+ ? previousErrors
768
+ : [...previousErrors, error];
769
+ ac[currentIndex] = Object.assign(Object.assign({}, acc), { errors, error });
770
+ }));
771
+ return error;
772
+ };
773
+ const reportActivePublishCommentError = (rawError, activeComment) => {
774
+ var _a;
775
+ if (!getActiveSessionForComment(activeComment))
776
+ return;
777
+ const error = recordPublishCommentError(rawError, activeComment);
778
+ queueCleanupFailedPublishSession(activeComment);
779
+ (_a = publishCommentOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentOptions, error, activeComment);
780
+ };
781
+ function publishAndRetryFailedChallengeVerification() {
782
+ return __awaiter(this, void 0, void 0, function* () {
783
+ if (isPublishSessionAbandoned(publishSessionId)) {
784
+ return;
785
+ }
786
+ const activeComment = comment;
787
+ updatePublishSessionComment(publishSessionId, activeComment);
788
+ activeComment.once("challenge", (challenge) => __awaiter(this, void 0, void 0, function* () {
789
+ lastChallenge = challenge;
790
+ publishCommentOptions.onChallenge(challenge, activeComment);
791
+ }));
792
+ activeComment.once("challengeverification", (challengeVerification) => __awaiter(this, void 0, void 0, function* () {
793
+ var _a, _b;
794
+ publishCommentOptions.onChallengeVerification(challengeVerification, activeComment);
795
+ if (!challengeVerification.challengeSuccess && lastChallenge) {
796
+ // publish again automatically on fail
797
+ const timestamp = Math.floor(Date.now() / 1000);
798
+ createCommentOptions = Object.assign(Object.assign({}, createCommentOptions), { timestamp });
799
+ createdAccountComment = Object.assign(Object.assign({}, createdAccountComment), { timestamp });
800
+ updatePublishSessionComment(publishSessionId, undefined);
801
+ yield saveCreatedAccountComment(createdAccountComment);
802
+ if (isPublishSessionAbandoned(publishSessionId)) {
803
+ return;
804
+ }
805
+ comment = backfillPublicationCommunityAddress(yield account.pkc.createComment(createCommentOptions), createCommentOptions);
806
+ syncCommentClientsSnapshot(publishSessionId, account.id, comment);
807
+ lastChallenge = undefined;
808
+ publishAndRetryFailedChallengeVerification();
809
+ }
810
+ else {
811
+ // the challengeverification message of a comment publication should in theory send back the CID
812
+ // of the published comment which is needed to resolve it for replies, upvotes, etc
813
+ const session = getPublishSession(publishSessionId);
814
+ const currentIndex = (_a = session === null || session === void 0 ? void 0 : session.currentIndex) !== null && _a !== void 0 ? _a : accountCommentIndex;
815
+ if (!session || isPublishSessionAbandoned(publishSessionId))
816
+ return;
817
+ queueMicrotask(() => cleanupPublishSessionOnTerminal(publishSessionId));
818
+ if ((_b = challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.commentUpdate) === null || _b === void 0 ? void 0 : _b.cid) {
819
+ const persistedCommentWithCid = addShortAddressesToAccountComment(sanitizeStoredAccountComment(normalizePublicationOptionsForStore(comment)));
820
+ const liveCommentWithCid = addShortAddressesToAccountComment(sanitizeAccountCommentForState(normalizePublicationOptionsForStore(comment)));
821
+ delete persistedCommentWithCid.clients;
822
+ delete persistedCommentWithCid.publishingState;
823
+ delete persistedCommentWithCid.error;
824
+ delete persistedCommentWithCid.errors;
825
+ delete liveCommentWithCid.clients;
826
+ delete liveCommentWithCid.publishingState;
827
+ delete liveCommentWithCid.error;
828
+ delete liveCommentWithCid.errors;
829
+ yield accountsDatabase.addAccountComment(account.id, persistedCommentWithCid, currentIndex);
830
+ accountsStore.setState(({ accountsComments, accountsCommentsIndexes, commentCidsToAccountsComments }) => {
831
+ var _a;
832
+ const updatedAccountComments = [...accountsComments[account.id]];
833
+ const updatedAccountComment = Object.assign(Object.assign({}, liveCommentWithCid), { index: currentIndex, accountId: account.id });
834
+ updatedAccountComments[currentIndex] = updatedAccountComment;
835
+ return {
836
+ accountsComments: Object.assign(Object.assign({}, accountsComments), { [account.id]: updatedAccountComments }),
837
+ accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [account.id]: getAccountCommentsIndex(updatedAccountComments) }),
838
+ commentCidsToAccountsComments: Object.assign(Object.assign({}, commentCidsToAccountsComments), { [(_a = challengeVerification === null || challengeVerification === void 0 ? void 0 : challengeVerification.commentUpdate) === null || _a === void 0 ? void 0 : _a.cid]: {
839
+ accountId: account.id,
840
+ accountCommentIndex: currentIndex,
841
+ } }),
842
+ };
843
+ });
844
+ // clone the comment or it bugs publishing callbacks
845
+ const updatingComment = yield account.pkc.createComment(normalizePublicationOptionsForPkc(account.pkc, Object.assign({}, comment)));
846
+ accountsActionsInternal
847
+ .startUpdatingAccountCommentOnCommentUpdateEvents(updatingComment, account, currentIndex)
848
+ .catch((error) => log.error("accountsActions.publishComment startUpdatingAccountCommentOnCommentUpdateEvents error", { comment, account, accountCommentIndex, error }));
849
+ }
850
+ }
851
+ }));
852
+ activeComment.on("error", (error) => {
853
+ reportActivePublishCommentError(error, activeComment);
854
+ });
855
+ activeComment.on("statechange", (state) => {
856
+ const session = getActiveSessionForComment(activeComment);
857
+ if (!session)
858
+ return;
859
+ const currentIndex = session.currentIndex;
860
+ let hasTerminalFailedState = false;
861
+ accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
862
+ const nextAccountComment = Object.assign(Object.assign({}, acc), { state });
863
+ ac[currentIndex] = nextAccountComment;
864
+ hasTerminalFailedState =
865
+ nextAccountComment.state === "stopped" &&
866
+ nextAccountComment.publishingState === "failed";
867
+ }));
868
+ if (hasTerminalFailedState) {
869
+ queueCleanupFailedPublishSession(activeComment);
870
+ }
871
+ });
872
+ activeComment.on("publishingstatechange", (publishingState) => __awaiter(this, void 0, void 0, function* () {
873
+ var _a;
874
+ const session = getActiveSessionForComment(activeComment);
875
+ if (!session)
876
+ return;
877
+ const currentIndex = session.currentIndex;
878
+ let hasTerminalFailedState = false;
879
+ accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
880
+ const nextAccountComment = Object.assign(Object.assign({}, acc), { publishingState });
881
+ ac[currentIndex] = nextAccountComment;
882
+ hasTerminalFailedState =
883
+ nextAccountComment.state === "stopped" &&
884
+ nextAccountComment.publishingState === "failed";
885
+ }));
886
+ if (hasTerminalFailedState) {
887
+ queueCleanupFailedPublishSession(activeComment);
888
+ }
889
+ (_a = publishCommentOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommentOptions, publishingState);
890
+ }));
891
+ // set clients on account comment so the frontend can display it, dont persist in db because a reload cancels publishing
892
+ utils.clientsOnStateChange(activeComment.clients, (clientState, clientType, clientUrl, chainTicker) => {
893
+ const session = getActiveSessionForComment(activeComment);
894
+ if (!session)
895
+ return;
896
+ const currentIndex = session.currentIndex;
897
+ accountsStore.setState(({ accountsComments }) => maybeUpdateAccountComment(accountsComments, account.id, currentIndex, (ac, acc) => {
898
+ const clients = getClientsSnapshotForState(activeComment.clients) || {};
899
+ const client = { state: clientState };
900
+ if (chainTicker) {
901
+ const chainProviders = Object.assign(Object.assign({}, clients[clientType][chainTicker]), { [clientUrl]: client });
902
+ clients[clientType] = Object.assign(Object.assign({}, clients[clientType]), { [chainTicker]: chainProviders });
903
+ }
904
+ else {
905
+ clients[clientType] = Object.assign(Object.assign({}, clients[clientType]), { [clientUrl]: client });
906
+ }
907
+ ac[currentIndex] = Object.assign(Object.assign({}, acc), { clients });
908
+ }));
909
+ });
910
+ listeners.push(activeComment);
911
+ try {
912
+ // publish will resolve after the challenge request
913
+ // if it fails before, like failing to resolve ENS, we can emit the error
914
+ yield activeComment.publish();
915
+ }
916
+ catch (error) {
917
+ reportActivePublishCommentError(error, activeComment);
918
+ }
919
+ });
920
+ }
921
+ return createdAccountComment;
922
+ });
923
+ export const deleteComment = (commentCidOrAccountCommentIndex, accountName) => __awaiter(void 0, void 0, void 0, function* () {
924
+ const { accounts, accountsComments, accountNamesToAccountIds, activeAccountId, commentCidsToAccountsComments, } = accountsStore.getState();
925
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
926
+ let account = accounts[activeAccountId];
927
+ if (accountName) {
928
+ const accountId = accountNamesToAccountIds[accountName];
929
+ account = accounts[accountId];
930
+ }
931
+ assert(account === null || account === void 0 ? void 0 : account.id, `accountsActions.deleteComment account.id '${account === null || account === void 0 ? void 0 : account.id}' doesn't exist`);
932
+ const accountComments = accountsComments[account.id] || [];
933
+ assert(accountComments.length > 0, `accountsActions.deleteComment no comments for account`);
934
+ let accountCommentIndex;
935
+ if (typeof commentCidOrAccountCommentIndex === "number") {
936
+ accountCommentIndex = commentCidOrAccountCommentIndex;
937
+ }
938
+ else {
939
+ const mapping = commentCidsToAccountsComments[commentCidOrAccountCommentIndex];
940
+ assert(mapping && mapping.accountId === account.id, `accountsActions.deleteComment cid '${commentCidOrAccountCommentIndex}' not found for account`);
941
+ accountCommentIndex = mapping.accountCommentIndex;
942
+ }
943
+ assert(accountCommentIndex >= 0 && accountCommentIndex < accountComments.length, `accountsActions.deleteComment index '${accountCommentIndex}' out of range`);
944
+ abandonAndStopPublishSession(account.id, accountCommentIndex);
945
+ shiftPublishSessionIndicesAfterDelete(account.id, accountCommentIndex);
946
+ const spliced = [...accountComments];
947
+ spliced.splice(accountCommentIndex, 1);
948
+ const reindexed = spliced.map((c, i) => (Object.assign(Object.assign({}, c), { index: i, accountId: account.id })));
949
+ const newAccountsComments = Object.assign(Object.assign({}, accountsComments), { [account.id]: reindexed });
950
+ const newCommentCidsToAccountsComments = getCommentCidsToAccountsComments(newAccountsComments);
951
+ accountsStore.setState(({ accountsCommentsIndexes }) => ({
952
+ accountsComments: newAccountsComments,
953
+ accountsCommentsIndexes: Object.assign(Object.assign({}, accountsCommentsIndexes), { [account.id]: getAccountCommentsIndex(reindexed) }),
954
+ commentCidsToAccountsComments: newCommentCidsToAccountsComments,
955
+ }));
956
+ yield accountsDatabase.deleteAccountComment(account.id, accountCommentIndex);
957
+ log("accountsActions.deleteComment", { accountId: account.id, accountCommentIndex });
958
+ });
959
+ export const publishVote = (publishVoteOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
960
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
961
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
962
+ let account = accounts[activeAccountId];
963
+ if (accountName) {
964
+ const accountId = accountNamesToAccountIds[accountName];
965
+ account = accounts[accountId];
966
+ }
967
+ validator.validateAccountsActionsPublishVoteArguments({
968
+ publishVoteOptions,
969
+ accountName,
970
+ account,
971
+ });
972
+ let createVoteOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author: account.author, signer: account.signer }, publishVoteOptions));
973
+ delete createVoteOptions.onChallenge;
974
+ delete createVoteOptions.onChallengeVerification;
975
+ delete createVoteOptions.onError;
976
+ delete createVoteOptions.onPublishingStateChange;
977
+ const storedCreateVoteOptions = normalizePublicationOptionsForStore(createVoteOptions);
978
+ let vote = backfillPublicationCommunityAddress(yield account.pkc.createVote(createVoteOptions), createVoteOptions);
979
+ let lastChallenge;
980
+ const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
981
+ var _a;
982
+ vote.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
983
+ lastChallenge = challenge;
984
+ publishVoteOptions.onChallenge(challenge, vote);
985
+ }));
986
+ vote.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
987
+ publishVoteOptions.onChallengeVerification(challengeVerification, vote);
988
+ if (!challengeVerification.challengeSuccess && lastChallenge) {
989
+ // publish again automatically on fail
990
+ createVoteOptions = Object.assign(Object.assign({}, createVoteOptions), { timestamp: Math.floor(Date.now() / 1000) });
991
+ vote = backfillPublicationCommunityAddress(yield account.pkc.createVote(createVoteOptions), createVoteOptions);
992
+ lastChallenge = undefined;
993
+ publishAndRetryFailedChallengeVerification();
994
+ }
995
+ }));
996
+ vote.on("error", (error) => { var _a; return (_a = publishVoteOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishVoteOptions, error, vote); });
997
+ // TODO: add publishingState to account votes
998
+ vote.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishVoteOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishVoteOptions, publishingState); });
999
+ listeners.push(vote);
1000
+ try {
1001
+ // publish will resolve after the challenge request
1002
+ // if it fails before, like failing to resolve ENS, we can emit the error
1003
+ yield vote.publish();
1004
+ }
1005
+ catch (error) {
1006
+ (_a = publishVoteOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishVoteOptions, error, vote);
1007
+ }
1008
+ });
1009
+ publishAndRetryFailedChallengeVerification();
1010
+ yield accountsDatabase.addAccountVote(account.id, storedCreateVoteOptions);
1011
+ log("accountsActions.publishVote", { createVoteOptions });
1012
+ accountsStore.setState(({ accountsVotes }) => ({
1013
+ accountsVotes: Object.assign(Object.assign({}, accountsVotes), { [account.id]: Object.assign(Object.assign({}, accountsVotes[account.id]), { [storedCreateVoteOptions.commentCid]: Object.assign(Object.assign({}, storedCreateVoteOptions), { signer: undefined, author: undefined }) }) }),
1014
+ }));
1015
+ });
1016
+ export const publishCommentEdit = (publishCommentEditOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
1017
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
1018
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
1019
+ let account = accounts[activeAccountId];
1020
+ if (accountName) {
1021
+ const accountId = accountNamesToAccountIds[accountName];
1022
+ account = accounts[accountId];
1023
+ }
1024
+ validator.validateAccountsActionsPublishCommentEditArguments({
1025
+ publishCommentEditOptions,
1026
+ accountName,
1027
+ account,
1028
+ });
1029
+ let createCommentEditOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author: account.author, signer: account.signer }, publishCommentEditOptions));
1030
+ delete createCommentEditOptions.onChallenge;
1031
+ delete createCommentEditOptions.onChallengeVerification;
1032
+ delete createCommentEditOptions.onError;
1033
+ delete createCommentEditOptions.onPublishingStateChange;
1034
+ const storedCreateCommentEditOptions = Object.assign(Object.assign({}, normalizePublicationOptionsForStore(createCommentEditOptions)), { clientId: uuid() });
1035
+ const storedCommentEdit = sanitizeStoredAccountEdit(storedCreateCommentEditOptions);
1036
+ let commentEdit = backfillPublicationCommunityAddress(yield account.pkc.createCommentEdit(createCommentEditOptions), createCommentEditOptions);
1037
+ let lastChallenge;
1038
+ let challengeSucceeded = false;
1039
+ let rollbackPendingEditPromise;
1040
+ const rollbackStoredCommentEdit = () => {
1041
+ if (!rollbackPendingEditPromise && !challengeSucceeded) {
1042
+ rollbackPendingEditPromise = Promise.all([
1043
+ accountsDatabase.deleteAccountEdit(account.id, storedCommentEdit),
1044
+ Promise.resolve(accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
1045
+ const nextState = removeStoredAccountEditSummaryFromState(accountsEditsSummaries, accountsEdits, account.id, storedCommentEdit);
1046
+ Object.assign(nextState, removeStoredAccountEditFromState(accountsEdits, account.id, storedCommentEdit));
1047
+ return nextState;
1048
+ })),
1049
+ ]).then(() => { });
1050
+ }
1051
+ return rollbackPendingEditPromise;
1052
+ };
1053
+ yield accountsDatabase.addAccountEdit(account.id, storedCreateCommentEditOptions);
1054
+ log("accountsActions.publishCommentEdit", { createCommentEditOptions });
1055
+ accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
1056
+ const nextState = addStoredAccountEditSummaryToState(accountsEditsSummaries, account.id, storedCommentEdit);
1057
+ Object.assign(nextState, addStoredAccountEditToState(accountsEdits, account.id, storedCommentEdit));
1058
+ return nextState;
1059
+ });
1060
+ const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
1061
+ var _a;
1062
+ commentEdit.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
1063
+ lastChallenge = challenge;
1064
+ publishCommentEditOptions.onChallenge(challenge, commentEdit);
1065
+ }));
1066
+ commentEdit.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
1067
+ publishCommentEditOptions.onChallengeVerification(challengeVerification, commentEdit);
1068
+ if (challengeVerification.challengeSuccess) {
1069
+ challengeSucceeded = true;
1070
+ }
1071
+ if (hasTerminalChallengeVerificationError(challengeVerification)) {
1072
+ lastChallenge = undefined;
1073
+ yield rollbackStoredCommentEdit();
1074
+ return;
1075
+ }
1076
+ if (!challengeVerification.challengeSuccess && lastChallenge) {
1077
+ // publish again automatically on fail
1078
+ createCommentEditOptions = Object.assign(Object.assign({}, createCommentEditOptions), { timestamp: Math.floor(Date.now() / 1000) });
1079
+ commentEdit = backfillPublicationCommunityAddress(yield account.pkc.createCommentEdit(createCommentEditOptions), createCommentEditOptions);
1080
+ lastChallenge = undefined;
1081
+ publishAndRetryFailedChallengeVerification();
1082
+ }
1083
+ }));
1084
+ commentEdit.on("error", (error) => __awaiter(void 0, void 0, void 0, function* () {
1085
+ var _a;
1086
+ yield rollbackStoredCommentEdit();
1087
+ (_a = publishCommentEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentEditOptions, error, commentEdit);
1088
+ }));
1089
+ // TODO: add publishingState to account edits
1090
+ commentEdit.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishCommentEditOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommentEditOptions, publishingState); });
1091
+ listeners.push(commentEdit);
1092
+ try {
1093
+ // publish will resolve after the challenge request
1094
+ // if it fails before, like failing to resolve ENS, we can emit the error
1095
+ yield commentEdit.publish();
1096
+ }
1097
+ catch (error) {
1098
+ yield rollbackStoredCommentEdit();
1099
+ (_a = publishCommentEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentEditOptions, error, commentEdit);
1100
+ }
1101
+ });
1102
+ publishAndRetryFailedChallengeVerification();
1103
+ });
1104
+ export const publishCommentModeration = (publishCommentModerationOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
1105
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
1106
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
1107
+ let account = accounts[activeAccountId];
1108
+ if (accountName) {
1109
+ const accountId = accountNamesToAccountIds[accountName];
1110
+ account = accounts[accountId];
1111
+ }
1112
+ validator.validateAccountsActionsPublishCommentModerationArguments({
1113
+ publishCommentModerationOptions,
1114
+ accountName,
1115
+ account,
1116
+ });
1117
+ let createCommentModerationOptions = normalizePublicationOptionsForPkc(account.pkc, Object.assign({ timestamp: Math.floor(Date.now() / 1000), author: account.author, signer: account.signer }, publishCommentModerationOptions));
1118
+ delete createCommentModerationOptions.onChallenge;
1119
+ delete createCommentModerationOptions.onChallengeVerification;
1120
+ delete createCommentModerationOptions.onError;
1121
+ delete createCommentModerationOptions.onPublishingStateChange;
1122
+ const storedCreateCommentModerationOptions = Object.assign(Object.assign({}, normalizePublicationOptionsForStore(createCommentModerationOptions)), { clientId: uuid() });
1123
+ const storedCommentModeration = sanitizeStoredAccountEdit(storedCreateCommentModerationOptions);
1124
+ let commentModeration = backfillPublicationCommunityAddress(yield account.pkc.createCommentModeration(createCommentModerationOptions), createCommentModerationOptions);
1125
+ let lastChallenge;
1126
+ let challengeSucceeded = false;
1127
+ let storedCommentModerationAdded = false;
1128
+ let rollbackStoredCommentModerationRequested = false;
1129
+ let rollbackPendingEditPromise;
1130
+ const rollbackStoredCommentModeration = () => {
1131
+ rollbackStoredCommentModerationRequested = true;
1132
+ if (!storedCommentModerationAdded) {
1133
+ return Promise.resolve();
1134
+ }
1135
+ if (!rollbackPendingEditPromise && !challengeSucceeded) {
1136
+ rollbackPendingEditPromise = Promise.all([
1137
+ accountsDatabase.deleteAccountEdit(account.id, storedCommentModeration),
1138
+ Promise.resolve(accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
1139
+ const nextState = removeStoredAccountEditSummaryFromState(accountsEditsSummaries, accountsEdits, account.id, storedCommentModeration);
1140
+ Object.assign(nextState, removeStoredAccountEditFromState(accountsEdits, account.id, storedCommentModeration));
1141
+ return nextState;
1142
+ })),
1143
+ ]).then(() => { });
1144
+ }
1145
+ return rollbackPendingEditPromise || Promise.resolve();
1146
+ };
1147
+ const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
1148
+ var _a;
1149
+ commentModeration.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
1150
+ lastChallenge = challenge;
1151
+ publishCommentModerationOptions.onChallenge(challenge, commentModeration);
1152
+ }));
1153
+ commentModeration.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
1154
+ publishCommentModerationOptions.onChallengeVerification(challengeVerification, commentModeration);
1155
+ if (challengeVerification.challengeSuccess) {
1156
+ challengeSucceeded = true;
1157
+ }
1158
+ if (hasTerminalChallengeVerificationError(challengeVerification)) {
1159
+ lastChallenge = undefined;
1160
+ yield rollbackStoredCommentModeration();
1161
+ return;
1162
+ }
1163
+ if (!challengeVerification.challengeSuccess && lastChallenge) {
1164
+ // publish again automatically on fail
1165
+ createCommentModerationOptions = Object.assign(Object.assign({}, createCommentModerationOptions), { timestamp: Math.floor(Date.now() / 1000) });
1166
+ commentModeration = backfillPublicationCommunityAddress(yield account.pkc.createCommentModeration(createCommentModerationOptions), createCommentModerationOptions);
1167
+ lastChallenge = undefined;
1168
+ publishAndRetryFailedChallengeVerification();
1169
+ }
1170
+ }));
1171
+ commentModeration.on("error", (error) => __awaiter(void 0, void 0, void 0, function* () {
1172
+ var _a;
1173
+ yield rollbackStoredCommentModeration();
1174
+ (_a = publishCommentModerationOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentModerationOptions, error, commentModeration);
1175
+ }));
1176
+ // TODO: add publishingState to account edits
1177
+ commentModeration.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishCommentModerationOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommentModerationOptions, publishingState); });
1178
+ listeners.push(commentModeration);
1179
+ try {
1180
+ // publish will resolve after the challenge request
1181
+ // if it fails before, like failing to resolve ENS, we can emit the error
1182
+ yield commentModeration.publish();
1183
+ }
1184
+ catch (error) {
1185
+ yield rollbackStoredCommentModeration();
1186
+ (_a = publishCommentModerationOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommentModerationOptions, error, commentModeration);
1187
+ }
1188
+ });
1189
+ publishAndRetryFailedChallengeVerification();
1190
+ yield accountsDatabase.addAccountEdit(account.id, storedCreateCommentModerationOptions);
1191
+ log("accountsActions.publishCommentModeration", { createCommentModerationOptions });
1192
+ accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
1193
+ const nextState = addStoredAccountEditSummaryToState(accountsEditsSummaries, account.id, storedCommentModeration);
1194
+ Object.assign(nextState, addStoredAccountEditToState(accountsEdits, account.id, storedCommentModeration));
1195
+ return nextState;
1196
+ });
1197
+ storedCommentModerationAdded = true;
1198
+ if (rollbackStoredCommentModerationRequested) {
1199
+ yield rollbackStoredCommentModeration();
1200
+ }
1201
+ });
1202
+ export const publishCommunityEdit = (communityAddress, publishCommunityEditOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
1203
+ var _a;
1204
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
1205
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountActions before initialized`);
1206
+ let account = accounts[activeAccountId];
1207
+ if (accountName) {
1208
+ const accountId = accountNamesToAccountIds[accountName];
1209
+ account = accounts[accountId];
1210
+ }
1211
+ validator.validateAccountsActionsPublishCommunityEditArguments({
1212
+ communityAddress,
1213
+ publishCommunityEditOptions,
1214
+ accountName,
1215
+ account,
1216
+ });
1217
+ const communityEditOptions = Object.assign({}, publishCommunityEditOptions);
1218
+ delete communityEditOptions.onChallenge;
1219
+ delete communityEditOptions.onChallengeVerification;
1220
+ delete communityEditOptions.onError;
1221
+ delete communityEditOptions.onPublishingStateChange;
1222
+ let createCommunityEditOptions = normalizeCommunityEditOptionsForPkc(account.pkc, {
1223
+ timestamp: Math.floor(Date.now() / 1000),
1224
+ author: account.author,
1225
+ signer: account.signer,
1226
+ // not possible to edit community.address over pubsub, only locally
1227
+ communityAddress,
1228
+ communityEdit: communityEditOptions,
1229
+ });
1230
+ const storedCreateCommunityEditOptions = Object.assign(Object.assign({}, normalizePublicationOptionsForStore(createCommunityEditOptions)), { clientId: uuid() });
1231
+ const storedCommunityEdit = sanitizeStoredAccountEdit(storedCreateCommunityEditOptions);
1232
+ let challengeSucceeded = false;
1233
+ let rollbackPendingEditPromise;
1234
+ const rollbackStoredCommunityEdit = () => {
1235
+ if (!rollbackPendingEditPromise && !challengeSucceeded) {
1236
+ rollbackPendingEditPromise = Promise.all([
1237
+ accountsDatabase.deleteAccountEdit(account.id, storedCommunityEdit),
1238
+ Promise.resolve(accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
1239
+ const nextState = removeStoredAccountEditSummaryFromState(accountsEditsSummaries, accountsEdits, account.id, storedCommunityEdit);
1240
+ Object.assign(nextState, removeStoredAccountEditFromState(accountsEdits, account.id, storedCommunityEdit));
1241
+ return nextState;
1242
+ })),
1243
+ ]).then(() => { });
1244
+ }
1245
+ return rollbackPendingEditPromise;
1246
+ };
1247
+ const storePublishedCommunityEdit = () => __awaiter(void 0, void 0, void 0, function* () {
1248
+ yield accountsDatabase.addAccountEdit(account.id, storedCreateCommunityEditOptions);
1249
+ accountsStore.setState(({ accountsEdits, accountsEditsSummaries }) => {
1250
+ const nextState = addStoredAccountEditSummaryToState(accountsEditsSummaries, account.id, storedCommunityEdit);
1251
+ Object.assign(nextState, addStoredAccountEditToState(accountsEdits, account.id, storedCommunityEdit));
1252
+ return nextState;
1253
+ });
1254
+ });
1255
+ // account is the owner of the community and can edit it locally, no need to publish
1256
+ if (accountOwnsCommunityLocally(account, communityAddress)) {
1257
+ yield communitiesStore
1258
+ .getState()
1259
+ .editCommunity(communityAddress, communityEditOptions, account);
1260
+ yield storePublishedCommunityEdit();
1261
+ // create fake success challenge verification for consistent behavior with remote community edit
1262
+ publishCommunityEditOptions.onChallengeVerification({ challengeSuccess: true });
1263
+ (_a = publishCommunityEditOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, "succeeded");
1264
+ return;
1265
+ }
1266
+ assert(!publishCommunityEditOptions.address ||
1267
+ publishCommunityEditOptions.address === communityAddress, `accountsActions.publishCommunityEdit can't edit address of a remote community`);
1268
+ let communityEdit = backfillPublicationCommunityAddress(yield createPkcCommunityEdit(account.pkc, createCommunityEditOptions), createCommunityEditOptions);
1269
+ let lastChallenge;
1270
+ const publishAndRetryFailedChallengeVerification = () => __awaiter(void 0, void 0, void 0, function* () {
1271
+ var _a;
1272
+ communityEdit.once("challenge", (challenge) => __awaiter(void 0, void 0, void 0, function* () {
1273
+ lastChallenge = challenge;
1274
+ publishCommunityEditOptions.onChallenge(challenge, communityEdit);
1275
+ }));
1276
+ communityEdit.once("challengeverification", (challengeVerification) => __awaiter(void 0, void 0, void 0, function* () {
1277
+ publishCommunityEditOptions.onChallengeVerification(challengeVerification, communityEdit);
1278
+ if (challengeVerification.challengeSuccess) {
1279
+ challengeSucceeded = true;
1280
+ }
1281
+ if (hasTerminalChallengeVerificationError(challengeVerification)) {
1282
+ lastChallenge = undefined;
1283
+ yield rollbackStoredCommunityEdit();
1284
+ return;
1285
+ }
1286
+ if (!challengeVerification.challengeSuccess && lastChallenge) {
1287
+ // publish again automatically on fail
1288
+ createCommunityEditOptions = Object.assign(Object.assign({}, createCommunityEditOptions), { timestamp: Math.floor(Date.now() / 1000) });
1289
+ communityEdit = backfillPublicationCommunityAddress(yield createPkcCommunityEdit(account.pkc, createCommunityEditOptions), createCommunityEditOptions);
1290
+ lastChallenge = undefined;
1291
+ publishAndRetryFailedChallengeVerification();
1292
+ }
1293
+ }));
1294
+ communityEdit.on("error", (error) => __awaiter(void 0, void 0, void 0, function* () {
1295
+ var _a;
1296
+ yield rollbackStoredCommunityEdit();
1297
+ (_a = publishCommunityEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, error, communityEdit);
1298
+ }));
1299
+ // TODO: add publishingState to account edits
1300
+ communityEdit.on("publishingstatechange", (publishingState) => { var _a; return (_a = publishCommunityEditOptions.onPublishingStateChange) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, publishingState); });
1301
+ listeners.push(communityEdit);
1302
+ try {
1303
+ // publish will resolve after the challenge request
1304
+ // if it fails before, like failing to resolve ENS, we can emit the error
1305
+ yield communityEdit.publish();
1306
+ }
1307
+ catch (error) {
1308
+ yield rollbackStoredCommunityEdit();
1309
+ (_a = publishCommunityEditOptions.onError) === null || _a === void 0 ? void 0 : _a.call(publishCommunityEditOptions, error, communityEdit);
1310
+ }
1311
+ });
1312
+ yield storePublishedCommunityEdit();
1313
+ publishAndRetryFailedChallengeVerification();
1314
+ log("accountsActions.publishCommunityEdit", { createCommunityEditOptions });
1315
+ });
1316
+ export const createCommunity = (createCommunityOptions, accountName) => __awaiter(void 0, void 0, void 0, function* () {
1317
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
1318
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountsActions before initialized`);
1319
+ let account = accounts[activeAccountId];
1320
+ if (accountName) {
1321
+ const accountId = accountNamesToAccountIds[accountName];
1322
+ account = accounts[accountId];
1323
+ }
1324
+ const community = yield communitiesStore
1325
+ .getState()
1326
+ .createCommunity(createCommunityOptions, account);
1327
+ log("accountsActions.createCommunity", { createCommunityOptions, community });
1328
+ return community;
1329
+ });
1330
+ export const deleteCommunity = (communityAddress, accountName) => __awaiter(void 0, void 0, void 0, function* () {
1331
+ const { accounts, accountNamesToAccountIds, activeAccountId } = accountsStore.getState();
1332
+ assert(accounts && accountNamesToAccountIds && activeAccountId, `can't use accountsStore.accountsActions before initialized`);
1333
+ let account = accounts[activeAccountId];
1334
+ if (accountName) {
1335
+ const accountId = accountNamesToAccountIds[accountName];
1336
+ account = accounts[accountId];
1337
+ }
1338
+ yield communitiesStore.getState().deleteCommunity(communityAddress, account);
1339
+ log("accountsActions.deleteCommunity", { communityAddress });
1340
+ });
1341
+ //# sourceMappingURL=accounts-actions.js.map