@bitsocial/bitsocial-react-hooks 0.1.5 → 0.1.7

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [0.1.7](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.6...v0.1.7) (2026-05-06)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **comments:** pass community identity to pkc comments ([8db8b8c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/8db8b8c033e3d4c39e5a17e069405560014826fa))
7
+
8
+
9
+
10
+ ## [0.1.6](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.5...v0.1.6) (2026-05-05)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **deps:** resolve axios dependabot alerts ([f05eac0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f05eac02887067fe1413d39aa7fbe21b593c01aa))
16
+ * **deps:** resolve dependabot alerts ([805ac34](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/805ac34b43cbf139c2ff8d479450a45338070ec9))
17
+ * **replies:** keep newly published account replies visible ([96ab074](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/96ab074a85222b838cc71c8c091aae2ece6039da))
18
+ * **tests:** stop account hook suite OOM ([1e217d6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1e217d6a11008cdd25b83ed0ef2d3e7d5c95e537))
19
+
20
+
21
+
1
22
  ## [0.1.5](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.4...v0.1.5) (2026-05-02)
2
23
 
3
24
 
package/README.md CHANGED
@@ -119,7 +119,7 @@ useNotifications(): {notifications: Notification[], markAsRead: Function}
119
119
  #### Comments Hooks
120
120
 
121
121
  ```
122
- useComment({commentCid: string, onlyIfCached?: boolean, autoUpdate?: boolean}): Comment & {refresh: Function}
122
+ useComment({commentCid: string, community?: CommunityIdentifier, onlyIfCached?: boolean, autoUpdate?: boolean}): Comment & {refresh: Function}
123
123
  useReplies({comment: Comment, onlyIfCached?: boolean, sortType?: string, flat?: boolean, repliesPerPage?: number, filter?: CommentsFilter, accountComments?: {newerThan: number, append?: boolean}}): {replies: Comment[], hasMore: boolean, loadMore: function, reset: function, updatedReplies: Comment[], bufferedReplies: Comment[]}
124
124
  useComments({commentCids: string[], onlyIfCached?: boolean, autoUpdate?: boolean}): {comments: Comment[], refresh: Function}
125
125
  useEditedComment({comment: Comment}): {editedComment: Comment | undefined}
@@ -256,7 +256,7 @@ await publishComment();
256
256
  #### Get a post
257
257
 
258
258
  ```jsx
259
- const post = useComment({ commentCid });
259
+ const post = useComment({ commentCid, community: { name: communityAddress, publicKey: communityPublicKey } });
260
260
 
261
261
  // manual refresh is always available
262
262
  await post.refresh();
@@ -290,7 +290,7 @@ if (valid === false) {
290
290
  #### Get a comment
291
291
 
292
292
  ```jsx
293
- const comment = useComment({ commentCid });
293
+ const comment = useComment({ commentCid, community: { name: communityAddress, publicKey: communityPublicKey } });
294
294
  const { comments, refresh } = useComments({ commentCids: [commentCid1, commentCid2, commentCid3] });
295
295
  await refresh();
296
296
 
@@ -1019,8 +1019,8 @@ const { replies } = useReplies({
1019
1019
 
1020
1020
  // pending local account comments are reconciled with their approved network version
1021
1021
  // so the same post or reply is not shown twice after moderation approval
1022
- // published account replies are only kept in useReplies while the canonical
1023
- // replies feed may still contain them; after the feed is exhausted, account-only
1022
+ // published account replies are kept in useReplies until the canonical replies
1023
+ // feed refreshes past the reply timestamp; after that exhausted feed, account-only
1024
1024
  // published replies are hidden unless the canonical feed includes their cid
1025
1025
  ```
1026
1026
 
@@ -1302,8 +1302,9 @@ const useRepliesOptions = {
1302
1302
  accountComments: { newerThan: Infinity, append: false },
1303
1303
  };
1304
1304
 
1305
- // accountComments keeps pending local replies visible, but published account
1306
- // replies must resolve through the canonical replies feed after it is exhausted
1305
+ // accountComments keeps pending and just-published local replies visible, but
1306
+ // published account replies must resolve through the canonical replies feed
1307
+ // after that feed refreshes past them and is exhausted
1307
1308
 
1308
1309
  const Reply = ({ reply, updatedReply }) => {
1309
1310
  const { replies, updatedReplies, bufferedReplies, hasMore, loadMore } = useReplies({
@@ -3,6 +3,7 @@ export declare function getCommentFreshness(comment: Comment | undefined): numbe
3
3
  export declare function preferFresher(current: Comment | undefined, candidate: Comment | undefined): Comment | undefined;
4
4
  /**
5
5
  * @param commentCid - The IPFS CID of the comment to get
6
+ * @param community - The community identifier, e.g. {name: 'memes.eth', publicKey: '12D3KooW...'}.
6
7
  * @param acountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, use
7
8
  * the active account.
8
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/hooks/comments.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,UAAU,CAAC;AAYlB,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAGxE;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,OAAO,GAAG,SAAS,CAIrB;AAqCD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAsKxE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CA0K3E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,wBAAwB,CAmDhG"}
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../../src/hooks/comments.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,UAAU,CAAC;AAalB,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAGxE;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,GAC7B,OAAO,GAAG,SAAS,CAIrB;AA0ED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,gBAAgB,CAuMxE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CA0K3E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,wBAAwB,CAmDhG"}
@@ -20,6 +20,7 @@ import { addCommentModeration, addCommentModerationToComments, } from "../lib/ut
20
20
  import useCommunitiesPagesStore from "../stores/communities-pages/index.js";
21
21
  import useRepliesPagesStore from "../stores/replies-pages/index.js";
22
22
  import shallow from "zustand/shallow";
23
+ import { assertCommunityRef } from "../lib/community-ref.js";
23
24
  export function getCommentFreshness(comment) {
24
25
  var _a, _b;
25
26
  if (!comment)
@@ -60,14 +61,47 @@ const getCommentsState = (comments) => comments.every((comment) => getCommentSta
60
61
  : "fetching-ipfs";
61
62
  let commentAutoUpdateSubscriptionCount = 0;
62
63
  let commentsAutoUpdateSubscriptionCount = 0;
64
+ const getCommentCreateCommentData = (commentCid, community, ...comments) => {
65
+ if (!commentCid) {
66
+ return undefined;
67
+ }
68
+ const createCommentData = { cid: commentCid };
69
+ let hasCommunityData = false;
70
+ for (const comment of comments) {
71
+ if (!comment) {
72
+ continue;
73
+ }
74
+ if (!createCommentData.communityPublicKey && comment.communityPublicKey) {
75
+ createCommentData.communityPublicKey = comment.communityPublicKey;
76
+ hasCommunityData = true;
77
+ }
78
+ if (!createCommentData.communityName && comment.communityName) {
79
+ createCommentData.communityName = comment.communityName;
80
+ hasCommunityData = true;
81
+ }
82
+ }
83
+ if (community === null || community === void 0 ? void 0 : community.publicKey) {
84
+ createCommentData.communityPublicKey = community.publicKey;
85
+ hasCommunityData = true;
86
+ }
87
+ if (community === null || community === void 0 ? void 0 : community.name) {
88
+ createCommentData.communityName = community.name;
89
+ hasCommunityData = true;
90
+ }
91
+ return hasCommunityData ? createCommentData : undefined;
92
+ };
63
93
  /**
64
94
  * @param commentCid - The IPFS CID of the comment to get
95
+ * @param community - The community identifier, e.g. {name: 'memes.eth', publicKey: '12D3KooW...'}.
65
96
  * @param acountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, use
66
97
  * the active account.
67
98
  */
68
99
  export function useComment(options) {
69
100
  assert(!options || typeof options === "object", `useComment options argument '${options}' not an object`);
70
- const { commentCid, accountName, onlyIfCached, autoUpdate = true } = options !== null && options !== void 0 ? options : {};
101
+ const { commentCid, community, accountName, onlyIfCached, autoUpdate = true } = options !== null && options !== void 0 ? options : {};
102
+ if (community !== undefined) {
103
+ assertCommunityRef(community, "useComment community");
104
+ }
71
105
  const account = useAccount({ accountName });
72
106
  const commentFromStore = useCommentsStore((state) => state.comments[commentCid || ""]);
73
107
  const addCommentToStore = useCommentsStore((state) => state.addCommentToStore);
@@ -83,6 +117,15 @@ export function useComment(options) {
83
117
  var _a;
84
118
  return (_a = state.accountsComments[(accountCommentInfo === null || accountCommentInfo === void 0 ? void 0 : accountCommentInfo.accountId) || ""]) === null || _a === void 0 ? void 0 : _a[Number(accountCommentInfo === null || accountCommentInfo === void 0 ? void 0 : accountCommentInfo.accountCommentIndex)];
85
119
  });
120
+ const createCommentData = useMemo(() => getCommentCreateCommentData(commentCid, community, communitiesPagesComment, repliesPagesComment), [
121
+ commentCid,
122
+ community === null || community === void 0 ? void 0 : community.name,
123
+ community === null || community === void 0 ? void 0 : community.publicKey,
124
+ communitiesPagesComment === null || communitiesPagesComment === void 0 ? void 0 : communitiesPagesComment.communityName,
125
+ communitiesPagesComment === null || communitiesPagesComment === void 0 ? void 0 : communitiesPagesComment.communityPublicKey,
126
+ repliesPagesComment === null || repliesPagesComment === void 0 ? void 0 : repliesPagesComment.communityName,
127
+ repliesPagesComment === null || repliesPagesComment === void 0 ? void 0 : repliesPagesComment.communityPublicKey,
128
+ ]);
86
129
  const autoUpdateSubscriptionId = useRef(`useComment-${++commentAutoUpdateSubscriptionCount}`);
87
130
  const currentCommentCidRef = useRef(commentCid);
88
131
  currentCommentCidRef.current = commentCid;
@@ -95,18 +138,24 @@ export function useComment(options) {
95
138
  validator.validateUseCommentArguments(commentCid, account);
96
139
  if (!commentFromStore && !onlyIfCached) {
97
140
  // if comment isn't already in store, add it
98
- addCommentToStore(commentCid, account).catch((error) => log.error("useComment addCommentToStore error", { commentCid, error }));
141
+ const addCommentPromise = createCommentData
142
+ ? addCommentToStore(commentCid, account, createCommentData)
143
+ : addCommentToStore(commentCid, account);
144
+ addCommentPromise.catch((error) => log.error("useComment addCommentToStore error", { commentCid, error }));
99
145
  }
100
- }, [commentCid, account === null || account === void 0 ? void 0 : account.id, onlyIfCached]);
146
+ }, [commentCid, account === null || account === void 0 ? void 0 : account.id, onlyIfCached, createCommentData]);
101
147
  useEffect(() => {
102
148
  if (!commentCid || !account || onlyIfCached || !autoUpdate) {
103
149
  return;
104
150
  }
105
- startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account).catch((error) => log.error("useComment startCommentAutoUpdate error", { commentCid, error }));
151
+ const startAutoUpdatePromise = createCommentData
152
+ ? startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account, createCommentData)
153
+ : startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account);
154
+ startAutoUpdatePromise.catch((error) => log.error("useComment startCommentAutoUpdate error", { commentCid, error }));
106
155
  return () => {
107
156
  stopCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current).catch((error) => log.error("useComment stopCommentAutoUpdate error", { commentCid, error }));
108
157
  };
109
- }, [commentCid, account === null || account === void 0 ? void 0 : account.id, onlyIfCached, autoUpdate]);
158
+ }, [commentCid, account === null || account === void 0 ? void 0 : account.id, onlyIfCached, autoUpdate, createCommentData]);
110
159
  let selectedComment = commentFromStore;
111
160
  if (commentCid && communitiesPagesComment) {
112
161
  selectedComment = preferFresher(selectedComment, communitiesPagesComment);
@@ -177,12 +226,14 @@ export function useComment(options) {
177
226
  throw Error("useComment cannot refresh comment not initialized yet");
178
227
  }
179
228
  const refreshCommentCid = commentCid;
180
- const refreshedComment = yield refreshCommentInStore(refreshCommentCid, account);
229
+ const refreshedComment = createCommentData
230
+ ? yield refreshCommentInStore(refreshCommentCid, account, createCommentData)
231
+ : yield refreshCommentInStore(refreshCommentCid, account);
181
232
  if (!autoUpdate && refreshedComment && currentCommentCidRef.current === refreshCommentCid) {
182
233
  setFrozenComment(refreshedComment);
183
234
  setFreezeSettledCid(refreshCommentCid);
184
235
  }
185
- }), [account, autoUpdate, commentCid, refreshCommentInStore]);
236
+ }), [account, autoUpdate, commentCid, createCommentData, refreshCommentInStore]);
186
237
  return useMemo(() => (Object.assign(Object.assign({}, comment), { replyCount,
187
238
  state,
188
239
  refresh, error: errors === null || errors === void 0 ? void 0 : errors[errors.length - 1], errors: errors || [] })), [comment, commentCid, errors, refresh, state, replyCount]);
@@ -1 +1 @@
1
- {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/hooks/comments.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAccount } from \"./accounts\";\nimport validator from \"../lib/validator\";\nimport Logger from \"@pkcprotocol/pkc-logger\";\nconst log = Logger(\"bitsocial-react-hooks:comments:hooks\");\nimport assert from \"assert\";\nimport {\n Comment,\n UseCommentsOptions,\n UseCommentsResult,\n UseCommentOptions,\n UseCommentResult,\n UseValidateCommentOptions,\n UseValidateCommentResult,\n} from \"../types\";\nimport useCommentsStore from \"../stores/comments\";\nimport useAccountsStore from \"../stores/accounts\";\nimport { commentIsValid } from \"../lib/utils\";\nimport {\n addCommentModeration,\n addCommentModerationToComments,\n} from \"../lib/utils/comment-moderation\";\nimport useCommunitiesPagesStore from \"../stores/communities-pages\";\nimport useRepliesPagesStore from \"../stores/replies-pages\";\nimport shallow from \"zustand/shallow\";\n\nexport function getCommentFreshness(comment: Comment | undefined): number {\n if (!comment) return 0;\n return Math.max(comment.updatedAt ?? 0, comment.timestamp ?? 0, 0);\n}\n\nexport function preferFresher(\n current: Comment | undefined,\n candidate: Comment | undefined,\n): Comment | undefined {\n if (!candidate) return current;\n if (!current) return candidate;\n return getCommentFreshness(candidate) > getCommentFreshness(current) ? candidate : current;\n}\n\nconst getCommentStateAndReplyCount = (comment: Comment | undefined) => {\n let state = comment?.updatingState || \"initializing\";\n // force 'fetching-ipns' even if could be something else, so the frontend can use\n // the correct loading skeleton\n if (comment?.timestamp) {\n state = \"fetching-update-ipns\";\n }\n // force succeeded even if the comment is fecthing a new update\n if (comment?.updatedAt) {\n state = \"succeeded\";\n }\n\n // force succeeded if the comment is newer than 5 minutes, no need to display loading skeleton if comment was just created\n let replyCount = comment?.replyCount;\n if (\n comment?.replyCount === undefined &&\n comment?.timestamp &&\n comment?.timestamp > Date.now() / 1000 - 5 * 60\n ) {\n state = \"succeeded\";\n // set replyCount because some frontend are likely to check if replyCount === undefined to show a loading skeleton\n replyCount = 0;\n }\n\n return { state, replyCount };\n};\n\nconst getCommentsState = (comments: (Comment | undefined)[]) =>\n comments.every((comment) => getCommentStateAndReplyCount(comment).state === \"succeeded\")\n ? \"succeeded\"\n : \"fetching-ipfs\";\n\nlet commentAutoUpdateSubscriptionCount = 0;\nlet commentsAutoUpdateSubscriptionCount = 0;\n\n/**\n * @param commentCid - The IPFS CID of the comment to get\n * @param acountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, use\n * the active account.\n */\nexport function useComment(options?: UseCommentOptions): UseCommentResult {\n assert(\n !options || typeof options === \"object\",\n `useComment options argument '${options}' not an object`,\n );\n const { commentCid, accountName, onlyIfCached, autoUpdate = true } = options ?? {};\n const account = useAccount({ accountName });\n const commentFromStore = useCommentsStore((state: any) => state.comments[commentCid || \"\"]);\n const addCommentToStore = useCommentsStore((state: any) => state.addCommentToStore);\n const startCommentAutoUpdate = useCommentsStore((state: any) => state.startCommentAutoUpdate);\n const stopCommentAutoUpdate = useCommentsStore((state: any) => state.stopCommentAutoUpdate);\n const refreshCommentInStore = useCommentsStore((state: any) => state.refreshComment);\n const communitiesPagesComment = useCommunitiesPagesStore(\n (state: any) => state.comments[commentCid || \"\"],\n );\n const repliesPagesComment = useRepliesPagesStore(\n (state: any) => state.comments[commentCid || \"\"],\n );\n const errors = useCommentsStore((state: any) => state.errors[commentCid || \"\"]);\n\n // get account comment of the cid if any\n const accountCommentInfo = useAccountsStore(\n (state: any) => state.commentCidsToAccountsComments[commentCid || \"\"],\n );\n const accountComment = useAccountsStore(\n (state: any) =>\n state.accountsComments[accountCommentInfo?.accountId || \"\"]?.[\n Number(accountCommentInfo?.accountCommentIndex)\n ],\n );\n const autoUpdateSubscriptionId = useRef(`useComment-${++commentAutoUpdateSubscriptionCount}`);\n const currentCommentCidRef = useRef<string | undefined>(commentCid);\n currentCommentCidRef.current = commentCid;\n const [frozenComment, setFrozenComment] = useState<Comment | undefined>();\n const [freezeSettledCid, setFreezeSettledCid] = useState<string>();\n\n useEffect(() => {\n if (!commentCid || !account) {\n return;\n }\n validator.validateUseCommentArguments(commentCid, account);\n if (!commentFromStore && !onlyIfCached) {\n // if comment isn't already in store, add it\n addCommentToStore(commentCid, account).catch((error: unknown) =>\n log.error(\"useComment addCommentToStore error\", { commentCid, error }),\n );\n }\n }, [commentCid, account?.id, onlyIfCached]);\n\n useEffect(() => {\n if (!commentCid || !account || onlyIfCached || !autoUpdate) {\n return;\n }\n\n startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account).catch(\n (error: unknown) =>\n log.error(\"useComment startCommentAutoUpdate error\", { commentCid, error }),\n );\n\n return () => {\n stopCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current).catch((error: unknown) =>\n log.error(\"useComment stopCommentAutoUpdate error\", { commentCid, error }),\n );\n };\n }, [commentCid, account?.id, onlyIfCached, autoUpdate]);\n\n let selectedComment = commentFromStore;\n\n if (commentCid && communitiesPagesComment) {\n selectedComment = preferFresher(selectedComment, communitiesPagesComment);\n }\n if (commentCid && repliesPagesComment) {\n selectedComment = preferFresher(selectedComment, repliesPagesComment);\n }\n\n // if comment is still not defined, but account comment is, use account comment\n // check `comment.timestamp` instead of `comment` in case comment exists but in a loading state\n const commentFromStoreNotLoaded = !selectedComment?.timestamp;\n if (commentCid && commentFromStoreNotLoaded && accountComment) {\n selectedComment = accountComment;\n }\n\n const selectedCommentState = getCommentStateAndReplyCount(selectedComment).state;\n const freezeSettledForCurrentCid = freezeSettledCid === commentCid;\n\n useEffect(() => {\n if (autoUpdate) {\n setFrozenComment(undefined);\n setFreezeSettledCid(undefined);\n return;\n }\n\n setFrozenComment(undefined);\n setFreezeSettledCid(undefined);\n }, [commentCid, autoUpdate]);\n\n useEffect(() => {\n if (autoUpdate) {\n return;\n }\n if (!commentCid) {\n setFrozenComment(undefined);\n setFreezeSettledCid(undefined);\n return;\n }\n if (freezeSettledForCurrentCid || !selectedComment) {\n return;\n }\n\n setFrozenComment(selectedComment);\n if (selectedCommentState === \"succeeded\") {\n setFreezeSettledCid(commentCid);\n }\n }, [autoUpdate, commentCid, selectedComment, selectedCommentState, freezeSettledForCurrentCid]);\n\n const frozenCommentForCurrentCid = frozenComment?.cid === commentCid ? frozenComment : undefined;\n let comment = autoUpdate\n ? selectedComment\n : freezeSettledForCurrentCid\n ? frozenCommentForCurrentCid\n : frozenCommentForCurrentCid || selectedComment;\n comment = addCommentModeration(comment);\n\n const { state, replyCount } = getCommentStateAndReplyCount(comment);\n\n if (account && commentCid) {\n log(\"useComment\", {\n commentCid,\n comment,\n replyCount,\n state,\n commentFromStore,\n communitiesPagesComment,\n repliesPagesComment,\n accountComment,\n commentsStore: useCommentsStore.getState().comments,\n account,\n onlyIfCached,\n autoUpdate,\n });\n }\n\n const refresh = useCallback(async () => {\n if (!commentCid || !account) {\n throw Error(\"useComment cannot refresh comment not initialized yet\");\n }\n\n const refreshCommentCid = commentCid;\n const refreshedComment = await refreshCommentInStore(refreshCommentCid, account);\n if (!autoUpdate && refreshedComment && currentCommentCidRef.current === refreshCommentCid) {\n setFrozenComment(refreshedComment);\n setFreezeSettledCid(refreshCommentCid);\n }\n }, [account, autoUpdate, commentCid, refreshCommentInStore]);\n\n return useMemo(\n () => ({\n ...comment,\n replyCount,\n state,\n refresh,\n error: errors?.[errors.length - 1],\n errors: errors || [],\n }),\n [comment, commentCid, errors, refresh, state, replyCount],\n );\n}\n\n/**\n * @param commentCids - The IPFS CIDs of the comments to get\n * @param acountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, use\n * the active account.\n */\nexport function useComments(options?: UseCommentsOptions): UseCommentsResult {\n assert(\n !options || typeof options === \"object\",\n `useComments options argument '${options}' not an object`,\n );\n const { commentCids = [], accountName, onlyIfCached, autoUpdate = true } = options ?? {};\n const account = useAccount({ accountName });\n const commentsStoreComments: (Comment | undefined)[] = useCommentsStore(\n (state: any) => commentCids.map((commentCid) => state.comments[commentCid || \"\"]),\n shallow,\n );\n const communitiesPagesComments: (Comment | undefined)[] = useCommunitiesPagesStore(\n (state: any) => commentCids.map((commentCid) => state.comments[commentCid || \"\"]),\n shallow,\n );\n\n const addCommentToStore = useCommentsStore((state: any) => state.addCommentToStore);\n const startCommentAutoUpdate = useCommentsStore((state: any) => state.startCommentAutoUpdate);\n const stopCommentAutoUpdate = useCommentsStore((state: any) => state.stopCommentAutoUpdate);\n const refreshCommentInStore = useCommentsStore((state: any) => state.refreshComment);\n const autoUpdateSubscriptionId = useRef(`useComments-${++commentsAutoUpdateSubscriptionCount}`);\n const commentCidsKey = JSON.stringify(commentCids);\n const commentsKey = `${account?.id || \"\"}:${commentCidsKey}`;\n const currentCommentsKeyRef = useRef(commentsKey);\n currentCommentsKeyRef.current = commentsKey;\n const [frozenComments, setFrozenComments] = useState<(Comment | undefined)[]>([]);\n const [frozenCommentsKey, setFrozenCommentsKey] = useState<string>();\n const [freezeSettledKey, setFreezeSettledKey] = useState<string>();\n\n useEffect(() => {\n if (!commentCids || !account) {\n return;\n }\n validator.validateUseCommentsArguments(commentCids, account);\n if (onlyIfCached) {\n return;\n }\n const uniqueCommentCids = new Set(commentCids);\n for (const commentCid of uniqueCommentCids) {\n addCommentToStore(commentCid, account).catch((error: unknown) =>\n log.error(\"useComments addCommentToStore error\", { commentCid, error }),\n );\n }\n }, [commentCidsKey, account?.id, onlyIfCached]);\n\n useEffect(() => {\n if (!commentCids || !account || onlyIfCached || !autoUpdate) {\n return;\n }\n\n const uniqueCommentCids = [...new Set(commentCids)];\n for (const commentCid of uniqueCommentCids) {\n startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account).catch(\n (error: unknown) =>\n log.error(\"useComments startCommentAutoUpdate error\", { commentCid, error }),\n );\n }\n\n return () => {\n for (const commentCid of uniqueCommentCids) {\n stopCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current).catch(\n (error: unknown) =>\n log.error(\"useComments stopCommentAutoUpdate error\", { commentCid, error }),\n );\n }\n };\n }, [commentCidsKey, account?.id, onlyIfCached, autoUpdate]);\n\n if (account && commentCids?.length) {\n log(\"useComments\", {\n commentCids,\n commentsStoreComments,\n commentsStore: useCommentsStore.getState().comments,\n account,\n });\n }\n\n // if comment from community pages exists and is fresher (or current missing), use it instead\n const liveComments = useMemo(() => {\n const result = [...commentsStoreComments];\n for (const i in result) {\n const candidate = communitiesPagesComments[i];\n if (candidate) result[i] = preferFresher(result[i], candidate);\n }\n return result;\n }, [commentsStoreComments, communitiesPagesComments]);\n\n const liveCommentsSettled = liveComments.every(\n (comment) => getCommentStateAndReplyCount(comment).state === \"succeeded\",\n );\n const freezeSettledForCurrentKey = freezeSettledKey === commentsKey;\n\n useEffect(() => {\n if (autoUpdate) {\n setFrozenComments([]);\n setFrozenCommentsKey(undefined);\n setFreezeSettledKey(undefined);\n return;\n }\n\n setFrozenComments([]);\n setFrozenCommentsKey(undefined);\n setFreezeSettledKey(undefined);\n }, [commentsKey, autoUpdate]);\n\n useEffect(() => {\n if (autoUpdate || freezeSettledForCurrentKey) {\n return;\n }\n\n setFrozenComments(liveComments);\n setFrozenCommentsKey(commentsKey);\n if (liveCommentsSettled) {\n setFreezeSettledKey(commentsKey);\n }\n }, [autoUpdate, commentsKey, freezeSettledForCurrentKey, liveComments, liveCommentsSettled]);\n\n const frozenCommentsForCurrentSelection =\n frozenCommentsKey === commentsKey ? frozenComments : undefined;\n const comments = autoUpdate ? liveComments : frozenCommentsForCurrentSelection || liveComments;\n const normalizedComments = useMemo(() => addCommentModerationToComments(comments), [comments]);\n\n // succeed if no comments are undefined\n const state = getCommentsState(normalizedComments);\n\n const refresh = useCallback(async () => {\n if (!account) {\n throw Error(\"useComments cannot refresh comments not initialized yet\");\n }\n const uniqueCommentCids = [...new Set(commentCids)];\n const refreshedComments = await Promise.all(\n uniqueCommentCids.map((commentCid) => refreshCommentInStore(commentCid, account)),\n );\n\n if (!autoUpdate && currentCommentsKeyRef.current === commentsKey) {\n const latestCommunitiesPagesComments = useCommunitiesPagesStore.getState().comments;\n const refreshedCommentsByCid = uniqueCommentCids.reduce(\n (\n refreshedCommentsMap: { [commentCid: string]: Comment | undefined },\n commentCid,\n index,\n ) => {\n refreshedCommentsMap[commentCid] = refreshedComments[index];\n return refreshedCommentsMap;\n },\n {},\n );\n setFrozenComments(\n commentCids.map((commentCid) =>\n preferFresher(\n refreshedCommentsByCid[commentCid || \"\"],\n latestCommunitiesPagesComments[commentCid || \"\"],\n ),\n ),\n );\n setFrozenCommentsKey(commentsKey);\n setFreezeSettledKey(commentsKey);\n }\n }, [account, autoUpdate, commentCids, commentsKey, refreshCommentInStore]);\n\n return useMemo(\n () => ({\n comments: normalizedComments,\n state,\n refresh,\n error: undefined,\n errors: [],\n }),\n [normalizedComments, commentsKey, refresh, state],\n );\n}\n\nexport function useValidateComment(options?: UseValidateCommentOptions): UseValidateCommentResult {\n assert(\n !options || typeof options === \"object\",\n `useValidateComment options argument '${options}' not an object`,\n );\n let { comment, validateReplies, accountName } = options ?? {};\n validateReplies = validateReplies ?? true;\n const [validated, setValidated] = useState<boolean | undefined>();\n const [errors] = useState([]);\n const account = useAccount({ accountName });\n\n useEffect(() => {\n if (!comment || !account?.pkc) {\n setValidated(undefined);\n return;\n }\n // don't automatically block community because what community it comes from\n // a malicious community could try to block other communities, etc\n const blockCommunity = false;\n commentIsValid(comment, { validateReplies, blockCommunity }, account.pkc).then((validated) =>\n setValidated(validated),\n );\n }, [comment, validateReplies, account?.pkc]);\n\n let state = \"initializing\";\n if (validated === true) {\n state = \"succeeded\";\n }\n if (validated === false) {\n state = \"failed\";\n }\n\n // start valid at true always because most of the time the value will be true and we dont want to cause a rerender\n let valid = true;\n if (validated == false) {\n valid = false;\n }\n // if comment isn't defined, it would be confusing for valid to be true\n if (!comment) {\n valid = false;\n }\n\n return useMemo(\n () => ({\n valid,\n state,\n error: errors[errors.length - 1],\n errors,\n }),\n [valid, state],\n );\n}\n"]}
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../src/hooks/comments.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { useAccount } from \"./accounts\";\nimport validator from \"../lib/validator\";\nimport Logger from \"@pkcprotocol/pkc-logger\";\nconst log = Logger(\"bitsocial-react-hooks:comments:hooks\");\nimport assert from \"assert\";\nimport {\n Comment,\n UseCommentsOptions,\n UseCommentsResult,\n UseCommentOptions,\n UseCommentResult,\n UseValidateCommentOptions,\n UseValidateCommentResult,\n} from \"../types\";\nimport useCommentsStore from \"../stores/comments\";\nimport useAccountsStore from \"../stores/accounts\";\nimport { commentIsValid } from \"../lib/utils\";\nimport {\n addCommentModeration,\n addCommentModerationToComments,\n} from \"../lib/utils/comment-moderation\";\nimport useCommunitiesPagesStore from \"../stores/communities-pages\";\nimport useRepliesPagesStore from \"../stores/replies-pages\";\nimport shallow from \"zustand/shallow\";\nimport { assertCommunityRef } from \"../lib/community-ref\";\n\nexport function getCommentFreshness(comment: Comment | undefined): number {\n if (!comment) return 0;\n return Math.max(comment.updatedAt ?? 0, comment.timestamp ?? 0, 0);\n}\n\nexport function preferFresher(\n current: Comment | undefined,\n candidate: Comment | undefined,\n): Comment | undefined {\n if (!candidate) return current;\n if (!current) return candidate;\n return getCommentFreshness(candidate) > getCommentFreshness(current) ? candidate : current;\n}\n\nconst getCommentStateAndReplyCount = (comment: Comment | undefined) => {\n let state = comment?.updatingState || \"initializing\";\n // force 'fetching-ipns' even if could be something else, so the frontend can use\n // the correct loading skeleton\n if (comment?.timestamp) {\n state = \"fetching-update-ipns\";\n }\n // force succeeded even if the comment is fecthing a new update\n if (comment?.updatedAt) {\n state = \"succeeded\";\n }\n\n // force succeeded if the comment is newer than 5 minutes, no need to display loading skeleton if comment was just created\n let replyCount = comment?.replyCount;\n if (\n comment?.replyCount === undefined &&\n comment?.timestamp &&\n comment?.timestamp > Date.now() / 1000 - 5 * 60\n ) {\n state = \"succeeded\";\n // set replyCount because some frontend are likely to check if replyCount === undefined to show a loading skeleton\n replyCount = 0;\n }\n\n return { state, replyCount };\n};\n\nconst getCommentsState = (comments: (Comment | undefined)[]) =>\n comments.every((comment) => getCommentStateAndReplyCount(comment).state === \"succeeded\")\n ? \"succeeded\"\n : \"fetching-ipfs\";\n\nlet commentAutoUpdateSubscriptionCount = 0;\nlet commentsAutoUpdateSubscriptionCount = 0;\n\nconst getCommentCreateCommentData = (\n commentCid: string | undefined,\n community: UseCommentOptions[\"community\"] | undefined,\n ...comments: (Comment | undefined)[]\n) => {\n if (!commentCid) {\n return undefined;\n }\n\n const createCommentData: Comment = { cid: commentCid };\n let hasCommunityData = false;\n for (const comment of comments) {\n if (!comment) {\n continue;\n }\n if (!createCommentData.communityPublicKey && comment.communityPublicKey) {\n createCommentData.communityPublicKey = comment.communityPublicKey;\n hasCommunityData = true;\n }\n if (!createCommentData.communityName && comment.communityName) {\n createCommentData.communityName = comment.communityName;\n hasCommunityData = true;\n }\n }\n\n if (community?.publicKey) {\n createCommentData.communityPublicKey = community.publicKey;\n hasCommunityData = true;\n }\n if (community?.name) {\n createCommentData.communityName = community.name;\n hasCommunityData = true;\n }\n\n return hasCommunityData ? createCommentData : undefined;\n};\n\n/**\n * @param commentCid - The IPFS CID of the comment to get\n * @param community - The community identifier, e.g. {name: 'memes.eth', publicKey: '12D3KooW...'}.\n * @param acountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, use\n * the active account.\n */\nexport function useComment(options?: UseCommentOptions): UseCommentResult {\n assert(\n !options || typeof options === \"object\",\n `useComment options argument '${options}' not an object`,\n );\n const { commentCid, community, accountName, onlyIfCached, autoUpdate = true } = options ?? {};\n if (community !== undefined) {\n assertCommunityRef(community, \"useComment community\");\n }\n const account = useAccount({ accountName });\n const commentFromStore = useCommentsStore((state: any) => state.comments[commentCid || \"\"]);\n const addCommentToStore = useCommentsStore((state: any) => state.addCommentToStore);\n const startCommentAutoUpdate = useCommentsStore((state: any) => state.startCommentAutoUpdate);\n const stopCommentAutoUpdate = useCommentsStore((state: any) => state.stopCommentAutoUpdate);\n const refreshCommentInStore = useCommentsStore((state: any) => state.refreshComment);\n const communitiesPagesComment = useCommunitiesPagesStore(\n (state: any) => state.comments[commentCid || \"\"],\n );\n const repliesPagesComment = useRepliesPagesStore(\n (state: any) => state.comments[commentCid || \"\"],\n );\n const errors = useCommentsStore((state: any) => state.errors[commentCid || \"\"]);\n\n // get account comment of the cid if any\n const accountCommentInfo = useAccountsStore(\n (state: any) => state.commentCidsToAccountsComments[commentCid || \"\"],\n );\n const accountComment = useAccountsStore(\n (state: any) =>\n state.accountsComments[accountCommentInfo?.accountId || \"\"]?.[\n Number(accountCommentInfo?.accountCommentIndex)\n ],\n );\n const createCommentData = useMemo(\n () =>\n getCommentCreateCommentData(\n commentCid,\n community,\n communitiesPagesComment,\n repliesPagesComment,\n ),\n [\n commentCid,\n community?.name,\n community?.publicKey,\n communitiesPagesComment?.communityName,\n communitiesPagesComment?.communityPublicKey,\n repliesPagesComment?.communityName,\n repliesPagesComment?.communityPublicKey,\n ],\n );\n const autoUpdateSubscriptionId = useRef(`useComment-${++commentAutoUpdateSubscriptionCount}`);\n const currentCommentCidRef = useRef<string | undefined>(commentCid);\n currentCommentCidRef.current = commentCid;\n const [frozenComment, setFrozenComment] = useState<Comment | undefined>();\n const [freezeSettledCid, setFreezeSettledCid] = useState<string>();\n\n useEffect(() => {\n if (!commentCid || !account) {\n return;\n }\n validator.validateUseCommentArguments(commentCid, account);\n if (!commentFromStore && !onlyIfCached) {\n // if comment isn't already in store, add it\n const addCommentPromise = createCommentData\n ? addCommentToStore(commentCid, account, createCommentData)\n : addCommentToStore(commentCid, account);\n addCommentPromise.catch((error: unknown) =>\n log.error(\"useComment addCommentToStore error\", { commentCid, error }),\n );\n }\n }, [commentCid, account?.id, onlyIfCached, createCommentData]);\n\n useEffect(() => {\n if (!commentCid || !account || onlyIfCached || !autoUpdate) {\n return;\n }\n\n const startAutoUpdatePromise = createCommentData\n ? startCommentAutoUpdate(\n commentCid,\n autoUpdateSubscriptionId.current,\n account,\n createCommentData,\n )\n : startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account);\n startAutoUpdatePromise.catch((error: unknown) =>\n log.error(\"useComment startCommentAutoUpdate error\", { commentCid, error }),\n );\n\n return () => {\n stopCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current).catch((error: unknown) =>\n log.error(\"useComment stopCommentAutoUpdate error\", { commentCid, error }),\n );\n };\n }, [commentCid, account?.id, onlyIfCached, autoUpdate, createCommentData]);\n\n let selectedComment = commentFromStore;\n\n if (commentCid && communitiesPagesComment) {\n selectedComment = preferFresher(selectedComment, communitiesPagesComment);\n }\n if (commentCid && repliesPagesComment) {\n selectedComment = preferFresher(selectedComment, repliesPagesComment);\n }\n\n // if comment is still not defined, but account comment is, use account comment\n // check `comment.timestamp` instead of `comment` in case comment exists but in a loading state\n const commentFromStoreNotLoaded = !selectedComment?.timestamp;\n if (commentCid && commentFromStoreNotLoaded && accountComment) {\n selectedComment = accountComment;\n }\n\n const selectedCommentState = getCommentStateAndReplyCount(selectedComment).state;\n const freezeSettledForCurrentCid = freezeSettledCid === commentCid;\n\n useEffect(() => {\n if (autoUpdate) {\n setFrozenComment(undefined);\n setFreezeSettledCid(undefined);\n return;\n }\n\n setFrozenComment(undefined);\n setFreezeSettledCid(undefined);\n }, [commentCid, autoUpdate]);\n\n useEffect(() => {\n if (autoUpdate) {\n return;\n }\n if (!commentCid) {\n setFrozenComment(undefined);\n setFreezeSettledCid(undefined);\n return;\n }\n if (freezeSettledForCurrentCid || !selectedComment) {\n return;\n }\n\n setFrozenComment(selectedComment);\n if (selectedCommentState === \"succeeded\") {\n setFreezeSettledCid(commentCid);\n }\n }, [autoUpdate, commentCid, selectedComment, selectedCommentState, freezeSettledForCurrentCid]);\n\n const frozenCommentForCurrentCid = frozenComment?.cid === commentCid ? frozenComment : undefined;\n let comment = autoUpdate\n ? selectedComment\n : freezeSettledForCurrentCid\n ? frozenCommentForCurrentCid\n : frozenCommentForCurrentCid || selectedComment;\n comment = addCommentModeration(comment);\n\n const { state, replyCount } = getCommentStateAndReplyCount(comment);\n\n if (account && commentCid) {\n log(\"useComment\", {\n commentCid,\n comment,\n replyCount,\n state,\n commentFromStore,\n communitiesPagesComment,\n repliesPagesComment,\n accountComment,\n commentsStore: useCommentsStore.getState().comments,\n account,\n onlyIfCached,\n autoUpdate,\n });\n }\n\n const refresh = useCallback(async () => {\n if (!commentCid || !account) {\n throw Error(\"useComment cannot refresh comment not initialized yet\");\n }\n\n const refreshCommentCid = commentCid;\n const refreshedComment = createCommentData\n ? await refreshCommentInStore(refreshCommentCid, account, createCommentData)\n : await refreshCommentInStore(refreshCommentCid, account);\n if (!autoUpdate && refreshedComment && currentCommentCidRef.current === refreshCommentCid) {\n setFrozenComment(refreshedComment);\n setFreezeSettledCid(refreshCommentCid);\n }\n }, [account, autoUpdate, commentCid, createCommentData, refreshCommentInStore]);\n\n return useMemo(\n () => ({\n ...comment,\n replyCount,\n state,\n refresh,\n error: errors?.[errors.length - 1],\n errors: errors || [],\n }),\n [comment, commentCid, errors, refresh, state, replyCount],\n );\n}\n\n/**\n * @param commentCids - The IPFS CIDs of the comments to get\n * @param acountName - The nickname of the account, e.g. 'Account 1'. If no accountName is provided, use\n * the active account.\n */\nexport function useComments(options?: UseCommentsOptions): UseCommentsResult {\n assert(\n !options || typeof options === \"object\",\n `useComments options argument '${options}' not an object`,\n );\n const { commentCids = [], accountName, onlyIfCached, autoUpdate = true } = options ?? {};\n const account = useAccount({ accountName });\n const commentsStoreComments: (Comment | undefined)[] = useCommentsStore(\n (state: any) => commentCids.map((commentCid) => state.comments[commentCid || \"\"]),\n shallow,\n );\n const communitiesPagesComments: (Comment | undefined)[] = useCommunitiesPagesStore(\n (state: any) => commentCids.map((commentCid) => state.comments[commentCid || \"\"]),\n shallow,\n );\n\n const addCommentToStore = useCommentsStore((state: any) => state.addCommentToStore);\n const startCommentAutoUpdate = useCommentsStore((state: any) => state.startCommentAutoUpdate);\n const stopCommentAutoUpdate = useCommentsStore((state: any) => state.stopCommentAutoUpdate);\n const refreshCommentInStore = useCommentsStore((state: any) => state.refreshComment);\n const autoUpdateSubscriptionId = useRef(`useComments-${++commentsAutoUpdateSubscriptionCount}`);\n const commentCidsKey = JSON.stringify(commentCids);\n const commentsKey = `${account?.id || \"\"}:${commentCidsKey}`;\n const currentCommentsKeyRef = useRef(commentsKey);\n currentCommentsKeyRef.current = commentsKey;\n const [frozenComments, setFrozenComments] = useState<(Comment | undefined)[]>([]);\n const [frozenCommentsKey, setFrozenCommentsKey] = useState<string>();\n const [freezeSettledKey, setFreezeSettledKey] = useState<string>();\n\n useEffect(() => {\n if (!commentCids || !account) {\n return;\n }\n validator.validateUseCommentsArguments(commentCids, account);\n if (onlyIfCached) {\n return;\n }\n const uniqueCommentCids = new Set(commentCids);\n for (const commentCid of uniqueCommentCids) {\n addCommentToStore(commentCid, account).catch((error: unknown) =>\n log.error(\"useComments addCommentToStore error\", { commentCid, error }),\n );\n }\n }, [commentCidsKey, account?.id, onlyIfCached]);\n\n useEffect(() => {\n if (!commentCids || !account || onlyIfCached || !autoUpdate) {\n return;\n }\n\n const uniqueCommentCids = [...new Set(commentCids)];\n for (const commentCid of uniqueCommentCids) {\n startCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current, account).catch(\n (error: unknown) =>\n log.error(\"useComments startCommentAutoUpdate error\", { commentCid, error }),\n );\n }\n\n return () => {\n for (const commentCid of uniqueCommentCids) {\n stopCommentAutoUpdate(commentCid, autoUpdateSubscriptionId.current).catch(\n (error: unknown) =>\n log.error(\"useComments stopCommentAutoUpdate error\", { commentCid, error }),\n );\n }\n };\n }, [commentCidsKey, account?.id, onlyIfCached, autoUpdate]);\n\n if (account && commentCids?.length) {\n log(\"useComments\", {\n commentCids,\n commentsStoreComments,\n commentsStore: useCommentsStore.getState().comments,\n account,\n });\n }\n\n // if comment from community pages exists and is fresher (or current missing), use it instead\n const liveComments = useMemo(() => {\n const result = [...commentsStoreComments];\n for (const i in result) {\n const candidate = communitiesPagesComments[i];\n if (candidate) result[i] = preferFresher(result[i], candidate);\n }\n return result;\n }, [commentsStoreComments, communitiesPagesComments]);\n\n const liveCommentsSettled = liveComments.every(\n (comment) => getCommentStateAndReplyCount(comment).state === \"succeeded\",\n );\n const freezeSettledForCurrentKey = freezeSettledKey === commentsKey;\n\n useEffect(() => {\n if (autoUpdate) {\n setFrozenComments([]);\n setFrozenCommentsKey(undefined);\n setFreezeSettledKey(undefined);\n return;\n }\n\n setFrozenComments([]);\n setFrozenCommentsKey(undefined);\n setFreezeSettledKey(undefined);\n }, [commentsKey, autoUpdate]);\n\n useEffect(() => {\n if (autoUpdate || freezeSettledForCurrentKey) {\n return;\n }\n\n setFrozenComments(liveComments);\n setFrozenCommentsKey(commentsKey);\n if (liveCommentsSettled) {\n setFreezeSettledKey(commentsKey);\n }\n }, [autoUpdate, commentsKey, freezeSettledForCurrentKey, liveComments, liveCommentsSettled]);\n\n const frozenCommentsForCurrentSelection =\n frozenCommentsKey === commentsKey ? frozenComments : undefined;\n const comments = autoUpdate ? liveComments : frozenCommentsForCurrentSelection || liveComments;\n const normalizedComments = useMemo(() => addCommentModerationToComments(comments), [comments]);\n\n // succeed if no comments are undefined\n const state = getCommentsState(normalizedComments);\n\n const refresh = useCallback(async () => {\n if (!account) {\n throw Error(\"useComments cannot refresh comments not initialized yet\");\n }\n const uniqueCommentCids = [...new Set(commentCids)];\n const refreshedComments = await Promise.all(\n uniqueCommentCids.map((commentCid) => refreshCommentInStore(commentCid, account)),\n );\n\n if (!autoUpdate && currentCommentsKeyRef.current === commentsKey) {\n const latestCommunitiesPagesComments = useCommunitiesPagesStore.getState().comments;\n const refreshedCommentsByCid = uniqueCommentCids.reduce(\n (\n refreshedCommentsMap: { [commentCid: string]: Comment | undefined },\n commentCid,\n index,\n ) => {\n refreshedCommentsMap[commentCid] = refreshedComments[index];\n return refreshedCommentsMap;\n },\n {},\n );\n setFrozenComments(\n commentCids.map((commentCid) =>\n preferFresher(\n refreshedCommentsByCid[commentCid || \"\"],\n latestCommunitiesPagesComments[commentCid || \"\"],\n ),\n ),\n );\n setFrozenCommentsKey(commentsKey);\n setFreezeSettledKey(commentsKey);\n }\n }, [account, autoUpdate, commentCids, commentsKey, refreshCommentInStore]);\n\n return useMemo(\n () => ({\n comments: normalizedComments,\n state,\n refresh,\n error: undefined,\n errors: [],\n }),\n [normalizedComments, commentsKey, refresh, state],\n );\n}\n\nexport function useValidateComment(options?: UseValidateCommentOptions): UseValidateCommentResult {\n assert(\n !options || typeof options === \"object\",\n `useValidateComment options argument '${options}' not an object`,\n );\n let { comment, validateReplies, accountName } = options ?? {};\n validateReplies = validateReplies ?? true;\n const [validated, setValidated] = useState<boolean | undefined>();\n const [errors] = useState([]);\n const account = useAccount({ accountName });\n\n useEffect(() => {\n if (!comment || !account?.pkc) {\n setValidated(undefined);\n return;\n }\n // don't automatically block community because what community it comes from\n // a malicious community could try to block other communities, etc\n const blockCommunity = false;\n commentIsValid(comment, { validateReplies, blockCommunity }, account.pkc).then((validated) =>\n setValidated(validated),\n );\n }, [comment, validateReplies, account?.pkc]);\n\n let state = \"initializing\";\n if (validated === true) {\n state = \"succeeded\";\n }\n if (validated === false) {\n state = \"failed\";\n }\n\n // start valid at true always because most of the time the value will be true and we dont want to cause a rerender\n let valid = true;\n if (validated == false) {\n valid = false;\n }\n // if comment isn't defined, it would be confusing for valid to be true\n if (!comment) {\n valid = false;\n }\n\n return useMemo(\n () => ({\n valid,\n state,\n error: errors[errors.length - 1],\n errors,\n }),\n [valid, state],\n );\n}\n"]}
@@ -1,6 +1,8 @@
1
- declare function renderHook<Result, Props>(callback: (props: Props) => Result, options?: {
1
+ type RenderHookOptions<Props> = {
2
2
  initialProps?: Props;
3
- }): {
3
+ trackHistory?: boolean;
4
+ };
5
+ declare function renderHook<Result, Props>(callback: (props: Props) => Result, options?: RenderHookOptions<Props>): {
4
6
  result: {
5
7
  current: Result | null;
6
8
  all: Result[];
@@ -22,7 +24,14 @@ declare const testUtils: {
22
24
  resetStores: () => Promise<void>;
23
25
  resetDatabasesAndStores: () => Promise<void>;
24
26
  createWaitFor: (rendered: any, waitForOptions?: WaitForOptions) => (waitForFunction: Function) => Promise<void>;
25
- renderHookWithHistory: typeof renderHook;
27
+ renderHookWithHistory: <Result, Props>(callback: (props: Props) => Result, options?: RenderHookOptions<Props>) => {
28
+ result: {
29
+ current: Result | null;
30
+ all: Result[];
31
+ };
32
+ rerender: (rerenderCallbackProps: Props) => void;
33
+ unmount: () => void;
34
+ };
26
35
  silenceWaitForWarning: boolean;
27
36
  };
28
37
  export default testUtils;
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/lib/test-utils.ts"],"names":[],"mappings":"AAqBA,iBAAS,UAAU,CAAC,MAAM,EAAE,KAAK,EAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,EAClC,OAAO,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE;;iBAGA,MAAM,GAAG,IAAI;aAAa,MAAM,EAAE;;sCAc3B,KAAK;;EAO/C;AA6DD,KAAK,cAAc,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAsEF,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,QAAA,MAAM,SAAS;;;;;;;;8BAvEkB,GAAG,mBAAmB,cAAc,uBAI3B,QAAQ;;;CA+EjD,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/lib/test-utils.ts"],"names":[],"mappings":"AAiBA,KAAK,iBAAiB,CAAC,KAAK,IAAI;IAC9B,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAMF,iBAAS,UAAU,CAAC,MAAM,EAAE,KAAK,EAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,EAClC,OAAO,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC;;iBAGA,MAAM,GAAG,IAAI;aAAa,MAAM,EAAE;;sCAgB3B,KAAK;;EAO/C;AA6DD,KAAK,cAAc,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAuEF,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,QAAA,MAAM,SAAS;;;;;;;;8BAxEkB,GAAG,mBAAmB,cAAc,uBAI3B,QAAQ;4BA6DnB,MAAM,EAAE,KAAK,YAChC,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,YACxB,iBAAiB,CAAC,KAAK,CAAC;;;;;;;;;CAiBnC,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -33,12 +33,14 @@ import { resetRepliesPagesStore, resetRepliesPagesDatabaseAndStore } from "../st
33
33
  // result.current via useEffect, which breaks polling-based waitFor patterns
34
34
  // when Zustand store updates trigger re-renders outside act().
35
35
  function renderHook(callback, options) {
36
- const _a = options || {}, { initialProps } = _a, renderOptions = __rest(_a, ["initialProps"]);
36
+ const _a = options || {}, { initialProps, trackHistory = false } = _a, renderOptions = __rest(_a, ["initialProps", "trackHistory"]);
37
37
  const result = { current: null, all: [] };
38
38
  function TestComponent({ renderCallbackProps }) {
39
39
  const pendingResult = callback(renderCallbackProps);
40
40
  result.current = pendingResult;
41
- result.all.push(pendingResult);
41
+ if (trackHistory) {
42
+ result.all.push(pendingResult);
43
+ }
42
44
  return null;
43
45
  }
44
46
  const { rerender: baseRerender, unmount } = render(React.createElement(TestComponent, { renderCallbackProps: initialProps }), renderOptions);
@@ -163,9 +165,7 @@ const resetDatabasesAndStores = () => __awaiter(void 0, void 0, void 0, function
163
165
  // always accounts last because it has async initialization
164
166
  yield resetAccountsDatabaseAndStore();
165
167
  });
166
- // renderHookWithHistory is kept for backward compatibility but our custom
167
- // renderHook already tracks result.all, so this is just a passthrough.
168
- const renderHookWithHistory = renderHook;
168
+ const renderHookWithHistory = (callback, options) => renderHook(callback, Object.assign(Object.assign({}, options), { trackHistory: true }));
169
169
  export { renderHook };
170
170
  const testUtils = {
171
171
  silenceTestWasNotWrappedInActWarning,
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/lib/test-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { render, act as tlAct } from \"@testing-library/react\";\nimport React from \"react\";\nimport { resetCommentsStore, resetCommentsDatabaseAndStore } from \"../stores/comments\";\nimport { resetCommunitiesStore, resetCommunitiesDatabaseAndStore } from \"../stores/communities\";\nimport { resetAccountsStore, resetAccountsDatabaseAndStore } from \"../stores/accounts\";\nimport { resetFeedsStore, resetFeedsDatabaseAndStore } from \"../stores/feeds\";\nimport {\n resetCommunitiesPagesStore,\n resetCommunitiesPagesDatabaseAndStore,\n} from \"../stores/communities-pages\";\nimport {\n resetAuthorsCommentsStore,\n resetAuthorsCommentsDatabaseAndStore,\n} from \"../stores/authors-comments\";\nimport { resetRepliesStore, resetRepliesDatabaseAndStore } from \"../stores/replies\";\nimport { resetRepliesPagesStore, resetRepliesPagesDatabaseAndStore } from \"../stores/replies-pages\";\n\n// Custom renderHook that sets result.current synchronously during render,\n// matching @testing-library/react-hooks behavior. RTL v16's renderHook defers\n// result.current via useEffect, which breaks polling-based waitFor patterns\n// when Zustand store updates trigger re-renders outside act().\nfunction renderHook<Result, Props>(\n callback: (props: Props) => Result,\n options?: { initialProps?: Props },\n) {\n const { initialProps, ...renderOptions } = options || {};\n const result = { current: null as Result | null, all: [] as Result[] };\n\n function TestComponent({ renderCallbackProps }: { renderCallbackProps: Props }) {\n const pendingResult = callback(renderCallbackProps);\n result.current = pendingResult;\n result.all.push(pendingResult);\n return null;\n }\n\n const { rerender: baseRerender, unmount } = render(\n React.createElement(TestComponent, { renderCallbackProps: initialProps as Props }),\n renderOptions as any,\n );\n\n function rerender(rerenderCallbackProps: Props) {\n return baseRerender(\n React.createElement(TestComponent, { renderCallbackProps: rerenderCallbackProps }),\n );\n }\n\n return { result, rerender, unmount };\n}\n\nconst restorables: any = [];\n\nconst silenceUpdateUnmountedComponentWarning = () => {\n const originalError = console.error;\n console.error = (...args) => {\n if (/Can't perform a React state update on an unmounted component/.test(args[0])) {\n return;\n }\n originalError.call(console, ...args);\n };\n const restore = () => {\n console.error = originalError;\n };\n restorables.push(restore);\n return restore;\n};\n\nconst silenceTestWasNotWrappedInActWarning = () => {\n const originalError = console.error;\n console.error = (...args) => {\n if (/inside a test was not wrapped in act/.test(args[0])) {\n return;\n }\n originalError.call(console, ...args);\n };\n const restore = () => {\n console.error = originalError;\n };\n restorables.push(restore);\n return restore;\n};\n\n// this warning is usually good to have, so don't include it in silenceReactWarnings\nconst silenceOverlappingActWarning = () => {\n const originalError = console.error;\n console.error = (...args) => {\n if (/overlapping act\\(\\) calls/.test(args[0])) {\n return;\n }\n originalError.call(console, ...args);\n };\n const restore = () => {\n console.error = originalError;\n };\n restorables.push(restore);\n return restore;\n};\n\nconst silenceReactWarnings = () => {\n silenceUpdateUnmountedComponentWarning();\n silenceTestWasNotWrappedInActWarning();\n};\n\nconst restoreAll = () => {\n for (const restore of restorables) {\n restore();\n }\n};\n\ntype WaitForOptions = {\n timeout?: number;\n interval?: number;\n};\nconst createWaitFor = (rendered: any, waitForOptions?: WaitForOptions) => {\n if (!rendered?.result) {\n throw Error(`createWaitFor invalid 'rendered' argument`);\n }\n const waitFor = async (waitForFunction: Function) => {\n const stackTraceLimit = Error.stackTraceLimit;\n Error.stackTraceLimit = 10;\n const errorWithUsefulStackTrace = new Error(\"waitFor\");\n Error.stackTraceLimit = stackTraceLimit;\n\n if (typeof waitForFunction !== \"function\") {\n throw Error(`waitFor invalid 'waitForFunction' argument`);\n }\n // @ts-ignore\n if (typeof waitForFunction.then === \"function\") {\n throw Error(`waitFor 'waitForFunction' can't be async`);\n }\n const { timeout = 2000, interval = 50 } = waitForOptions || {};\n const start = Date.now();\n while (true) {\n // flush pending React/Zustand state updates before each check\n await tlAct(async () => {});\n try {\n if (waitForFunction()) return;\n } catch {\n // condition threw (e.g. accessing property on undefined), keep waiting\n }\n if (Date.now() - start >= timeout) {\n errorWithUsefulStackTrace.message = `Timed out in waitFor after ${timeout}ms. ${waitForFunction.toString()}`;\n if (!testUtils.silenceWaitForWarning) {\n console.warn(errorWithUsefulStackTrace);\n }\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n };\n return waitFor;\n};\n\n// always reset the least important store first, because a store even can affect another store\nconst resetStores = async () => {\n await resetRepliesPagesStore();\n await resetRepliesStore();\n await resetAuthorsCommentsStore();\n await resetCommunitiesPagesStore();\n await resetFeedsStore();\n await resetCommunitiesStore();\n await resetCommentsStore();\n // always accounts last because it has async initialization\n await resetAccountsStore();\n};\n\nconst resetDatabasesAndStores = async () => {\n await resetRepliesPagesDatabaseAndStore();\n await resetRepliesDatabaseAndStore();\n await resetAuthorsCommentsDatabaseAndStore();\n await resetCommunitiesPagesDatabaseAndStore();\n await resetFeedsDatabaseAndStore();\n await resetCommunitiesDatabaseAndStore();\n await resetCommentsDatabaseAndStore();\n // always accounts last because it has async initialization\n await resetAccountsDatabaseAndStore();\n};\n\n// renderHookWithHistory is kept for backward compatibility but our custom\n// renderHook already tracks result.all, so this is just a passthrough.\nconst renderHookWithHistory = renderHook;\n\nexport { renderHook };\n\nconst testUtils = {\n silenceTestWasNotWrappedInActWarning,\n silenceUpdateUnmountedComponentWarning,\n silenceOverlappingActWarning,\n silenceReactWarnings,\n restoreAll,\n resetStores,\n resetDatabasesAndStores,\n createWaitFor,\n renderHookWithHistory,\n // can be useful to silence warnings in tests that use retry\n silenceWaitForWarning: false,\n};\n\nexport default testUtils;\n"]}
1
+ {"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/lib/test-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { render, act as tlAct } from \"@testing-library/react\";\nimport React from \"react\";\nimport { resetCommentsStore, resetCommentsDatabaseAndStore } from \"../stores/comments\";\nimport { resetCommunitiesStore, resetCommunitiesDatabaseAndStore } from \"../stores/communities\";\nimport { resetAccountsStore, resetAccountsDatabaseAndStore } from \"../stores/accounts\";\nimport { resetFeedsStore, resetFeedsDatabaseAndStore } from \"../stores/feeds\";\nimport {\n resetCommunitiesPagesStore,\n resetCommunitiesPagesDatabaseAndStore,\n} from \"../stores/communities-pages\";\nimport {\n resetAuthorsCommentsStore,\n resetAuthorsCommentsDatabaseAndStore,\n} from \"../stores/authors-comments\";\nimport { resetRepliesStore, resetRepliesDatabaseAndStore } from \"../stores/replies\";\nimport { resetRepliesPagesStore, resetRepliesPagesDatabaseAndStore } from \"../stores/replies-pages\";\n\ntype RenderHookOptions<Props> = {\n initialProps?: Props;\n trackHistory?: boolean;\n};\n\n// Custom renderHook that sets result.current synchronously during render,\n// matching @testing-library/react-hooks behavior. RTL v16's renderHook defers\n// result.current via useEffect, which breaks polling-based waitFor patterns\n// when Zustand store updates trigger re-renders outside act().\nfunction renderHook<Result, Props>(\n callback: (props: Props) => Result,\n options?: RenderHookOptions<Props>,\n) {\n const { initialProps, trackHistory = false, ...renderOptions } = options || {};\n const result = { current: null as Result | null, all: [] as Result[] };\n\n function TestComponent({ renderCallbackProps }: { renderCallbackProps: Props }) {\n const pendingResult = callback(renderCallbackProps);\n result.current = pendingResult;\n if (trackHistory) {\n result.all.push(pendingResult);\n }\n return null;\n }\n\n const { rerender: baseRerender, unmount } = render(\n React.createElement(TestComponent, { renderCallbackProps: initialProps as Props }),\n renderOptions as any,\n );\n\n function rerender(rerenderCallbackProps: Props) {\n return baseRerender(\n React.createElement(TestComponent, { renderCallbackProps: rerenderCallbackProps }),\n );\n }\n\n return { result, rerender, unmount };\n}\n\nconst restorables: any = [];\n\nconst silenceUpdateUnmountedComponentWarning = () => {\n const originalError = console.error;\n console.error = (...args) => {\n if (/Can't perform a React state update on an unmounted component/.test(args[0])) {\n return;\n }\n originalError.call(console, ...args);\n };\n const restore = () => {\n console.error = originalError;\n };\n restorables.push(restore);\n return restore;\n};\n\nconst silenceTestWasNotWrappedInActWarning = () => {\n const originalError = console.error;\n console.error = (...args) => {\n if (/inside a test was not wrapped in act/.test(args[0])) {\n return;\n }\n originalError.call(console, ...args);\n };\n const restore = () => {\n console.error = originalError;\n };\n restorables.push(restore);\n return restore;\n};\n\n// this warning is usually good to have, so don't include it in silenceReactWarnings\nconst silenceOverlappingActWarning = () => {\n const originalError = console.error;\n console.error = (...args) => {\n if (/overlapping act\\(\\) calls/.test(args[0])) {\n return;\n }\n originalError.call(console, ...args);\n };\n const restore = () => {\n console.error = originalError;\n };\n restorables.push(restore);\n return restore;\n};\n\nconst silenceReactWarnings = () => {\n silenceUpdateUnmountedComponentWarning();\n silenceTestWasNotWrappedInActWarning();\n};\n\nconst restoreAll = () => {\n for (const restore of restorables) {\n restore();\n }\n};\n\ntype WaitForOptions = {\n timeout?: number;\n interval?: number;\n};\nconst createWaitFor = (rendered: any, waitForOptions?: WaitForOptions) => {\n if (!rendered?.result) {\n throw Error(`createWaitFor invalid 'rendered' argument`);\n }\n const waitFor = async (waitForFunction: Function) => {\n const stackTraceLimit = Error.stackTraceLimit;\n Error.stackTraceLimit = 10;\n const errorWithUsefulStackTrace = new Error(\"waitFor\");\n Error.stackTraceLimit = stackTraceLimit;\n\n if (typeof waitForFunction !== \"function\") {\n throw Error(`waitFor invalid 'waitForFunction' argument`);\n }\n // @ts-ignore\n if (typeof waitForFunction.then === \"function\") {\n throw Error(`waitFor 'waitForFunction' can't be async`);\n }\n const { timeout = 2000, interval = 50 } = waitForOptions || {};\n const start = Date.now();\n while (true) {\n // flush pending React/Zustand state updates before each check\n await tlAct(async () => {});\n try {\n if (waitForFunction()) return;\n } catch {\n // condition threw (e.g. accessing property on undefined), keep waiting\n }\n if (Date.now() - start >= timeout) {\n errorWithUsefulStackTrace.message = `Timed out in waitFor after ${timeout}ms. ${waitForFunction.toString()}`;\n if (!testUtils.silenceWaitForWarning) {\n console.warn(errorWithUsefulStackTrace);\n }\n return;\n }\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n };\n return waitFor;\n};\n\n// always reset the least important store first, because a store even can affect another store\nconst resetStores = async () => {\n await resetRepliesPagesStore();\n await resetRepliesStore();\n await resetAuthorsCommentsStore();\n await resetCommunitiesPagesStore();\n await resetFeedsStore();\n await resetCommunitiesStore();\n await resetCommentsStore();\n // always accounts last because it has async initialization\n await resetAccountsStore();\n};\n\nconst resetDatabasesAndStores = async () => {\n await resetRepliesPagesDatabaseAndStore();\n await resetRepliesDatabaseAndStore();\n await resetAuthorsCommentsDatabaseAndStore();\n await resetCommunitiesPagesDatabaseAndStore();\n await resetFeedsDatabaseAndStore();\n await resetCommunitiesDatabaseAndStore();\n await resetCommentsDatabaseAndStore();\n // always accounts last because it has async initialization\n await resetAccountsDatabaseAndStore();\n};\n\nconst renderHookWithHistory = <Result, Props>(\n callback: (props: Props) => Result,\n options?: RenderHookOptions<Props>,\n) => renderHook(callback, { ...options, trackHistory: true });\n\nexport { renderHook };\n\nconst testUtils = {\n silenceTestWasNotWrappedInActWarning,\n silenceUpdateUnmountedComponentWarning,\n silenceOverlappingActWarning,\n silenceReactWarnings,\n restoreAll,\n resetStores,\n resetDatabasesAndStores,\n createWaitFor,\n renderHookWithHistory,\n // can be useful to silence warnings in tests that use retry\n silenceWaitForWarning: false,\n};\n\nexport default testUtils;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"comments-store.d.ts","sourceRoot":"","sources":["../../../src/stores/comments/comments-store.ts"],"names":[],"mappings":"AAKA,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,eAAO,MAAM,GAAG,QAAkD,CAAC;AACnE,OAAO,EAAW,QAAQ,EAAW,MAAM,aAAa,CAAC;AAkBzD,eAAO,MAAM,SAAS,EAAE,GAAQ,CAAC;AAEjC,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,EAAE,CAAA;KAAE,CAAC;IAC1C,iBAAiB,EAAE,QAAQ,CAAC;IAC5B,sBAAsB,EAAE,QAAQ,CAAC;IACjC,qBAAqB,EAAE,QAAQ,CAAC;IAChC,cAAc,EAAE,QAAQ,CAAC;CAC1B,CAAC;AAyCF,QAAA,MAAM,aAAa,4EAkUjB,CAAC;AAsBH,eAAO,MAAM,kBAAkB,qBAgC9B,CAAC;AAGF,eAAO,MAAM,6BAA6B,qBAGzC,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"comments-store.d.ts","sourceRoot":"","sources":["../../../src/stores/comments/comments-store.ts"],"names":[],"mappings":"AAKA,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,eAAO,MAAM,GAAG,QAAkD,CAAC;AACnE,OAAO,EAAW,QAAQ,EAAW,MAAM,aAAa,CAAC;AAkBzD,eAAO,MAAM,SAAS,EAAE,GAAQ,CAAC;AAEjC,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,KAAK,EAAE,CAAA;KAAE,CAAC;IAC1C,iBAAiB,EAAE,QAAQ,CAAC;IAC5B,sBAAsB,EAAE,QAAQ,CAAC;IACjC,qBAAqB,EAAE,QAAQ,CAAC;IAChC,cAAc,EAAE,QAAQ,CAAC;CAC1B,CAAC;AAuDF,QAAA,MAAM,aAAa,4EA2UjB,CAAC;AA8BH,eAAO,MAAM,kBAAkB,qBAgC9B,CAAC;AAGF,eAAO,MAAM,6BAA6B,qBAGzC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -39,6 +39,16 @@ const removeCommentListener = (comment, event, listener) => {
39
39
  };
40
40
  const getCommentAutoUpdateSubscribersCount = (commentCid) => Object.keys(commentAutoUpdateSubscribers[commentCid] || {}).length;
41
41
  const hasCommentAutoUpdateSubscribers = (commentCid) => getCommentAutoUpdateSubscribersCount(commentCid) > 0;
42
+ const mergeCommentData = (commentCid, ...commentDataList) => {
43
+ const mergedCommentData = { cid: commentCid };
44
+ for (const commentData of commentDataList) {
45
+ if (commentData && typeof commentData === "object") {
46
+ Object.assign(mergedCommentData, utils.clone(commentData));
47
+ }
48
+ }
49
+ mergedCommentData.cid = commentCid;
50
+ return mergedCommentData;
51
+ };
42
52
  const releaseLiveComment = (commentCid, comment) => {
43
53
  const liveComment = comment || liveComments[commentCid];
44
54
  if (liveComment) {
@@ -172,8 +182,7 @@ const commentsStore = createStore((setState, getState) => {
172
182
  return liveCommentPromises[commentCid];
173
183
  }
174
184
  const liveCommentPromise = (() => __awaiter(void 0, void 0, void 0, function* () {
175
- const initialComment = normalizeCommentCommunityAddress(utils.clone(commentData || { cid: commentCid })) ||
176
- { cid: commentCid };
185
+ const initialComment = normalizeCommentCommunityAddress(mergeCommentData(commentCid, commentData));
177
186
  const liveComment = normalizeCommentCommunityAddress(yield account.pkc.createComment(initialComment));
178
187
  initializeComment(commentCid, liveComment, account);
179
188
  return liveComment;
@@ -226,7 +235,7 @@ const commentsStore = createStore((setState, getState) => {
226
235
  return {
227
236
  comments: {},
228
237
  errors: {},
229
- addCommentToStore(commentCid, account) {
238
+ addCommentToStore(commentCid, account, commentData) {
230
239
  return __awaiter(this, void 0, void 0, function* () {
231
240
  const { comments } = getState();
232
241
  const pendingKey = commentCid + account.id;
@@ -238,9 +247,9 @@ const commentsStore = createStore((setState, getState) => {
238
247
  pkcGetCommentPending[pendingKey] = true;
239
248
  try {
240
249
  // try to find comment in database
241
- comment = yield getCommentFromDatabase(commentCid, account);
250
+ comment = yield getCommentFromDatabase(commentCid, account, commentData);
242
251
  if (!comment) {
243
- comment = yield ensureLiveComment(commentCid, account, { cid: commentCid });
252
+ comment = yield ensureLiveComment(commentCid, account, commentData);
244
253
  comment = normalizeCommentCommunityAddress(comment);
245
254
  log("commentsStore.addCommentToStore", { commentCid, comment, account });
246
255
  setState((state) => ({
@@ -254,7 +263,7 @@ const commentsStore = createStore((setState, getState) => {
254
263
  }));
255
264
  // add comment replies pages to repliesPagesStore so they can be used in useComment
256
265
  repliesPagesStore.getState().addRepliesPageCommentsToStore(comment);
257
- comment = yield ensureLiveComment(commentCid, account, comment);
266
+ comment = yield ensureLiveComment(commentCid, account, mergeCommentData(commentCid, comment, commentData));
258
267
  }
259
268
  if (comment) {
260
269
  requestCommentUpdate(commentCid, comment, { stopAfterNextUpdate: true });
@@ -269,7 +278,7 @@ const commentsStore = createStore((setState, getState) => {
269
278
  }
270
279
  });
271
280
  },
272
- startCommentAutoUpdate(commentCid, subscriberId, account) {
281
+ startCommentAutoUpdate(commentCid, subscriberId, account, commentData) {
273
282
  return __awaiter(this, void 0, void 0, function* () {
274
283
  const hadAutoUpdateSubscribers = hasCommentAutoUpdateSubscribers(commentCid);
275
284
  commentAutoUpdateSubscribers[commentCid] = Object.assign(Object.assign({}, (commentAutoUpdateSubscribers[commentCid] || {})), { [subscriberId]: true });
@@ -277,7 +286,7 @@ const commentsStore = createStore((setState, getState) => {
277
286
  return;
278
287
  }
279
288
  const storedComment = getState().comments[commentCid];
280
- const liveComment = yield ensureLiveComment(commentCid, account, storedComment || { cid: commentCid });
289
+ const liveComment = yield ensureLiveComment(commentCid, account, mergeCommentData(commentCid, storedComment, commentData));
281
290
  if (!storedComment) {
282
291
  setState((state) => ({
283
292
  comments: Object.assign(Object.assign({}, state.comments), { [commentCid]: utils.clone(liveComment) }),
@@ -308,10 +317,10 @@ const commentsStore = createStore((setState, getState) => {
308
317
  maybeReleaseStoppedLiveComment(commentCid, liveComment);
309
318
  });
310
319
  },
311
- refreshComment(commentCid, account) {
320
+ refreshComment(commentCid, account, commentData) {
312
321
  return __awaiter(this, void 0, void 0, function* () {
313
322
  const storedComment = getState().comments[commentCid];
314
- const liveComment = yield ensureLiveComment(commentCid, account, storedComment || { cid: commentCid });
323
+ const liveComment = yield ensureLiveComment(commentCid, account, mergeCommentData(commentCid, storedComment, commentData));
315
324
  if (!hasCommentAutoUpdateSubscribers(commentCid) &&
316
325
  (liveComment === null || liveComment === void 0 ? void 0 : liveComment.updatingState) !== "stopped") {
317
326
  yield stopLiveComment(commentCid, liveComment);
@@ -325,13 +334,13 @@ const commentsStore = createStore((setState, getState) => {
325
334
  },
326
335
  };
327
336
  });
328
- const getCommentFromDatabase = (commentCid, account) => __awaiter(void 0, void 0, void 0, function* () {
337
+ const getCommentFromDatabase = (commentCid, account, initialCommentData) => __awaiter(void 0, void 0, void 0, function* () {
329
338
  const commentData = yield commentsDatabase.getItem(commentCid);
330
339
  if (!commentData) {
331
340
  return;
332
341
  }
333
342
  try {
334
- const comment = normalizeCommentCommunityAddress(yield account.pkc.createComment(commentData));
343
+ const comment = normalizeCommentCommunityAddress(yield account.pkc.createComment(mergeCommentData(commentCid, commentData, initialCommentData)));
335
344
  return comment;
336
345
  }
337
346
  catch (e) {