@bitsocial/bitsocial-react-hooks 0.1.4 → 0.1.6
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 +225 -0
- package/README.md +7 -0
- package/dist/lib/test-utils.d.ts +12 -3
- package/dist/lib/test-utils.d.ts.map +1 -1
- package/dist/lib/test-utils.js +5 -5
- package/dist/lib/test-utils.js.map +1 -1
- package/dist/stores/replies/replies-store.d.ts.map +1 -1
- package/dist/stores/replies/replies-store.js +20 -2
- package/dist/stores/replies/replies-store.js.map +1 -1
- package/dist/stores/replies/utils.d.ts +16 -2
- package/dist/stores/replies/utils.d.ts.map +1 -1
- package/dist/stores/replies/utils.js +31 -6
- package/dist/stores/replies/utils.js.map +1 -1
- package/package.json +9 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
## [0.1.6](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.5...v0.1.6) (2026-05-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **deps:** resolve axios dependabot alerts ([f05eac0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f05eac02887067fe1413d39aa7fbe21b593c01aa))
|
|
7
|
+
* **deps:** resolve dependabot alerts ([805ac34](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/805ac34b43cbf139c2ff8d479450a45338070ec9))
|
|
8
|
+
* **replies:** keep newly published account replies visible ([96ab074](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/96ab074a85222b838cc71c8c091aae2ece6039da))
|
|
9
|
+
* **tests:** stop account hook suite OOM ([1e217d6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1e217d6a11008cdd25b83ed0ef2d3e7d5c95e537))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [0.1.5](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.4...v0.1.5) (2026-05-02)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* **ci:** fetch tags for release notes ([6d22e9f](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/6d22e9f154621124757aef393dd8717657042c0a))
|
|
19
|
+
* **replies:** hide purged account replies ([570a5f2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/570a5f24dbbb370c6d2ced6a2f6aff8fcfb053e2))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## [0.1.4](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.3...v0.1.4) (2026-04-30)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* **ci:** create GitHub release after publish ([26562d5](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/26562d5100e7108ba4c505df99d4aaed4594d4fb))
|
|
29
|
+
* **stores:** dedupe pending comments after approval ([1fe46f7](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1fe46f7279a2d758dca30f0117fff62a2ab44a46))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## [0.1.3](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/v0.1.2...v0.1.3) (2026-04-29)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Bug Fixes
|
|
37
|
+
|
|
38
|
+
* **accounts:** use explicit RPC fallbacks for ETH defaults ([b0c9907](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b0c9907ae50139434ba86adf151b3d90de093d2c))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## [0.1.2](https://github.com/bitsocialnet/bitsocial-react-hooks/compare/d95bed5a75b832fbbfc980b34ead43d8e6848fba...v0.1.2) (2026-04-20)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Bug Fixes
|
|
46
|
+
|
|
47
|
+
* **accounts-store:** add fetching link dimensions state ([15cf17f](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/15cf17f29a56334024e09c3a05b60e513df30d59))
|
|
48
|
+
* **accounts-store:** add fetching link dimensions state ([f226408](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f226408dc7ef44d442c0341fdba3834068e8030f))
|
|
49
|
+
* **accounts-store:** dont mutate subscriptions array ([a3088a3](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a3088a3a1605aee31fbc6539e5bcb115116a80cf))
|
|
50
|
+
* **accounts-store:** instantly return account comment index from usePublishComment ([3e16386](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3e1638684a157191e41eb3251232c4570835b4ec))
|
|
51
|
+
* **accounts-store:** only fetch 10 comment updates on init, it slows down fetching comments/subs ([e45f527](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/e45f52713d3ca1cb6831cb40525d4d30129a35d2))
|
|
52
|
+
* **accounts-store:** subscribe and block actions add to db async, so feedback is more instant ([d551fd5](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d551fd58ac5e048d240954993792fe3e7325a3b5))
|
|
53
|
+
* **accounts-store:** validate replies notifications properly ([9e7b06b](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/9e7b06b846b514b11c66c704a71ee8da9ddce296))
|
|
54
|
+
* **accounts:** address account history review regressions ([fbe9c3d](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/fbe9c3d37853ceb360cbe1c560ccc6690a1716f6))
|
|
55
|
+
* **accounts:** address final account history review findings ([7feb65d](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/7feb65d5f351c4a231f3cc9f34e7c6710b6f7cc2))
|
|
56
|
+
* **accounts:** align pending comment failure state with plebbit-js ([#48](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/48)) ([a9f7111](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a9f71118667184095b064d54f2d427636acfb049))
|
|
57
|
+
* **accounts:** compact legacy stored account comments ([#44](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/44)) ([5f90193](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/5f90193153cb7d0d1be5105e6cb45e8a8bb35300))
|
|
58
|
+
* **accounts:** deeply compact stored account comments ([#46](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/46)) ([f2f8b4c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f2f8b4cc82fad6d07aa8f3c0d22f42fa5e1046fb))
|
|
59
|
+
* **accounts:** defer moderation rollback until edit is stored ([b59b8a0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b59b8a07aa47a3501e052f548fa7f69105040c82))
|
|
60
|
+
* **accounts:** optimistically remove pending comment on abandon delete ([bde1501](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/bde1501c703ae474c6de3b46cd05511fd3d8900e))
|
|
61
|
+
* **accounts:** preserve legacy publication field names ([#29](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/29)) ([dc23dca](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/dc23dca88055c13a52f6ee6106a25cc64f105210))
|
|
62
|
+
* **accounts:** roll back failed optimistic comment edits ([#34](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/34)) ([45aa5f6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/45aa5f6baa8bc7be7348bec45f941a93e3535743))
|
|
63
|
+
* **accounts:** rollback terminal comment edit challenge failures ([#35](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/35)) ([d8af0ad](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d8af0adffb8d4debe0a20b8805667093c77f3fad)), closes [#33](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/33)
|
|
64
|
+
* **accounts:** simplify account history query naming ([38a67e3](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/38a67e349a7346393b2cb4946676663c6804f023))
|
|
65
|
+
* **accounts:** stabilize account history e2e paths ([b9705b6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b9705b65e959b0bedba21dbb8a0c340c183f069e))
|
|
66
|
+
* **accounts:** start comment moderation publish earlier ([10ef375](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/10ef375402a4009685906386f939cf019d9f9550))
|
|
67
|
+
* **accounts:** stop auto-generating sol wallets ([2eab3dc](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/2eab3dce70703e65f324db1834f8fd1ebf8b5b6c)), closes [#20](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/20)
|
|
68
|
+
* **accounts:** stop stale moderation edits from sticking ([f8af7b6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f8af7b652dc924b4392105cc4166ab01486bd79f))
|
|
69
|
+
* **accounts:** switch default eth rpc to publicnode ([85d3ee4](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/85d3ee498d33080c223e5dde0ce011145a58e7f7))
|
|
70
|
+
* **actions:** add exports and test ([b298a50](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b298a505f49b4db103aaffd258195d2df9a07ab5))
|
|
71
|
+
* **actions:** ignore stale usePublishComment updates after abandon ([cb0ad7e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/cb0ad7ecb2735c98ccd5764c0901aae6ebf16b16))
|
|
72
|
+
* **actions:** implement usePublishCommentModeration ([1a8a5c1](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1a8a5c1074c581bf0f2aa9832195d79e5e48bf56))
|
|
73
|
+
* address community refactor follow-up bugs ([#24](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/24)) ([1c38324](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1c383246951879a56a4870a205003d5ddf06cbc2)), closes [#22](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/22)
|
|
74
|
+
* **authors-comments-store:** scrolling comments stalls sometimes ([173b214](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/173b21424bf38ff389cec9cb47620784888ef194))
|
|
75
|
+
* **authors-comments:** tolerate React 19 batching off-by-one in discover lastCommentCid test ([20676f8](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/20676f8e80993d974eb11b86b1f4dac0a5854cfd))
|
|
76
|
+
* **authors:** align author name resolution with pkc-js ([#53](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/53)) ([3294f39](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3294f391958b68804b444555f9883106081d8c94))
|
|
77
|
+
* **authors:** support .bso author address resolution ([35da119](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/35da11928797495073ae52bede4df62c72e6872b)), closes [#21](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/21)
|
|
78
|
+
* **authors:** undefined useAuthorAddress with argument accountComment before challenge verification ([6ec824e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/6ec824eaadb7dacc024b7fc74d2a97174075647c))
|
|
79
|
+
* **build:** remove consumer patch requirements ([#50](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/50)) ([cd76e12](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/cd76e12f362fbe6bd27c8f688ef4bec2838efb92))
|
|
80
|
+
* **build:** support TypeScript 6 compiler checks ([29cd3e6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/29cd3e6f58a0188dbed6db75840f0689df630cd1))
|
|
81
|
+
* **chain:** auto generated wallets had timestamps in ms, not seconds ([24f2373](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/24f2373f9f8cfadadac58e2afa027637b670b879))
|
|
82
|
+
* **ci:** align browser e2e pkc options ([b29ca70](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b29ca70187535e6f0f81c27d38337a8f07a51c3c))
|
|
83
|
+
* **ci:** avoid husky during yarn install ([a3c2184](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a3c218401f36262e706a64a7dbaef010e605e653))
|
|
84
|
+
* **ci:** disable husky during yarn install to prevent git dependency postinstall failure ([9dd99f7](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/9dd99f7fb062ae709afcec6afc39f864b8e1e63b))
|
|
85
|
+
* **ci:** drop legacy yarn install flags ([5921bde](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/5921bded2f869ba9f6cd983a4ee7e346dd0f8dfc))
|
|
86
|
+
* **ci:** push dist auto-commit from branch instead of detached HEAD ([57a3921](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/57a39219cdf3db1cbc310836290ecf9b18becf72))
|
|
87
|
+
* **ci:** reduce e2e debug output ([ce7eeb1](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ce7eeb11bab3475b7ebbd71b0f55adb34312ae50))
|
|
88
|
+
* **ci:** remove setup-node yarn cache ([ec3a133](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ec3a1336f852f82cebb5cf2678a11fe8a5e18b21))
|
|
89
|
+
* **ci:** replace tsgo with tsc in type-check script ([5b2144d](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/5b2144d0ba9b8df380280b7bdc828ba5c6b5232e))
|
|
90
|
+
* **ci:** retry yarn install with cache clean on corrupt tar extraction ([434bec2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/434bec2fd4ef4d4bd183900d555dea6800e2a0de))
|
|
91
|
+
* **ci:** skip non-e2e build scripts during checks install ([c7f18d9](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/c7f18d94380a572a985d919d5949dc372aee18ab))
|
|
92
|
+
* **ci:** use --network-concurrency 1 to avoid yarn v1 parallel tar extraction race ([2073797](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/2073797468bbeef8c813b060f7162a49e9f2b943))
|
|
93
|
+
* **comments:** address PR 31 review follow-ups ([#32](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/32)) ([0b0d635](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/0b0d6359520abebbd1116dfeafabd270b773342f))
|
|
94
|
+
* **comments:** new comments shouldnt show updating state for 5 minutes ([1691bdf](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1691bdfb087da23e8c14592500788b3f099782b2))
|
|
95
|
+
* **comments:** plebbit.createComment throws adds useComment().error ([8ff7aba](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/8ff7aba2a1133d1de80775de7370a36a497abce7))
|
|
96
|
+
* **comments:** resolve pending mod-queue comments without updatedAt in useComment path ([7236fc4](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/7236fc422d09189862cd9ffeb0417d07b73c6893)), closes [#8](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/8)
|
|
97
|
+
* **communities:** unwrap stats cid content ([#51](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/51)) ([39d4d7a](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/39d4d7ab99b991ce21815b5718ee5c5c89eee111))
|
|
98
|
+
* correct property exclusion in useEditedComment comparison logic ([f1c6af5](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f1c6af5b1d8de111bb79d2c782d9142d9c5fd644))
|
|
99
|
+
* **deps:** patch minimatch security override ([3264934](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3264934d5815b362ba583da11279a9af3f38e87d))
|
|
100
|
+
* **deps:** remediate dependabot alerts via ethers upgrade and transitive resolutions ([ecf5c6e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ecf5c6e67b6c78f0bb68d1d8a5de135d1cce4244))
|
|
101
|
+
* **deps:** resolve Dependabot alerts for protobufjs and follow-redirects ([3b993b6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3b993b6a92a50b7ae17e109d4844bf0be9b611ae))
|
|
102
|
+
* **deps:** resolve dependabot transitive vulnerabilities ([8403967](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/84039678ddab805c4a9be7b4c627ba9f927967fd))
|
|
103
|
+
* **deps:** resolve lodash dependabot alerts ([6db0e8e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/6db0e8e3e1186e92c0590cee9d9bf319af436f22))
|
|
104
|
+
* **e2e:** add auto-cleanup to custom renderHook to prevent root leaks ([fe274a6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/fe274a675b8086bb97624152a862c60ed3c6c7aa))
|
|
105
|
+
* **e2e:** bypass RTL auto-cleanup by managing React root directly ([f7bf6e5](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f7bf6e54aa9386f874b238d9ef72e1c6ce6a59a5))
|
|
106
|
+
* **e2e:** migrate vitest-e2e config to Vitest 4 browser provider API ([23907ff](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/23907ff4bdb26743b426705a2f6db84506eb07dc))
|
|
107
|
+
* **e2e:** test comment validation directly via commentIsValid ([00743c4](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/00743c41a0cbbb88d29dccf21f45b69c16b8850c))
|
|
108
|
+
* **e2e:** unmount beforeEach root before creating new one in validate comments ([f1185c0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f1185c00e8102c5c8e5d7a19e7cd7828a14b688e))
|
|
109
|
+
* **e2e:** use custom renderHook in browser tests to avoid React 19 unmounted root error ([b541452](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b5414520852cf65f4347d45238d75caddb574de2))
|
|
110
|
+
* **feed-stores:** hasMore is true when feed cache expires ([ec1dd54](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ec1dd542d5b045f9a27eca54614212b0c6e0f458))
|
|
111
|
+
* **feeds:** crash when switching accounts ([c7450a9](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/c7450a9c1fed135375777406c4b821f9627c738f))
|
|
112
|
+
* **feeds:** evict approved posts from mod queue feeds ([b1682b1](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b1682b1054bc818424658205f02e7a4ad6ef5600)), closes [#17](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/17)
|
|
113
|
+
* **feeds:** feeds fetch infinite pages when subplebbit.fetchedAt cache expires ([6606b68](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/6606b68420bf47d4fbd01470788d90a16b2c93c3))
|
|
114
|
+
* **feeds:** filter stale public posts out of pending approval feeds ([a1b77b2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a1b77b209692272fc50a3497d704c1135413c89e)), closes [#18](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/18)
|
|
115
|
+
* **feeds:** hot score needs Math.abs or negative score is ignored ([d41b6a2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d41b6a277dd487beb7a6bc48a7c655eff0285290))
|
|
116
|
+
* **feeds:** refresh subplebbit snapshots on feed reset ([b98fb82](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b98fb823318491690734febaeabb9ddf1c2950dc)), closes [#19](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/19)
|
|
117
|
+
* filter API is now {filter: Function: key: string} ([bb91724](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/bb91724d01c49f87da5599c37799ad6a933ba780))
|
|
118
|
+
* fix subplebbit blocking issue ([e7c5031](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/e7c50315e70ac5e574e10c0fe20472c24f1ff195))
|
|
119
|
+
* harden hook error paths and cleanup leaks ([09fc6ea](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/09fc6ea47fcfc0ea3d8d01c6d2c85ac386002179))
|
|
120
|
+
* **hooks:** mirror moderation flags into commentModeration ([a16a1b5](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a16a1b5c4af610a7bbf75716c942862c4424920f)), closes [#11](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/11)
|
|
121
|
+
* **lint:** resolve yarn lint issues ([ec7c43a](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ec7c43a286225f9969b9700f2fe15f46481d513b))
|
|
122
|
+
* **mock-content:** use real private key ([590e168](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/590e1682e901f9de60eefbb3b3dc14655c0c065d))
|
|
123
|
+
* **moderation:** add live e2e coverage and sourcemaps ([dac0604](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/dac0604195cb85fa035aea8f64457666d5b10f04))
|
|
124
|
+
* **pkc-js:** normalize short address params ([60e02c2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/60e02c2fed9629208123cd47663fb919fe663a7f))
|
|
125
|
+
* **plebbit-rpc:** add initial rpc settings state ([64b6451](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/64b64514de4814727dfa418d4e71d3cf293531c0))
|
|
126
|
+
* **plebbit-rpc:** update usePlebbitRpcSettings to new api ([375677c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/375677c489f9d3f85b841e819b76c674f4d5b745))
|
|
127
|
+
* **replies store:** sync updated feeds with local reply deletions ([7f9318f](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/7f9318f235aec04590e2b936bde9e2a47695bdf1))
|
|
128
|
+
* **replies:** tolerate async page fetch timing in sort type best fallback test ([8438da0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/8438da05be82c659ce3c05a086dc57b7cb5f7068))
|
|
129
|
+
* restore CI after address refactor follow-ups ([68e0289](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/68e0289739b0c17f40272fe9e7dd064697c01dc8))
|
|
130
|
+
* restore publication mock types for ci type-check ([231547e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/231547ee864a0eada541aeb4a939522dc4f5d4b5))
|
|
131
|
+
* **states:** non chainproviders clients are showing as 'resolving-address' state ([edc5d85](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/edc5d85713f63281f0d1aaecabf89c8e35589046))
|
|
132
|
+
* **states:** show updating states when posts cache is expired ([9809e94](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/9809e948eff14428314c368404c43a98d51c7114))
|
|
133
|
+
* **subplebbits:** plebbit.createSubplebbit throws adds useSubplebbit().error ([6750688](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/675068878177771ee8233e68aa4d4a933fba82f9))
|
|
134
|
+
* **subplebbits:** update subplebbit stats on subplebbit change ([d24b67e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d24b67eccb765e833c5430b674e0342e2500e859))
|
|
135
|
+
* **subplebbit:** treat .eth and .bso subplebbit addresses as equivalent ([d56c73b](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d56c73b10efaa0a12623cadd43c757cac204efd9)), closes [#12](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/12)
|
|
136
|
+
* **test:** prevent replies.test.ts cascade from prototype pollution and timing races ([ef9ce90](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ef9ce907fc3a67a33cab1e938afef888a446d095)), closes [#5](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/5)
|
|
137
|
+
* **tests:** correct assignment-as-comparison, unused waitFor2, and mock restore bugs ([3a7f2fe](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3a7f2fedd38d56aae57a7cc5b8b5cc79fdff13eb))
|
|
138
|
+
* **tests:** relax transient plebbit rpc state assertion ([f1ee69d](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f1ee69ddbbef1e03b272512e18d3ef34c37f52c2))
|
|
139
|
+
* **test:** stabilize filtered multi-community feed assertion ([07bc14c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/07bc14c0e47194c0d088f5cc3300def3a3dc9db7))
|
|
140
|
+
* **test:** stabilize initial hot feed assertion ([01344a4](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/01344a492bbfe422c7b2bdd51e52edfd7e29e37c))
|
|
141
|
+
* **tests:** wait for appended reply before asserting order ([aeb7e6b](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/aeb7e6b4858f188277e89b5dfe1f7afc412c2a09))
|
|
142
|
+
* **test:** use high custom ports for test IPFS nodes to avoid conflicts ([d0d8862](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d0d8862b46b78c6211e50497953117cb05dfece8))
|
|
143
|
+
* **test:** wait for parent comment indexing before publishing reply ([3a300f9](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3a300f9de17266c36293ebfb862251b4ff93437f))
|
|
144
|
+
* **test:** wait for updatedAt instead of timestamp for parent indexing ([aecf86f](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/aecf86f6ad6eb6bbfbd91cecfe690cea2906ac31))
|
|
145
|
+
* **types:** declare window defaults for account generator ([a08cb1a](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a08cb1ad7313d27cffb7b8f0f2a6b395d23e76e4))
|
|
146
|
+
* **utils:** incorrect import ([b74cc63](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b74cc63f9622fb4d0d52cb2e30c321d6aff955c2))
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
### Features
|
|
150
|
+
|
|
151
|
+
* **accounts-store:** add default sol chain provider ([c660709](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/c660709eaa602c4f70e9ac5a20ac1c6ee6b29a1e))
|
|
152
|
+
* **accounts-store:** generate eth and sol wallets based on the plebbit private key ([def94d0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/def94d0addb936a869b0e24324105dbd496ea281))
|
|
153
|
+
* **accounts-store:** implement comment.linkHtmlTagName ([2edeb5c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/2edeb5c20b274f717e28c2e4c4c0fd4e99a2a697))
|
|
154
|
+
* **accounts-store:** migrate account db ([450858c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/450858c243d8c1191d444bd1571ef07dedb2f2fc))
|
|
155
|
+
* **accounts-store:** validate replies pages for notifications ([b97761f](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b97761fcb33825063d3c3c8c72eb453e06b09514))
|
|
156
|
+
* **accounts:** add abandonPublish and hard-delete account comments ([fe5e5b7](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/fe5e5b786a7d1b87d06e6895753fb075028cf988)), closes [plebbit/plebbit-react-hooks#2](https://github.com/plebbit/plebbit-react-hooks/issues/2) [#7](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/7)
|
|
157
|
+
* **accounts:** dedupe equivalent .eth and .bso account subplebbits under canonical .bso key ([09967e8](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/09967e87cdf12c52e3be642d34bccc1123624a4d)), closes [#16](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/16)
|
|
158
|
+
* **account:** wire bso-resolver into pkc ([3138d4c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/3138d4c1f35d72dc9de0ce4def38dd463d0c6a9f))
|
|
159
|
+
* add onlyIfCached to hooks to improve performance ([b01838c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b01838c5bd1fe904cb938a18ac8a5eb119a91b6b))
|
|
160
|
+
* **authors:** add .sol to useResolvedAuthorAddress ([0a3df5c](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/0a3df5c93f4b046c940b02219c13b75ae108fabe))
|
|
161
|
+
* **authors:** add setAuthorAvatarsWhitelistedTokenAddresses ([21dd181](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/21dd181a8afa71babcf2a4559d0dd45484b502bd))
|
|
162
|
+
* **chain:** validate wallet timestamp must be less than Date.now() / 1000 ([9e70b9a](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/9e70b9a91addd93c4f6a8a3796efa36adfd2635f))
|
|
163
|
+
* **comments:** add auto update controls and refresh ([#31](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/31)) ([15cf2df](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/15cf2df879f5ab4a9bc224c203504a864c962f9b))
|
|
164
|
+
* **comments:** implement useValidateComment ([b337c52](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b337c520222c71409352aa07ef44b6924fec73ba))
|
|
165
|
+
* **comments:** useComment can use comment from replies pages ([f259741](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f2597418aec9ac2be14cee3b9790ef7fa2f884e2))
|
|
166
|
+
* **feeds-store:** add validatePages: false ([9b11dd8](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/9b11dd888f319ad038a24c9b1da373858ce00417))
|
|
167
|
+
* **feeds-store:** if no next cid and no page cids, use preloaded page of any sort type ([5a24836](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/5a24836e0ce8e4a5a514184e6c4f45e85b394d3a))
|
|
168
|
+
* **feeds:** add old and best sort ([e5b30dc](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/e5b30dcd62f1f355bc3ce52555e7f71ea4cae06b))
|
|
169
|
+
* **feeds:** implement auto set correct time for topAll and controversialAll when newerThan is set ([4f33f77](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/4f33f772d94060072c65fbbd2b7ebacae8f59c06))
|
|
170
|
+
* **feeds:** implement useFeed modQueue pendingApproval ([5135645](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/51356455aae0420a855f3fd1f53c2bc589e4a3c3))
|
|
171
|
+
* **feeds:** implement useFeed().bufferedFeed ([7efd7f8](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/7efd7f888d0053b8e5ec385ded0d546046f90c0f))
|
|
172
|
+
* **feeds:** implement useFeed().reset() ([773df5a](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/773df5ad8d8477849e0effceaa57f7b1a28e1082))
|
|
173
|
+
* **feeds:** implement useFeed().updatedFeeds ([f9c08b0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f9c08b0dcf5a234f1755ea6cfd9a612f9502a733))
|
|
174
|
+
* **feeds:** implement useFeed({accountComments}) ([7064e8f](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/7064e8f84d54ab7be573023c753b70e737ff9e3b))
|
|
175
|
+
* **feeds:** implement useFeed({newerThan: seconds}) ([571861a](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/571861a1aaadc2eca9b3edc93444fbc33acbe084))
|
|
176
|
+
* **feeds:** implement useFeeds().subplebbitAddressesWithNewerPosts ([b32bdf6](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b32bdf6a820bf68aac84423ffc4adec9d9ebaad3))
|
|
177
|
+
* **feeds:** support in-place time-window expansion ([e3526ef](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/e3526efd55678d1278cc882b2edbbaa0352be9f2))
|
|
178
|
+
* **hooks:** require explicit community objects ([#49](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/49)) ([c46ddc0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/c46ddc05834d934c5c4fc849ba42d414d8174460))
|
|
179
|
+
* **mock:** add `purged` moderation field to mock and tests ([f813f94](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f813f9480a203ea06d9bc44af98027dba789ba3f)), closes [#1](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/1)
|
|
180
|
+
* **plebbit-rpc:** implement usePlebbitRpcSettings ([ae28916](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ae28916952b17625db64b40583fd9f7d7189f590))
|
|
181
|
+
* **protocol:** migrate hooks library to pkc-js ([153df23](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/153df23a533131f9e8942fadd12a6337694ff646))
|
|
182
|
+
* **replies-pages-store:** implement replies pages store ([d3d98f4](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d3d98f4e5612983e38ccb465af59e4d87123d8a4))
|
|
183
|
+
* **replies-store:** if no nextCid, all replies are preloaded and use any sort type ([15782c2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/15782c25a81cde42e7afd51452151926ce8e1b61))
|
|
184
|
+
* **replies-store:** implement replies-store ([b244273](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b2442732d854a9df972fb67b93e82fdb10730d42))
|
|
185
|
+
* **replies:** add account comments to usereplies ([dc7f658](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/dc7f658d1518973eceeb0998d313a45be8ae1ce0))
|
|
186
|
+
* **replies:** add replies pages clients fetching state ([f071225](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f071225bab8540bf6e993e5383999e87ff2e479b))
|
|
187
|
+
* **replies:** implement flat ([b5a387b](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b5a387b6beb1dcfff8212f393790fa89df1a74d7))
|
|
188
|
+
* **replies:** implement useReplies().bufferedReplies ([e0d4213](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/e0d4213014ded7995e6b989628d91b4ec0851802))
|
|
189
|
+
* **replies:** implement useReplies().updatedReplies ([63dd2e8](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/63dd2e8dd0869ae464fc927ba36e95da399d415b))
|
|
190
|
+
* **replies:** implement useReplies({validateOptimistically}) ([5b6e22b](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/5b6e22b3ef0e3187bec8d9ee09d6f827d10145e8))
|
|
191
|
+
* **states:** useClientsStates gets comment and subplebbit updating states ([c341a25](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/c341a25f3f99186f1c4383f06c2f616ad0fc0999))
|
|
192
|
+
* **states:** useClientsStates when publishing ([ac21c96](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ac21c96bb9b8fd302713d469190e8c3860aa62cb))
|
|
193
|
+
* **states:** useSubplebbitsStates ([84c7a42](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/84c7a426d7a3f802b1c2cbda89f8b89e34407e35))
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
### Performance Improvements
|
|
197
|
+
|
|
198
|
+
* **accounts-store:** use entries instead of keys ([42d6b15](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/42d6b15360601df4b16fa89e485890510a9b1dc8))
|
|
199
|
+
* **accounts:** slim account history storage and query hot paths ([4a85fbc](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/4a85fbce10afb957a9d292c57e70f8ea2f741645))
|
|
200
|
+
* **ci:** parallelize e2e suites and inline dist publish in main workflow ([6d40eec](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/6d40eecf2e514bdd6d98f5b67f1c2992f3f2a8d0)), closes [#6](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/6)
|
|
201
|
+
* **feeds-store:** dont use subplebbit relative sorting anymore as it gives bad feed results ([b8201c9](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/b8201c924e57285c33080f1b8f36e3032d8987f1))
|
|
202
|
+
* **feeds:** expire subplebbits cache 1h after fetch (for feeds only) ([f7c87b0](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/f7c87b00bb7be6cdab77d63e40e7f73aacce1a8b))
|
|
203
|
+
* **feeds:** optimize buffered feeds that dont change ([1acd1fd](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/1acd1fd8182b20d9f34306fc79088a3a3bc3e64d))
|
|
204
|
+
* improve perf ([7cb055e](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/7cb055e6c6b055708f85648ce9584ec0f9556614))
|
|
205
|
+
* **replies:** add cached-only mode to useReplies ([#37](https://github.com/bitsocialnet/bitsocial-react-hooks/issues/37)) ([125df99](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/125df993e522ac438f18b290911dc501cc79b125))
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
### Reverts
|
|
209
|
+
|
|
210
|
+
* Revert "update to rpcOptions instead of port" ([0ca7d53](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/0ca7d5306fe82cefee8c32fc9480cd429d961021))
|
|
211
|
+
* Revert "change plebbit data path to /tmp for electron. May eliminate SQLite IO errors" ([bcf1a94](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/bcf1a94e01376996f25a5be5a901c9e8071df97e))
|
|
212
|
+
* Revert "use latest signer schema" ([26690be](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/26690bebda858bdb8111eab786dd1cd06563099c))
|
|
213
|
+
* Revert "update plebbit-js" ([a4c63e3](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/a4c63e37cf0e5f5fdeedd1f34de6d0fe26a9dfd0))
|
|
214
|
+
* Revert "fix undefined plebbit.dataPath before setAccount" ([d95bed5](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/d95bed5a75b832fbbfc980b34ead43d8e6848fba))
|
|
215
|
+
* dont use real signer for mock content, didnt work ([629c2f2](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/629c2f2a6f76129eb51e7e66b82517d1aaee2458))
|
|
216
|
+
* not necessary to mock ens ([ba1dc84](https://github.com/bitsocialnet/bitsocial-react-hooks/commit/ba1dc849341232de72e80f2b6406aa6dfc73538c))
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
### BREAKING CHANGES
|
|
220
|
+
|
|
221
|
+
* useFeed({filter}) and useAuthorComments({filter}) are now {filter: Function, key:
|
|
222
|
+
string}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
package/README.md
CHANGED
|
@@ -1019,6 +1019,9 @@ 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 kept in useReplies until the canonical replies
|
|
1023
|
+
// feed refreshes past the reply timestamp; after that exhausted feed, account-only
|
|
1024
|
+
// published replies are hidden unless the canonical feed includes their cid
|
|
1022
1025
|
```
|
|
1023
1026
|
|
|
1024
1027
|
#### Determine if a comment is your own
|
|
@@ -1299,6 +1302,10 @@ const useRepliesOptions = {
|
|
|
1299
1302
|
accountComments: { newerThan: Infinity, append: false },
|
|
1300
1303
|
};
|
|
1301
1304
|
|
|
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
|
|
1308
|
+
|
|
1302
1309
|
const Reply = ({ reply, updatedReply }) => {
|
|
1303
1310
|
const { replies, updatedReplies, bufferedReplies, hasMore, loadMore } = useReplies({
|
|
1304
1311
|
...useRepliesOptions,
|
package/dist/lib/test-utils.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
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:
|
|
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":"
|
|
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"}
|
package/dist/lib/test-utils.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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":"replies-store.d.ts","sourceRoot":"","sources":["../../../src/stores/replies/replies-store.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,IAAI,EACJ,KAAK,EACL,OAAO,EAGP,kBAAkB,EAClB,mBAAmB,EAGpB,MAAM,aAAa,CAAC;AAwBrB,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAKxC,MAAM,MAAM,YAAY,GAAG;IACzB,YAAY,EAAE,mBAAmB,CAAC;IAClC,aAAa,EAAE,KAAK,CAAC;IACrB,WAAW,EAAE,KAAK,CAAC;IACnB,YAAY,EAAE,KAAK,CAAC;IACpB,wBAAwB,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACzD,aAAa,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC/C,eAAe,EAAE,QAAQ,CAAC;IAC1B,6BAA6B,EAAE,QAAQ,CAAC;IACxC,uBAAuB,EAAE,QAAQ,CAAC;IAClC,SAAS,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,QAAQ,CAAC;CACvB,CAAC;AAgBF,eAAO,MAAM,qBAAqB,GAAI,aAAa,OAAO,CAAC,kBAAkB,CAAC,WAG7E,CAAC;
|
|
1
|
+
{"version":3,"file":"replies-store.d.ts","sourceRoot":"","sources":["../../../src/stores/replies/replies-store.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,IAAI,EACJ,KAAK,EACL,OAAO,EAGP,kBAAkB,EAClB,mBAAmB,EAGpB,MAAM,aAAa,CAAC;AAwBrB,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAKxC,MAAM,MAAM,YAAY,GAAG;IACzB,YAAY,EAAE,mBAAmB,CAAC;IAClC,aAAa,EAAE,KAAK,CAAC;IACrB,WAAW,EAAE,KAAK,CAAC;IACnB,YAAY,EAAE,KAAK,CAAC;IACpB,wBAAwB,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACzD,aAAa,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAC/C,eAAe,EAAE,QAAQ,CAAC;IAC1B,6BAA6B,EAAE,QAAQ,CAAC;IACxC,uBAAuB,EAAE,QAAQ,CAAC;IAClC,SAAS,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,QAAQ,CAAC;CACvB,CAAC;AAgBF,eAAO,MAAM,qBAAqB,GAAI,aAAa,OAAO,CAAC,kBAAkB,CAAC,WAG7E,CAAC;AAeF,QAAA,MAAM,YAAY,2EA2Sf,CAAC;AAkLJ,eAAO,MAAM,iCAAiC,GAC5C,SAAS,OAAO,EAChB,aAAa,OAAO,CAAC,kBAAkB,CAAC;;;CAoCzC,CAAC;AAKF,eAAO,MAAM,iBAAiB,qBAkB7B,CAAC;AAGF,eAAO,MAAM,4BAA4B,qBAGxC,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -39,6 +39,14 @@ export const feedOptionsToFeedName = (feedOptions) => {
|
|
|
39
39
|
feedOptions = addDefaultFeedOptions(feedOptions);
|
|
40
40
|
return `${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.accountId}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.commentCid}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.postCid}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.sortType}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.flat}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.onlyIfCached}-${(_a = feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.accountComments) === null || _a === void 0 ? void 0 : _a.newerThan}-${(_b = feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.accountComments) === null || _b === void 0 ? void 0 : _b.append}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.repliesPerPage}-${(_c = feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.filter) === null || _c === void 0 ? void 0 : _c.key}-${feedOptions === null || feedOptions === void 0 ? void 0 : feedOptions.streamPage}`;
|
|
41
41
|
};
|
|
42
|
+
const getFeedsUpdatedAts = (feedsOptions, comments) => {
|
|
43
|
+
var _a;
|
|
44
|
+
const feedsUpdatedAts = {};
|
|
45
|
+
for (const feedName in feedsOptions) {
|
|
46
|
+
feedsUpdatedAts[feedName] = (_a = comments[feedsOptions[feedName].commentCid]) === null || _a === void 0 ? void 0 : _a.updatedAt;
|
|
47
|
+
}
|
|
48
|
+
return feedsUpdatedAts;
|
|
49
|
+
};
|
|
42
50
|
// don't updateFeeds more than once per updateFeedsMinIntervalTime
|
|
43
51
|
let updateFeedsPending = false;
|
|
44
52
|
let updateFeedsAgain = false;
|
|
@@ -193,7 +201,15 @@ const repliesStore = createStore((setState, getState) => ({
|
|
|
193
201
|
// calculate new feeds
|
|
194
202
|
const filteredSortedFeeds = getFilteredSortedFeeds(feedsOptions, comments, repliesPages, accounts);
|
|
195
203
|
const bufferedFeedsWithoutPreviousLoadedFeeds = getBufferedFeedsWithoutLoadedFeeds(filteredSortedFeeds, previousState.loadedFeeds);
|
|
196
|
-
const
|
|
204
|
+
const canonicalLoadedFeeds = yield getLoadedFeeds(feedsOptions, previousState.loadedFeeds, bufferedFeedsWithoutPreviousLoadedFeeds, accounts, { addAccountComments: false });
|
|
205
|
+
const canonicalBufferedFeeds = getBufferedFeedsWithoutLoadedFeeds(bufferedFeedsWithoutPreviousLoadedFeeds, canonicalLoadedFeeds);
|
|
206
|
+
const canonicalFeedsHaveMore = getFeedsHaveMore(feedsOptions, canonicalBufferedFeeds, comments, repliesPages, accounts);
|
|
207
|
+
const canonicalFeedsUpdatedAts = getFeedsUpdatedAts(feedsOptions, comments);
|
|
208
|
+
const loadedFeedsWithAccountComments = Object.assign({}, canonicalLoadedFeeds);
|
|
209
|
+
const accountCommentsChangedFeeds = addAccountsComments(feedsOptions, loadedFeedsWithAccountComments, canonicalFeedsHaveMore, canonicalFeedsUpdatedAts);
|
|
210
|
+
const loadedFeeds = accountCommentsChangedFeeds
|
|
211
|
+
? loadedFeedsWithAccountComments
|
|
212
|
+
: canonicalLoadedFeeds;
|
|
197
213
|
// after loaded feeds are caculated, remove new loaded feeds (again) from buffered feeds
|
|
198
214
|
const bufferedFeeds = getBufferedFeedsWithoutLoadedFeeds(bufferedFeedsWithoutPreviousLoadedFeeds, loadedFeeds);
|
|
199
215
|
const bufferedFeedsReplyCounts = getFeedsReplyCounts(feedsOptions, bufferedFeeds);
|
|
@@ -378,8 +394,10 @@ export const getRepliesFirstPageSkipValidation = (comment, feedOptions) => {
|
|
|
378
394
|
if (filteredSortedFeeds[feedName].length > repliesPerPage) {
|
|
379
395
|
bufferedFeeds[feedName] = filteredSortedFeeds[feedName].splice(repliesPerPage);
|
|
380
396
|
}
|
|
381
|
-
addAccountsComments(feedsOptions, filteredSortedFeeds);
|
|
382
397
|
const feedsHaveMore = getFeedsHaveMore(feedsOptions, bufferedFeeds, comments, repliesPages, accounts);
|
|
398
|
+
addAccountsComments(feedsOptions, filteredSortedFeeds, feedsHaveMore, {
|
|
399
|
+
[feedName]: comment.updatedAt,
|
|
400
|
+
});
|
|
383
401
|
return { replies: filteredSortedFeeds[feedName], hasMore: feedsHaveMore[feedName] };
|
|
384
402
|
};
|
|
385
403
|
// reset store in between tests
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replies-store.js","sourceRoot":"","sources":["../../../src/stores/replies/replies-store.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"assert\";\nimport Logger from \"@pkcprotocol/pkc-logger\";\nconst log = Logger(\"bitsocial-react-hooks:replies:stores\");\nimport {\n Feed,\n Feeds,\n Comment,\n Comments,\n Account,\n RepliesFeedOptions,\n RepliesFeedsOptions,\n RepliesPage,\n CommentsFilter,\n} from \"../../types\";\nimport createStore from \"zustand\";\nimport localForageLru from \"../../lib/localforage-lru\";\nimport accountsStore from \"../accounts\";\nimport repliesCommentsStore from \"./replies-comments-store\";\nimport repliesPagesStore from \"../replies-pages\";\nimport {\n getFeedsCommentsFirstPageCids,\n getLoadedFeeds,\n getBufferedFeedsWithoutLoadedFeeds,\n getUpdatedFeeds,\n getFeedsReplyCounts,\n getFeedsHaveMore,\n feedsCommentsChanged,\n getFeedsComments,\n getFeedsCommentsLoadedCount,\n getFeedsCommentsRepliesPagesFirstUpdatedAts,\n getFilteredSortedFeeds,\n getSortTypeFromComment,\n addAccountsComments,\n} from \"./utils\";\n\n// reddit loads approximately 25 posts per page\n// while infinite scrolling\nexport const defaultRepliesPerPage = 25;\n\n// keep large buffer because fetching cids is slow\nconst commentRepliesLeftBeforeNextPage = 50;\n\nexport type RepliesState = {\n feedsOptions: RepliesFeedsOptions;\n bufferedFeeds: Feeds;\n loadedFeeds: Feeds;\n updatedFeeds: Feeds;\n bufferedFeedsReplyCounts: { [feedName: string]: number };\n feedsHaveMore: { [feedName: string]: boolean };\n addFeedsToStore: Function;\n addFeedToStoreOrUpdateComment: Function;\n incrementFeedPageNumber: Function;\n resetFeed: Function;\n updateFeeds: Function;\n};\n\nconst defaultAccountComments = { newerThan: Infinity, append: false };\nconst addDefaultFeedOptions = (feedOptions: any) => {\n feedOptions = { ...feedOptions };\n if (feedOptions.flat === undefined || feedOptions.flat === null) {\n feedOptions.flat = false;\n }\n feedOptions.onlyIfCached = feedOptions.onlyIfCached === true;\n if (feedOptions.accountComments === undefined || feedOptions.accountComments === null) {\n feedOptions.accountComments = defaultAccountComments;\n }\n feedOptions.repliesPerPage = feedOptions.repliesPerPage || defaultRepliesPerPage;\n return feedOptions;\n};\n\nexport const feedOptionsToFeedName = (feedOptions: Partial<RepliesFeedOptions>) => {\n feedOptions = addDefaultFeedOptions(feedOptions);\n return `${feedOptions?.accountId}-${feedOptions?.commentCid}-${feedOptions?.postCid}-${feedOptions?.sortType}-${feedOptions?.flat}-${feedOptions?.onlyIfCached}-${feedOptions?.accountComments?.newerThan}-${feedOptions?.accountComments?.append}-${feedOptions?.repliesPerPage}-${feedOptions?.filter?.key}-${feedOptions?.streamPage}`;\n};\n\n// don't updateFeeds more than once per updateFeedsMinIntervalTime\nlet updateFeedsPending = false;\nlet updateFeedsAgain = false;\nconst updateFeedsMinIntervalTime = 100;\n\nconst repliesStore = createStore<RepliesState>((setState: Function, getState: Function) => ({\n feedsOptions: {},\n bufferedFeeds: {},\n loadedFeeds: {},\n updatedFeeds: {},\n bufferedFeedsReplyCounts: {},\n feedsHaveMore: {},\n\n addFeedsToStore(feedOptionsArray: RepliesFeedOptions[]) {\n if (!feedOptionsArray.length) {\n return;\n }\n const { feedsOptions: previousFeedsOptions } = getState();\n const newFeedsOptions: RepliesFeedsOptions = {};\n\n // get all newFeedsOptions\n for (let feedOptions of feedOptionsArray) {\n const feedName = feedOptionsToFeedName(feedOptions);\n // feed is in store already, do nothing\n // if the feed already exist but is at page 0, reset it to page 1\n if (previousFeedsOptions[feedName] && previousFeedsOptions[feedName].pageNumber !== 0) {\n continue;\n }\n\n feedOptions = addDefaultFeedOptions(feedOptions);\n\n // to add a buffered feed, add a feed with pageNumber 0\n feedOptions.pageNumber = 1;\n newFeedsOptions[feedName] = feedOptions;\n }\n\n // set new feedsOptions state (first loop already skips existing feeds)\n let feedsChanged = false;\n setState(({ feedsOptions }: RepliesState) => {\n if (!Object.keys(newFeedsOptions).length) return {};\n feedsChanged = true;\n return { feedsOptions: { ...feedsOptions, ...newFeedsOptions } };\n });\n if (feedsChanged) {\n log(\"repliesStore.addFeedsToStore\", newFeedsOptions);\n }\n return feedsChanged;\n },\n\n async addFeedToStoreOrUpdateComment(comment: Comment, feedOptions: RepliesFeedOptions) {\n // init here because must be called after async accounts store finished initializing\n initializeRepliesStore();\n\n // validate options\n assert(\n comment && comment.cid && typeof comment.cid === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment comment.cid '${comment?.cid}' invalid`,\n );\n assert(\n feedOptions.commentCid && typeof feedOptions.commentCid === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.commentCid '${feedOptions.commentCid}' invalid`,\n );\n assert(\n feedOptions.sortType && typeof feedOptions.sortType === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.sortType '${feedOptions.sortType}' invalid`,\n );\n const account = accountsStore.getState().accounts[feedOptions.accountId];\n assert(\n typeof account?.pkc?.createComment === \"function\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.accountId '${feedOptions.accountId}' invalid`,\n );\n assert(\n !feedOptions.repliesPerPage || typeof feedOptions.repliesPerPage === \"number\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.repliesPerPage '${feedOptions.repliesPerPage}' invalid`,\n );\n assert(\n !feedOptions.filter || typeof feedOptions.filter?.filter === \"function\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.filter.filter '${feedOptions.filter?.filter}' invalid`,\n );\n assert(\n !feedOptions.filter || typeof feedOptions.filter?.key === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.filter.key '${feedOptions.filter?.key}' invalid`,\n );\n\n // if replies feed aren't in store yet, add them recursively\n // TODO: optimize performance by only adding feeds that are in page 1, and add more on each page increase\n const commentsToAddToStoreOrUpdate: Comment[] = [];\n const feedsToAddToStore: RepliesFeedOptions[] = [];\n\n // use the sort type availabe on the comment when missing\n const sortType = getSortTypeFromComment(comment, feedOptions);\n\n const addRepliesFeedsToStoreRecursively = (comment: Comment) => {\n // NOTE: even a comment with no replies needs a feed, to know it has 0 replies and not displace the UI when a new replies appears\n commentsToAddToStoreOrUpdate.push(comment);\n feedsToAddToStore.push({\n ...feedOptions,\n commentCid: comment?.cid,\n commentDepth: comment?.depth,\n });\n\n // flat doesn't need nested feeds\n if (!feedOptions.flat) {\n for (const reply of comment.replies?.pages?.[sortType]?.comments || []) {\n addRepliesFeedsToStoreRecursively(reply);\n }\n }\n };\n addRepliesFeedsToStoreRecursively(comment);\n\n // add feeds to store and update feeds\n const { addFeedsToStore, updateFeeds } = getState();\n const feedsChanged = addFeedsToStore(feedsToAddToStore);\n // add comments to store (do it after addFeedsToStore because it can trigger updateFeeds)\n repliesCommentsStore\n .getState()\n .addCommentsToStoreOrUpdateComments(commentsToAddToStoreOrUpdate);\n if (feedsChanged) {\n log(\"repliesStore.addFeedToStoreOrUpdateComment\", {\n comment,\n feedOptions,\n sortType,\n feedsToAddToStore,\n commentsToAddToStoreOrUpdate,\n });\n updateFeeds();\n }\n },\n\n incrementFeedPageNumber(feedName: string) {\n const { feedsOptions, loadedFeeds, bufferedFeeds, updateFeeds } = getState();\n assert(\n feedsOptions[feedName],\n `repliesStore.incrementFeedPageNumber feed name '${feedName}' does not exist in feeds store`,\n );\n log(\"repliesStore.incrementFeedPageNumber\", { feedName });\n\n // TODO: fix design issue, pageNumber shouldnt be increased when loadMore is called and repliesPerPage not reached\n // assert(\n // feedsOptions[feedName].pageNumber * feedsOptions[feedName].repliesPerPage <= loadedFeeds[feedName].length,\n // `repliesStore.incrementFeedPageNumber cannot increment feed page number before current page has loaded`\n // )\n if (\n feedsOptions[feedName].pageNumber * feedsOptions[feedName].repliesPerPage <=\n loadedFeeds[feedName].length\n ) {\n assert(\n bufferedFeeds[feedName].length > 0,\n `repliesStore.incrementFeedPageNumber cannot increment feed page number before current page has loaded`,\n );\n }\n\n setState(({ feedsOptions, loadedFeeds }: any) => {\n // don't increment page number before the current page has loaded\n // if (feedsOptions[feedName].pageNumber * feedsOptions[feedName].repliesPerPage > loadedFeeds[feedName].length) {\n // return {}\n // }\n const feedOptions = {\n ...feedsOptions[feedName],\n pageNumber: feedsOptions[feedName].pageNumber + 1,\n };\n return { feedsOptions: { ...feedsOptions, [feedName]: feedOptions } };\n });\n\n // do not update feed at the same time as increment a page number or it might cause\n // a race condition, rather schedule a feed update\n updateFeeds();\n },\n\n resetFeed(feedName: string) {\n const { feedsOptions, updateFeeds } = getState();\n assert(\n feedsOptions[feedName],\n `repliesStore.resetFeed feed name '${feedName}' does not exist in feeds store`,\n );\n assert(\n feedsOptions[feedName].pageNumber >= 1,\n `repliesStore.resetFeed cannot reset feed page number '${feedsOptions[feedName].pageNumber}' lower than 1`,\n );\n log(\"repliesStore.resetFeed\", { feedName });\n\n setState(({ feedsOptions, loadedFeeds, updatedFeeds }: any) => {\n const feedOptions = {\n ...feedsOptions[feedName],\n pageNumber: 1,\n };\n return {\n feedsOptions: { ...feedsOptions, [feedName]: feedOptions },\n loadedFeeds: { ...loadedFeeds, [feedName]: [] },\n updatedFeeds: { ...updatedFeeds, [feedName]: [] },\n };\n });\n\n updateFeeds();\n },\n\n // recalculate all feeds using new comments.replies.pages, repliesPagesStore and page numbers\n updateFeeds() {\n if (updateFeedsPending) {\n updateFeedsAgain = true;\n return;\n }\n updateFeedsPending = true;\n\n // don't update feeds more than once per updateFeedsMinIntervalTime\n const timeUntilNextUpdate = Date.now() % updateFeedsMinIntervalTime;\n\n setTimeout(async () => {\n // get state from all stores\n const previousState = getState();\n const { feedsOptions, updateFeeds } = previousState;\n const { comments } = repliesCommentsStore.getState();\n const { repliesPages } = repliesPagesStore.getState();\n const { accounts } = accountsStore.getState();\n\n // calculate new feeds\n const filteredSortedFeeds = getFilteredSortedFeeds(\n feedsOptions,\n comments,\n repliesPages,\n accounts,\n );\n const bufferedFeedsWithoutPreviousLoadedFeeds = getBufferedFeedsWithoutLoadedFeeds(\n filteredSortedFeeds,\n previousState.loadedFeeds,\n );\n const loadedFeeds = await getLoadedFeeds(\n feedsOptions,\n previousState.loadedFeeds,\n bufferedFeedsWithoutPreviousLoadedFeeds,\n accounts,\n );\n // after loaded feeds are caculated, remove new loaded feeds (again) from buffered feeds\n const bufferedFeeds = getBufferedFeedsWithoutLoadedFeeds(\n bufferedFeedsWithoutPreviousLoadedFeeds,\n loadedFeeds,\n );\n const bufferedFeedsReplyCounts = getFeedsReplyCounts(feedsOptions, bufferedFeeds);\n const feedsHaveMore = getFeedsHaveMore(\n feedsOptions,\n bufferedFeeds,\n comments,\n repliesPages,\n accounts,\n );\n const updatedFeeds = await getUpdatedFeeds(\n feedsOptions,\n filteredSortedFeeds,\n previousState.updatedFeeds,\n loadedFeeds,\n accounts,\n );\n\n // set new feeds\n setState((state: any) => ({\n bufferedFeeds,\n loadedFeeds,\n bufferedFeedsReplyCounts,\n updatedFeeds,\n feedsHaveMore,\n }));\n log(\"repliesStore.updateFeeds\", {\n feedsOptions,\n bufferedFeeds,\n loadedFeeds,\n bufferedFeedsReplyCounts,\n updatedFeeds,\n feedsHaveMore,\n comments,\n repliesPages,\n });\n\n updateFeedsPending = false;\n\n // if updateFeeds was called while updateFeedsPending = true, call updateFeeds again\n if (updateFeedsAgain) {\n updateFeedsAgain = false;\n updateFeeds();\n }\n }, timeUntilNextUpdate);\n },\n}));\n\nlet repliesStoreInitialized = false;\nconst initializeRepliesStore = async () => {\n if (repliesStoreInitialized) {\n return;\n }\n repliesStoreInitialized = true;\n // TODO: optimize subscriptions e.g. updateFeedsOnFeedsCommentsChange(comment)\n // subscribe to comments store changes\n repliesCommentsStore.subscribe(updateFeedsOnFeedsCommentsChange);\n // subscribe to bufferedFeedsReplyCounts change\n repliesStore.subscribe(addRepliesPagesOnLowBufferedFeedsReplyCounts);\n // subscribe to replies pages store changes\n repliesPagesStore.subscribe(updateFeedsOnFeedsRepliesPagesChange);\n // subscribe to accounts store changes\n accountsStore.subscribe(updateFeedsOnAccountsCommentsChange);\n};\n\nlet previousRepliesPages: { [pageCid: string]: RepliesPage } = {};\nconst updateFeedsOnFeedsRepliesPagesChange = (repliesPagesStoreState: any) => {\n const { repliesPages } = repliesPagesStoreState;\n\n // no changes, do nothing\n if (repliesPages === previousRepliesPages) {\n return;\n }\n previousRepliesPages = repliesPages;\n\n // currently only the feeds use repliesPagesStore, so any change must\n // trigger a feed update, if in the future another hook uses the repliesPagesStore\n // we should check if the replies pages changed are actually used by the feeds before\n // triggering an update\n repliesStore.getState().updateFeeds();\n};\n\nlet previousBufferedFeedsReplyCountsPageCids: string[] = [];\nlet previousBufferedFeedsComments = new Map<string, Comments>();\nlet previousBufferedFeedsReplyCounts: { [feedName: string]: number } = {};\nconst addRepliesPagesOnLowBufferedFeedsReplyCounts = (repliesStoreState: any) => {\n const { bufferedFeedsReplyCounts, feedsOptions } = repliesStore.getState();\n const { comments } = repliesCommentsStore.getState();\n\n // if feeds comments have changed, we must try adding them even if buffered replies counts haven't changed\n const bufferedFeedsComments = getFeedsComments(feedsOptions, comments);\n const _feedsCommentsChanged = feedsCommentsChanged(\n previousBufferedFeedsComments,\n bufferedFeedsComments,\n );\n const bufferedFeedsReplyCountsChanged =\n previousBufferedFeedsReplyCounts !== bufferedFeedsReplyCounts;\n\n // if feeds comments havent changed and buffered replies counts also havent changed, do nothing\n if (!_feedsCommentsChanged && !bufferedFeedsReplyCountsChanged) {\n return;\n }\n previousBufferedFeedsComments = bufferedFeedsComments;\n previousBufferedFeedsReplyCounts = bufferedFeedsReplyCounts;\n\n // in case feeds comments changed, but the first page cids haven't\n const bufferedFeedsReplyCountsPageCids = getFeedsCommentsFirstPageCids(bufferedFeedsComments);\n const bufferedFeedsReplyCountsPageCidsChanged =\n bufferedFeedsReplyCountsPageCids.toString() !==\n previousBufferedFeedsReplyCountsPageCids.toString();\n if (!bufferedFeedsReplyCountsPageCidsChanged && !bufferedFeedsReplyCountsChanged) {\n return;\n }\n previousBufferedFeedsReplyCountsPageCids = bufferedFeedsReplyCountsPageCids;\n\n const { addNextRepliesPageToStore } = repliesPagesStore.getState();\n const { accounts } = accountsStore.getState();\n\n // bufferedFeedsReplyCounts have changed, check if any of them are low\n for (const feedName in bufferedFeedsReplyCounts) {\n if (feedsOptions[feedName].onlyIfCached) {\n continue;\n }\n const account = accounts[feedsOptions[feedName].accountId];\n const feedReplyCount = bufferedFeedsReplyCounts[feedName];\n let sortType = feedsOptions[feedName].sortType;\n const commentCid = feedsOptions[feedName].commentCid;\n\n // TODO: maybe skip if comment community address, comment cid or comment author is blocked?\n\n // comment hasn't loaded yet\n if (!comments[commentCid]) {\n continue;\n }\n\n sortType = getSortTypeFromComment(comments[commentCid], feedsOptions[feedName]);\n\n // comment replies count is low, fetch next replies page\n if (feedReplyCount <= commentRepliesLeftBeforeNextPage) {\n addNextRepliesPageToStore(comments[commentCid], sortType, account).catch((error: unknown) =>\n log.error(\"repliesStore repliesPagesStore.addNextRepliesPageToStore error\", {\n commentCid,\n comment: comments[commentCid],\n sortType,\n error,\n }),\n );\n }\n }\n};\n\nlet previousFeedsCommentsFirstPageCids: string[] = [];\nlet previousFeedsComments: Map<string, Comments> = new Map();\nlet previousFeedsCommentsLoadedCount = 0;\nlet previousFeedsCommentsRepliesPagesFirstUpdatedAts = \"\";\nconst updateFeedsOnFeedsCommentsChange = (repliesCommentsStoreState: any) => {\n const { comments } = repliesCommentsStoreState;\n const { feedsOptions, updateFeeds } = repliesStore.getState();\n\n // feeds comments haven't changed, do nothing\n const feedsComments = getFeedsComments(feedsOptions, comments);\n if (!feedsCommentsChanged(previousFeedsComments, feedsComments)) {\n return;\n }\n previousFeedsComments = feedsComments;\n\n // decide if feeds comments have changed by looking at all feeds comments page cids\n // (in case that a comment changed, but its first page cid didn't)\n const feedsCommentsFirstPageCids = getFeedsCommentsFirstPageCids(feedsComments);\n\n // first page cids haven't changed, do nothing\n if (feedsCommentsFirstPageCids.toString() === previousFeedsCommentsFirstPageCids.toString()) {\n // if no new feed comments have loaded, do nothing\n // in case a comment loads with no first page cid and first pages cids don't change, need to trigger hasMore update\n const feedsCommentsLoadedCount = getFeedsCommentsLoadedCount(feedsComments);\n if (feedsCommentsLoadedCount === previousFeedsCommentsLoadedCount) {\n // if comment.replies.pages haven't changed, do nothing\n const feedsCommentsRepliesPagesFirstUpdatedAts =\n getFeedsCommentsRepliesPagesFirstUpdatedAts(feedsComments);\n if (\n feedsCommentsRepliesPagesFirstUpdatedAts ===\n previousFeedsCommentsRepliesPagesFirstUpdatedAts\n ) {\n return;\n }\n\n previousFeedsCommentsRepliesPagesFirstUpdatedAts = feedsCommentsRepliesPagesFirstUpdatedAts;\n }\n previousFeedsCommentsLoadedCount = feedsCommentsLoadedCount;\n }\n\n // feeds comments have changed, update feeds\n previousFeedsCommentsFirstPageCids = feedsCommentsFirstPageCids;\n updateFeeds();\n};\n\nlet previousAccountsCommentsCount = 0;\nlet previousAccountsCommentsCids = \"\";\nconst updateFeedsOnAccountsCommentsChange = (accountsStoreState: any) => {\n const { accountsComments } = accountsStoreState;\n const accountsCommentsCount = Object.values(accountsComments as Comment[][]).reduce(\n (count, accountComments) => count + accountComments.length,\n 0,\n );\n\n // no changes, do nothing\n if (accountsCommentsCount === previousAccountsCommentsCount) {\n // if cids haven't changed (account comments receive cids after pending), do nothing\n const accountsCommentsCids = Object.values(accountsComments as Comment[][]).reduce(\n (cids, accountComments) => cids + String(accountComments.map((comment) => comment.cid || \"\")),\n \"\",\n );\n if (accountsCommentsCids === previousAccountsCommentsCids) {\n return;\n }\n previousAccountsCommentsCids = accountsCommentsCids;\n }\n previousAccountsCommentsCount = accountsCommentsCount;\n\n // TODO: only update the feeds that are relevant to the new accountComment.parentCid/postCid\n repliesStore.getState().updateFeeds();\n};\n\n// needed to view replies instantly without waiting for zustant store react rerenders. must be synchronous\nexport const getRepliesFirstPageSkipValidation = (\n comment: Comment,\n feedOptions: Partial<RepliesFeedOptions>,\n) => {\n const feedName = `firstPageSkipValidation-${comment?.cid}`;\n const feedsOptions: any = { [feedName]: feedOptions };\n const { accounts } = accountsStore.getState();\n\n // don't use comments store, only use preloaded comment.replies.pages\n const comments = { [comment.cid]: comment };\n\n // don't use any reply pages, they can't provide instant loading like preloaded comment.replies.pages\n const repliesPages = {};\n\n const filteredSortedFeeds = getFilteredSortedFeeds(\n feedsOptions,\n comments,\n repliesPages,\n accounts,\n );\n\n // only get first page and put next page in buffered\n const bufferedFeeds: Feeds = { [feedName]: [] };\n const repliesPerPage = feedOptions.repliesPerPage || defaultRepliesPerPage;\n if (filteredSortedFeeds[feedName].length > repliesPerPage) {\n bufferedFeeds[feedName] = filteredSortedFeeds[feedName].splice(repliesPerPage);\n }\n addAccountsComments(feedsOptions, filteredSortedFeeds);\n\n const feedsHaveMore = getFeedsHaveMore(\n feedsOptions,\n bufferedFeeds,\n comments,\n repliesPages,\n accounts,\n );\n return { replies: filteredSortedFeeds[feedName], hasMore: feedsHaveMore[feedName] };\n};\n\n// reset store in between tests\nconst originalState = repliesStore.getState();\n// async function because some stores have async init\nexport const resetRepliesStore = async () => {\n previousBufferedFeedsReplyCounts = {};\n previousBufferedFeedsReplyCountsPageCids = [];\n previousBufferedFeedsComments = new Map();\n previousFeedsCommentsFirstPageCids = [];\n previousFeedsComments = new Map();\n previousFeedsCommentsLoadedCount = 0;\n previousFeedsCommentsRepliesPagesFirstUpdatedAts = \"\";\n previousRepliesPages = {};\n previousAccountsCommentsCount = 0;\n previousAccountsCommentsCids = \"\";\n updateFeedsPending = false;\n // destroy all component subscriptions to the store\n repliesStore.destroy();\n // restore original state\n repliesStore.setState(originalState);\n repliesCommentsStore.setState({ ...repliesCommentsStore.getState(), comments: {} });\n repliesStoreInitialized = false;\n};\n\n// reset database and store in between tests\nexport const resetRepliesDatabaseAndStore = async () => {\n await localForageLru.createInstance({ name: \"bitsocialReactHooks-repliesPages\" }).clear();\n await resetRepliesStore();\n};\n\nexport default repliesStore;\n"]}
|
|
1
|
+
{"version":3,"file":"replies-store.js","sourceRoot":"","sources":["../../../src/stores/replies/replies-store.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"assert\";\nimport Logger from \"@pkcprotocol/pkc-logger\";\nconst log = Logger(\"bitsocial-react-hooks:replies:stores\");\nimport {\n Feed,\n Feeds,\n Comment,\n Comments,\n Account,\n RepliesFeedOptions,\n RepliesFeedsOptions,\n RepliesPage,\n CommentsFilter,\n} from \"../../types\";\nimport createStore from \"zustand\";\nimport localForageLru from \"../../lib/localforage-lru\";\nimport accountsStore from \"../accounts\";\nimport repliesCommentsStore from \"./replies-comments-store\";\nimport repliesPagesStore from \"../replies-pages\";\nimport {\n getFeedsCommentsFirstPageCids,\n getLoadedFeeds,\n getBufferedFeedsWithoutLoadedFeeds,\n getUpdatedFeeds,\n getFeedsReplyCounts,\n getFeedsHaveMore,\n feedsCommentsChanged,\n getFeedsComments,\n getFeedsCommentsLoadedCount,\n getFeedsCommentsRepliesPagesFirstUpdatedAts,\n getFilteredSortedFeeds,\n getSortTypeFromComment,\n addAccountsComments,\n} from \"./utils\";\n\n// reddit loads approximately 25 posts per page\n// while infinite scrolling\nexport const defaultRepliesPerPage = 25;\n\n// keep large buffer because fetching cids is slow\nconst commentRepliesLeftBeforeNextPage = 50;\n\nexport type RepliesState = {\n feedsOptions: RepliesFeedsOptions;\n bufferedFeeds: Feeds;\n loadedFeeds: Feeds;\n updatedFeeds: Feeds;\n bufferedFeedsReplyCounts: { [feedName: string]: number };\n feedsHaveMore: { [feedName: string]: boolean };\n addFeedsToStore: Function;\n addFeedToStoreOrUpdateComment: Function;\n incrementFeedPageNumber: Function;\n resetFeed: Function;\n updateFeeds: Function;\n};\n\nconst defaultAccountComments = { newerThan: Infinity, append: false };\nconst addDefaultFeedOptions = (feedOptions: any) => {\n feedOptions = { ...feedOptions };\n if (feedOptions.flat === undefined || feedOptions.flat === null) {\n feedOptions.flat = false;\n }\n feedOptions.onlyIfCached = feedOptions.onlyIfCached === true;\n if (feedOptions.accountComments === undefined || feedOptions.accountComments === null) {\n feedOptions.accountComments = defaultAccountComments;\n }\n feedOptions.repliesPerPage = feedOptions.repliesPerPage || defaultRepliesPerPage;\n return feedOptions;\n};\n\nexport const feedOptionsToFeedName = (feedOptions: Partial<RepliesFeedOptions>) => {\n feedOptions = addDefaultFeedOptions(feedOptions);\n return `${feedOptions?.accountId}-${feedOptions?.commentCid}-${feedOptions?.postCid}-${feedOptions?.sortType}-${feedOptions?.flat}-${feedOptions?.onlyIfCached}-${feedOptions?.accountComments?.newerThan}-${feedOptions?.accountComments?.append}-${feedOptions?.repliesPerPage}-${feedOptions?.filter?.key}-${feedOptions?.streamPage}`;\n};\n\nconst getFeedsUpdatedAts = (feedsOptions: RepliesFeedsOptions, comments: Comments) => {\n const feedsUpdatedAts: { [feedName: string]: number | undefined } = {};\n for (const feedName in feedsOptions) {\n feedsUpdatedAts[feedName] = comments[feedsOptions[feedName].commentCid]?.updatedAt;\n }\n return feedsUpdatedAts;\n};\n\n// don't updateFeeds more than once per updateFeedsMinIntervalTime\nlet updateFeedsPending = false;\nlet updateFeedsAgain = false;\nconst updateFeedsMinIntervalTime = 100;\n\nconst repliesStore = createStore<RepliesState>((setState: Function, getState: Function) => ({\n feedsOptions: {},\n bufferedFeeds: {},\n loadedFeeds: {},\n updatedFeeds: {},\n bufferedFeedsReplyCounts: {},\n feedsHaveMore: {},\n\n addFeedsToStore(feedOptionsArray: RepliesFeedOptions[]) {\n if (!feedOptionsArray.length) {\n return;\n }\n const { feedsOptions: previousFeedsOptions } = getState();\n const newFeedsOptions: RepliesFeedsOptions = {};\n\n // get all newFeedsOptions\n for (let feedOptions of feedOptionsArray) {\n const feedName = feedOptionsToFeedName(feedOptions);\n // feed is in store already, do nothing\n // if the feed already exist but is at page 0, reset it to page 1\n if (previousFeedsOptions[feedName] && previousFeedsOptions[feedName].pageNumber !== 0) {\n continue;\n }\n\n feedOptions = addDefaultFeedOptions(feedOptions);\n\n // to add a buffered feed, add a feed with pageNumber 0\n feedOptions.pageNumber = 1;\n newFeedsOptions[feedName] = feedOptions;\n }\n\n // set new feedsOptions state (first loop already skips existing feeds)\n let feedsChanged = false;\n setState(({ feedsOptions }: RepliesState) => {\n if (!Object.keys(newFeedsOptions).length) return {};\n feedsChanged = true;\n return { feedsOptions: { ...feedsOptions, ...newFeedsOptions } };\n });\n if (feedsChanged) {\n log(\"repliesStore.addFeedsToStore\", newFeedsOptions);\n }\n return feedsChanged;\n },\n\n async addFeedToStoreOrUpdateComment(comment: Comment, feedOptions: RepliesFeedOptions) {\n // init here because must be called after async accounts store finished initializing\n initializeRepliesStore();\n\n // validate options\n assert(\n comment && comment.cid && typeof comment.cid === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment comment.cid '${comment?.cid}' invalid`,\n );\n assert(\n feedOptions.commentCid && typeof feedOptions.commentCid === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.commentCid '${feedOptions.commentCid}' invalid`,\n );\n assert(\n feedOptions.sortType && typeof feedOptions.sortType === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.sortType '${feedOptions.sortType}' invalid`,\n );\n const account = accountsStore.getState().accounts[feedOptions.accountId];\n assert(\n typeof account?.pkc?.createComment === \"function\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.accountId '${feedOptions.accountId}' invalid`,\n );\n assert(\n !feedOptions.repliesPerPage || typeof feedOptions.repliesPerPage === \"number\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.repliesPerPage '${feedOptions.repliesPerPage}' invalid`,\n );\n assert(\n !feedOptions.filter || typeof feedOptions.filter?.filter === \"function\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.filter.filter '${feedOptions.filter?.filter}' invalid`,\n );\n assert(\n !feedOptions.filter || typeof feedOptions.filter?.key === \"string\",\n `repliesStore.addFeedToStoreOrUpdateComment feedOptions.filter.key '${feedOptions.filter?.key}' invalid`,\n );\n\n // if replies feed aren't in store yet, add them recursively\n // TODO: optimize performance by only adding feeds that are in page 1, and add more on each page increase\n const commentsToAddToStoreOrUpdate: Comment[] = [];\n const feedsToAddToStore: RepliesFeedOptions[] = [];\n\n // use the sort type availabe on the comment when missing\n const sortType = getSortTypeFromComment(comment, feedOptions);\n\n const addRepliesFeedsToStoreRecursively = (comment: Comment) => {\n // NOTE: even a comment with no replies needs a feed, to know it has 0 replies and not displace the UI when a new replies appears\n commentsToAddToStoreOrUpdate.push(comment);\n feedsToAddToStore.push({\n ...feedOptions,\n commentCid: comment?.cid,\n commentDepth: comment?.depth,\n });\n\n // flat doesn't need nested feeds\n if (!feedOptions.flat) {\n for (const reply of comment.replies?.pages?.[sortType]?.comments || []) {\n addRepliesFeedsToStoreRecursively(reply);\n }\n }\n };\n addRepliesFeedsToStoreRecursively(comment);\n\n // add feeds to store and update feeds\n const { addFeedsToStore, updateFeeds } = getState();\n const feedsChanged = addFeedsToStore(feedsToAddToStore);\n // add comments to store (do it after addFeedsToStore because it can trigger updateFeeds)\n repliesCommentsStore\n .getState()\n .addCommentsToStoreOrUpdateComments(commentsToAddToStoreOrUpdate);\n if (feedsChanged) {\n log(\"repliesStore.addFeedToStoreOrUpdateComment\", {\n comment,\n feedOptions,\n sortType,\n feedsToAddToStore,\n commentsToAddToStoreOrUpdate,\n });\n updateFeeds();\n }\n },\n\n incrementFeedPageNumber(feedName: string) {\n const { feedsOptions, loadedFeeds, bufferedFeeds, updateFeeds } = getState();\n assert(\n feedsOptions[feedName],\n `repliesStore.incrementFeedPageNumber feed name '${feedName}' does not exist in feeds store`,\n );\n log(\"repliesStore.incrementFeedPageNumber\", { feedName });\n\n // TODO: fix design issue, pageNumber shouldnt be increased when loadMore is called and repliesPerPage not reached\n // assert(\n // feedsOptions[feedName].pageNumber * feedsOptions[feedName].repliesPerPage <= loadedFeeds[feedName].length,\n // `repliesStore.incrementFeedPageNumber cannot increment feed page number before current page has loaded`\n // )\n if (\n feedsOptions[feedName].pageNumber * feedsOptions[feedName].repliesPerPage <=\n loadedFeeds[feedName].length\n ) {\n assert(\n bufferedFeeds[feedName].length > 0,\n `repliesStore.incrementFeedPageNumber cannot increment feed page number before current page has loaded`,\n );\n }\n\n setState(({ feedsOptions, loadedFeeds }: any) => {\n // don't increment page number before the current page has loaded\n // if (feedsOptions[feedName].pageNumber * feedsOptions[feedName].repliesPerPage > loadedFeeds[feedName].length) {\n // return {}\n // }\n const feedOptions = {\n ...feedsOptions[feedName],\n pageNumber: feedsOptions[feedName].pageNumber + 1,\n };\n return { feedsOptions: { ...feedsOptions, [feedName]: feedOptions } };\n });\n\n // do not update feed at the same time as increment a page number or it might cause\n // a race condition, rather schedule a feed update\n updateFeeds();\n },\n\n resetFeed(feedName: string) {\n const { feedsOptions, updateFeeds } = getState();\n assert(\n feedsOptions[feedName],\n `repliesStore.resetFeed feed name '${feedName}' does not exist in feeds store`,\n );\n assert(\n feedsOptions[feedName].pageNumber >= 1,\n `repliesStore.resetFeed cannot reset feed page number '${feedsOptions[feedName].pageNumber}' lower than 1`,\n );\n log(\"repliesStore.resetFeed\", { feedName });\n\n setState(({ feedsOptions, loadedFeeds, updatedFeeds }: any) => {\n const feedOptions = {\n ...feedsOptions[feedName],\n pageNumber: 1,\n };\n return {\n feedsOptions: { ...feedsOptions, [feedName]: feedOptions },\n loadedFeeds: { ...loadedFeeds, [feedName]: [] },\n updatedFeeds: { ...updatedFeeds, [feedName]: [] },\n };\n });\n\n updateFeeds();\n },\n\n // recalculate all feeds using new comments.replies.pages, repliesPagesStore and page numbers\n updateFeeds() {\n if (updateFeedsPending) {\n updateFeedsAgain = true;\n return;\n }\n updateFeedsPending = true;\n\n // don't update feeds more than once per updateFeedsMinIntervalTime\n const timeUntilNextUpdate = Date.now() % updateFeedsMinIntervalTime;\n\n setTimeout(async () => {\n // get state from all stores\n const previousState = getState();\n const { feedsOptions, updateFeeds } = previousState;\n const { comments } = repliesCommentsStore.getState();\n const { repliesPages } = repliesPagesStore.getState();\n const { accounts } = accountsStore.getState();\n\n // calculate new feeds\n const filteredSortedFeeds = getFilteredSortedFeeds(\n feedsOptions,\n comments,\n repliesPages,\n accounts,\n );\n const bufferedFeedsWithoutPreviousLoadedFeeds = getBufferedFeedsWithoutLoadedFeeds(\n filteredSortedFeeds,\n previousState.loadedFeeds,\n );\n const canonicalLoadedFeeds = await getLoadedFeeds(\n feedsOptions,\n previousState.loadedFeeds,\n bufferedFeedsWithoutPreviousLoadedFeeds,\n accounts,\n { addAccountComments: false },\n );\n const canonicalBufferedFeeds = getBufferedFeedsWithoutLoadedFeeds(\n bufferedFeedsWithoutPreviousLoadedFeeds,\n canonicalLoadedFeeds,\n );\n const canonicalFeedsHaveMore = getFeedsHaveMore(\n feedsOptions,\n canonicalBufferedFeeds,\n comments,\n repliesPages,\n accounts,\n );\n const canonicalFeedsUpdatedAts = getFeedsUpdatedAts(feedsOptions, comments);\n const loadedFeedsWithAccountComments = { ...canonicalLoadedFeeds };\n const accountCommentsChangedFeeds = addAccountsComments(\n feedsOptions,\n loadedFeedsWithAccountComments,\n canonicalFeedsHaveMore,\n canonicalFeedsUpdatedAts,\n );\n const loadedFeeds = accountCommentsChangedFeeds\n ? loadedFeedsWithAccountComments\n : canonicalLoadedFeeds;\n // after loaded feeds are caculated, remove new loaded feeds (again) from buffered feeds\n const bufferedFeeds = getBufferedFeedsWithoutLoadedFeeds(\n bufferedFeedsWithoutPreviousLoadedFeeds,\n loadedFeeds,\n );\n const bufferedFeedsReplyCounts = getFeedsReplyCounts(feedsOptions, bufferedFeeds);\n const feedsHaveMore = getFeedsHaveMore(\n feedsOptions,\n bufferedFeeds,\n comments,\n repliesPages,\n accounts,\n );\n const updatedFeeds = await getUpdatedFeeds(\n feedsOptions,\n filteredSortedFeeds,\n previousState.updatedFeeds,\n loadedFeeds,\n accounts,\n );\n\n // set new feeds\n setState((state: any) => ({\n bufferedFeeds,\n loadedFeeds,\n bufferedFeedsReplyCounts,\n updatedFeeds,\n feedsHaveMore,\n }));\n log(\"repliesStore.updateFeeds\", {\n feedsOptions,\n bufferedFeeds,\n loadedFeeds,\n bufferedFeedsReplyCounts,\n updatedFeeds,\n feedsHaveMore,\n comments,\n repliesPages,\n });\n\n updateFeedsPending = false;\n\n // if updateFeeds was called while updateFeedsPending = true, call updateFeeds again\n if (updateFeedsAgain) {\n updateFeedsAgain = false;\n updateFeeds();\n }\n }, timeUntilNextUpdate);\n },\n}));\n\nlet repliesStoreInitialized = false;\nconst initializeRepliesStore = async () => {\n if (repliesStoreInitialized) {\n return;\n }\n repliesStoreInitialized = true;\n // TODO: optimize subscriptions e.g. updateFeedsOnFeedsCommentsChange(comment)\n // subscribe to comments store changes\n repliesCommentsStore.subscribe(updateFeedsOnFeedsCommentsChange);\n // subscribe to bufferedFeedsReplyCounts change\n repliesStore.subscribe(addRepliesPagesOnLowBufferedFeedsReplyCounts);\n // subscribe to replies pages store changes\n repliesPagesStore.subscribe(updateFeedsOnFeedsRepliesPagesChange);\n // subscribe to accounts store changes\n accountsStore.subscribe(updateFeedsOnAccountsCommentsChange);\n};\n\nlet previousRepliesPages: { [pageCid: string]: RepliesPage } = {};\nconst updateFeedsOnFeedsRepliesPagesChange = (repliesPagesStoreState: any) => {\n const { repliesPages } = repliesPagesStoreState;\n\n // no changes, do nothing\n if (repliesPages === previousRepliesPages) {\n return;\n }\n previousRepliesPages = repliesPages;\n\n // currently only the feeds use repliesPagesStore, so any change must\n // trigger a feed update, if in the future another hook uses the repliesPagesStore\n // we should check if the replies pages changed are actually used by the feeds before\n // triggering an update\n repliesStore.getState().updateFeeds();\n};\n\nlet previousBufferedFeedsReplyCountsPageCids: string[] = [];\nlet previousBufferedFeedsComments = new Map<string, Comments>();\nlet previousBufferedFeedsReplyCounts: { [feedName: string]: number } = {};\nconst addRepliesPagesOnLowBufferedFeedsReplyCounts = (repliesStoreState: any) => {\n const { bufferedFeedsReplyCounts, feedsOptions } = repliesStore.getState();\n const { comments } = repliesCommentsStore.getState();\n\n // if feeds comments have changed, we must try adding them even if buffered replies counts haven't changed\n const bufferedFeedsComments = getFeedsComments(feedsOptions, comments);\n const _feedsCommentsChanged = feedsCommentsChanged(\n previousBufferedFeedsComments,\n bufferedFeedsComments,\n );\n const bufferedFeedsReplyCountsChanged =\n previousBufferedFeedsReplyCounts !== bufferedFeedsReplyCounts;\n\n // if feeds comments havent changed and buffered replies counts also havent changed, do nothing\n if (!_feedsCommentsChanged && !bufferedFeedsReplyCountsChanged) {\n return;\n }\n previousBufferedFeedsComments = bufferedFeedsComments;\n previousBufferedFeedsReplyCounts = bufferedFeedsReplyCounts;\n\n // in case feeds comments changed, but the first page cids haven't\n const bufferedFeedsReplyCountsPageCids = getFeedsCommentsFirstPageCids(bufferedFeedsComments);\n const bufferedFeedsReplyCountsPageCidsChanged =\n bufferedFeedsReplyCountsPageCids.toString() !==\n previousBufferedFeedsReplyCountsPageCids.toString();\n if (!bufferedFeedsReplyCountsPageCidsChanged && !bufferedFeedsReplyCountsChanged) {\n return;\n }\n previousBufferedFeedsReplyCountsPageCids = bufferedFeedsReplyCountsPageCids;\n\n const { addNextRepliesPageToStore } = repliesPagesStore.getState();\n const { accounts } = accountsStore.getState();\n\n // bufferedFeedsReplyCounts have changed, check if any of them are low\n for (const feedName in bufferedFeedsReplyCounts) {\n if (feedsOptions[feedName].onlyIfCached) {\n continue;\n }\n const account = accounts[feedsOptions[feedName].accountId];\n const feedReplyCount = bufferedFeedsReplyCounts[feedName];\n let sortType = feedsOptions[feedName].sortType;\n const commentCid = feedsOptions[feedName].commentCid;\n\n // TODO: maybe skip if comment community address, comment cid or comment author is blocked?\n\n // comment hasn't loaded yet\n if (!comments[commentCid]) {\n continue;\n }\n\n sortType = getSortTypeFromComment(comments[commentCid], feedsOptions[feedName]);\n\n // comment replies count is low, fetch next replies page\n if (feedReplyCount <= commentRepliesLeftBeforeNextPage) {\n addNextRepliesPageToStore(comments[commentCid], sortType, account).catch((error: unknown) =>\n log.error(\"repliesStore repliesPagesStore.addNextRepliesPageToStore error\", {\n commentCid,\n comment: comments[commentCid],\n sortType,\n error,\n }),\n );\n }\n }\n};\n\nlet previousFeedsCommentsFirstPageCids: string[] = [];\nlet previousFeedsComments: Map<string, Comments> = new Map();\nlet previousFeedsCommentsLoadedCount = 0;\nlet previousFeedsCommentsRepliesPagesFirstUpdatedAts = \"\";\nconst updateFeedsOnFeedsCommentsChange = (repliesCommentsStoreState: any) => {\n const { comments } = repliesCommentsStoreState;\n const { feedsOptions, updateFeeds } = repliesStore.getState();\n\n // feeds comments haven't changed, do nothing\n const feedsComments = getFeedsComments(feedsOptions, comments);\n if (!feedsCommentsChanged(previousFeedsComments, feedsComments)) {\n return;\n }\n previousFeedsComments = feedsComments;\n\n // decide if feeds comments have changed by looking at all feeds comments page cids\n // (in case that a comment changed, but its first page cid didn't)\n const feedsCommentsFirstPageCids = getFeedsCommentsFirstPageCids(feedsComments);\n\n // first page cids haven't changed, do nothing\n if (feedsCommentsFirstPageCids.toString() === previousFeedsCommentsFirstPageCids.toString()) {\n // if no new feed comments have loaded, do nothing\n // in case a comment loads with no first page cid and first pages cids don't change, need to trigger hasMore update\n const feedsCommentsLoadedCount = getFeedsCommentsLoadedCount(feedsComments);\n if (feedsCommentsLoadedCount === previousFeedsCommentsLoadedCount) {\n // if comment.replies.pages haven't changed, do nothing\n const feedsCommentsRepliesPagesFirstUpdatedAts =\n getFeedsCommentsRepliesPagesFirstUpdatedAts(feedsComments);\n if (\n feedsCommentsRepliesPagesFirstUpdatedAts ===\n previousFeedsCommentsRepliesPagesFirstUpdatedAts\n ) {\n return;\n }\n\n previousFeedsCommentsRepliesPagesFirstUpdatedAts = feedsCommentsRepliesPagesFirstUpdatedAts;\n }\n previousFeedsCommentsLoadedCount = feedsCommentsLoadedCount;\n }\n\n // feeds comments have changed, update feeds\n previousFeedsCommentsFirstPageCids = feedsCommentsFirstPageCids;\n updateFeeds();\n};\n\nlet previousAccountsCommentsCount = 0;\nlet previousAccountsCommentsCids = \"\";\nconst updateFeedsOnAccountsCommentsChange = (accountsStoreState: any) => {\n const { accountsComments } = accountsStoreState;\n const accountsCommentsCount = Object.values(accountsComments as Comment[][]).reduce(\n (count, accountComments) => count + accountComments.length,\n 0,\n );\n\n // no changes, do nothing\n if (accountsCommentsCount === previousAccountsCommentsCount) {\n // if cids haven't changed (account comments receive cids after pending), do nothing\n const accountsCommentsCids = Object.values(accountsComments as Comment[][]).reduce(\n (cids, accountComments) => cids + String(accountComments.map((comment) => comment.cid || \"\")),\n \"\",\n );\n if (accountsCommentsCids === previousAccountsCommentsCids) {\n return;\n }\n previousAccountsCommentsCids = accountsCommentsCids;\n }\n previousAccountsCommentsCount = accountsCommentsCount;\n\n // TODO: only update the feeds that are relevant to the new accountComment.parentCid/postCid\n repliesStore.getState().updateFeeds();\n};\n\n// needed to view replies instantly without waiting for zustant store react rerenders. must be synchronous\nexport const getRepliesFirstPageSkipValidation = (\n comment: Comment,\n feedOptions: Partial<RepliesFeedOptions>,\n) => {\n const feedName = `firstPageSkipValidation-${comment?.cid}`;\n const feedsOptions: any = { [feedName]: feedOptions };\n const { accounts } = accountsStore.getState();\n\n // don't use comments store, only use preloaded comment.replies.pages\n const comments = { [comment.cid]: comment };\n\n // don't use any reply pages, they can't provide instant loading like preloaded comment.replies.pages\n const repliesPages = {};\n\n const filteredSortedFeeds = getFilteredSortedFeeds(\n feedsOptions,\n comments,\n repliesPages,\n accounts,\n );\n\n // only get first page and put next page in buffered\n const bufferedFeeds: Feeds = { [feedName]: [] };\n const repliesPerPage = feedOptions.repliesPerPage || defaultRepliesPerPage;\n if (filteredSortedFeeds[feedName].length > repliesPerPage) {\n bufferedFeeds[feedName] = filteredSortedFeeds[feedName].splice(repliesPerPage);\n }\n const feedsHaveMore = getFeedsHaveMore(\n feedsOptions,\n bufferedFeeds,\n comments,\n repliesPages,\n accounts,\n );\n addAccountsComments(feedsOptions, filteredSortedFeeds, feedsHaveMore, {\n [feedName]: comment.updatedAt,\n });\n return { replies: filteredSortedFeeds[feedName], hasMore: feedsHaveMore[feedName] };\n};\n\n// reset store in between tests\nconst originalState = repliesStore.getState();\n// async function because some stores have async init\nexport const resetRepliesStore = async () => {\n previousBufferedFeedsReplyCounts = {};\n previousBufferedFeedsReplyCountsPageCids = [];\n previousBufferedFeedsComments = new Map();\n previousFeedsCommentsFirstPageCids = [];\n previousFeedsComments = new Map();\n previousFeedsCommentsLoadedCount = 0;\n previousFeedsCommentsRepliesPagesFirstUpdatedAts = \"\";\n previousRepliesPages = {};\n previousAccountsCommentsCount = 0;\n previousAccountsCommentsCids = \"\";\n updateFeedsPending = false;\n // destroy all component subscriptions to the store\n repliesStore.destroy();\n // restore original state\n repliesStore.setState(originalState);\n repliesCommentsStore.setState({ ...repliesCommentsStore.getState(), comments: {} });\n repliesStoreInitialized = false;\n};\n\n// reset database and store in between tests\nexport const resetRepliesDatabaseAndStore = async () => {\n await localForageLru.createInstance({ name: \"bitsocialReactHooks-repliesPages\" }).clear();\n await resetRepliesStore();\n};\n\nexport default repliesStore;\n"]}
|
|
@@ -3,8 +3,21 @@ import { Feeds, RepliesFeedOptions, RepliesFeedsOptions, Comment, Comments, Acco
|
|
|
3
3
|
* Calculate the feeds from all the loaded replies pages, filter and sort them
|
|
4
4
|
*/
|
|
5
5
|
export declare const getFilteredSortedFeeds: (feedsOptions: RepliesFeedsOptions, comments: Comments, repliesPages: RepliesPages, accounts: Accounts) => Feeds;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
type GetLoadedFeedsOptions = {
|
|
7
|
+
addAccountComments?: boolean;
|
|
8
|
+
feedsHaveMore?: {
|
|
9
|
+
[feedName: string]: boolean;
|
|
10
|
+
};
|
|
11
|
+
feedsUpdatedAts?: {
|
|
12
|
+
[feedName: string]: number | undefined;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare const getLoadedFeeds: (feedsOptions: RepliesFeedsOptions, loadedFeeds: Feeds, bufferedFeeds: Feeds, accounts: Accounts, options?: GetLoadedFeedsOptions) => Promise<Feeds>;
|
|
16
|
+
export declare const addAccountsComments: (feedsOptions: RepliesFeedsOptions, loadedFeeds: Feeds, feedsHaveMore?: {
|
|
17
|
+
[feedName: string]: boolean;
|
|
18
|
+
}, feedsUpdatedAts?: {
|
|
19
|
+
[feedName: string]: number | undefined;
|
|
20
|
+
}) => boolean;
|
|
8
21
|
export declare const getBufferedFeedsWithoutLoadedFeeds: (bufferedFeeds: Feeds, loadedFeeds: Feeds) => Feeds;
|
|
9
22
|
export declare const getUpdatedFeeds: (feedsOptions: RepliesFeedsOptions, filteredSortedFeeds: Feeds, updatedFeeds: Feeds, loadedFeeds: Feeds, accounts: Accounts) => Promise<Feeds>;
|
|
10
23
|
export declare const getFeedsReplyCounts: (feedsOptions: RepliesFeedsOptions, feeds: Feeds) => {
|
|
@@ -22,4 +35,5 @@ export declare const getFeedsCommentsFirstPageCids: (feedsComments: Map<string,
|
|
|
22
35
|
export declare const getFeedsCommentsRepliesPagesFirstUpdatedAts: (feedsComments: Map<string, Comment>) => string;
|
|
23
36
|
export declare const getFeedsCommentsLoadedCount: (feedsComments: Map<string, Comment>) => number;
|
|
24
37
|
export declare const getSortTypeFromComment: (comment: Comment, feedOptions: RepliesFeedOptions) => string;
|
|
38
|
+
export {};
|
|
25
39
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/stores/replies/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,EACL,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,EACP,QAAQ,EAER,QAAQ,EAER,YAAY,EACb,MAAM,aAAa,CAAC;AASrB;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,cAAc,mBAAmB,EACjC,UAAU,QAAQ,EAClB,cAAc,YAAY,EAC1B,UAAU,QAAQ,UAmEnB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/stores/replies/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,EACL,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,EACP,QAAQ,EAER,QAAQ,EAER,YAAY,EACb,MAAM,aAAa,CAAC;AASrB;;GAEG;AACH,eAAO,MAAM,sBAAsB,GACjC,cAAc,mBAAmB,EACjC,UAAU,QAAQ,EAClB,cAAc,YAAY,EAC1B,UAAU,QAAQ,UAmEnB,CAAC;AA8FF,KAAK,qBAAqB,GAAG;IAC3B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAChD,eAAe,CAAC,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CAC9D,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,cAAc,mBAAmB,EACjC,aAAa,KAAK,EAClB,eAAe,KAAK,EACpB,UAAU,QAAQ,EAClB,UAAS,qBAA0B,mBA0EpC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,cAAc,mBAAmB,EACjC,aAAa,KAAK,EAClB,gBAAgB;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAC/C,kBAAkB;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,YAoI7D,CAAC;AAEF,eAAO,MAAM,kCAAkC,GAAI,eAAe,KAAK,EAAE,aAAa,KAAK,UAoC1F,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,cAAc,mBAAmB,EACjC,qBAAqB,KAAK,EAC1B,cAAc,KAAK,EACnB,aAAa,KAAK,EAClB,UAAU,QAAQ,mBAmEnB,CAAC;AAIF,eAAO,MAAM,mBAAmB,GAAI,cAAc,mBAAmB,EAAE,OAAO,KAAK;;CAMlF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,cAAc,mBAAmB,EACjC,eAAe,KAAK,EACpB,UAAU,QAAQ,EAClB,cAAc,YAAY,EAC1B,UAAU,QAAQ;;CA+CnB,CAAC;AAGF,eAAO,MAAM,gBAAgB,GAAI,cAAc,mBAAmB,EAAE,UAAU,QAAQ,yBASrF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,uBAAuB,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,YAYpC,CAAC;AAGF,eAAO,MAAM,6BAA6B,GAAI,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAAM,EA4BzF,CAAC;AAGF,eAAO,MAAM,2CAA2C,GACtD,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,KAClC,MAWF,CAAC;AAGF,eAAO,MAAM,2BAA2B,GAAI,eAAe,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,MAQjF,CAAC;AAGF,eAAO,MAAM,sBAAsB,GAAI,SAAS,OAAO,EAAE,aAAa,kBAAkB,WA0EvF,CAAC"}
|
|
@@ -132,7 +132,21 @@ const getApprovalPublicationKey = (comment) => {
|
|
|
132
132
|
(_j = comment.link) !== null && _j !== void 0 ? _j : "",
|
|
133
133
|
].join("\0");
|
|
134
134
|
};
|
|
135
|
-
|
|
135
|
+
const isActivePublishingState = (publishingState) => publishingState === "pending" ||
|
|
136
|
+
(publishingState === null || publishingState === void 0 ? void 0 : publishingState.startsWith("publishing")) ||
|
|
137
|
+
(publishingState === null || publishingState === void 0 ? void 0 : publishingState.startsWith("waiting-")) ||
|
|
138
|
+
(publishingState === null || publishingState === void 0 ? void 0 : publishingState.startsWith("fetching-link-dimensions"));
|
|
139
|
+
const isPublishedAccountReply = (reply) => typeof (reply === null || reply === void 0 ? void 0 : reply.index) === "number" &&
|
|
140
|
+
!!reply.cid &&
|
|
141
|
+
reply.pendingApproval !== true &&
|
|
142
|
+
!isActivePublishingState(reply.publishingState);
|
|
143
|
+
const canonicalFeedRefreshedAfterReply = (reply, feedUpdatedAt) => typeof feedUpdatedAt !== "number" ||
|
|
144
|
+
typeof reply.timestamp !== "number" ||
|
|
145
|
+
feedUpdatedAt > reply.timestamp;
|
|
146
|
+
const shouldHidePublishedAccountReply = (reply, hidePublishedAccountReplies, feedUpdatedAt) => hidePublishedAccountReplies &&
|
|
147
|
+
isPublishedAccountReply(reply) &&
|
|
148
|
+
canonicalFeedRefreshedAfterReply(reply, feedUpdatedAt);
|
|
149
|
+
export const getLoadedFeeds = (feedsOptions_1, loadedFeeds_1, bufferedFeeds_1, accounts_1, ...args_1) => __awaiter(void 0, [feedsOptions_1, loadedFeeds_1, bufferedFeeds_1, accounts_1, ...args_1], void 0, function* (feedsOptions, loadedFeeds, bufferedFeeds, accounts, options = {}) {
|
|
136
150
|
var _a;
|
|
137
151
|
const loadedFeedsMissingReplies = {};
|
|
138
152
|
for (const feedName in feedsOptions) {
|
|
@@ -177,14 +191,16 @@ export const getLoadedFeeds = (feedsOptions, loadedFeeds, bufferedFeeds, account
|
|
|
177
191
|
}
|
|
178
192
|
// add account comments
|
|
179
193
|
newLoadedFeeds = Object.assign(Object.assign({}, loadedFeeds), newLoadedFeeds);
|
|
180
|
-
const accountCommentsChangedFeeds =
|
|
194
|
+
const accountCommentsChangedFeeds = options.addAccountComments === false
|
|
195
|
+
? false
|
|
196
|
+
: addAccountsComments(feedsOptions, newLoadedFeeds, options.feedsHaveMore, options.feedsUpdatedAts);
|
|
181
197
|
// do nothing if there are no missing replies
|
|
182
198
|
if (Object.keys(loadedFeedsMissingReplies).length === 0 && !accountCommentsChangedFeeds) {
|
|
183
199
|
return loadedFeeds;
|
|
184
200
|
}
|
|
185
201
|
return newLoadedFeeds;
|
|
186
202
|
});
|
|
187
|
-
export const addAccountsComments = (feedsOptions, loadedFeeds) => {
|
|
203
|
+
export const addAccountsComments = (feedsOptions, loadedFeeds, feedsHaveMore, feedsUpdatedAts) => {
|
|
188
204
|
let loadedFeedsChanged = false;
|
|
189
205
|
const accountsComments = accountsStore.getState().accountsComments || {};
|
|
190
206
|
for (const feedName in feedsOptions) {
|
|
@@ -195,8 +211,13 @@ export const addAccountsComments = (feedsOptions, loadedFeeds) => {
|
|
|
195
211
|
}
|
|
196
212
|
const newerThanTimestamp = newerThan === Infinity ? 0 : Math.floor(Date.now() / 1000) - newerThan;
|
|
197
213
|
const isNewerThan = (reply) => reply.timestamp > newerThanTimestamp;
|
|
214
|
+
const hidePublishedAccountReplies = (feedsHaveMore === null || feedsHaveMore === void 0 ? void 0 : feedsHaveMore[feedName]) === false;
|
|
215
|
+
const feedUpdatedAt = feedsUpdatedAts === null || feedsUpdatedAts === void 0 ? void 0 : feedsUpdatedAts[feedName];
|
|
198
216
|
const accountComments = accountsComments[accountId] || [];
|
|
199
217
|
const accountReplies = accountComments.filter((reply) => {
|
|
218
|
+
if (shouldHidePublishedAccountReply(reply, hidePublishedAccountReplies, feedUpdatedAt)) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
200
221
|
if (!isNewerThan(reply)) {
|
|
201
222
|
return false;
|
|
202
223
|
}
|
|
@@ -223,12 +244,12 @@ export const addAccountsComments = (feedsOptions, loadedFeeds) => {
|
|
|
223
244
|
prunedLoadedFeed.push(reply);
|
|
224
245
|
continue;
|
|
225
246
|
}
|
|
226
|
-
if (reply
|
|
227
|
-
approvedPublicationKeys.has(getApprovalPublicationKey(reply))) {
|
|
247
|
+
if (shouldHidePublishedAccountReply(reply, hidePublishedAccountReplies, feedUpdatedAt)) {
|
|
228
248
|
loadedFeedsChanged = true;
|
|
229
249
|
continue;
|
|
230
250
|
}
|
|
231
|
-
if (
|
|
251
|
+
if (reply.pendingApproval === true &&
|
|
252
|
+
approvedPublicationKeys.has(getApprovalPublicationKey(reply))) {
|
|
232
253
|
loadedFeedsChanged = true;
|
|
233
254
|
continue;
|
|
234
255
|
}
|
|
@@ -240,6 +261,10 @@ export const addAccountsComments = (feedsOptions, loadedFeeds) => {
|
|
|
240
261
|
continue;
|
|
241
262
|
}
|
|
242
263
|
}
|
|
264
|
+
if (!validAccountIndices.has(reply.index)) {
|
|
265
|
+
loadedFeedsChanged = true;
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
243
268
|
prunedLoadedFeed.push(reply);
|
|
244
269
|
}
|
|
245
270
|
loadedFeed = loadedFeeds[feedName] = prunedLoadedFeed;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/stores/replies/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"assert\";\nimport {\n Feed,\n Feeds,\n RepliesFeedOptions,\n RepliesFeedsOptions,\n Comment,\n Comments,\n Account,\n Accounts,\n RepliesPage,\n RepliesPages,\n} from \"../../types\";\nimport { getRepliesPages, getRepliesFirstPageCid } from \"../replies-pages\";\nimport repliesSorter from \"../feeds/feed-sorter\";\nimport accountsStore from \"../accounts\";\nimport { flattenCommentsPages, commentIsValid, removeInvalidComments } from \"../../lib/utils\";\nimport { areEquivalentCommunityAddresses } from \"../../lib/community-address\";\nimport Logger from \"@pkcprotocol/pkc-logger\";\nconst log = Logger(\"bitsocial-react-hooks:replies:stores\");\n\n/**\n * Calculate the feeds from all the loaded replies pages, filter and sort them\n */\nexport const getFilteredSortedFeeds = (\n feedsOptions: RepliesFeedsOptions,\n comments: Comments,\n repliesPages: RepliesPages,\n accounts: Accounts,\n) => {\n // calculate each feed\n let feeds: Feeds = {};\n for (const feedName in feedsOptions) {\n let { commentCid, sortType, accountId, filter, flat } = feedsOptions[feedName];\n\n // find all fetched replies\n let bufferedFeedReplies = [];\n const comment = comments[commentCid];\n\n sortType = getSortTypeFromComment(comment, feedsOptions[feedName]);\n\n // comment has loaded and cache not expired\n if (comment) {\n // use comment preloaded replies if any\n const preloadedReplies = getPreloadedReplies(comment, sortType);\n if (preloadedReplies) {\n for (const reply of preloadedReplies) {\n // replies are manually validated, could have fake communityAddress\n if (!areEquivalentCommunityAddresses(reply.communityAddress, comment.communityAddress)) {\n break;\n }\n bufferedFeedReplies.push(reply);\n }\n }\n\n // add all replies from comment replies pages\n const _repliesPages = getRepliesPages(comment, sortType, repliesPages);\n for (const repliesPage of _repliesPages) {\n if (repliesPage?.comments) {\n for (const reply of repliesPage.comments) {\n // replies are manually validated, could have fake communityAddress\n if (\n !areEquivalentCommunityAddresses(reply.communityAddress, comment.communityAddress)\n ) {\n break;\n }\n bufferedFeedReplies.push(reply);\n }\n }\n }\n }\n\n if (flat) {\n bufferedFeedReplies = flattenCommentsPages({ comments: bufferedFeedReplies });\n }\n\n // sort the feed before filtering to get more accurate results\n const sortedBufferedFeedReplies = repliesSorter.sort(sortType, bufferedFeedReplies);\n\n // filter the feed\n const filteredSortedBufferedFeedReplies = [];\n for (const reply of sortedBufferedFeedReplies) {\n // TODO: maybe skip if comment community address, comment cid or comment author is blocked?\n\n // feedOptions filter function\n if (filter && !filter.filter(reply)) {\n continue;\n }\n\n filteredSortedBufferedFeedReplies.push(reply);\n }\n\n feeds[feedName] = filteredSortedBufferedFeedReplies;\n }\n return feeds;\n};\n\nconst getPreloadedReplies = (comment: Comment, sortType: string) => {\n let preloadedReplies = comment.replies?.pages?.[sortType]?.comments;\n if (preloadedReplies) {\n return preloadedReplies;\n }\n // TODO: should we check pageCids? it's possible to have pageCids\n // and use 'best' preloadedReplies, if they have no nextCid (all replies are preloaded)\n // changing this might bug out nested immediate react renders\n // only check on comment.depth: 0 for now\n const hasPageCids = Object.keys(comment.replies?.pageCids || {}).length !== 0;\n if (hasPageCids && comment.depth === 0) {\n return;\n }\n const pages: any[] = Object.values(comment.replies?.pages || {});\n if (!pages.length) {\n return;\n }\n const nextCids = pages.map((page: any) => page?.nextCid).filter((nextCid) => !!nextCid);\n if (nextCids.length > 0) {\n return;\n }\n // if has a preloaded page, but no pageCids and no nextCids, it means all replies fit in a single preloaded page\n // so any sort type can be used, and later be resorted by the client\n if (pages[0]?.comments?.length) {\n return pages[0].comments;\n }\n};\n\nconst previousPageNumbers: { [feedName: string]: number } = {};\nconst pageNumberIncreased = (\n feedName: string,\n pageNumber: number,\n loadedFeed: Comment[],\n bufferedFeed: Comment[],\n) => {\n const isFirstPage = !loadedFeed && bufferedFeed?.length;\n // first page should always update\n // pageNumber has changed should always update\n if (isFirstPage || previousPageNumbers[feedName] !== pageNumber) {\n previousPageNumbers[feedName] = pageNumber;\n return true;\n }\n return false;\n};\n\nconst alwaysStreamPage = (feedOptions: RepliesFeedOptions) => {\n // feedOptions.streamPage set to true means always stream page\n if (feedOptions.streamPage) {\n return true;\n }\n // always stream top level replies and/or flat\n return feedOptions.commentDepth > 0 && !feedOptions.flat ? false : true;\n};\n\nconst getApprovalPublicationKey = (comment: Comment) =>\n [\n comment.timestamp ?? \"\",\n comment.parentCid ?? \"\",\n comment.postCid ?? \"\",\n comment.communityAddress ?? \"\",\n comment.author?.address ?? \"\",\n comment.title ?? \"\",\n comment.content ?? \"\",\n comment.link ?? \"\",\n ].join(\"\\0\");\n\nexport const getLoadedFeeds = async (\n feedsOptions: RepliesFeedsOptions,\n loadedFeeds: Feeds,\n bufferedFeeds: Feeds,\n accounts: Accounts,\n) => {\n const loadedFeedsMissingReplies: Feeds = {};\n for (const feedName in feedsOptions) {\n const { pageNumber, repliesPerPage, accountId, streamPage } = feedsOptions[feedName];\n\n // TODO: fix design issue, pageNumber shouldnt be increased when loadMore is called and repliesPerPage not reached\n // if not always streaming replies, and page number didn't increase, skip updating\n // so UI isn't displaced when new nested replies are added\n if (\n !alwaysStreamPage(feedsOptions[feedName]) &&\n !pageNumberIncreased(feedName, pageNumber, loadedFeeds[feedName], bufferedFeeds[feedName])\n ) {\n continue;\n }\n\n const pkc = accounts[accountId]?.pkc;\n const loadedFeedReplyCount = pageNumber * repliesPerPage;\n const currentLoadedFeed = loadedFeeds[feedName] || [];\n // don't count account replies\n const missingRepliesCount =\n loadedFeedReplyCount - currentLoadedFeed.filter((reply) => reply.index === undefined).length;\n\n // get new replies from buffered feed\n const bufferedFeed = bufferedFeeds[feedName] || [];\n\n let missingReplies: any[] = [];\n for (const reply of bufferedFeed) {\n if (missingReplies.length >= missingRepliesCount) {\n missingReplies = await removeInvalidComments(\n missingReplies,\n { validateReplies: false },\n pkc,\n );\n // only stop if there were no invalid comments\n if (missingReplies.length >= missingRepliesCount) {\n break;\n }\n }\n missingReplies.push(reply);\n }\n\n // the current loaded feed already exist and doesn't need new replies\n if (missingReplies.length === 0 && loadedFeeds[feedName]) {\n continue;\n }\n loadedFeedsMissingReplies[feedName] = missingReplies;\n }\n\n let newLoadedFeeds: Feeds = {};\n for (const feedName in loadedFeedsMissingReplies) {\n newLoadedFeeds[feedName] = [\n ...(loadedFeeds[feedName] || []),\n ...loadedFeedsMissingReplies[feedName],\n ];\n }\n\n // add account comments\n newLoadedFeeds = { ...loadedFeeds, ...newLoadedFeeds };\n const accountCommentsChangedFeeds = addAccountsComments(feedsOptions, newLoadedFeeds);\n\n // do nothing if there are no missing replies\n if (Object.keys(loadedFeedsMissingReplies).length === 0 && !accountCommentsChangedFeeds) {\n return loadedFeeds;\n }\n return newLoadedFeeds;\n};\n\nexport const addAccountsComments = (feedsOptions: RepliesFeedsOptions, loadedFeeds: Feeds) => {\n let loadedFeedsChanged = false;\n const accountsComments = accountsStore.getState().accountsComments || {};\n for (const feedName in feedsOptions) {\n const {\n accountId,\n accountComments: accountCommentsOptions,\n commentCid,\n postCid,\n commentDepth,\n flat,\n } = feedsOptions[feedName];\n const { newerThan, append } = accountCommentsOptions || {};\n if (!newerThan) {\n continue;\n }\n const newerThanTimestamp =\n newerThan === Infinity ? 0 : Math.floor(Date.now() / 1000) - newerThan;\n const isNewerThan = (reply: Comment) => reply.timestamp > newerThanTimestamp;\n\n const accountComments = accountsComments[accountId] || [];\n const accountReplies = accountComments.filter((reply) => {\n if (!isNewerThan(reply)) {\n return false;\n }\n if (flat) {\n // if flat, add all account replies with greater comment depth\n return reply.postCid === postCid && reply.depth > commentDepth;\n }\n return reply.parentCid === commentCid;\n });\n const validAccountIndices = new Set(accountReplies.map((r) => r.index));\n const accountCidToReply = new Map<string, Comment>();\n for (const r of accountReplies) {\n if (r.cid) accountCidToReply.set(r.cid, r);\n }\n\n let loadedFeed = loadedFeeds[feedName] || [];\n const approvedPublicationKeys = new Set(\n loadedFeed\n .filter((reply) => reply.pendingApproval !== true)\n .map((reply) => getApprovalPublicationKey(reply)),\n );\n // prune stale local-account entries and replace when cid matches but index changed\n const prunedLoadedFeed: Comment[] = [];\n for (const reply of loadedFeed) {\n if (reply.index === undefined) {\n prunedLoadedFeed.push(reply);\n continue;\n }\n if (\n reply.pendingApproval === true &&\n approvedPublicationKeys.has(getApprovalPublicationKey(reply))\n ) {\n loadedFeedsChanged = true;\n continue;\n }\n if (!validAccountIndices.has(reply.index)) {\n loadedFeedsChanged = true;\n continue;\n }\n if (reply.cid) {\n const freshAccountReply = accountCidToReply.get(reply.cid);\n if (freshAccountReply && freshAccountReply.index !== reply.index) {\n prunedLoadedFeed.push(freshAccountReply);\n loadedFeedsChanged = true;\n continue;\n }\n }\n prunedLoadedFeed.push(reply);\n }\n loadedFeed = loadedFeeds[feedName] = prunedLoadedFeed;\n\n if (!accountReplies.length) {\n continue;\n }\n // if a loaded comment doesn't have a cid, then it's pending\n // and pending account comments should always have unique timestamps\n const loadedFeedMap = new Map();\n loadedFeed.forEach((reply, loadedFeedIndex) => {\n if (reply.cid) loadedFeedMap.set(reply.cid, loadedFeedIndex);\n if (typeof reply.index === \"number\") loadedFeedMap.set(reply.index, loadedFeedIndex);\n if (!reply.cid) loadedFeedMap.set(reply.timestamp, loadedFeedIndex);\n if (reply.pendingApproval !== true) {\n loadedFeedMap.set(getApprovalPublicationKey(reply), loadedFeedIndex);\n }\n });\n for (const accountReply of accountReplies) {\n // account reply with cid already added\n if (accountReply.cid && loadedFeedMap.has(accountReply.cid)) {\n continue;\n }\n if (\n accountReply.pendingApproval === true &&\n loadedFeedMap.has(getApprovalPublicationKey(accountReply))\n ) {\n continue;\n }\n // account reply without cid already added, but now we have the cid\n if (accountReply.cid && loadedFeedMap.has(accountReply.index)) {\n const loadedFeedIndex = loadedFeedMap.get(accountReply.index);\n // update the feed with the accountReply.cid now that we have it\n loadedFeed[loadedFeedIndex] = accountReply;\n loadedFeedsChanged = true;\n continue;\n }\n if (loadedFeedMap.has(accountReply.index)) {\n continue;\n }\n // pending account reply without cid already added\n if (!accountReply.cid && loadedFeedMap.has(accountReply.timestamp)) {\n continue;\n }\n if (append) {\n loadedFeed.push(accountReply);\n } else {\n loadedFeed.unshift(accountReply);\n }\n loadedFeedsChanged = true;\n }\n }\n return loadedFeedsChanged;\n};\n\nexport const getBufferedFeedsWithoutLoadedFeeds = (bufferedFeeds: Feeds, loadedFeeds: Feeds) => {\n // contruct a list of replies already loaded to remove them from buffered feeds\n const loadedFeedsReplies: { [key: string]: Set<string> } = {};\n for (const feedName in loadedFeeds) {\n loadedFeedsReplies[feedName] = new Set();\n for (const reply of loadedFeeds[feedName]) {\n loadedFeedsReplies[feedName].add(reply.cid);\n }\n }\n\n const newBufferedFeeds: Feeds = {};\n for (const feedName in bufferedFeeds) {\n newBufferedFeeds[feedName] = [];\n let bufferedFeedReplyChanged = false;\n for (const [i, reply] of bufferedFeeds[feedName].entries()) {\n if (loadedFeedsReplies[feedName]?.has(reply.cid)) {\n continue;\n }\n newBufferedFeeds[feedName].push(reply);\n if (\n !bufferedFeedReplyChanged &&\n (newBufferedFeeds[feedName][i]?.cid !== bufferedFeeds[feedName][i]?.cid ||\n (newBufferedFeeds[feedName][i]?.updatedAt || 0) >\n (bufferedFeeds[feedName][i]?.updatedAt || 0))\n ) {\n bufferedFeedReplyChanged = true;\n }\n }\n if (\n !bufferedFeedReplyChanged &&\n newBufferedFeeds[feedName].length === bufferedFeeds[feedName].length\n ) {\n newBufferedFeeds[feedName] = bufferedFeeds[feedName];\n }\n }\n return newBufferedFeeds;\n};\n\nexport const getUpdatedFeeds = async (\n feedsOptions: RepliesFeedsOptions,\n filteredSortedFeeds: Feeds,\n updatedFeeds: Feeds,\n loadedFeeds: Feeds,\n accounts: Accounts,\n) => {\n const newUpdatedFeeds: Feeds = { ...updatedFeeds };\n const feedNames = new Set([\n ...Object.keys(filteredSortedFeeds || {}),\n ...Object.keys(loadedFeeds || {}),\n ...Object.keys(updatedFeeds || {}),\n ]);\n for (const feedName of feedNames) {\n const pkc = accounts[feedsOptions[feedName]?.accountId]?.pkc;\n const loadedFeed = loadedFeeds[feedName] || [];\n const previousUpdatedFeed = updatedFeeds[feedName] || [];\n const updatedFeed = [...loadedFeed];\n let updatedFeedChanged = false;\n\n // Keep updated feeds in lock-step with loaded feeds so local deletions\n // (e.g. abandoned pending replies) disappear without requiring a feed reset.\n if (previousUpdatedFeed.length !== updatedFeed.length) {\n updatedFeedChanged = true;\n }\n\n const filteredRepliesByCid = new Map<string, Comment>();\n for (const reply of filteredSortedFeeds[feedName] || []) {\n if (reply?.cid) {\n filteredRepliesByCid.set(reply.cid, reply);\n }\n }\n\n for (let i = 0; i < updatedFeed.length; i++) {\n const loadedReply = updatedFeed[i];\n if (!loadedReply?.cid) {\n continue;\n }\n\n const previousUpdatedReply = previousUpdatedFeed[i];\n if (\n previousUpdatedReply?.cid === loadedReply.cid &&\n (previousUpdatedReply.updatedAt || 0) > (loadedReply.updatedAt || 0)\n ) {\n updatedFeed[i] = previousUpdatedReply;\n updatedFeedChanged = true;\n }\n\n const candidateReply = filteredRepliesByCid.get(loadedReply.cid);\n if (!candidateReply) {\n continue;\n }\n if ((candidateReply.updatedAt || 0) <= (updatedFeed[i]?.updatedAt || 0)) {\n continue;\n }\n if (!(await commentIsValid(candidateReply, { validateReplies: false }, pkc))) {\n continue;\n }\n updatedFeed[i] = candidateReply;\n updatedFeedChanged = true;\n }\n\n if (updatedFeedChanged) {\n newUpdatedFeeds[feedName] = updatedFeed;\n continue;\n }\n\n if (!updatedFeeds[feedName]) {\n newUpdatedFeeds[feedName] = updatedFeed;\n }\n }\n return newUpdatedFeeds;\n};\n\n// find how many replies are in each comments in a buffereds feeds\n// NOTE: not useful, could use feed.length, copied over from useFeed and easier to keep it\nexport const getFeedsReplyCounts = (feedsOptions: RepliesFeedsOptions, feeds: Feeds) => {\n const feedsReplyCounts: { [feedName: string]: number } = {};\n for (const feedName in feedsOptions) {\n feedsReplyCounts[feedName] = feeds[feedName]?.length || 0;\n }\n return feedsReplyCounts;\n};\n\n/**\n * Get which feeds have more replies, i.e. have not reached the final page of all comments\n */\nexport const getFeedsHaveMore = (\n feedsOptions: RepliesFeedsOptions,\n bufferedFeeds: Feeds,\n comments: Comments,\n repliesPages: RepliesPages,\n accounts: Accounts,\n) => {\n const feedsHaveMore: { [feedName: string]: boolean } = {};\n for (const feedName in feedsOptions) {\n // if the feed still has buffered replies, then it still has more\n if (bufferedFeeds[feedName]?.length) {\n feedsHaveMore[feedName] = true;\n continue;\n }\n\n let { commentCid, sortType, onlyIfCached } = feedsOptions[feedName];\n\n // TODO: maybe skip if comment cid is blocked?\n\n const comment = comments[commentCid];\n // if at least comment hasn't loaded yet, then the feed still has more\n if (!comment?.updatedAt) {\n feedsHaveMore[feedName] = !onlyIfCached;\n continue;\n }\n\n sortType = getSortTypeFromComment(comment, feedsOptions[feedName]);\n\n const firstPageCid = getRepliesFirstPageCid(comment, sortType);\n // TODO: if a loaded comment doesn't have a first page, it's unclear what we should do\n // should we try to use another sort type by default, like 'best', or should we just ignore it?\n // 'continue' to ignore it for now\n if (!firstPageCid) {\n feedsHaveMore[feedName] = false;\n continue;\n }\n const pages = getRepliesPages(comment, sortType, repliesPages);\n // if first page isn't loaded yet, then the feed still has more\n if (!pages.length) {\n feedsHaveMore[feedName] = !onlyIfCached;\n continue;\n }\n const lastPage = pages[pages.length - 1];\n if (lastPage.nextCid) {\n feedsHaveMore[feedName] = !onlyIfCached;\n continue;\n }\n\n // if buffered feeds are empty and no last page of any comment has a next page, then has more is false\n feedsHaveMore[feedName] = false;\n }\n return feedsHaveMore;\n};\n\n// get all comments replies pages cids of all feeds, use to check if a commentsStore change should trigger updateFeeds\nexport const getFeedsComments = (feedsOptions: RepliesFeedsOptions, comments: Comments) => {\n const feedsComments = new Map<string, Comment>();\n for (const feedName in feedsOptions) {\n feedsComments.set(\n feedsOptions[feedName].commentCid,\n comments[feedsOptions[feedName].commentCid],\n );\n }\n return feedsComments;\n};\n\nexport const feedsCommentsChanged = (\n previousFeedsComments: Map<string, Comment>,\n feedsComments: Map<string, Comment>,\n) => {\n if (previousFeedsComments.size !== feedsComments.size) {\n return true;\n }\n for (let commentCid of previousFeedsComments.keys()) {\n // check if the object is still the same\n if (previousFeedsComments.get(commentCid) !== feedsComments.get(commentCid)) {\n return true;\n }\n }\n return false;\n};\n\n// get all comments replies pages cids of all feeds, use to check if a commentsStore change should trigger updateFeeds\nexport const getFeedsCommentsFirstPageCids = (feedsComments: Map<string, Comment>): string[] => {\n // find all the feeds comments first page cids\n const feedsCommentsFirstPageCids = new Set<string>();\n for (const comment of feedsComments.values()) {\n if (!comment?.replies) {\n continue;\n }\n\n // check pages\n if (comment.replies.pages) {\n for (const page of Object.values<RepliesPage>(comment.replies.pages)) {\n if (page?.nextCid) {\n feedsCommentsFirstPageCids.add(page?.nextCid);\n }\n }\n }\n\n // check pageCids\n if (comment.replies.pageCids) {\n for (const pageCid of Object.values<string>(comment.replies.pageCids)) {\n if (pageCid) {\n feedsCommentsFirstPageCids.add(pageCid);\n }\n }\n }\n }\n\n return [...feedsCommentsFirstPageCids].sort();\n};\n\n// get all comments replies pages first reply updatedAts, use to check if a commentsStore change should trigger updateFeeds\nexport const getFeedsCommentsRepliesPagesFirstUpdatedAts = (\n feedsComments: Map<string, Comment>,\n): string => {\n let feedsCommentsRepliesPagesFirstUpdatedAts = \"\";\n for (const comment of feedsComments.values()) {\n for (const page of Object.values<RepliesPage>(comment?.replies?.pages || {})) {\n if (page?.comments?.[0]?.updatedAt) {\n feedsCommentsRepliesPagesFirstUpdatedAts +=\n page.comments[0].cid + page.comments[0].updatedAt;\n }\n }\n }\n return feedsCommentsRepliesPagesFirstUpdatedAts;\n};\n\n// get number of feeds comments that are loaded\nexport const getFeedsCommentsLoadedCount = (feedsComments: Map<string, Comment>): number => {\n let count = 0;\n for (const comment of feedsComments.values()) {\n if (comment?.updatedAt) {\n count++;\n }\n }\n return count;\n};\n\n// selected sort type could be missing from comment, or not optimized\nexport const getSortTypeFromComment = (comment: Comment, feedOptions: RepliesFeedOptions) => {\n let { sortType, flat } = feedOptions;\n\n if (!comment) {\n return sortType;\n }\n\n // 'topAll' and 'best' are similar enough to be used interchangeably\n if (\n sortType === \"best\" &&\n !comment.replies?.pages?.best &&\n !comment.replies?.pageCids?.best &&\n (comment.replies?.pages?.topAll || comment.replies?.pageCids?.topAll)\n ) {\n sortType = \"topAll\";\n } else if (\n sortType === \"topAll\" &&\n !comment.replies?.pages?.topAll &&\n !comment.replies?.pageCids?.topAll &&\n (comment.replies?.pages?.best || comment.replies?.pageCids?.best)\n ) {\n sortType = \"best\";\n }\n\n // if 'new' sort type and flat: true, use 'newFlat'\n else if (\n sortType === \"new\" &&\n flat &&\n (comment.replies?.pages?.newFlat || comment.replies?.pageCids?.newFlat)\n ) {\n sortType = \"newFlat\";\n }\n // if 'old' sort type and flat: true, use 'oldFlat'\n else if (\n sortType === \"old\" &&\n flat &&\n (comment.replies?.pages?.oldFlat || comment.replies?.pageCids?.oldFlat)\n ) {\n sortType = \"oldFlat\";\n }\n\n // if 'newFlat' is missing, use 'new'\n else if (\n sortType === \"newFlat\" &&\n !comment.replies?.pages?.newFlat &&\n !comment.replies?.pageCids?.newFlat &&\n (comment.replies?.pages?.new || comment.replies?.pageCids?.new)\n ) {\n sortType = \"new\";\n }\n // if 'oldFlat' is missing, use 'old'\n else if (\n sortType === \"oldFlat\" &&\n !comment.replies?.pages?.oldFlat &&\n !comment.replies?.pageCids?.oldFlat &&\n (comment.replies?.pages?.old || comment.replies?.pageCids?.old)\n ) {\n sortType = \"old\";\n }\n\n // TODO: if sort type doesn't exist on comment, maybe use first existing?\n // else if (!comment.replies?.pages?.[sortType] && !comment.replies?.pageCids?.[sortType]) {\n // const firstPageSortType = comment.replies?.pages && Object.keys(comment.replies.pages)[0]\n // if (firstPageSortType) {\n // sortType = firstPageSortType\n // }\n // else {\n // const firstPageCidSortType = comment.replies?.pageCids && Object.keys(comment.replies.pageCids)[0]\n // if (firstPageCidSortType) {\n // sortType = firstPageCidSortType\n // }\n // }\n // }\n return sortType;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/stores/replies/utils.ts"],"names":[],"mappings":";;;;;;;;;AAaA,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,aAAa,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,sCAAsC,CAAC,CAAC;AAE3D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,YAAiC,EACjC,QAAkB,EAClB,YAA0B,EAC1B,QAAkB,EAClB,EAAE;IACF,sBAAsB;IACtB,IAAI,KAAK,GAAU,EAAE,CAAC;IACtB,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE/E,2BAA2B;QAC3B,IAAI,mBAAmB,GAAG,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAErC,QAAQ,GAAG,sBAAsB,CAAC,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEnE,2CAA2C;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,uCAAuC;YACvC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAChE,IAAI,gBAAgB,EAAE,CAAC;gBACrB,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;oBACrC,mEAAmE;oBACnE,IAAI,CAAC,+BAA+B,CAAC,KAAK,CAAC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBACvF,MAAM;oBACR,CAAC;oBACD,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;YAED,6CAA6C;YAC7C,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;YACvE,KAAK,MAAM,WAAW,IAAI,aAAa,EAAE,CAAC;gBACxC,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,QAAQ,EAAE,CAAC;oBAC1B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;wBACzC,mEAAmE;wBACnE,IACE,CAAC,+BAA+B,CAAC,KAAK,CAAC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAClF,CAAC;4BACD,MAAM;wBACR,CAAC;wBACD,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBAClC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,IAAI,EAAE,CAAC;YACT,mBAAmB,GAAG,oBAAoB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAChF,CAAC;QAED,8DAA8D;QAC9D,MAAM,yBAAyB,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAEpF,kBAAkB;QAClB,MAAM,iCAAiC,GAAG,EAAE,CAAC;QAC7C,KAAK,MAAM,KAAK,IAAI,yBAAyB,EAAE,CAAC;YAC9C,2FAA2F;YAE3F,8BAA8B;YAC9B,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,iCAAiC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,CAAC,QAAQ,CAAC,GAAG,iCAAiC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,OAAgB,EAAE,QAAgB,EAAE,EAAE;;IACjE,IAAI,gBAAgB,GAAG,MAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAG,QAAQ,CAAC,0CAAE,QAAQ,CAAC;IACpE,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,iEAAiE;IACjE,uFAAuF;IACvF,6DAA6D;IAC7D,yCAAyC;IACzC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,KAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;IAC9E,IAAI,WAAW,IAAI,OAAO,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAU,MAAM,CAAC,MAAM,CAAC,CAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,KAAI,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACxF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IACD,gHAAgH;IAChH,oEAAoE;IACpE,IAAI,MAAA,MAAA,KAAK,CAAC,CAAC,CAAC,0CAAE,QAAQ,0CAAE,MAAM,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC3B,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAmC,EAAE,CAAC;AAC/D,MAAM,mBAAmB,GAAG,CAC1B,QAAgB,EAChB,UAAkB,EAClB,UAAqB,EACrB,YAAuB,EACvB,EAAE;IACF,MAAM,WAAW,GAAG,CAAC,UAAU,KAAI,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,CAAA,CAAC;IACxD,kCAAkC;IAClC,8CAA8C;IAC9C,IAAI,WAAW,IAAI,mBAAmB,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE,CAAC;QAChE,mBAAmB,CAAC,QAAQ,CAAC,GAAG,UAAU,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,WAA+B,EAAE,EAAE;IAC3D,8DAA8D;IAC9D,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,8CAA8C;IAC9C,OAAO,WAAW,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC,CAAC;AAEF,MAAM,yBAAyB,GAAG,CAAC,OAAgB,EAAE,EAAE;;IACrD,OAAA;QACE,MAAA,OAAO,CAAC,SAAS,mCAAI,EAAE;QACvB,MAAA,OAAO,CAAC,SAAS,mCAAI,EAAE;QACvB,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE;QACrB,MAAA,OAAO,CAAC,gBAAgB,mCAAI,EAAE;QAC9B,MAAA,MAAA,OAAO,CAAC,MAAM,0CAAE,OAAO,mCAAI,EAAE;QAC7B,MAAA,OAAO,CAAC,KAAK,mCAAI,EAAE;QACnB,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE;QACrB,MAAA,OAAO,CAAC,IAAI,mCAAI,EAAE;KACnB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;CAAA,CAAC;AAEf,MAAM,uBAAuB,GAAG,CAAC,eAAwB,EAAE,EAAE,CAC3D,eAAe,KAAK,SAAS;KAC7B,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,UAAU,CAAC,YAAY,CAAC,CAAA;KACzC,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,UAAU,CAAC,UAAU,CAAC,CAAA;KACvC,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,UAAU,CAAC,0BAA0B,CAAC,CAAA,CAAC;AAE1D,MAAM,uBAAuB,GAAG,CAAC,KAAc,EAAE,EAAE,CACjD,OAAO,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,CAAA,KAAK,QAAQ;IAChC,CAAC,CAAC,KAAK,CAAC,GAAG;IACX,KAAK,CAAC,eAAe,KAAK,IAAI;IAC9B,CAAC,uBAAuB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;AAElD,MAAM,gCAAgC,GAAG,CAAC,KAAc,EAAE,aAAsB,EAAE,EAAE,CAClF,OAAO,aAAa,KAAK,QAAQ;IACjC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;IACnC,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC;AAElC,MAAM,+BAA+B,GAAG,CACtC,KAAc,EACd,2BAAoC,EACpC,aAAsB,EACtB,EAAE,CACF,2BAA2B;IAC3B,uBAAuB,CAAC,KAAK,CAAC;IAC9B,gCAAgC,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;AAQzD,MAAM,CAAC,MAAM,cAAc,GAAG,wEAM5B,EAAE,+GALF,YAAiC,EACjC,WAAkB,EAClB,aAAoB,EACpB,QAAkB,EAClB,UAAiC,EAAE;;IAEnC,MAAM,yBAAyB,GAAU,EAAE,CAAC;IAC5C,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAErF,kHAAkH;QAClH,kFAAkF;QAClF,0DAA0D;QAC1D,IACE,CAAC,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YACzC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,EAC1F,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,GAAG,GAAG,MAAA,QAAQ,CAAC,SAAS,CAAC,0CAAE,GAAG,CAAC;QACrC,MAAM,oBAAoB,GAAG,UAAU,GAAG,cAAc,CAAC;QACzD,MAAM,iBAAiB,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtD,8BAA8B;QAC9B,MAAM,mBAAmB,GACvB,oBAAoB,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QAE/F,qCAAqC;QACrC,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnD,IAAI,cAAc,GAAU,EAAE,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YACjC,IAAI,cAAc,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC;gBACjD,cAAc,GAAG,MAAM,qBAAqB,CAC1C,cAAc,EACd,EAAE,eAAe,EAAE,KAAK,EAAE,EAC1B,GAAG,CACJ,CAAC;gBACF,8CAA8C;gBAC9C,IAAI,cAAc,CAAC,MAAM,IAAI,mBAAmB,EAAE,CAAC;oBACjD,MAAM;gBACR,CAAC;YACH,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAED,qEAAqE;QACrE,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,SAAS;QACX,CAAC;QACD,yBAAyB,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC;IACvD,CAAC;IAED,IAAI,cAAc,GAAU,EAAE,CAAC;IAC/B,KAAK,MAAM,QAAQ,IAAI,yBAAyB,EAAE,CAAC;QACjD,cAAc,CAAC,QAAQ,CAAC,GAAG;YACzB,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChC,GAAG,yBAAyB,CAAC,QAAQ,CAAC;SACvC,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,cAAc,mCAAQ,WAAW,GAAK,cAAc,CAAE,CAAC;IACvD,MAAM,2BAA2B,GAC/B,OAAO,CAAC,kBAAkB,KAAK,KAAK;QAClC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,mBAAmB,CACjB,YAAY,EACZ,cAAc,EACd,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,eAAe,CACxB,CAAC;IAER,6CAA6C;IAC7C,IAAI,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACxF,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC,CAAA,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,YAAiC,EACjC,WAAkB,EAClB,aAA+C,EAC/C,eAA4D,EAC5D,EAAE;IACF,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,MAAM,gBAAgB,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,gBAAgB,IAAI,EAAE,CAAC;IACzE,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,EACJ,SAAS,EACT,eAAe,EAAE,sBAAsB,EACvC,UAAU,EACV,OAAO,EACP,YAAY,EACZ,IAAI,GACL,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC3B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,sBAAsB,IAAI,EAAE,CAAC;QAC3D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QACD,MAAM,kBAAkB,GACtB,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,SAAS,CAAC;QACzE,MAAM,WAAW,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,GAAG,kBAAkB,CAAC;QAC7E,MAAM,2BAA2B,GAAG,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,QAAQ,CAAC,MAAK,KAAK,CAAC;QACxE,MAAM,aAAa,GAAG,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAG,QAAQ,CAAC,CAAC;QAElD,MAAM,eAAe,GAAG,gBAAgB,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC1D,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,IAAI,+BAA+B,CAAC,KAAK,EAAE,2BAA2B,EAAE,aAAa,CAAC,EAAE,CAAC;gBACvF,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,IAAI,EAAE,CAAC;gBACT,8DAA8D;gBAC9D,OAAO,KAAK,CAAC,OAAO,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,GAAG,YAAY,CAAC;YACjE,CAAC;YACD,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC;QACxC,CAAC,CAAC,CAAC;QACH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAmB,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,CAAC,GAAG;gBAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,uBAAuB,GAAG,IAAI,GAAG,CACrC,UAAU;aACP,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC;aACjD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CACpD,CAAC;QACF,mFAAmF;QACnF,MAAM,gBAAgB,GAAc,EAAE,CAAC;QACvC,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC7B,SAAS;YACX,CAAC;YACD,IAAI,+BAA+B,CAAC,KAAK,EAAE,2BAA2B,EAAE,aAAa,CAAC,EAAE,CAAC;gBACvF,kBAAkB,GAAG,IAAI,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,IACE,KAAK,CAAC,eAAe,KAAK,IAAI;gBAC9B,uBAAuB,CAAC,GAAG,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,EAC7D,CAAC;gBACD,kBAAkB,GAAG,IAAI,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBACd,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC3D,IAAI,iBAAiB,IAAI,iBAAiB,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;oBACjE,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;oBACzC,kBAAkB,GAAG,IAAI,CAAC;oBAC1B,SAAS;gBACX,CAAC;YACH,CAAC;YACD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1C,kBAAkB,GAAG,IAAI,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,GAAG,gBAAgB,CAAC;QAEtD,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,4DAA4D;QAC5D,oEAAoE;QACpE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAE,CAAC;QAChC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE;YAC5C,IAAI,KAAK,CAAC,GAAG;gBAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;YAC7D,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;gBAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;YACrF,IAAI,CAAC,KAAK,CAAC,GAAG;gBAAE,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YACpE,IAAI,KAAK,CAAC,eAAe,KAAK,IAAI,EAAE,CAAC;gBACnC,aAAa,CAAC,GAAG,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,MAAM,YAAY,IAAI,cAAc,EAAE,CAAC;YAC1C,uCAAuC;YACvC,IAAI,YAAY,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5D,SAAS;YACX,CAAC;YACD,IACE,YAAY,CAAC,eAAe,KAAK,IAAI;gBACrC,aAAa,CAAC,GAAG,CAAC,yBAAyB,CAAC,YAAY,CAAC,CAAC,EAC1D,CAAC;gBACD,SAAS;YACX,CAAC;YACD,mEAAmE;YACnE,IAAI,YAAY,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9D,MAAM,eAAe,GAAG,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBAC9D,gEAAgE;gBAChE,UAAU,CAAC,eAAe,CAAC,GAAG,YAAY,CAAC;gBAC3C,kBAAkB,GAAG,IAAI,CAAC;gBAC1B,SAAS;YACX,CAAC;YACD,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1C,SAAS;YACX,CAAC;YACD,kDAAkD;YAClD,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnE,SAAS;YACX,CAAC;YACD,IAAI,MAAM,EAAE,CAAC;gBACX,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YACnC,CAAC;YACD,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,aAAoB,EAAE,WAAkB,EAAE,EAAE;;IAC7F,+EAA+E;IAC/E,MAAM,kBAAkB,GAAmC,EAAE,CAAC;IAC9D,KAAK,MAAM,QAAQ,IAAI,WAAW,EAAE,CAAC;QACnC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,kBAAkB,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAU,EAAE,CAAC;IACnC,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;QACrC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,wBAAwB,GAAG,KAAK,CAAC;QACrC,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3D,IAAI,MAAA,kBAAkB,CAAC,QAAQ,CAAC,0CAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjD,SAAS;YACX,CAAC;YACD,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvC,IACE,CAAC,wBAAwB;gBACzB,CAAC,CAAA,MAAA,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,0CAAE,GAAG,OAAK,MAAA,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,0CAAE,GAAG,CAAA;oBACrE,CAAC,CAAA,MAAA,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,0CAAE,SAAS,KAAI,CAAC,CAAC;wBAC7C,CAAC,CAAA,MAAA,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,0CAAE,SAAS,KAAI,CAAC,CAAC,CAAC,EACjD,CAAC;gBACD,wBAAwB,GAAG,IAAI,CAAC;YAClC,CAAC;QACH,CAAC;QACD,IACE,CAAC,wBAAwB;YACzB,gBAAgB,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,QAAQ,CAAC,CAAC,MAAM,EACpE,CAAC;YACD,gBAAgB,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,YAAiC,EACjC,mBAA0B,EAC1B,YAAmB,EACnB,WAAkB,EAClB,QAAkB,EAClB,EAAE;;IACF,MAAM,eAAe,qBAAe,YAAY,CAAE,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;QACxB,GAAG,MAAM,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC;QACzC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QACjC,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;KACnC,CAAC,CAAC;IACH,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAA,QAAQ,CAAC,MAAA,YAAY,CAAC,QAAQ,CAAC,0CAAE,SAAS,CAAC,0CAAE,GAAG,CAAC;QAC7D,MAAM,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,mBAAmB,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,WAAW,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;QACpC,IAAI,kBAAkB,GAAG,KAAK,CAAC;QAE/B,uEAAuE;QACvE,6EAA6E;QAC7E,IAAI,mBAAmB,CAAC,MAAM,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;YACtD,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAmB,CAAC;QACxD,KAAK,MAAM,KAAK,IAAI,mBAAmB,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACxD,IAAI,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,GAAG,EAAE,CAAC;gBACf,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,GAAG,CAAA,EAAE,CAAC;gBACtB,SAAS;YACX,CAAC;YAED,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;YACpD,IACE,CAAA,oBAAoB,aAApB,oBAAoB,uBAApB,oBAAoB,CAAE,GAAG,MAAK,WAAW,CAAC,GAAG;gBAC7C,CAAC,oBAAoB,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,SAAS,IAAI,CAAC,CAAC,EACpE,CAAC;gBACD,WAAW,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC;gBACtC,kBAAkB,GAAG,IAAI,CAAC;YAC5B,CAAC;YAED,MAAM,cAAc,GAAG,oBAAoB,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,CAAA,MAAA,WAAW,CAAC,CAAC,CAAC,0CAAE,SAAS,KAAI,CAAC,CAAC,EAAE,CAAC;gBACxE,SAAS;YACX,CAAC;YACD,IAAI,CAAC,CAAC,MAAM,cAAc,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC7E,SAAS;YACX,CAAC;YACD,WAAW,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC;YAChC,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,kBAAkB,EAAE,CAAC;YACvB,eAAe,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC;YACxC,SAAS;QACX,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,eAAe,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC,CAAA,CAAC;AAEF,kEAAkE;AAClE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,YAAiC,EAAE,KAAY,EAAE,EAAE;;IACrF,MAAM,gBAAgB,GAAmC,EAAE,CAAC;IAC5D,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAA,MAAA,KAAK,CAAC,QAAQ,CAAC,0CAAE,MAAM,KAAI,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,YAAiC,EACjC,aAAoB,EACpB,QAAkB,EAClB,YAA0B,EAC1B,QAAkB,EAClB,EAAE;;IACF,MAAM,aAAa,GAAoC,EAAE,CAAC;IAC1D,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,iEAAiE;QACjE,IAAI,MAAA,aAAa,CAAC,QAAQ,CAAC,0CAAE,MAAM,EAAE,CAAC;YACpC,aAAa,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAEpE,8CAA8C;QAE9C,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACrC,sEAAsE;QACtE,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,CAAA,EAAE,CAAC;YACxB,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;YACxC,SAAS;QACX,CAAC;QAED,QAAQ,GAAG,sBAAsB,CAAC,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEnE,MAAM,YAAY,GAAG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/D,sFAAsF;QACtF,+FAA+F;QAC/F,kCAAkC;QAClC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;YAChC,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC/D,+DAA+D;QAC/D,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAClB,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;YACxC,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;YACxC,SAAS;QACX,CAAC;QAED,sGAAsG;QACtG,aAAa,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;IAClC,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAEF,sHAAsH;AACtH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,YAAiC,EAAE,QAAkB,EAAE,EAAE;IACxF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAmB,CAAC;IACjD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,aAAa,CAAC,GAAG,CACf,YAAY,CAAC,QAAQ,CAAC,CAAC,UAAU,EACjC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAC5C,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,qBAA2C,EAC3C,aAAmC,EACnC,EAAE;IACF,IAAI,qBAAqB,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,IAAI,UAAU,IAAI,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC;QACpD,wCAAwC;QACxC,IAAI,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5E,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,sHAAsH;AACtH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,aAAmC,EAAY,EAAE;IAC7F,8CAA8C;IAC9C,MAAM,0BAA0B,GAAG,IAAI,GAAG,EAAU,CAAC;IACrD,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,CAAA,EAAE,CAAC;YACtB,SAAS;QACX,CAAC;QAED,cAAc;QACd,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAc,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrE,IAAI,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,EAAE,CAAC;oBAClB,0BAA0B,CAAC,GAAG,CAAC,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,OAAO,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;QAED,iBAAiB;QACjB,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC7B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAS,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACtE,IAAI,OAAO,EAAE,CAAC;oBACZ,0BAA0B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,0BAA0B,CAAC,CAAC,IAAI,EAAE,CAAC;AAChD,CAAC,CAAC;AAEF,2HAA2H;AAC3H,MAAM,CAAC,MAAM,2CAA2C,GAAG,CACzD,aAAmC,EAC3B,EAAE;;IACV,IAAI,wCAAwC,GAAG,EAAE,CAAC;IAClD,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;QAC7C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAc,CAAA,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,0CAAE,KAAK,KAAI,EAAE,CAAC,EAAE,CAAC;YAC7E,IAAI,MAAA,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,0CAAG,CAAC,CAAC,0CAAE,SAAS,EAAE,CAAC;gBACnC,wCAAwC;oBACtC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,wCAAwC,CAAC;AAClD,CAAC,CAAC;AAEF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,aAAmC,EAAU,EAAE;IACzF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;QAC7C,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,EAAE,CAAC;YACvB,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,qEAAqE;AACrE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAgB,EAAE,WAA+B,EAAE,EAAE;;IAC1F,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC;IAErC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,oEAAoE;IACpE,IACE,QAAQ,KAAK,MAAM;QACnB,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,IAAI,CAAA;QAC7B,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,IAAI,CAAA;QAChC,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,MAAM,MAAI,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,MAAM,CAAA,CAAC,EACrE,CAAC;QACD,QAAQ,GAAG,QAAQ,CAAC;IACtB,CAAC;SAAM,IACL,QAAQ,KAAK,QAAQ;QACrB,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,MAAM,CAAA;QAC/B,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,MAAM,CAAA;QAClC,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,IAAI,MAAI,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,IAAI,CAAA,CAAC,EACjE,CAAC;QACD,QAAQ,GAAG,MAAM,CAAC;IACpB,CAAC;IAED,mDAAmD;SAC9C,IACH,QAAQ,KAAK,KAAK;QAClB,IAAI;QACJ,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,OAAO,MAAI,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,OAAO,CAAA,CAAC,EACvE,CAAC;QACD,QAAQ,GAAG,SAAS,CAAC;IACvB,CAAC;IACD,mDAAmD;SAC9C,IACH,QAAQ,KAAK,KAAK;QAClB,IAAI;QACJ,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,OAAO,MAAI,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,OAAO,CAAA,CAAC,EACvE,CAAC;QACD,QAAQ,GAAG,SAAS,CAAC;IACvB,CAAC;IAED,qCAAqC;SAChC,IACH,QAAQ,KAAK,SAAS;QACtB,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,OAAO,CAAA;QAChC,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,OAAO,CAAA;QACnC,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,GAAG,MAAI,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,QAAQ,0CAAE,GAAG,CAAA,CAAC,EAC/D,CAAC;QACD,QAAQ,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,qCAAqC;SAChC,IACH,QAAQ,KAAK,SAAS;QACtB,CAAC,CAAA,MAAA,MAAA,OAAO,CAAC,OAAO,0CAAE,KAAK,0CAAE,OAAO,CAAA;QAChC,CAAC,CAAA,OAAA,OAAA,OAAO,CAAC,OAAO,4CAAE,QAAQ,4CAAE,OAAO,CAAA;QACnC,CAAC,CAAA,OAAA,OAAA,OAAO,CAAC,OAAO,4CAAE,KAAK,4CAAE,GAAG,MAAI,OAAA,OAAA,OAAO,CAAC,OAAO,4CAAE,QAAQ,4CAAE,GAAG,CAAA,CAAC,EAC/D,CAAC;QACD,QAAQ,GAAG,KAAK,CAAC;IACnB,CAAC;IAED,yEAAyE;IACzE,4FAA4F;IAC5F,8FAA8F;IAC9F,6BAA6B;IAC7B,mCAAmC;IACnC,MAAM;IACN,WAAW;IACX,yGAAyG;IACzG,kCAAkC;IAClC,wCAAwC;IACxC,QAAQ;IACR,MAAM;IACN,IAAI;IACJ,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC","sourcesContent":["import assert from \"assert\";\nimport {\n Feed,\n Feeds,\n RepliesFeedOptions,\n RepliesFeedsOptions,\n Comment,\n Comments,\n Account,\n Accounts,\n RepliesPage,\n RepliesPages,\n} from \"../../types\";\nimport { getRepliesPages, getRepliesFirstPageCid } from \"../replies-pages\";\nimport repliesSorter from \"../feeds/feed-sorter\";\nimport accountsStore from \"../accounts\";\nimport { flattenCommentsPages, commentIsValid, removeInvalidComments } from \"../../lib/utils\";\nimport { areEquivalentCommunityAddresses } from \"../../lib/community-address\";\nimport Logger from \"@pkcprotocol/pkc-logger\";\nconst log = Logger(\"bitsocial-react-hooks:replies:stores\");\n\n/**\n * Calculate the feeds from all the loaded replies pages, filter and sort them\n */\nexport const getFilteredSortedFeeds = (\n feedsOptions: RepliesFeedsOptions,\n comments: Comments,\n repliesPages: RepliesPages,\n accounts: Accounts,\n) => {\n // calculate each feed\n let feeds: Feeds = {};\n for (const feedName in feedsOptions) {\n let { commentCid, sortType, accountId, filter, flat } = feedsOptions[feedName];\n\n // find all fetched replies\n let bufferedFeedReplies = [];\n const comment = comments[commentCid];\n\n sortType = getSortTypeFromComment(comment, feedsOptions[feedName]);\n\n // comment has loaded and cache not expired\n if (comment) {\n // use comment preloaded replies if any\n const preloadedReplies = getPreloadedReplies(comment, sortType);\n if (preloadedReplies) {\n for (const reply of preloadedReplies) {\n // replies are manually validated, could have fake communityAddress\n if (!areEquivalentCommunityAddresses(reply.communityAddress, comment.communityAddress)) {\n break;\n }\n bufferedFeedReplies.push(reply);\n }\n }\n\n // add all replies from comment replies pages\n const _repliesPages = getRepliesPages(comment, sortType, repliesPages);\n for (const repliesPage of _repliesPages) {\n if (repliesPage?.comments) {\n for (const reply of repliesPage.comments) {\n // replies are manually validated, could have fake communityAddress\n if (\n !areEquivalentCommunityAddresses(reply.communityAddress, comment.communityAddress)\n ) {\n break;\n }\n bufferedFeedReplies.push(reply);\n }\n }\n }\n }\n\n if (flat) {\n bufferedFeedReplies = flattenCommentsPages({ comments: bufferedFeedReplies });\n }\n\n // sort the feed before filtering to get more accurate results\n const sortedBufferedFeedReplies = repliesSorter.sort(sortType, bufferedFeedReplies);\n\n // filter the feed\n const filteredSortedBufferedFeedReplies = [];\n for (const reply of sortedBufferedFeedReplies) {\n // TODO: maybe skip if comment community address, comment cid or comment author is blocked?\n\n // feedOptions filter function\n if (filter && !filter.filter(reply)) {\n continue;\n }\n\n filteredSortedBufferedFeedReplies.push(reply);\n }\n\n feeds[feedName] = filteredSortedBufferedFeedReplies;\n }\n return feeds;\n};\n\nconst getPreloadedReplies = (comment: Comment, sortType: string) => {\n let preloadedReplies = comment.replies?.pages?.[sortType]?.comments;\n if (preloadedReplies) {\n return preloadedReplies;\n }\n // TODO: should we check pageCids? it's possible to have pageCids\n // and use 'best' preloadedReplies, if they have no nextCid (all replies are preloaded)\n // changing this might bug out nested immediate react renders\n // only check on comment.depth: 0 for now\n const hasPageCids = Object.keys(comment.replies?.pageCids || {}).length !== 0;\n if (hasPageCids && comment.depth === 0) {\n return;\n }\n const pages: any[] = Object.values(comment.replies?.pages || {});\n if (!pages.length) {\n return;\n }\n const nextCids = pages.map((page: any) => page?.nextCid).filter((nextCid) => !!nextCid);\n if (nextCids.length > 0) {\n return;\n }\n // if has a preloaded page, but no pageCids and no nextCids, it means all replies fit in a single preloaded page\n // so any sort type can be used, and later be resorted by the client\n if (pages[0]?.comments?.length) {\n return pages[0].comments;\n }\n};\n\nconst previousPageNumbers: { [feedName: string]: number } = {};\nconst pageNumberIncreased = (\n feedName: string,\n pageNumber: number,\n loadedFeed: Comment[],\n bufferedFeed: Comment[],\n) => {\n const isFirstPage = !loadedFeed && bufferedFeed?.length;\n // first page should always update\n // pageNumber has changed should always update\n if (isFirstPage || previousPageNumbers[feedName] !== pageNumber) {\n previousPageNumbers[feedName] = pageNumber;\n return true;\n }\n return false;\n};\n\nconst alwaysStreamPage = (feedOptions: RepliesFeedOptions) => {\n // feedOptions.streamPage set to true means always stream page\n if (feedOptions.streamPage) {\n return true;\n }\n // always stream top level replies and/or flat\n return feedOptions.commentDepth > 0 && !feedOptions.flat ? false : true;\n};\n\nconst getApprovalPublicationKey = (comment: Comment) =>\n [\n comment.timestamp ?? \"\",\n comment.parentCid ?? \"\",\n comment.postCid ?? \"\",\n comment.communityAddress ?? \"\",\n comment.author?.address ?? \"\",\n comment.title ?? \"\",\n comment.content ?? \"\",\n comment.link ?? \"\",\n ].join(\"\\0\");\n\nconst isActivePublishingState = (publishingState?: string) =>\n publishingState === \"pending\" ||\n publishingState?.startsWith(\"publishing\") ||\n publishingState?.startsWith(\"waiting-\") ||\n publishingState?.startsWith(\"fetching-link-dimensions\");\n\nconst isPublishedAccountReply = (reply: Comment) =>\n typeof reply?.index === \"number\" &&\n !!reply.cid &&\n reply.pendingApproval !== true &&\n !isActivePublishingState(reply.publishingState);\n\nconst canonicalFeedRefreshedAfterReply = (reply: Comment, feedUpdatedAt?: number) =>\n typeof feedUpdatedAt !== \"number\" ||\n typeof reply.timestamp !== \"number\" ||\n feedUpdatedAt > reply.timestamp;\n\nconst shouldHidePublishedAccountReply = (\n reply: Comment,\n hidePublishedAccountReplies: boolean,\n feedUpdatedAt?: number,\n) =>\n hidePublishedAccountReplies &&\n isPublishedAccountReply(reply) &&\n canonicalFeedRefreshedAfterReply(reply, feedUpdatedAt);\n\ntype GetLoadedFeedsOptions = {\n addAccountComments?: boolean;\n feedsHaveMore?: { [feedName: string]: boolean };\n feedsUpdatedAts?: { [feedName: string]: number | undefined };\n};\n\nexport const getLoadedFeeds = async (\n feedsOptions: RepliesFeedsOptions,\n loadedFeeds: Feeds,\n bufferedFeeds: Feeds,\n accounts: Accounts,\n options: GetLoadedFeedsOptions = {},\n) => {\n const loadedFeedsMissingReplies: Feeds = {};\n for (const feedName in feedsOptions) {\n const { pageNumber, repliesPerPage, accountId, streamPage } = feedsOptions[feedName];\n\n // TODO: fix design issue, pageNumber shouldnt be increased when loadMore is called and repliesPerPage not reached\n // if not always streaming replies, and page number didn't increase, skip updating\n // so UI isn't displaced when new nested replies are added\n if (\n !alwaysStreamPage(feedsOptions[feedName]) &&\n !pageNumberIncreased(feedName, pageNumber, loadedFeeds[feedName], bufferedFeeds[feedName])\n ) {\n continue;\n }\n\n const pkc = accounts[accountId]?.pkc;\n const loadedFeedReplyCount = pageNumber * repliesPerPage;\n const currentLoadedFeed = loadedFeeds[feedName] || [];\n // don't count account replies\n const missingRepliesCount =\n loadedFeedReplyCount - currentLoadedFeed.filter((reply) => reply.index === undefined).length;\n\n // get new replies from buffered feed\n const bufferedFeed = bufferedFeeds[feedName] || [];\n\n let missingReplies: any[] = [];\n for (const reply of bufferedFeed) {\n if (missingReplies.length >= missingRepliesCount) {\n missingReplies = await removeInvalidComments(\n missingReplies,\n { validateReplies: false },\n pkc,\n );\n // only stop if there were no invalid comments\n if (missingReplies.length >= missingRepliesCount) {\n break;\n }\n }\n missingReplies.push(reply);\n }\n\n // the current loaded feed already exist and doesn't need new replies\n if (missingReplies.length === 0 && loadedFeeds[feedName]) {\n continue;\n }\n loadedFeedsMissingReplies[feedName] = missingReplies;\n }\n\n let newLoadedFeeds: Feeds = {};\n for (const feedName in loadedFeedsMissingReplies) {\n newLoadedFeeds[feedName] = [\n ...(loadedFeeds[feedName] || []),\n ...loadedFeedsMissingReplies[feedName],\n ];\n }\n\n // add account comments\n newLoadedFeeds = { ...loadedFeeds, ...newLoadedFeeds };\n const accountCommentsChangedFeeds =\n options.addAccountComments === false\n ? false\n : addAccountsComments(\n feedsOptions,\n newLoadedFeeds,\n options.feedsHaveMore,\n options.feedsUpdatedAts,\n );\n\n // do nothing if there are no missing replies\n if (Object.keys(loadedFeedsMissingReplies).length === 0 && !accountCommentsChangedFeeds) {\n return loadedFeeds;\n }\n return newLoadedFeeds;\n};\n\nexport const addAccountsComments = (\n feedsOptions: RepliesFeedsOptions,\n loadedFeeds: Feeds,\n feedsHaveMore?: { [feedName: string]: boolean },\n feedsUpdatedAts?: { [feedName: string]: number | undefined },\n) => {\n let loadedFeedsChanged = false;\n const accountsComments = accountsStore.getState().accountsComments || {};\n for (const feedName in feedsOptions) {\n const {\n accountId,\n accountComments: accountCommentsOptions,\n commentCid,\n postCid,\n commentDepth,\n flat,\n } = feedsOptions[feedName];\n const { newerThan, append } = accountCommentsOptions || {};\n if (!newerThan) {\n continue;\n }\n const newerThanTimestamp =\n newerThan === Infinity ? 0 : Math.floor(Date.now() / 1000) - newerThan;\n const isNewerThan = (reply: Comment) => reply.timestamp > newerThanTimestamp;\n const hidePublishedAccountReplies = feedsHaveMore?.[feedName] === false;\n const feedUpdatedAt = feedsUpdatedAts?.[feedName];\n\n const accountComments = accountsComments[accountId] || [];\n const accountReplies = accountComments.filter((reply) => {\n if (shouldHidePublishedAccountReply(reply, hidePublishedAccountReplies, feedUpdatedAt)) {\n return false;\n }\n if (!isNewerThan(reply)) {\n return false;\n }\n if (flat) {\n // if flat, add all account replies with greater comment depth\n return reply.postCid === postCid && reply.depth > commentDepth;\n }\n return reply.parentCid === commentCid;\n });\n const validAccountIndices = new Set(accountReplies.map((r) => r.index));\n const accountCidToReply = new Map<string, Comment>();\n for (const r of accountReplies) {\n if (r.cid) accountCidToReply.set(r.cid, r);\n }\n\n let loadedFeed = loadedFeeds[feedName] || [];\n const approvedPublicationKeys = new Set(\n loadedFeed\n .filter((reply) => reply.pendingApproval !== true)\n .map((reply) => getApprovalPublicationKey(reply)),\n );\n // prune stale local-account entries and replace when cid matches but index changed\n const prunedLoadedFeed: Comment[] = [];\n for (const reply of loadedFeed) {\n if (reply.index === undefined) {\n prunedLoadedFeed.push(reply);\n continue;\n }\n if (shouldHidePublishedAccountReply(reply, hidePublishedAccountReplies, feedUpdatedAt)) {\n loadedFeedsChanged = true;\n continue;\n }\n if (\n reply.pendingApproval === true &&\n approvedPublicationKeys.has(getApprovalPublicationKey(reply))\n ) {\n loadedFeedsChanged = true;\n continue;\n }\n if (reply.cid) {\n const freshAccountReply = accountCidToReply.get(reply.cid);\n if (freshAccountReply && freshAccountReply.index !== reply.index) {\n prunedLoadedFeed.push(freshAccountReply);\n loadedFeedsChanged = true;\n continue;\n }\n }\n if (!validAccountIndices.has(reply.index)) {\n loadedFeedsChanged = true;\n continue;\n }\n prunedLoadedFeed.push(reply);\n }\n loadedFeed = loadedFeeds[feedName] = prunedLoadedFeed;\n\n if (!accountReplies.length) {\n continue;\n }\n // if a loaded comment doesn't have a cid, then it's pending\n // and pending account comments should always have unique timestamps\n const loadedFeedMap = new Map();\n loadedFeed.forEach((reply, loadedFeedIndex) => {\n if (reply.cid) loadedFeedMap.set(reply.cid, loadedFeedIndex);\n if (typeof reply.index === \"number\") loadedFeedMap.set(reply.index, loadedFeedIndex);\n if (!reply.cid) loadedFeedMap.set(reply.timestamp, loadedFeedIndex);\n if (reply.pendingApproval !== true) {\n loadedFeedMap.set(getApprovalPublicationKey(reply), loadedFeedIndex);\n }\n });\n for (const accountReply of accountReplies) {\n // account reply with cid already added\n if (accountReply.cid && loadedFeedMap.has(accountReply.cid)) {\n continue;\n }\n if (\n accountReply.pendingApproval === true &&\n loadedFeedMap.has(getApprovalPublicationKey(accountReply))\n ) {\n continue;\n }\n // account reply without cid already added, but now we have the cid\n if (accountReply.cid && loadedFeedMap.has(accountReply.index)) {\n const loadedFeedIndex = loadedFeedMap.get(accountReply.index);\n // update the feed with the accountReply.cid now that we have it\n loadedFeed[loadedFeedIndex] = accountReply;\n loadedFeedsChanged = true;\n continue;\n }\n if (loadedFeedMap.has(accountReply.index)) {\n continue;\n }\n // pending account reply without cid already added\n if (!accountReply.cid && loadedFeedMap.has(accountReply.timestamp)) {\n continue;\n }\n if (append) {\n loadedFeed.push(accountReply);\n } else {\n loadedFeed.unshift(accountReply);\n }\n loadedFeedsChanged = true;\n }\n }\n return loadedFeedsChanged;\n};\n\nexport const getBufferedFeedsWithoutLoadedFeeds = (bufferedFeeds: Feeds, loadedFeeds: Feeds) => {\n // contruct a list of replies already loaded to remove them from buffered feeds\n const loadedFeedsReplies: { [key: string]: Set<string> } = {};\n for (const feedName in loadedFeeds) {\n loadedFeedsReplies[feedName] = new Set();\n for (const reply of loadedFeeds[feedName]) {\n loadedFeedsReplies[feedName].add(reply.cid);\n }\n }\n\n const newBufferedFeeds: Feeds = {};\n for (const feedName in bufferedFeeds) {\n newBufferedFeeds[feedName] = [];\n let bufferedFeedReplyChanged = false;\n for (const [i, reply] of bufferedFeeds[feedName].entries()) {\n if (loadedFeedsReplies[feedName]?.has(reply.cid)) {\n continue;\n }\n newBufferedFeeds[feedName].push(reply);\n if (\n !bufferedFeedReplyChanged &&\n (newBufferedFeeds[feedName][i]?.cid !== bufferedFeeds[feedName][i]?.cid ||\n (newBufferedFeeds[feedName][i]?.updatedAt || 0) >\n (bufferedFeeds[feedName][i]?.updatedAt || 0))\n ) {\n bufferedFeedReplyChanged = true;\n }\n }\n if (\n !bufferedFeedReplyChanged &&\n newBufferedFeeds[feedName].length === bufferedFeeds[feedName].length\n ) {\n newBufferedFeeds[feedName] = bufferedFeeds[feedName];\n }\n }\n return newBufferedFeeds;\n};\n\nexport const getUpdatedFeeds = async (\n feedsOptions: RepliesFeedsOptions,\n filteredSortedFeeds: Feeds,\n updatedFeeds: Feeds,\n loadedFeeds: Feeds,\n accounts: Accounts,\n) => {\n const newUpdatedFeeds: Feeds = { ...updatedFeeds };\n const feedNames = new Set([\n ...Object.keys(filteredSortedFeeds || {}),\n ...Object.keys(loadedFeeds || {}),\n ...Object.keys(updatedFeeds || {}),\n ]);\n for (const feedName of feedNames) {\n const pkc = accounts[feedsOptions[feedName]?.accountId]?.pkc;\n const loadedFeed = loadedFeeds[feedName] || [];\n const previousUpdatedFeed = updatedFeeds[feedName] || [];\n const updatedFeed = [...loadedFeed];\n let updatedFeedChanged = false;\n\n // Keep updated feeds in lock-step with loaded feeds so local deletions\n // (e.g. abandoned pending replies) disappear without requiring a feed reset.\n if (previousUpdatedFeed.length !== updatedFeed.length) {\n updatedFeedChanged = true;\n }\n\n const filteredRepliesByCid = new Map<string, Comment>();\n for (const reply of filteredSortedFeeds[feedName] || []) {\n if (reply?.cid) {\n filteredRepliesByCid.set(reply.cid, reply);\n }\n }\n\n for (let i = 0; i < updatedFeed.length; i++) {\n const loadedReply = updatedFeed[i];\n if (!loadedReply?.cid) {\n continue;\n }\n\n const previousUpdatedReply = previousUpdatedFeed[i];\n if (\n previousUpdatedReply?.cid === loadedReply.cid &&\n (previousUpdatedReply.updatedAt || 0) > (loadedReply.updatedAt || 0)\n ) {\n updatedFeed[i] = previousUpdatedReply;\n updatedFeedChanged = true;\n }\n\n const candidateReply = filteredRepliesByCid.get(loadedReply.cid);\n if (!candidateReply) {\n continue;\n }\n if ((candidateReply.updatedAt || 0) <= (updatedFeed[i]?.updatedAt || 0)) {\n continue;\n }\n if (!(await commentIsValid(candidateReply, { validateReplies: false }, pkc))) {\n continue;\n }\n updatedFeed[i] = candidateReply;\n updatedFeedChanged = true;\n }\n\n if (updatedFeedChanged) {\n newUpdatedFeeds[feedName] = updatedFeed;\n continue;\n }\n\n if (!updatedFeeds[feedName]) {\n newUpdatedFeeds[feedName] = updatedFeed;\n }\n }\n return newUpdatedFeeds;\n};\n\n// find how many replies are in each comments in a buffereds feeds\n// NOTE: not useful, could use feed.length, copied over from useFeed and easier to keep it\nexport const getFeedsReplyCounts = (feedsOptions: RepliesFeedsOptions, feeds: Feeds) => {\n const feedsReplyCounts: { [feedName: string]: number } = {};\n for (const feedName in feedsOptions) {\n feedsReplyCounts[feedName] = feeds[feedName]?.length || 0;\n }\n return feedsReplyCounts;\n};\n\n/**\n * Get which feeds have more replies, i.e. have not reached the final page of all comments\n */\nexport const getFeedsHaveMore = (\n feedsOptions: RepliesFeedsOptions,\n bufferedFeeds: Feeds,\n comments: Comments,\n repliesPages: RepliesPages,\n accounts: Accounts,\n) => {\n const feedsHaveMore: { [feedName: string]: boolean } = {};\n for (const feedName in feedsOptions) {\n // if the feed still has buffered replies, then it still has more\n if (bufferedFeeds[feedName]?.length) {\n feedsHaveMore[feedName] = true;\n continue;\n }\n\n let { commentCid, sortType, onlyIfCached } = feedsOptions[feedName];\n\n // TODO: maybe skip if comment cid is blocked?\n\n const comment = comments[commentCid];\n // if at least comment hasn't loaded yet, then the feed still has more\n if (!comment?.updatedAt) {\n feedsHaveMore[feedName] = !onlyIfCached;\n continue;\n }\n\n sortType = getSortTypeFromComment(comment, feedsOptions[feedName]);\n\n const firstPageCid = getRepliesFirstPageCid(comment, sortType);\n // TODO: if a loaded comment doesn't have a first page, it's unclear what we should do\n // should we try to use another sort type by default, like 'best', or should we just ignore it?\n // 'continue' to ignore it for now\n if (!firstPageCid) {\n feedsHaveMore[feedName] = false;\n continue;\n }\n const pages = getRepliesPages(comment, sortType, repliesPages);\n // if first page isn't loaded yet, then the feed still has more\n if (!pages.length) {\n feedsHaveMore[feedName] = !onlyIfCached;\n continue;\n }\n const lastPage = pages[pages.length - 1];\n if (lastPage.nextCid) {\n feedsHaveMore[feedName] = !onlyIfCached;\n continue;\n }\n\n // if buffered feeds are empty and no last page of any comment has a next page, then has more is false\n feedsHaveMore[feedName] = false;\n }\n return feedsHaveMore;\n};\n\n// get all comments replies pages cids of all feeds, use to check if a commentsStore change should trigger updateFeeds\nexport const getFeedsComments = (feedsOptions: RepliesFeedsOptions, comments: Comments) => {\n const feedsComments = new Map<string, Comment>();\n for (const feedName in feedsOptions) {\n feedsComments.set(\n feedsOptions[feedName].commentCid,\n comments[feedsOptions[feedName].commentCid],\n );\n }\n return feedsComments;\n};\n\nexport const feedsCommentsChanged = (\n previousFeedsComments: Map<string, Comment>,\n feedsComments: Map<string, Comment>,\n) => {\n if (previousFeedsComments.size !== feedsComments.size) {\n return true;\n }\n for (let commentCid of previousFeedsComments.keys()) {\n // check if the object is still the same\n if (previousFeedsComments.get(commentCid) !== feedsComments.get(commentCid)) {\n return true;\n }\n }\n return false;\n};\n\n// get all comments replies pages cids of all feeds, use to check if a commentsStore change should trigger updateFeeds\nexport const getFeedsCommentsFirstPageCids = (feedsComments: Map<string, Comment>): string[] => {\n // find all the feeds comments first page cids\n const feedsCommentsFirstPageCids = new Set<string>();\n for (const comment of feedsComments.values()) {\n if (!comment?.replies) {\n continue;\n }\n\n // check pages\n if (comment.replies.pages) {\n for (const page of Object.values<RepliesPage>(comment.replies.pages)) {\n if (page?.nextCid) {\n feedsCommentsFirstPageCids.add(page?.nextCid);\n }\n }\n }\n\n // check pageCids\n if (comment.replies.pageCids) {\n for (const pageCid of Object.values<string>(comment.replies.pageCids)) {\n if (pageCid) {\n feedsCommentsFirstPageCids.add(pageCid);\n }\n }\n }\n }\n\n return [...feedsCommentsFirstPageCids].sort();\n};\n\n// get all comments replies pages first reply updatedAts, use to check if a commentsStore change should trigger updateFeeds\nexport const getFeedsCommentsRepliesPagesFirstUpdatedAts = (\n feedsComments: Map<string, Comment>,\n): string => {\n let feedsCommentsRepliesPagesFirstUpdatedAts = \"\";\n for (const comment of feedsComments.values()) {\n for (const page of Object.values<RepliesPage>(comment?.replies?.pages || {})) {\n if (page?.comments?.[0]?.updatedAt) {\n feedsCommentsRepliesPagesFirstUpdatedAts +=\n page.comments[0].cid + page.comments[0].updatedAt;\n }\n }\n }\n return feedsCommentsRepliesPagesFirstUpdatedAts;\n};\n\n// get number of feeds comments that are loaded\nexport const getFeedsCommentsLoadedCount = (feedsComments: Map<string, Comment>): number => {\n let count = 0;\n for (const comment of feedsComments.values()) {\n if (comment?.updatedAt) {\n count++;\n }\n }\n return count;\n};\n\n// selected sort type could be missing from comment, or not optimized\nexport const getSortTypeFromComment = (comment: Comment, feedOptions: RepliesFeedOptions) => {\n let { sortType, flat } = feedOptions;\n\n if (!comment) {\n return sortType;\n }\n\n // 'topAll' and 'best' are similar enough to be used interchangeably\n if (\n sortType === \"best\" &&\n !comment.replies?.pages?.best &&\n !comment.replies?.pageCids?.best &&\n (comment.replies?.pages?.topAll || comment.replies?.pageCids?.topAll)\n ) {\n sortType = \"topAll\";\n } else if (\n sortType === \"topAll\" &&\n !comment.replies?.pages?.topAll &&\n !comment.replies?.pageCids?.topAll &&\n (comment.replies?.pages?.best || comment.replies?.pageCids?.best)\n ) {\n sortType = \"best\";\n }\n\n // if 'new' sort type and flat: true, use 'newFlat'\n else if (\n sortType === \"new\" &&\n flat &&\n (comment.replies?.pages?.newFlat || comment.replies?.pageCids?.newFlat)\n ) {\n sortType = \"newFlat\";\n }\n // if 'old' sort type and flat: true, use 'oldFlat'\n else if (\n sortType === \"old\" &&\n flat &&\n (comment.replies?.pages?.oldFlat || comment.replies?.pageCids?.oldFlat)\n ) {\n sortType = \"oldFlat\";\n }\n\n // if 'newFlat' is missing, use 'new'\n else if (\n sortType === \"newFlat\" &&\n !comment.replies?.pages?.newFlat &&\n !comment.replies?.pageCids?.newFlat &&\n (comment.replies?.pages?.new || comment.replies?.pageCids?.new)\n ) {\n sortType = \"new\";\n }\n // if 'oldFlat' is missing, use 'old'\n else if (\n sortType === \"oldFlat\" &&\n !comment.replies?.pages?.oldFlat &&\n !comment.replies?.pageCids?.oldFlat &&\n (comment.replies?.pages?.old || comment.replies?.pageCids?.old)\n ) {\n sortType = \"old\";\n }\n\n // TODO: if sort type doesn't exist on comment, maybe use first existing?\n // else if (!comment.replies?.pages?.[sortType] && !comment.replies?.pageCids?.[sortType]) {\n // const firstPageSortType = comment.replies?.pages && Object.keys(comment.replies.pages)[0]\n // if (firstPageSortType) {\n // sortType = firstPageSortType\n // }\n // else {\n // const firstPageCidSortType = comment.replies?.pageCids && Object.keys(comment.replies.pageCids)[0]\n // if (firstPageCidSortType) {\n // sortType = firstPageCidSortType\n // }\n // }\n // }\n return sortType;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
|
-
"version": "0.1.
|
|
16
|
+
"version": "0.1.6",
|
|
17
17
|
"packageManager": "yarn@4.13.0",
|
|
18
18
|
"files": [
|
|
19
|
+
"CHANGELOG.md",
|
|
19
20
|
"dist"
|
|
20
21
|
],
|
|
21
22
|
"main": "dist/index.js",
|
|
@@ -41,11 +42,12 @@
|
|
|
41
42
|
"lint": "oxlint src/**/*.{js,ts,tsx}",
|
|
42
43
|
"prettier": "oxfmt src/**/*.{js,ts,tsx} test/**/*.{js,ts,tsx} config/**/*.{js,ts,tsx}",
|
|
43
44
|
"type-check": "node ./node_modules/typescript/bin/tsc --noEmit --project config/tsconfig.json",
|
|
44
|
-
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
|
|
45
|
+
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0",
|
|
46
|
+
"changelog:release-notes": "node scripts/changelog-release-notes.mjs"
|
|
45
47
|
},
|
|
46
48
|
"dependencies": {
|
|
47
49
|
"@bitsocial/bso-resolver": "0.0.6",
|
|
48
|
-
"@pkcprotocol/pkc-js": "0.0.
|
|
50
|
+
"@pkcprotocol/pkc-js": "0.0.24",
|
|
49
51
|
"@pkcprotocol/pkc-logger": "0.1.0",
|
|
50
52
|
"assert": "2.0.0",
|
|
51
53
|
"ethers": "5.8.0",
|
|
@@ -56,7 +58,7 @@
|
|
|
56
58
|
"peer-id": "0.16.0",
|
|
57
59
|
"quick-lru": "5.1.1",
|
|
58
60
|
"uint8arrays": "3.1.1",
|
|
59
|
-
"uuid": "
|
|
61
|
+
"uuid": "14.0.0",
|
|
60
62
|
"viem": "2.45.0",
|
|
61
63
|
"zustand": "4.0.0"
|
|
62
64
|
},
|
|
@@ -65,8 +67,10 @@
|
|
|
65
67
|
},
|
|
66
68
|
"resolutions": {
|
|
67
69
|
"follow-redirects": "1.16.0",
|
|
70
|
+
"postcss": "8.5.10",
|
|
68
71
|
"protobufjs": "7.5.5",
|
|
69
|
-
"
|
|
72
|
+
"uuid": "14.0.0",
|
|
73
|
+
"axios": "1.15.2",
|
|
70
74
|
"vite": "8.0.7",
|
|
71
75
|
"tar": "7.5.11",
|
|
72
76
|
"undici": "7.24.0",
|