remove old batch loaders

This commit is contained in:
hzrd149 2025-02-04 11:10:07 -06:00
parent 6f933ad3e1
commit 3e0cd807c2
36 changed files with 417 additions and 993 deletions

View File

@ -45,8 +45,8 @@
"@satellite-earth/core": "^0.5.0",
"@scure/base": "^1.2.4",
"@snort/worker-relay": "^1.3.1",
"@uiw/codemirror-theme-github": "^4.23.7",
"@uiw/react-codemirror": "^4.23.7",
"@uiw/codemirror-theme-github": "^4.23.8",
"@uiw/react-codemirror": "^4.23.8",
"@webscopeio/react-textarea-autocomplete": "^4.9.2",
"ansi-to-html": "^0.7.2",
"applesauce-accounts": "next",

366
pnpm-lock.yaml generated
View File

@ -91,11 +91,11 @@ importers:
specifier: ^1.3.1
version: 1.3.1
'@uiw/codemirror-theme-github':
specifier: ^4.23.7
version: 4.23.7(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
specifier: ^4.23.8
version: 4.23.8(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
'@uiw/react-codemirror':
specifier: ^4.23.7
version: 4.23.7(@babel/runtime@7.26.7)(@codemirror/autocomplete@6.18.4)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.2)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
specifier: ^4.23.8
version: 4.23.8(@babel/runtime@7.26.7)(@codemirror/autocomplete@6.18.4)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.2)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@webscopeio/react-textarea-autocomplete':
specifier: ^4.9.2
version: 4.9.2(prop-types@15.8.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@ -104,28 +104,28 @@ importers:
version: 0.7.2
applesauce-accounts:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-content:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-core:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-factory:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-loaders:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-net:
specifier: ^0.10.0
version: 0.10.0(typescript@5.7.3)
applesauce-react:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-signers:
specifier: next
version: 0.0.0-next-20250203215539(typescript@5.7.3)
version: 0.0.0-next-20250204170704(typescript@5.7.3)
bech32:
specifier: ^2.0.0
version: 2.0.0
@ -269,7 +269,7 @@ importers:
version: 9.0.3(@types/react@18.3.18)(react@19.0.0)
react-mosaic-component:
specifier: ^6.1.1
version: 6.1.1(@types/node@22.13.0)(@types/react@18.3.18)(dnd-core@16.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
version: 6.1.1(@types/node@22.13.1)(@types/react@18.3.18)(dnd-core@16.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-photo-album:
specifier: ^2.4.1
version: 2.4.1(react@19.0.0)
@ -357,7 +357,7 @@ importers:
version: 6.0.2(@capacitor/core@6.2.0)
'@capacitor/assets':
specifier: ^3.0.5
version: 3.0.5(@types/node@22.13.0)(typescript@5.7.3)
version: 3.0.5(@types/node@22.13.1)(typescript@5.7.3)
'@capacitor/cli':
specifier: ^6.2.0
version: 6.2.0
@ -426,7 +426,7 @@ importers:
version: 4.7.5
'@vitejs/plugin-react':
specifier: ^4.3.4
version: 4.3.4(vite@5.4.14(@types/node@22.13.0)(terser@5.37.0))
version: 4.3.4(vite@5.4.14(@types/node@22.13.1)(terser@5.37.0))
camelcase:
specifier: ^8.0.0
version: 8.0.0
@ -441,13 +441,13 @@ importers:
version: 5.7.3
vite:
specifier: ^5.4.14
version: 5.4.14(@types/node@22.13.0)(terser@5.37.0)
version: 5.4.14(@types/node@22.13.1)(terser@5.37.0)
vite-plugin-pwa:
specifier: ^0.21.1
version: 0.21.1(vite@5.4.14(@types/node@22.13.0)(terser@5.37.0))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0)
version: 0.21.1(vite@5.4.14(@types/node@22.13.1)(terser@5.37.0))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0)
vite-tsconfig-paths:
specifier: ^5.1.4
version: 5.1.4(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.0)(terser@5.37.0))
version: 5.1.4(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(terser@5.37.0))
workbox-build:
specifier: ^7.3.0
version: 7.3.0(@types/babel__core@7.20.5)
@ -1720,98 +1720,98 @@ packages:
rollup:
optional: true
'@rollup/rollup-android-arm-eabi@4.34.1':
resolution: {integrity: sha512-kwctwVlswSEsr4ljpmxKrRKp1eG1v2NAhlzFzDf1x1OdYaMjBYjDCbHkzWm57ZXzTwqn8stMXgROrnMw8dJK3w==}
'@rollup/rollup-android-arm-eabi@4.34.2':
resolution: {integrity: sha512-6Fyg9yQbwJR+ykVdT9sid1oc2ewejS6h4wzQltmJfSW53N60G/ah9pngXGANdy9/aaE/TcUFpWosdm7JXS1WTQ==}
cpu: [arm]
os: [android]
'@rollup/rollup-android-arm64@4.34.1':
resolution: {integrity: sha512-4H5ZtZitBPlbPsTv6HBB8zh1g5d0T8TzCmpndQdqq20Ugle/nroOyDMf9p7f88Gsu8vBLU78/cuh8FYHZqdXxw==}
'@rollup/rollup-android-arm64@4.34.2':
resolution: {integrity: sha512-K5GfWe+vtQ3kyEbihrimM38UgX57UqHp+oME7X/EX9Im6suwZfa7Hsr8AtzbJvukTpwMGs+4s29YMSO3rwWtsw==}
cpu: [arm64]
os: [android]
'@rollup/rollup-darwin-arm64@4.34.1':
resolution: {integrity: sha512-f2AJ7Qwx9z25hikXvg+asco8Sfuc5NCLg8rmqQBIOUoWys5sb/ZX9RkMZDPdnnDevXAMJA5AWLnRBmgdXGEUiA==}
'@rollup/rollup-darwin-arm64@4.34.2':
resolution: {integrity: sha512-PSN58XG/V/tzqDb9kDGutUruycgylMlUE59f40ny6QIRNsTEIZsrNQTJKUN2keMMSmlzgunMFqyaGLmly39sug==}
cpu: [arm64]
os: [darwin]
'@rollup/rollup-darwin-x64@4.34.1':
resolution: {integrity: sha512-+/2JBrRfISCsWE4aEFXxd+7k9nWGXA8+wh7ZUHn/u8UDXOU9LN+QYKKhd57sIn6WRcorOnlqPMYFIwie/OHXWw==}
'@rollup/rollup-darwin-x64@4.34.2':
resolution: {integrity: sha512-gQhK788rQJm9pzmXyfBB84VHViDERhAhzGafw+E5mUpnGKuxZGkMVDa3wgDFKT6ukLC5V7QTifzsUKdNVxp5qQ==}
cpu: [x64]
os: [darwin]
'@rollup/rollup-freebsd-arm64@4.34.1':
resolution: {integrity: sha512-SUeB0pYjIXwT2vfAMQ7E4ERPq9VGRrPR7Z+S4AMssah5EHIilYqjWQoTn5dkDtuIJUSTs8H+C9dwoEcg3b0sCA==}
'@rollup/rollup-freebsd-arm64@4.34.2':
resolution: {integrity: sha512-eiaHgQwGPpxLC3+zTAcdKl4VsBl3r0AiJOd1Um/ArEzAjN/dbPK1nROHrVkdnoE6p7Svvn04w3f/jEZSTVHunA==}
cpu: [arm64]
os: [freebsd]
'@rollup/rollup-freebsd-x64@4.34.1':
resolution: {integrity: sha512-L3T66wAZiB/ooiPbxz0s6JEX6Sr2+HfgPSK+LMuZkaGZFAFCQAHiP3dbyqovYdNaiUXcl9TlgnIbcsIicAnOZg==}
'@rollup/rollup-freebsd-x64@4.34.2':
resolution: {integrity: sha512-lhdiwQ+jf8pewYOTG4bag0Qd68Jn1v2gO1i0mTuiD+Qkt5vNfHVK/jrT7uVvycV8ZchlzXp5HDVmhpzjC6mh0g==}
cpu: [x64]
os: [freebsd]
'@rollup/rollup-linux-arm-gnueabihf@4.34.1':
resolution: {integrity: sha512-UBXdQ4+ATARuFgsFrQ+tAsKvBi/Hly99aSVdeCUiHV9dRTTpMU7OrM3WXGys1l40wKVNiOl0QYY6cZQJ2xhKlQ==}
'@rollup/rollup-linux-arm-gnueabihf@4.34.2':
resolution: {integrity: sha512-lfqTpWjSvbgQP1vqGTXdv+/kxIznKXZlI109WkIFPbud41bjigjNmOAAKoazmRGx+k9e3rtIdbq2pQZPV1pMig==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm-musleabihf@4.34.1':
resolution: {integrity: sha512-m/yfZ25HGdcCSwmopEJm00GP7xAUyVcBPjttGLRAqZ60X/bB4Qn6gP7XTwCIU6bITeKmIhhwZ4AMh2XLro+4+w==}
'@rollup/rollup-linux-arm-musleabihf@4.34.2':
resolution: {integrity: sha512-RGjqULqIurqqv+NJTyuPgdZhka8ImMLB32YwUle2BPTDqDoXNgwFjdjQC59FbSk08z0IqlRJjrJ0AvDQ5W5lpw==}
cpu: [arm]
os: [linux]
'@rollup/rollup-linux-arm64-gnu@4.34.1':
resolution: {integrity: sha512-Wy+cUmFuvziNL9qWRRzboNprqSQ/n38orbjRvd6byYWridp5TJ3CD+0+HUsbcWVSNz9bxkDUkyASGP0zS7GAvg==}
'@rollup/rollup-linux-arm64-gnu@4.34.2':
resolution: {integrity: sha512-ZvkPiheyXtXlFqHpsdgscx+tZ7hoR59vOettvArinEspq5fxSDSgfF+L5wqqJ9R4t+n53nyn0sKxeXlik7AY9Q==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-arm64-musl@4.34.1':
resolution: {integrity: sha512-CQ3MAGgiFmQW5XJX5W3wnxOBxKwFlUAgSXFA2SwgVRjrIiVt5LHfcQLeNSHKq5OEZwv+VCBwlD1+YKCjDG8cpg==}
'@rollup/rollup-linux-arm64-musl@4.34.2':
resolution: {integrity: sha512-UlFk+E46TZEoxD9ufLKDBzfSG7Ki03fo6hsNRRRHF+KuvNZ5vd1RRVQm8YZlGsjcJG8R252XFK0xNPay+4WV7w==}
cpu: [arm64]
os: [linux]
'@rollup/rollup-linux-loongarch64-gnu@4.34.1':
resolution: {integrity: sha512-rSzb1TsY4lSwH811cYC3OC2O2mzNMhM13vcnA7/0T6Mtreqr3/qs6WMDriMRs8yvHDI54qxHgOk8EV5YRAHFbw==}
'@rollup/rollup-linux-loongarch64-gnu@4.34.2':
resolution: {integrity: sha512-hJhfsD9ykx59jZuuoQgYT1GEcNNi3RCoEmbo5OGfG8RlHOiVS7iVNev9rhLKh7UBYq409f4uEw0cclTXx8nh8Q==}
cpu: [loong64]
os: [linux]
'@rollup/rollup-linux-powerpc64le-gnu@4.34.1':
resolution: {integrity: sha512-fwr0n6NS0pG3QxxlqVYpfiY64Fd1Dqd8Cecje4ILAV01ROMp4aEdCj5ssHjRY3UwU7RJmeWd5fi89DBqMaTawg==}
'@rollup/rollup-linux-powerpc64le-gnu@4.34.2':
resolution: {integrity: sha512-g/O5IpgtrQqPegvqopvmdCF9vneLE7eqYfdPWW8yjPS8f63DNam3U4ARL1PNNB64XHZDHKpvO2Giftf43puB8Q==}
cpu: [ppc64]
os: [linux]
'@rollup/rollup-linux-riscv64-gnu@4.34.1':
resolution: {integrity: sha512-4uJb9qz7+Z/yUp5RPxDGGGUcoh0PnKF33QyWgEZ3X/GocpWb6Mb+skDh59FEt5d8+Skxqs9mng6Swa6B2AmQZg==}
'@rollup/rollup-linux-riscv64-gnu@4.34.2':
resolution: {integrity: sha512-bSQijDC96M6PuooOuXHpvXUYiIwsnDmqGU8+br2U7iPoykNi9JtMUpN7K6xml29e0evK0/g0D1qbAUzWZFHY5Q==}
cpu: [riscv64]
os: [linux]
'@rollup/rollup-linux-s390x-gnu@4.34.1':
resolution: {integrity: sha512-QlIo8ndocWBEnfmkYqj8vVtIUpIqJjfqKggjy7IdUncnt8BGixte1wDON7NJEvLg3Kzvqxtbo8tk+U1acYEBlw==}
'@rollup/rollup-linux-s390x-gnu@4.34.2':
resolution: {integrity: sha512-49TtdeVAsdRuiUHXPrFVucaP4SivazetGUVH8CIxVsNsaPHV4PFkpLmH9LeqU/R4Nbgky9lzX5Xe1NrzLyraVA==}
cpu: [s390x]
os: [linux]
'@rollup/rollup-linux-x64-gnu@4.34.1':
resolution: {integrity: sha512-hzpleiKtq14GWjz3ahWvJXgU1DQC9DteiwcsY4HgqUJUGxZThlL66MotdUEK9zEo0PK/2ADeZGM9LIondE302A==}
'@rollup/rollup-linux-x64-gnu@4.34.2':
resolution: {integrity: sha512-j+jFdfOycLIQ7FWKka9Zd3qvsIyugg5LeZuHF6kFlXo6MSOc6R1w37YUVy8VpAKd81LMWGi5g9J25P09M0SSIw==}
cpu: [x64]
os: [linux]
'@rollup/rollup-linux-x64-musl@4.34.1':
resolution: {integrity: sha512-jqtKrO715hDlvUcEsPn55tZt2TEiBvBtCMkUuU0R6fO/WPT7lO9AONjPbd8II7/asSiNVQHCMn4OLGigSuxVQA==}
'@rollup/rollup-linux-x64-musl@4.34.2':
resolution: {integrity: sha512-aDPHyM/D2SpXfSNCVWCxyHmOqN9qb7SWkY1+vaXqMNMXslZYnwh9V/UCudl6psyG0v6Ukj7pXanIpfZwCOEMUg==}
cpu: [x64]
os: [linux]
'@rollup/rollup-win32-arm64-msvc@4.34.1':
resolution: {integrity: sha512-RnHy7yFf2Wz8Jj1+h8klB93N0NHNHXFhNwAmiy9zJdpY7DE01VbEVtPdrK1kkILeIbHGRJjvfBDBhnxBr8kD4g==}
'@rollup/rollup-win32-arm64-msvc@4.34.2':
resolution: {integrity: sha512-LQRkCyUBnAo7r8dbEdtNU08EKLCJMgAk2oP5H3R7BnUlKLqgR3dUjrLBVirmc1RK6U6qhtDw29Dimeer8d5hzQ==}
cpu: [arm64]
os: [win32]
'@rollup/rollup-win32-ia32-msvc@4.34.1':
resolution: {integrity: sha512-i7aT5HdiZIcd7quhzvwQ2oAuX7zPYrYfkrd1QFfs28Po/i0q6kas/oRrzGlDhAEyug+1UfUtkWdmoVlLJj5x9Q==}
'@rollup/rollup-win32-ia32-msvc@4.34.2':
resolution: {integrity: sha512-wt8OhpQUi6JuPFkm1wbVi1BByeag87LDFzeKSXzIdGcX4bMLqORTtKxLoCbV57BHYNSUSOKlSL4BYYUghainYA==}
cpu: [ia32]
os: [win32]
'@rollup/rollup-win32-x64-msvc@4.34.1':
resolution: {integrity: sha512-k3MVFD9Oq+laHkw2N2v7ILgoa9017ZMF/inTtHzyTVZjYs9cSH18sdyAf6spBAJIGwJ5UaC7et2ZH1WCdlhkMw==}
'@rollup/rollup-win32-x64-msvc@4.34.2':
resolution: {integrity: sha512-rUrqINax0TvrPBXrFKg0YbQx18NpPN3NNrgmaao9xRNbTwek7lOXObhx8tQy8gelmQ/gLaGy1WptpU2eKJZImg==}
cpu: [x64]
os: [win32]
@ -2005,8 +2005,8 @@ packages:
'@types/node@12.20.55':
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
'@types/node@22.13.0':
resolution: {integrity: sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==}
'@types/node@22.13.1':
resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==}
'@types/normalize-package-data@2.4.4':
resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
@ -2061,8 +2061,8 @@ packages:
'@types/webxr@0.5.21':
resolution: {integrity: sha512-geZIAtLzjGmgY2JUi6VxXdCrTb99A7yP49lxLr2Nm/uIK0PkkxcEi4OGhoGDO4pxCf3JwGz2GiJL2Ej4K2bKaA==}
'@uiw/codemirror-extensions-basic-setup@4.23.7':
resolution: {integrity: sha512-9/2EUa1Lck4kFKkR2BkxlZPpgD/EWuKHnOlysf1yHKZGraaZmZEaUw+utDK4QcuJc8Iz097vsLz4f4th5EU27g==}
'@uiw/codemirror-extensions-basic-setup@4.23.8':
resolution: {integrity: sha512-XJR/8AEVcE7ufy1BhW2nCN9qSVDYEdCtYLfvhaMwl6Q3qcaYYCGE2K5QbFCy7LsdP/3uZKvc1OskuqatoOPdhQ==}
peerDependencies:
'@codemirror/autocomplete': '>=6.0.0'
'@codemirror/commands': '>=6.0.0'
@ -2072,18 +2072,18 @@ packages:
'@codemirror/state': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
'@uiw/codemirror-theme-github@4.23.7':
resolution: {integrity: sha512-r9SstBZD7Ow1sQ8F0EpsRGx9b11K552M2FayvyLWTkal64YJmQMKW0S2KcWykgCMKLWhmDFi7LX+h8cg6nek8g==}
'@uiw/codemirror-theme-github@4.23.8':
resolution: {integrity: sha512-+LVpFdF6RMjDsTo+HkJYBWkEGy2AgcZJVCDku+yWme/shEtV/FulpGwHeb+NrArAFNyXjUXSVMPhLq3+syOLhw==}
'@uiw/codemirror-themes@4.23.7':
resolution: {integrity: sha512-UNf1XOx1hG9OmJnrtT86PxKcdcwhaNhbrcD+nsk8WxRJ3n5c8nH6euDvgVPdVLPwbizsaQcZTILACgA/FjRpVg==}
'@uiw/codemirror-themes@4.23.8':
resolution: {integrity: sha512-PZmJBZxWMuZ48p/2D5aRPl8zTlBq1d/+NeRqyyH6P6k6yWDF6h71m0Dt+fjslgPE7KmWXux2hbejXXXoRLZO9Q==}
peerDependencies:
'@codemirror/language': '>=6.0.0'
'@codemirror/state': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
'@uiw/react-codemirror@4.23.7':
resolution: {integrity: sha512-Nh/0P6W+kWta+ARp9YpnKPD9ick5teEnwmtNoPQnyd6NPv0EQP3Ui4YmRVNj1nkUEo+QjrAUaEfcejJ2up/HZA==}
'@uiw/react-codemirror@4.23.8':
resolution: {integrity: sha512-/NA5Pj4MmXkLSlmlUm4yfEmRLntrNq5TkQKBSINn7TukXQ4fc+C6Bk0U60Qa4rkvCSgwzZdQ2exyP0t0+2GtqA==}
peerDependencies:
'@babel/runtime': '>=7.11.0'
'@codemirror/state': '>=6.0.0'
@ -2192,32 +2192,32 @@ packages:
engines: {node: '>=8.0.0'}
hasBin: true
applesauce-accounts@0.0.0-next-20250203215539:
resolution: {integrity: sha512-PuxwOkGC1wZrfVy585JTE6Eo7vnu9uN5Dt7rEb7PC/NFntv1RFSNfKOrXlEqzltiIo6StErN2ypFz2Tvtj20Eg==}
applesauce-accounts@0.0.0-next-20250204170704:
resolution: {integrity: sha512-y80D4PfoT9gkd+TtUExeQdiq5grlchUbsdjRfmEG3JuAopTCzdgEAa2L7wfLT4DmsUwBvO8ISAm+zKRZ+GI/NQ==}
applesauce-content@0.0.0-next-20250203215539:
resolution: {integrity: sha512-B7lNI/wtB1JZ20h6keFwMscP/ClVuyCC0e/fI4fhtv1RzPbr+GMrHD+liIJZnIqodptD/li3B8ixH41Ux20JlA==}
applesauce-content@0.0.0-next-20250204170704:
resolution: {integrity: sha512-hY6H2v6wSa/rzq6OCnjSL+y2Lv4/AR5z7irdqbSuzhSElslm78pqUPjsFlnVt7nu5K+1cAv0B/Ib/2yhaacgYw==}
applesauce-core@0.0.0-next-20250203215539:
resolution: {integrity: sha512-0Io5Vu1tXYm0ddtaK1DyboxrUblaKhEfYs/TIe9WhcGjBcHBNJgyqoAlZ9YNJ6TN6VX6CmyVAq779KH3IWtWgQ==}
applesauce-core@0.0.0-next-20250204170704:
resolution: {integrity: sha512-TcvcmFHYmduVFZsR+87/cPldZEUz/uafyHIMGPdM8Go4TWg/SMB2tRILdDuUrEjgIgtUVskAGlPF4uIoiH/bEA==}
applesauce-core@0.10.0:
resolution: {integrity: sha512-QMhUh4FIARcqY5soCB4Z8DIu+py0rYb28IgWT4gP9DLBGpDrY8lStXk7W1/46TLjEH97y0hbiXFK7kMCZ31oOQ==}
applesauce-factory@0.0.0-next-20250203215539:
resolution: {integrity: sha512-1jMAzucp8as7bIyOHKwCHGQnkVuOmlaxoDohMth6nVhXclLBUp7pXzHDIwfqQndWWMCMq5TcPQAfYmlVsFQgAQ==}
applesauce-factory@0.0.0-next-20250204170704:
resolution: {integrity: sha512-5lA2aWaKibpt3jNQkNSJJWjopk9CNSWJzDOiM156fBG2Qhe8GzdN7fBiCPlm+iPCRogGyDCAHabSS+JnZB6LTA==}
applesauce-loaders@0.0.0-next-20250203215539:
resolution: {integrity: sha512-ZhzJnnLLigJ/WGXtm3oeQSC3MwGpII92FmO0/Rbrd4vceOOx7b9hEbseDTtfYUtY8e/abahYuKqLH0d8QQFtiA==}
applesauce-loaders@0.0.0-next-20250204170704:
resolution: {integrity: sha512-7mYbE2qJA58A5cfdnpfQbdkohRvg6uhct+QieLlGOc/mNEmMxpA10GP9Wu7FprokWdCJEs0Pn7q7pobsJgPpKw==}
applesauce-net@0.10.0:
resolution: {integrity: sha512-ZsAs/MkeGHiPZ2/a8lwP8lx/Eh+5Dot0qG4BLTAqjg4emP/RsiqW+hyc6v6QcVbdvuR0+hP1gka3+wWtiy/cTA==}
applesauce-react@0.0.0-next-20250203215539:
resolution: {integrity: sha512-KVizXnEkyjHJuVyl11oUArKAIk760U9olSH0hSSkhvPmvzmfUKFvNmugaIeyarr5FJA1qoebkrpsYzbIkvXnMA==}
applesauce-react@0.0.0-next-20250204170704:
resolution: {integrity: sha512-rHA9dO4k5UUeZESMtsrD0oGk7q26AFlpjLjWHBDKiFxRPsr5MusoKyW8X2fZOrN1fyNhgHD+lhCtesTWVUOU7Q==}
applesauce-signers@0.0.0-next-20250203215539:
resolution: {integrity: sha512-o2xftPZuBDLWobAGPdCxWkAGY8F7NqmS85Dra8sVjSB8ZqFOIjII+2iBcqKAk5ytU23FAH3TzZXt1/11w0dGgQ==}
applesauce-signers@0.0.0-next-20250204170704:
resolution: {integrity: sha512-SZUA5uZQChBReIRj34t1y4ZQnV8LR96oHyMelnhAPFJXZT57wUfMJB7Z6KVkxbMHwo2SYUP6qi4MpkC6KQyGng==}
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@ -2454,8 +2454,8 @@ packages:
resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==}
engines: {node: '>=16'}
caniuse-lite@1.0.30001696:
resolution: {integrity: sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==}
caniuse-lite@1.0.30001697:
resolution: {integrity: sha512-GwNPlWJin8E+d7Gxq96jxM6w0w+VFeyyXRsjU58emtkYqnbwHqXm5uT2uCmO0RQE9htWknOP4xtBlLmM/gWxvQ==}
canvas-color-tracker@1.3.1:
resolution: {integrity: sha512-eNycxGS7oQ3IS/9QQY41f/aQjiO9Y/MtedhCgSdsbLSxC9EyUD8L3ehl/Q3Kfmvt8um79S45PBV+5Rxm5ztdSw==}
@ -3033,8 +3033,8 @@ packages:
engines: {node: '>=0.10.0'}
hasBin: true
electron-to-chromium@1.5.90:
resolution: {integrity: sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==}
electron-to-chromium@1.5.91:
resolution: {integrity: sha512-sNSHHyq048PFmZY4S90ax61q+gLCs0X0YmcOII9wG9S2XwbVr+h4VW2wWhnbp/Eys3cCwTxVF292W3qPaxIapQ==}
elementtree@0.1.7:
resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==}
@ -3807,8 +3807,8 @@ packages:
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
engines: {node: '>= 0.4'}
is-weakref@1.1.0:
resolution: {integrity: sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==}
is-weakref@1.1.1:
resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
engines: {node: '>= 0.4'}
is-weakset@2.0.4:
@ -5135,8 +5135,8 @@ packages:
engines: {node: '>=10.0.0'}
hasBin: true
rollup@4.34.1:
resolution: {integrity: sha512-iYZ/+PcdLYSGfH3S+dGahlW/RWmsqDhLgj1BT9DH/xXJ0ggZN7xkdP9wipPNjjNLczI+fmMLmTB9pye+d2r4GQ==}
rollup@4.34.2:
resolution: {integrity: sha512-sBDUoxZEaqLu9QeNalL8v3jw6WjPku4wfZGyTU7l7m1oC+rpRihXc/n/H+4148ZkGz5Xli8CHMns//fFGKvpIQ==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
@ -6849,12 +6849,12 @@ snapshots:
dependencies:
'@capacitor/core': 6.2.0
'@capacitor/assets@3.0.5(@types/node@22.13.0)(typescript@5.7.3)':
'@capacitor/assets@3.0.5(@types/node@22.13.1)(typescript@5.7.3)':
dependencies:
'@capacitor/cli': 5.7.8
'@ionic/utils-array': 2.1.6
'@ionic/utils-fs': 3.1.7
'@trapezedev/project': 7.1.3(@types/node@22.13.0)(typescript@5.7.3)
'@trapezedev/project': 7.1.3(@types/node@22.13.1)(typescript@5.7.3)
commander: 8.3.0
debug: 4.3.4
fs-extra: 10.1.0
@ -7907,61 +7907,61 @@ snapshots:
optionalDependencies:
rollup: 2.79.2
'@rollup/rollup-android-arm-eabi@4.34.1':
'@rollup/rollup-android-arm-eabi@4.34.2':
optional: true
'@rollup/rollup-android-arm64@4.34.1':
'@rollup/rollup-android-arm64@4.34.2':
optional: true
'@rollup/rollup-darwin-arm64@4.34.1':
'@rollup/rollup-darwin-arm64@4.34.2':
optional: true
'@rollup/rollup-darwin-x64@4.34.1':
'@rollup/rollup-darwin-x64@4.34.2':
optional: true
'@rollup/rollup-freebsd-arm64@4.34.1':
'@rollup/rollup-freebsd-arm64@4.34.2':
optional: true
'@rollup/rollup-freebsd-x64@4.34.1':
'@rollup/rollup-freebsd-x64@4.34.2':
optional: true
'@rollup/rollup-linux-arm-gnueabihf@4.34.1':
'@rollup/rollup-linux-arm-gnueabihf@4.34.2':
optional: true
'@rollup/rollup-linux-arm-musleabihf@4.34.1':
'@rollup/rollup-linux-arm-musleabihf@4.34.2':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.34.1':
'@rollup/rollup-linux-arm64-gnu@4.34.2':
optional: true
'@rollup/rollup-linux-arm64-musl@4.34.1':
'@rollup/rollup-linux-arm64-musl@4.34.2':
optional: true
'@rollup/rollup-linux-loongarch64-gnu@4.34.1':
'@rollup/rollup-linux-loongarch64-gnu@4.34.2':
optional: true
'@rollup/rollup-linux-powerpc64le-gnu@4.34.1':
'@rollup/rollup-linux-powerpc64le-gnu@4.34.2':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.34.1':
'@rollup/rollup-linux-riscv64-gnu@4.34.2':
optional: true
'@rollup/rollup-linux-s390x-gnu@4.34.1':
'@rollup/rollup-linux-s390x-gnu@4.34.2':
optional: true
'@rollup/rollup-linux-x64-gnu@4.34.1':
'@rollup/rollup-linux-x64-gnu@4.34.2':
optional: true
'@rollup/rollup-linux-x64-musl@4.34.1':
'@rollup/rollup-linux-x64-musl@4.34.2':
optional: true
'@rollup/rollup-win32-arm64-msvc@4.34.1':
'@rollup/rollup-win32-arm64-msvc@4.34.2':
optional: true
'@rollup/rollup-win32-ia32-msvc@4.34.1':
'@rollup/rollup-win32-ia32-msvc@4.34.2':
optional: true
'@rollup/rollup-win32-x64-msvc@4.34.1':
'@rollup/rollup-win32-x64-msvc@4.34.2':
optional: true
'@sagold/json-pointer@5.1.2': {}
@ -8077,7 +8077,7 @@ snapshots:
'@trapezedev/gradle-parse@7.1.3': {}
'@trapezedev/project@7.1.3(@types/node@22.13.0)(typescript@5.7.3)':
'@trapezedev/project@7.1.3(@types/node@22.13.1)(typescript@5.7.3)':
dependencies:
'@ionic/utils-fs': 3.1.7
'@ionic/utils-subprocess': 2.1.14
@ -8099,7 +8099,7 @@ snapshots:
replace: 1.2.2
tempy: 1.0.1
tmp: 0.2.3
ts-node: 10.9.2(@types/node@22.13.0)(typescript@5.7.3)
ts-node: 10.9.2(@types/node@22.13.1)(typescript@5.7.3)
xcode: 3.0.1
xml-js: 1.6.11
xpath: 0.0.32
@ -8180,7 +8180,7 @@ snapshots:
'@types/fs-extra@8.1.5':
dependencies:
'@types/node': 22.13.0
'@types/node': 22.13.1
'@types/geojson@7946.0.16': {}
@ -8232,7 +8232,7 @@ snapshots:
'@types/node@12.20.55': {}
'@types/node@22.13.0':
'@types/node@22.13.1':
dependencies:
undici-types: 6.20.0
@ -8286,7 +8286,7 @@ snapshots:
'@types/webxr@0.5.21': {}
'@uiw/codemirror-extensions-basic-setup@4.23.7(@codemirror/autocomplete@6.18.4)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
'@uiw/codemirror-extensions-basic-setup@4.23.8(@codemirror/autocomplete@6.18.4)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
dependencies:
'@codemirror/autocomplete': 6.18.4
'@codemirror/commands': 6.8.0
@ -8296,28 +8296,28 @@ snapshots:
'@codemirror/state': 6.5.2
'@codemirror/view': 6.36.2
'@uiw/codemirror-theme-github@4.23.7(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
'@uiw/codemirror-theme-github@4.23.8(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
dependencies:
'@uiw/codemirror-themes': 4.23.7(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
'@uiw/codemirror-themes': 4.23.8(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
transitivePeerDependencies:
- '@codemirror/language'
- '@codemirror/state'
- '@codemirror/view'
'@uiw/codemirror-themes@4.23.7(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
'@uiw/codemirror-themes@4.23.8(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
dependencies:
'@codemirror/language': 6.10.8
'@codemirror/state': 6.5.2
'@codemirror/view': 6.36.2
'@uiw/react-codemirror@4.23.7(@babel/runtime@7.26.7)(@codemirror/autocomplete@6.18.4)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.2)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
'@uiw/react-codemirror@4.23.8(@babel/runtime@7.26.7)(@codemirror/autocomplete@6.18.4)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.2)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@babel/runtime': 7.26.7
'@codemirror/commands': 6.8.0
'@codemirror/state': 6.5.2
'@codemirror/theme-one-dark': 6.1.2
'@codemirror/view': 6.36.2
'@uiw/codemirror-extensions-basic-setup': 4.23.7(@codemirror/autocomplete@6.18.4)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
'@uiw/codemirror-extensions-basic-setup': 4.23.8(@codemirror/autocomplete@6.18.4)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.8)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
codemirror: 6.0.1
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
@ -8329,14 +8329,14 @@ snapshots:
'@ungap/structured-clone@1.3.0': {}
'@vitejs/plugin-react@4.3.4(vite@5.4.14(@types/node@22.13.0)(terser@5.37.0))':
'@vitejs/plugin-react@4.3.4(vite@5.4.14(@types/node@22.13.1)(terser@5.37.0))':
dependencies:
'@babel/core': 7.26.7
'@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.7)
'@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.7)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
vite: 5.4.14(@types/node@22.13.0)(terser@5.37.0)
vite: 5.4.14(@types/node@22.13.1)(terser@5.37.0)
transitivePeerDependencies:
- supports-color
@ -8423,10 +8423,10 @@ snapshots:
dependencies:
entities: 2.2.0
applesauce-accounts@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-accounts@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
'@noble/hashes': 1.7.1
applesauce-signers: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-signers: 0.0.0-next-20250204170704(typescript@5.7.3)
nanoid: 5.0.9
nostr-tools: 2.10.4(typescript@5.7.3)
rxjs: 7.8.1
@ -8434,13 +8434,13 @@ snapshots:
- supports-color
- typescript
applesauce-content@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-content@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
'@cashu/cashu-ts': 2.0.0-rc1
'@types/hast': 3.0.4
'@types/mdast': 4.0.4
'@types/unist': 3.0.3
applesauce-core: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250204170704(typescript@5.7.3)
mdast-util-find-and-replace: 3.0.2
nostr-tools: 2.10.4(typescript@5.7.3)
remark: 15.0.1
@ -8451,7 +8451,7 @@ snapshots:
- supports-color
- typescript
applesauce-core@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-core@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
'@scure/base': 1.2.4
debug: 4.4.0
@ -8479,19 +8479,19 @@ snapshots:
- supports-color
- typescript
applesauce-factory@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-factory@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
applesauce-content: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-content: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250204170704(typescript@5.7.3)
nanoid: 5.0.9
nostr-tools: 2.10.4(typescript@5.7.3)
transitivePeerDependencies:
- supports-color
- typescript
applesauce-loaders@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-loaders@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
applesauce-core: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250204170704(typescript@5.7.3)
nanoid: 5.0.9
nostr-tools: 2.10.4(typescript@5.7.3)
rx-nostr: 3.5.0
@ -8510,12 +8510,12 @@ snapshots:
- supports-color
- typescript
applesauce-react@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-react@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
applesauce-accounts: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-content: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-factory: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-accounts: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-content: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250204170704(typescript@5.7.3)
applesauce-factory: 0.0.0-next-20250204170704(typescript@5.7.3)
nostr-tools: 2.10.4(typescript@5.7.3)
react: 18.3.1
rxjs: 7.8.1
@ -8523,12 +8523,12 @@ snapshots:
- supports-color
- typescript
applesauce-signers@0.0.0-next-20250203215539(typescript@5.7.3):
applesauce-signers@0.0.0-next-20250204170704(typescript@5.7.3):
dependencies:
'@noble/hashes': 1.7.1
'@noble/secp256k1': 1.7.1
'@scure/base': 1.2.4
applesauce-core: 0.0.0-next-20250203215539(typescript@5.7.3)
applesauce-core: 0.0.0-next-20250204170704(typescript@5.7.3)
debug: 4.4.0
nanoid: 5.0.9
nostr-tools: 2.10.4(typescript@5.7.3)
@ -8752,8 +8752,8 @@ snapshots:
browserslist@4.24.4:
dependencies:
caniuse-lite: 1.0.30001696
electron-to-chromium: 1.5.90
caniuse-lite: 1.0.30001697
electron-to-chromium: 1.5.91
node-releases: 2.0.19
update-browserslist-db: 1.1.2(browserslist@4.24.4)
@ -8802,7 +8802,7 @@ snapshots:
camelcase@8.0.0: {}
caniuse-lite@1.0.30001696: {}
caniuse-lite@1.0.30001697: {}
canvas-color-tracker@1.3.1:
dependencies:
@ -9450,7 +9450,7 @@ snapshots:
dependencies:
jake: 10.9.2
electron-to-chromium@1.5.90: {}
electron-to-chromium@1.5.91: {}
elementtree@0.1.7:
dependencies:
@ -9533,7 +9533,7 @@ snapshots:
is-shared-array-buffer: 1.0.4
is-string: 1.1.1
is-typed-array: 1.1.15
is-weakref: 1.1.0
is-weakref: 1.1.1
math-intrinsics: 1.1.0
object-inspect: 1.13.3
object-keys: 1.1.1
@ -10310,7 +10310,7 @@ snapshots:
is-weakmap@2.0.2: {}
is-weakref@1.1.0:
is-weakref@1.1.1:
dependencies:
call-bound: 1.0.3
@ -11472,26 +11472,26 @@ snapshots:
dependencies:
dnd-core: 16.0.1
react-dnd-multi-backend@8.1.2(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
react-dnd-multi-backend@8.1.2(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
dnd-core: 16.0.1
dnd-multi-backend: 8.1.2(dnd-core@16.0.1)
react: 19.0.0
react-dnd: 16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0)
react-dnd-preview: 8.1.2(react-dnd@16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0))(react@19.0.0)
react-dnd: 16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0)
react-dnd-preview: 8.1.2(react-dnd@16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0))(react@19.0.0)
react-dom: 19.0.0(react@19.0.0)
react-dnd-preview@8.1.2(react-dnd@16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0))(react@19.0.0):
react-dnd-preview@8.1.2(react-dnd@16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0))(react@19.0.0):
dependencies:
react: 19.0.0
react-dnd: 16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0)
react-dnd: 16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0)
react-dnd-touch-backend@16.0.1:
dependencies:
'@react-dnd/invariant': 4.0.2
dnd-core: 16.0.1
react-dnd@16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0):
react-dnd@16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0):
dependencies:
'@react-dnd/invariant': 4.0.2
'@react-dnd/shallowequal': 4.0.2
@ -11500,7 +11500,7 @@ snapshots:
hoist-non-react-statics: 3.3.2
react: 19.0.0
optionalDependencies:
'@types/node': 22.13.0
'@types/node': 22.13.1
'@types/react': 18.3.18
react-dom@19.0.0(react@19.0.0):
@ -11569,7 +11569,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
react-mosaic-component@6.1.1(@types/node@22.13.0)(@types/react@18.3.18)(dnd-core@16.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
react-mosaic-component@6.1.1(@types/node@22.13.1)(@types/react@18.3.18)(dnd-core@16.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
classnames: 2.5.1
immutability-helper: 3.1.1
@ -11577,9 +11577,9 @@ snapshots:
prop-types: 15.8.1
rdndmb-html5-to-touch: 8.1.2(dnd-core@16.0.1)
react: 19.0.0
react-dnd: 16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0)
react-dnd: 16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0)
react-dnd-html5-backend: 16.0.1
react-dnd-multi-backend: 8.1.2(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.13.0)(@types/react@18.3.18)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-dnd-multi-backend: 8.1.2(dnd-core@16.0.1)(react-dnd@16.0.1(@types/node@22.13.1)(@types/react@18.3.18)(react@19.0.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react-dnd-touch-backend: 16.0.1
uuid: 9.0.1
transitivePeerDependencies:
@ -11911,29 +11911,29 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
rollup@4.34.1:
rollup@4.34.2:
dependencies:
'@types/estree': 1.0.6
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.34.1
'@rollup/rollup-android-arm64': 4.34.1
'@rollup/rollup-darwin-arm64': 4.34.1
'@rollup/rollup-darwin-x64': 4.34.1
'@rollup/rollup-freebsd-arm64': 4.34.1
'@rollup/rollup-freebsd-x64': 4.34.1
'@rollup/rollup-linux-arm-gnueabihf': 4.34.1
'@rollup/rollup-linux-arm-musleabihf': 4.34.1
'@rollup/rollup-linux-arm64-gnu': 4.34.1
'@rollup/rollup-linux-arm64-musl': 4.34.1
'@rollup/rollup-linux-loongarch64-gnu': 4.34.1
'@rollup/rollup-linux-powerpc64le-gnu': 4.34.1
'@rollup/rollup-linux-riscv64-gnu': 4.34.1
'@rollup/rollup-linux-s390x-gnu': 4.34.1
'@rollup/rollup-linux-x64-gnu': 4.34.1
'@rollup/rollup-linux-x64-musl': 4.34.1
'@rollup/rollup-win32-arm64-msvc': 4.34.1
'@rollup/rollup-win32-ia32-msvc': 4.34.1
'@rollup/rollup-win32-x64-msvc': 4.34.1
'@rollup/rollup-android-arm-eabi': 4.34.2
'@rollup/rollup-android-arm64': 4.34.2
'@rollup/rollup-darwin-arm64': 4.34.2
'@rollup/rollup-darwin-x64': 4.34.2
'@rollup/rollup-freebsd-arm64': 4.34.2
'@rollup/rollup-freebsd-x64': 4.34.2
'@rollup/rollup-linux-arm-gnueabihf': 4.34.2
'@rollup/rollup-linux-arm-musleabihf': 4.34.2
'@rollup/rollup-linux-arm64-gnu': 4.34.2
'@rollup/rollup-linux-arm64-musl': 4.34.2
'@rollup/rollup-linux-loongarch64-gnu': 4.34.2
'@rollup/rollup-linux-powerpc64le-gnu': 4.34.2
'@rollup/rollup-linux-riscv64-gnu': 4.34.2
'@rollup/rollup-linux-s390x-gnu': 4.34.2
'@rollup/rollup-linux-x64-gnu': 4.34.2
'@rollup/rollup-linux-x64-musl': 4.34.2
'@rollup/rollup-win32-arm64-msvc': 4.34.2
'@rollup/rollup-win32-ia32-msvc': 4.34.2
'@rollup/rollup-win32-x64-msvc': 4.34.2
fsevents: 2.3.3
rtl-css-js@1.16.1:
@ -12500,14 +12500,14 @@ snapshots:
ts-easing@0.2.0: {}
ts-node@10.9.2(@types/node@22.13.0)(typescript@5.7.3):
ts-node@10.9.2(@types/node@22.13.1)(typescript@5.7.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.11
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
'@types/node': 22.13.0
'@types/node': 22.13.1
acorn: 8.14.0
acorn-walk: 8.3.4
arg: 4.1.3
@ -12722,35 +12722,35 @@ snapshots:
vite-plugin-funding@0.1.0: {}
vite-plugin-pwa@0.21.1(vite@5.4.14(@types/node@22.13.0)(terser@5.37.0))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0):
vite-plugin-pwa@0.21.1(vite@5.4.14(@types/node@22.13.1)(terser@5.37.0))(workbox-build@7.3.0(@types/babel__core@7.20.5))(workbox-window@7.3.0):
dependencies:
debug: 4.4.0
pretty-bytes: 6.1.1
tinyglobby: 0.2.10
vite: 5.4.14(@types/node@22.13.0)(terser@5.37.0)
vite: 5.4.14(@types/node@22.13.1)(terser@5.37.0)
workbox-build: 7.3.0(@types/babel__core@7.20.5)
workbox-window: 7.3.0
transitivePeerDependencies:
- supports-color
vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.0)(terser@5.37.0)):
vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@5.4.14(@types/node@22.13.1)(terser@5.37.0)):
dependencies:
debug: 4.4.0
globrex: 0.1.2
tsconfck: 3.1.4(typescript@5.7.3)
optionalDependencies:
vite: 5.4.14(@types/node@22.13.0)(terser@5.37.0)
vite: 5.4.14(@types/node@22.13.1)(terser@5.37.0)
transitivePeerDependencies:
- supports-color
- typescript
vite@5.4.14(@types/node@22.13.0)(terser@5.37.0):
vite@5.4.14(@types/node@22.13.1)(terser@5.37.0):
dependencies:
esbuild: 0.21.5
postcss: 8.5.1
rollup: 4.34.1
rollup: 4.34.2
optionalDependencies:
'@types/node': 22.13.0
'@types/node': 22.13.1
fsevents: 2.3.3
terser: 5.37.0
@ -12805,7 +12805,7 @@ snapshots:
is-finalizationregistry: 1.1.1
is-generator-function: 1.1.0
is-regex: 1.2.1
is-weakref: 1.1.0
is-weakref: 1.1.1
isarray: 2.0.5
which-boxed-primitive: 1.1.1
which-collection: 1.0.2

View File

@ -1,148 +0,0 @@
import { NostrEvent } from "nostr-tools";
import { AbstractRelay } from "nostr-tools/abstract-relay";
import _throttle from "lodash.throttle";
import debug, { Debugger } from "debug";
import { EventStore } from "applesauce-core";
import { getEventUID } from "applesauce-core/helpers";
import { createDefer, Deferred } from "applesauce-core/promise";
import { Subject } from "rxjs";
import PersistentSubscription from "./persistent-subscription";
import SuperMap from "./super-map";
/** Batches requests for events with #d tags from a single relay */
export default class BatchIdentifierLoader {
store: EventStore;
kinds: number[];
relay: AbstractRelay;
/** list of identifiers that have been loaded */
requested = new Set<string>();
/** identifier -> event uid -> event */
identifiers = new SuperMap<string, Map<string, NostrEvent>>(() => new Map());
onIdentifierUpdate = new Subject<string>();
subscription: PersistentSubscription;
// a map of identifiers that are waiting for the current request to finish
private next = new Map<string, Deferred<Map<string, NostrEvent>>>();
// a map of identifiers currently being requested from the relay
private pending = new Map<string, Deferred<Map<string, NostrEvent>>>();
log: Debugger;
active = false;
constructor(store: EventStore, relay: AbstractRelay, kinds: number[], log?: Debugger) {
this.store = store;
this.relay = relay;
this.kinds = kinds;
this.log = log || debug("BatchIdentifierLoader");
this.subscription = new PersistentSubscription(this.relay, {
onevent: (event) => this.handleEvent(event),
oneose: () => this.handleEOSE(),
});
}
requestEvents(identifier: string): Promise<Map<string, NostrEvent>> {
// if there is a cache only return it if we have requested this id before
if (this.identifiers.has(identifier) && this.requested.has(identifier)) {
return Promise.resolve(this.identifiers.get(identifier));
}
if (this.pending.has(identifier)) return this.pending.get(identifier)!;
if (this.next.has(identifier)) return this.next.get(identifier)!;
const defer = createDefer<Map<string, NostrEvent>>();
this.next.set(identifier, defer);
// request subscription update
this.requestUpdate();
return defer;
}
requestUpdate = _throttle(
() => {
// don't do anything if the subscription is already running
if (this.active) return;
this.active = true;
this.update();
},
500,
{ leading: false, trailing: true },
);
handleEvent(event: NostrEvent) {
event = this.store.add(event, this.relay.url);
// add event to cache
for (const tag of event.tags) {
if (tag[0] === "d" && tag[1]) {
const identifier = tag[1];
this.identifiers.get(identifier).set(getEventUID(event), event);
this.changedIdentifiers.add(identifier);
}
}
}
private changedIdentifiers = new Set<string>();
handleEOSE() {
// resolve all pending from the last request
for (const [identifier, defer] of this.pending) {
defer.resolve(this.identifiers.get(identifier));
this.changedIdentifiers.add(identifier);
}
// reset
this.pending.clear();
this.active = false;
for (const identifier of this.changedIdentifiers) {
this.onIdentifierUpdate.next(identifier);
}
// do next request or close the subscription
if (this.next.size > 0) this.requestUpdate();
}
async update() {
// copy everything from next to pending
for (const [identifier, defer] of this.next) this.pending.set(identifier, defer);
this.next.clear();
// update subscription
if (this.pending.size > 0) {
this.log(`Updating filters ${this.pending.size} events`);
const dTags: string[] = [];
const identifiers = Array.from(this.pending.keys());
for (const identifier of identifiers) {
this.requested.add(identifier);
dTags.push(identifier);
}
try {
this.active = true;
this.subscription.filters = [];
if (dTags.length > 0) this.subscription.filters.push({ "#d": dTags, kinds: this.kinds });
await this.subscription.update();
} catch (error) {
if (error instanceof Error) this.log(`Failed to update subscription`, error.message);
this.active = false;
}
} else {
this.log("Closing");
this.subscription.close();
this.active = false;
}
}
destroy() {
this.subscription.destroy();
}
}

View File

@ -1,148 +0,0 @@
import { NostrEvent } from "nostr-tools";
import { AbstractRelay } from "nostr-tools/abstract-relay";
import _throttle from "lodash.throttle";
import debug, { Debugger } from "debug";
import { createDefer, Deferred } from "applesauce-core/promise";
import { Subject } from "rxjs";
import PersistentSubscription from "./persistent-subscription";
import SuperMap from "./super-map";
import { eventStore } from "../services/event-store";
/** Batches requests for events that reference another event (via #e tag) from a single relay */
export default class BatchRelationLoader {
kinds: number[];
relay: AbstractRelay;
requested = new Set<string>();
/** event id / coordinate -> event id -> event */
references = new SuperMap<string, Map<string, NostrEvent>>(() => new Map());
onEventUpdate = new Subject<string>();
subscription: PersistentSubscription;
// a map of events that are waiting for the current request to finish
private next = new Map<string, Deferred<Map<string, NostrEvent>>>();
// a map of events currently being requested from the relay
private pending = new Map<string, Deferred<Map<string, NostrEvent>>>();
log: Debugger;
active = false;
constructor(relay: AbstractRelay, kinds: number[], log?: Debugger) {
this.relay = relay;
this.kinds = kinds;
this.log = log || debug("BatchRelationLoader");
this.subscription = new PersistentSubscription(this.relay, {
onevent: (event) => this.handleEvent(event),
oneose: () => this.handleEOSE(),
});
}
requestEvents(uid: string): Promise<Map<string, NostrEvent>> {
// if there is a cache only return it if we have requested this id before
if (this.references.has(uid) && this.requested.has(uid)) {
return Promise.resolve(this.references.get(uid));
}
if (this.pending.has(uid)) return this.pending.get(uid)!;
if (this.next.has(uid)) return this.next.get(uid)!;
const defer = createDefer<Map<string, NostrEvent>>();
this.next.set(uid, defer);
// request subscription update
this.requestUpdate();
return defer;
}
requestUpdate = _throttle(
() => {
// don't do anything if the subscription is already running
if (this.active) return;
this.active = true;
this.update();
},
500,
{ leading: false, trailing: true },
);
handleEvent(event: NostrEvent) {
event = eventStore.add(event, this.relay.url);
// add event to cache
const updateIds = new Set<string>();
for (const tag of event.tags) {
if (tag[0] === "e" && tag[1]) {
const id = tag[1];
this.references.get(id).set(event.id, event);
updateIds.add(id);
} else if (tag[0] === "a" && tag[1]) {
const cord = tag[1];
this.references.get(cord).set(event.id, event);
updateIds.add(cord);
}
}
for (const id of updateIds) this.onEventUpdate.next(id);
}
handleEOSE() {
// resolve all pending from the last request
for (const [uid, defer] of this.pending) {
defer.resolve(this.references.get(uid));
}
// reset
this.pending.clear();
this.active = false;
// do next request or close the subscription
if (this.next.size > 0) this.requestUpdate();
}
async update() {
// copy everything from next to pending
for (const [uid, defer] of this.next) this.pending.set(uid, defer);
this.next.clear();
// update subscription
if (this.pending.size > 0) {
this.log(`Updating filters ${this.pending.size} events`);
const ids: string[] = [];
const cords: string[] = [];
const uids = Array.from(this.pending.keys());
for (const uid of uids) {
this.requested.add(uid);
if (uid.includes(":")) cords.push(uid);
else ids.push(uid);
}
try {
this.active = true;
this.subscription.filters = [];
if (ids.length > 0) this.subscription.filters.push({ "#e": ids, kinds: this.kinds });
if (cords.length > 0) this.subscription.filters.push({ "#a": cords, kinds: this.kinds });
await this.subscription.update();
} catch (error) {
if (error instanceof Error) this.log(`Failed to update subscription`, error.message);
this.active = false;
}
} else {
this.log("Closing");
this.subscription.close();
this.active = false;
}
}
destroy() {
this.subscription.destroy();
}
}

View File

@ -1,84 +0,0 @@
import { nanoid } from "nanoid";
import { Filter, Relay } from "nostr-tools";
import { AbstractRelay, Subscription, SubscriptionParams } from "nostr-tools/abstract-relay";
import { isFilterEqual } from "applesauce-core/helpers";
import relayPoolService from "../services/relay-pool";
export default class PersistentSubscription {
id: string;
relay: Relay;
filters: Filter[];
connecting = false;
params: Partial<SubscriptionParams>;
subscription: Subscription | null = null;
get eosed() {
return !!this.subscription?.eosed;
}
get closed() {
return !this.subscription || this.subscription.closed;
}
active = false;
constructor(relay: AbstractRelay, params?: Partial<SubscriptionParams>) {
this.id = nanoid(8);
this.filters = [];
this.params = {
//@ts-expect-error
id: this.id,
...params,
};
this.relay = relay;
}
/** attempts to update the subscription */
async update() {
if (!this.filters || this.filters.length === 0) throw new Error("Missing filters");
if (this.connecting) throw new Error("Cant update while connecting");
this.active = true;
this.connecting = true;
if ((await relayPoolService.waitForOpen(this.relay)) === false) {
this.connecting = false;
this.active = false;
throw new Error("Failed to connect to relay");
}
this.connecting = false;
// recreate the subscription if its closed since nostr-tools cant reopen a sub
if (!this.subscription || this.subscription.closed) {
this.subscription = this.relay.subscribe(this.filters, {
...this.params,
oneose: () => {
this.params.oneose?.();
},
onclose: (reason) => {
if (!this.closed) {
relayPoolService.handleRelayNotice(this.relay, reason);
this.active = false;
}
this.params.onclose?.(reason);
},
});
} else if (isFilterEqual(this.subscription.filters, this.filters) === false) {
this.subscription.filters = this.filters;
// NOTE: reset the eosed flag since nostr-tools dose not
this.subscription.eosed = false;
this.subscription.fire();
} else throw new Error("Subscription filters have not changed");
}
close() {
if (this.subscription?.closed === false) this.subscription.close();
this.active = false;
return this;
}
destroy() {
this.close();
}
}

View File

@ -1,6 +0,0 @@
export enum RelayMode {
NONE = 0,
READ = 1,
WRITE = 2,
BOTH = 1 | 2,
}

View File

@ -23,8 +23,8 @@ import { useObservable } from "applesauce-react/hooks";
import { useReadRelays } from "../../hooks/use-client-relays";
import { getPageDefer, getPageSummary } from "../../helpers/nostr/wiki";
import UserName from "../user/user-name";
import dictionaryService from "../../services/dictionary";
import { useWebOfTrust } from "../../providers/global/web-of-trust-provider";
import useWikiPages from "../../hooks/use-wiki-pages";
export default function WikiLink({
children,
@ -43,11 +43,10 @@ export default function WikiLink({
topic = properties.href.replace(/^#\/page\//, "");
}
const subject = useMemo(
() => (topic ? dictionaryService.requestTopic(topic, readRelays) : undefined),
[topic, readRelays],
);
const events = useObservable(subject);
// TODO: if topic cant be found, render something else
if (!topic) return null;
const events = useWikiPages(topic, readRelays);
const sorted = useMemo(() => {
if (!events) return [];
@ -97,7 +96,7 @@ export default function WikiLink({
<UserName pubkey={page.pubkey} />: {getPageSummary(page)}
</Text>
))}
{events?.size === 0 && <Text fontStyle="italic">There is no entry for this topic</Text>}
{events?.length === 0 && <Text fontStyle="italic">There is no entry for this topic</Text>}
</PopoverBody>
</PopoverContent>
</Portal>

View File

@ -1,16 +1,15 @@
import { Button, ButtonProps, IconButton, useDisclosure } from "@chakra-ui/react";
import { getZapSender } from "applesauce-core/helpers";
import { getEventUID, getZapSender } from "applesauce-core/helpers";
import { useActiveAccount } from "applesauce-react/hooks";
import { humanReadableSats } from "../../helpers/lightning";
import { totalZaps } from "../../helpers/nostr/zaps";
import useEventZaps from "../../hooks/use-event-zaps";
import eventZapsService from "../../services/event-zaps";
import { requestZaps } from "../../services/event-zaps-loader";
import { NostrEvent } from "../../types/nostr-event";
import { LightningIcon } from "../icons";
import ZapModal from "../event-zap-modal";
import useUserLNURLMetadata from "../../hooks/use-user-lnurl-metadata";
import { getEventUID } from "../../helpers/nostr/event";
import { useReadRelays } from "../../hooks/use-client-relays";
export type NoteZapButtonProps = Omit<ButtonProps, "children"> & {
@ -30,7 +29,7 @@ export default function EventZapButton({ event, allowComment, showEventPreview,
const readRelays = useReadRelays();
const onZapped = () => {
onClose();
eventZapsService.requestZaps(getEventUID(event), readRelays, true);
requestZaps(getEventUID(event), readRelays, true);
};
const total = totalZaps(zaps);

View File

@ -2,13 +2,13 @@ import { IconButton, IconButtonProps, useDisclosure } from "@chakra-ui/react";
import { useActiveAccount } from "applesauce-react/hooks";
import useEventZaps from "../../hooks/use-event-zaps";
import eventZapsService from "../../services/event-zaps";
import { NostrEvent } from "../../types/nostr-event";
import { LightningIcon } from "../icons";
import ZapModal from "../event-zap-modal";
import useUserLNURLMetadata from "../../hooks/use-user-lnurl-metadata";
import { getEventUID } from "../../helpers/nostr/event";
import { useReadRelays } from "../../hooks/use-client-relays";
import { requestZaps } from "../../services/event-zaps-loader";
export default function EventZapIconButton({
event,
@ -22,7 +22,7 @@ export default function EventZapIconButton({
const readRelays = useReadRelays();
const onZapped = () => {
onClose();
eventZapsService.requestZaps(getEventUID(event), readRelays, true);
requestZaps(getEventUID(event), readRelays, true);
};
const canZap = !!metadata?.allowsNostr || event.tags.some((t) => t[0] === "zap");

View File

@ -1,6 +1,5 @@
import SuperMap from "../classes/super-map";
import { NostrEvent } from "../types/nostr-event";
import { getThreadReferences, sortByDate } from "./nostr/event";
const DAY_IN_SECONDS = 60 * 60 * 24;

View File

@ -2,19 +2,21 @@ import { useMemo } from "react";
import { useStoreQuery } from "applesauce-react/hooks";
import { ChannelMetadataQuery } from "applesauce-core/queries";
import channelMetadataService from "../services/channel-metadata";
import useSingleEvent from "./use-single-event";
import channelMetadataLoader from "../services/channel-metadata-loader";
import { useReadRelays } from "./use-client-relays";
export default function useChannelMetadata(
channelId: string | undefined,
relays: Iterable<string> = [],
additionalRelays?: string[],
force?: boolean,
) {
const relays = useReadRelays(additionalRelays);
const channel = useSingleEvent(channelId);
useMemo(() => {
if (!channelId) return;
return channelMetadataService.requestMetadata(relays, channelId, { alwaysRequest: force, ignoreCache: force });
}, [channelId, Array.from(relays).join("|"), force]);
return channelMetadataLoader.next({ value: channelId, relays, force });
}, [channelId, relays.join("|"), force]);
const metadata = useStoreQuery(ChannelMetadataQuery, channel && [channel]);

View File

@ -4,19 +4,15 @@ import { getEventUID } from "applesauce-core/helpers";
import { useStoreQuery } from "applesauce-react/hooks";
import { ReactionsQuery } from "applesauce-core/queries";
import eventReactionsService from "../services/event-reactions";
import { useReadRelays } from "./use-client-relays";
import { requestReactions } from "../services/event-reactions-loader";
export default function useEventReactions(
event: NostrEvent,
additionalRelays?: Iterable<string>,
alwaysRequest = true,
) {
export default function useEventReactions(event: NostrEvent, additionalRelays?: string[], force?: boolean) {
const relays = useReadRelays(additionalRelays);
useEffect(() => {
eventReactionsService.requestReactions(getEventUID(event), relays, alwaysRequest);
}, [event, relays, alwaysRequest]);
requestReactions(getEventUID(event), relays, force);
}, [event, relays.join(","), force]);
return useStoreQuery(ReactionsQuery, [event]);
}

View File

@ -2,16 +2,16 @@ import { useEffect, useMemo } from "react";
import { useStoreQuery } from "applesauce-react/hooks";
import { parseCoordinate } from "applesauce-core/helpers";
import { EventZapsQuery } from "applesauce-core/queries";
import { requestZaps } from "../services/event-zaps-loader";
import eventZapsService from "../services/event-zaps";
import { useReadRelays } from "./use-client-relays";
export default function useEventZaps(uid: string, additionalRelays?: Iterable<string>, alwaysRequest = false) {
const readRelays = useReadRelays(additionalRelays);
export default function useEventZaps(uid: string, additionalRelays?: Iterable<string>, force?: boolean) {
const relay = useReadRelays(additionalRelays);
useEffect(() => {
eventZapsService.requestZaps(uid, readRelays, alwaysRequest);
}, [uid, readRelays.join("|"), alwaysRequest]);
requestZaps(uid, relay, force);
}, [uid, relay.join("|"), force]);
const pointer = useMemo(() => {
if (uid.includes(":")) return parseCoordinate(uid, true);

View File

@ -0,0 +1,21 @@
import { useEffect } from "react";
import { useStoreQuery } from "applesauce-react/hooks";
import { NostrEvent } from "nostr-tools";
import { useReadRelays } from "./use-client-relays";
import wikiPageLoader from "../services/wiki-page-loader";
import { WikiPagesQuery } from "../queries/wiki-pages";
export default function useWikiPages(
topic: string,
additionalRelays?: Iterable<string>,
force?: boolean,
): NostrEvent[] {
const relays = useReadRelays(additionalRelays);
useEffect(() => {
wikiPageLoader.next({ value: topic, relays, force });
}, [topic, relays.join("|"), force]);
return useStoreQuery(WikiPagesQuery, topic ? [topic] : undefined) ?? [];
}

10
src/queries/wiki-pages.ts Normal file
View File

@ -0,0 +1,10 @@
import { Query } from "applesauce-core";
import { NostrEvent } from "nostr-tools";
import { WIKI_PAGE_KIND } from "../helpers/nostr/wiki";
export function WikiPagesQuery(topic: string): Query<NostrEvent[]> {
return {
key: topic,
run: (store) => store.timeline([{ kinds: [WIKI_PAGE_KIND], "#d": [topic] }]),
};
}

View File

@ -0,0 +1,28 @@
import { Query } from "applesauce-core";
import { groupBy, map } from "rxjs";
import { NostrEvent } from "nostr-tools";
import { WIKI_PAGE_KIND } from "../helpers/nostr/wiki";
import { getReplaceableIdentifier } from "applesauce-core/helpers";
export function WikiTopicsQuery(): Query<Record<string, NostrEvent[]>> {
return {
key: "topics",
run: (store) =>
store.timeline([{ kinds: [WIKI_PAGE_KIND] }]).pipe(
map((events) => {
const topics: Record<string, NostrEvent[]> = {};
for (const event of events) {
const d = getReplaceableIdentifier(event);
if (!d) continue;
if (!topics[d]) topics[d] = [event];
else topics[d].push(event);
}
return topics;
}),
),
};
}

View File

@ -0,0 +1,19 @@
import { kinds } from "nostr-tools";
import { cacheRequest } from "./cache-relay";
import { TagValueLoader } from "applesauce-loaders";
import rxNostr from "./rx-nostr";
import { eventStore } from "./event-store";
const channelMetadataLoader = new TagValueLoader(rxNostr, "e", {
name: "channel-metadata",
kinds: [kinds.ChannelMetadata],
cacheRequest,
});
// start the loader and send all events to the event store
channelMetadataLoader.subscribe((packet) => {
eventStore.add(packet.event, packet.from);
});
export default channelMetadataLoader;

View File

@ -1,157 +0,0 @@
import dayjs from "dayjs";
import { Debugger } from "debug";
import _throttle from "lodash.throttle";
import { Filter, kinds } from "nostr-tools";
import SuperMap from "../classes/super-map";
import { NostrEvent } from "../types/nostr-event";
import { logger } from "../helpers/debug";
import { eventStore } from "./event-store";
import relayPoolService from "./relay-pool";
import PersistentSubscription from "../classes/persistent-subscription";
import { getChannelPointer, markFromCache } from "applesauce-core/helpers";
import { AbstractRelay } from "nostr-tools/abstract-relay";
import { cacheRelay$, getCacheRelay } from "./cache-relay";
export type RequestOptions = {
/** Always request the event from the relays */
alwaysRequest?: boolean;
/** ignore the cache on initial load */
ignoreCache?: boolean;
};
const RELAY_REQUEST_BATCH_TIME = 1000;
/** This class is ued to batch requests to a single relay */
class ChannelMetadataRelayLoader {
private subscription: PersistentSubscription;
private requestNext = new Set<string>();
private requested = new Map<string, Date>();
log: Debugger;
isCache = false;
constructor(relay: AbstractRelay, log?: Debugger) {
this.log = log || logger.extend("ChannelMetadataRelayLoader");
this.subscription = new PersistentSubscription(relay, {
onevent: (event) => this.handleEvent(event),
oneose: () => this.handleEOSE(),
});
}
private handleEvent(event: NostrEvent) {
const channelId = getChannelPointer(event)?.id;
if (!channelId) return;
// remove the pubkey from the waiting list
this.requested.delete(channelId);
if (this.isCache) markFromCache(event);
eventStore.add(event);
}
private handleEOSE() {
// relays says it has nothing left
this.requested.clear();
}
requestMetadata(channelId: string) {
this.requestNext.add(channelId);
this.updateThrottle();
}
updateThrottle = _throttle(this.update, RELAY_REQUEST_BATCH_TIME);
update() {
let needsUpdate = false;
for (const channelId of this.requestNext) {
if (!this.requested.has(channelId)) {
this.requested.set(channelId, new Date());
needsUpdate = true;
}
}
this.requestNext.clear();
// prune requests
const timeout = dayjs().subtract(1, "minute");
for (const [channelId, date] of this.requested) {
if (dayjs(date).isBefore(timeout)) {
this.requested.delete(channelId);
needsUpdate = true;
}
}
// update the subscription
if (needsUpdate) {
if (this.requested.size > 0) {
const query: Filter = {
kinds: [kinds.ChannelMetadata],
"#e": Array.from(this.requested.keys()),
};
if (query["#e"] && query["#e"].length > 0) this.log(`Updating query`, query["#e"].length);
this.subscription.filters = [query];
this.subscription.update();
} else {
this.subscription.close();
}
}
}
}
/** This is a clone of ReplaceableEventLoaderService to support channel metadata */
class ChannelMetadataService {
private loaders = new SuperMap<AbstractRelay, ChannelMetadataRelayLoader>(
(relay) => new ChannelMetadataRelayLoader(relay, this.log.extend(relay.url)),
);
log = logger.extend("ChannelMetadata");
constructor() {
cacheRelay$.subscribe((cacheRelay) => {
if (!cacheRelay) return;
const loader = this.loaders.get(cacheRelay as AbstractRelay);
loader.isCache = true;
});
}
handleEvent(event: NostrEvent) {
eventStore.add(event);
const channelId = getChannelPointer(event)?.id;
if (!channelId) return;
}
private requestChannelMetadataFromRelays(relays: Iterable<string>, channelId: string) {
const relayUrls = Array.from(relays);
for (const url of relayUrls) {
const relay = relayPoolService.getRelay(url);
if (relay) this.loaders.get(relay).requestMetadata(channelId);
}
}
private loaded = new Map<string, boolean>();
requestMetadata(relays: Iterable<string>, channelId: string, opts: RequestOptions = {}) {
const loaded = this.loaded.get(channelId);
const cacheRelay = getCacheRelay();
if (!loaded && cacheRelay) {
this.loaders.get(cacheRelay as AbstractRelay).requestMetadata(channelId);
}
if (opts?.alwaysRequest || (!loaded && opts.ignoreCache)) {
this.requestChannelMetadataFromRelays(relays, channelId);
}
}
}
const channelMetadataService = new ChannelMetadataService();
if (import.meta.env.DEV) {
//@ts-expect-error debug
window.channelMetadataService = channelMetadataService;
}
export default channelMetadataService;

View File

@ -1,6 +1,6 @@
import rxNostr from "./rx-nostr";
import accounts from "./accounts";
import channelMetadataService from "./channel-metadata";
import channelMetadataService from "./channel-metadata-loader";
import { eventStore, queryStore } from "./event-store";
import localSettings from "./local-settings";
import readStatusService from "./read-status";

View File

@ -1,91 +0,0 @@
import { NostrEvent } from "nostr-tools";
import { AbstractRelay } from "nostr-tools/abstract-relay";
import { EventStore } from "applesauce-core";
import { BehaviorSubject } from "rxjs";
import { WIKI_PAGE_KIND } from "../helpers/nostr/wiki";
import { logger } from "../helpers/debug";
import SuperMap from "../classes/super-map";
import BatchIdentifierLoader from "../classes/batch-identifier-loader";
import relayPoolService from "./relay-pool";
import { eventStore } from "./event-store";
import { getCacheRelay } from "./cache-relay";
class DictionaryService {
log = logger.extend("DictionaryService");
store: EventStore;
topics = new SuperMap<string, BehaviorSubject<Map<string, NostrEvent>>>(
() => new BehaviorSubject<Map<string, NostrEvent>>(new Map()),
);
loaders = new SuperMap<AbstractRelay, BatchIdentifierLoader>((relay) => {
const loader = new BatchIdentifierLoader(this.store, relay, [WIKI_PAGE_KIND], this.log.extend(relay.url));
loader.onIdentifierUpdate.subscribe((identifier) => {
this.updateSubject(identifier);
});
return loader;
});
constructor(store: EventStore) {
this.store = store;
}
// merged results from all loaders for a single event
private updateSubject(identifier: string) {
const events = new Map<string, NostrEvent>();
const subject = this.topics.get(identifier);
for (const [relay, loader] of this.loaders) {
if (loader.identifiers.has(identifier)) {
const other = loader.identifiers.get(identifier);
for (const [uid, e] of other) {
if (e.content.trim().length === 0) continue;
const existing = events.get(uid);
if (!existing || e.created_at > existing.created_at) events.set(uid, e);
}
}
}
subject.next(events);
}
getTopic(topic: string) {
return this.topics.get(topic);
}
requestTopic(topic: string, urls: Iterable<string | URL | AbstractRelay>, alwaysRequest = true) {
const subject = this.topics.get(topic);
if (subject.value && !alwaysRequest) return subject;
const cacheRelay = getCacheRelay();
if (cacheRelay) {
this.loaders.get(cacheRelay as AbstractRelay).requestEvents(topic);
}
const relays = relayPoolService.getRelays(urls);
for (const relay of relays) {
this.loaders.get(relay).requestEvents(topic);
}
return subject;
}
handleEvent(event: NostrEvent) {
event = this.store.add(event);
const cacheRelay = getCacheRelay();
// pretend it came from the local relay
// TODO: remove this once DictionaryService uses subscriptions from event store
if (cacheRelay) this.loaders.get(cacheRelay as AbstractRelay).handleEvent(event);
}
}
const dictionaryService = new DictionaryService(eventStore);
if (import.meta.env.DEV) {
// @ts-expect-error debug
window.dictionaryService = dictionaryService;
}
export default dictionaryService;

View File

@ -0,0 +1,38 @@
import { kinds } from "nostr-tools";
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
import { getCoordinateFromAddressPointer, isAddressPointer, isEventPointer } from "applesauce-core/helpers";
import { cacheRequest } from "./cache-relay";
import { TagValueLoader } from "applesauce-loaders";
import rxNostr from "./rx-nostr";
import { eventStore } from "./event-store";
export function requestReactions(id: string | EventPointer | AddressPointer, relays: string[], force?: boolean) {
if (typeof id === "string") {
if (id.includes(":")) replaceableEventsZapsLoader.next({ value: id, relays, force });
else singleEventsZapsLoader.next({ value: id, relays, force });
} else if (isEventPointer(id)) {
singleEventsZapsLoader.next({ value: id.id, relays, force });
} else if (isAddressPointer(id)) {
replaceableEventsZapsLoader.next({ value: getCoordinateFromAddressPointer(id), relays, force });
}
}
const replaceableEventsZapsLoader = new TagValueLoader(rxNostr, "a", {
name: "reactions",
kinds: [kinds.Reaction],
cacheRequest,
});
const singleEventsZapsLoader = new TagValueLoader(rxNostr, "e", {
name: "reactions",
kinds: [kinds.Reaction],
cacheRequest,
});
// start the loader and send all events to the event store
replaceableEventsZapsLoader.subscribe((packet) => {
eventStore.add(packet.event, packet.from);
});
singleEventsZapsLoader.subscribe((packet) => {
eventStore.add(packet.event, packet.from);
});

View File

@ -1,41 +0,0 @@
import { kinds } from "nostr-tools";
import _throttle from "lodash.throttle";
import { AbstractRelay } from "nostr-tools/abstract-relay";
import SuperMap from "../classes/super-map";
import relayPoolService from "./relay-pool";
import BatchRelationLoader from "../classes/batch-relation-loader";
import { logger } from "../helpers/debug";
import { getCacheRelay } from "./cache-relay";
class EventReactionsService {
log = logger.extend("EventReactionsService");
private loaded = new Map<string, boolean>();
loaders = new SuperMap<AbstractRelay, BatchRelationLoader>((relay) => {
return new BatchRelationLoader(relay, [kinds.Reaction], this.log.extend(relay.url));
});
requestReactions(uid: string, urls: Iterable<string | URL | AbstractRelay>, alwaysRequest = false) {
if (this.loaded.get(uid) && !alwaysRequest) return;
const cacheRelay = getCacheRelay();
if (cacheRelay) {
this.loaders.get(cacheRelay as AbstractRelay).requestEvents(uid);
}
const relays = relayPoolService.getRelays(urls);
for (const relay of relays) {
this.loaders.get(relay).requestEvents(uid);
}
}
}
const eventReactionsService = new EventReactionsService();
if (import.meta.env.DEV) {
// @ts-expect-error debug
window.eventReactionsService = eventReactionsService;
}
export default eventReactionsService;

View File

@ -0,0 +1,34 @@
import { kinds } from "nostr-tools";
import { getCoordinateFromAddressPointer, isAddressPointer, isEventPointer } from "applesauce-core/helpers";
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
import { TagValueLoader } from "applesauce-loaders";
import { cacheRequest } from "./cache-relay";
import rxNostr from "./rx-nostr";
import { eventStore } from "./event-store";
export function requestZaps(id: string | EventPointer | AddressPointer, relays: string[], force?: boolean) {
if (typeof id === "string") {
if (id.includes(":")) replaceableEventsZapsLoader.next({ value: id, relays, force });
else singleEventsZapsLoader.next({ value: id, relays, force });
} else if (isEventPointer(id)) {
singleEventsZapsLoader.next({ value: id.id, relays, force });
} else if (isAddressPointer(id)) {
replaceableEventsZapsLoader.next({ value: getCoordinateFromAddressPointer(id), relays, force });
}
}
const replaceableEventsZapsLoader = new TagValueLoader(rxNostr, "a", {
name: "zaps",
kinds: [kinds.Zap],
cacheRequest,
});
const singleEventsZapsLoader = new TagValueLoader(rxNostr, "e", { name: "zaps", kinds: [kinds.Zap], cacheRequest });
// start the loader and send all events to the event store
replaceableEventsZapsLoader.subscribe((packet) => {
eventStore.add(packet.event, packet.from);
});
singleEventsZapsLoader.subscribe((packet) => {
eventStore.add(packet.event, packet.from);
});

View File

@ -1,42 +0,0 @@
import { kinds } from "nostr-tools";
import _throttle from "lodash.throttle";
import { AbstractRelay } from "nostr-tools/abstract-relay";
import SuperMap from "../classes/super-map";
import relayPoolService from "./relay-pool";
import BatchRelationLoader from "../classes/batch-relation-loader";
import { logger } from "../helpers/debug";
import { getCacheRelay } from "./cache-relay";
class EventZapsService {
log = logger.extend("EventZapsService");
private loaded = new Map<string, boolean>();
loaders = new SuperMap<AbstractRelay, BatchRelationLoader>((relay) => {
const loader = new BatchRelationLoader(relay, [kinds.Zap], this.log.extend(relay.url));
return loader;
});
requestZaps(uid: string, urls: Iterable<string | URL | AbstractRelay>, alwaysRequest = true) {
if (this.loaded.get(uid) && !alwaysRequest) return;
const cacheRelay = getCacheRelay();
if (cacheRelay) {
this.loaders.get(cacheRelay as AbstractRelay).requestEvents(uid);
}
const relays = relayPoolService.getRelays(urls);
for (const relay of relays) {
this.loaders.get(relay).requestEvents(uid);
}
}
}
const eventZapsService = new EventZapsService();
if (import.meta.env.DEV) {
// @ts-expect-error debug
window.eventZapsService = eventZapsService;
}
export default eventZapsService;

View File

@ -0,0 +1,15 @@
import { TagValueLoader } from "applesauce-loaders";
import { WIKI_PAGE_KIND } from "../helpers/nostr/wiki";
import { eventStore } from "./event-store";
import { cacheRequest } from "./cache-relay";
import rxNostr from "./rx-nostr";
const wikiPageLoader = new TagValueLoader(rxNostr, "d", { name: "wiki-pages", kinds: [WIKI_PAGE_KIND], cacheRequest });
// start the loader and send all events to the event store
wikiPageLoader.subscribe((packet) => {
eventStore.add(packet.event, packet.from);
});
export default wikiPageLoader;

View File

@ -52,11 +52,11 @@ export default function EmojiPackCard({ pack, ...props }: Omit<CardProps, "child
)}
</CardBody>
<CardFooter p="2" display="flex" pt="0">
<ButtonGroup size="sm" variant="ghost">
<ButtonGroup size="sm" variant="ghost" zIndex={1}>
<EventZapButton event={pack} />
<EmojiPackFavoriteButton pack={pack} />
</ButtonGroup>
<ButtonGroup size="sm" ml="auto" variant="ghost">
<ButtonGroup size="sm" ml="auto" variant="ghost" zIndex={1}>
<EmojiPackMenu pack={pack} aria-label="emoji pack menu" />
</ButtonGroup>
</CardFooter>

View File

@ -1,10 +1,10 @@
import { Button, ButtonProps, useDisclosure } from "@chakra-ui/react";
import { NostrEvent } from "../../../types/nostr-event";
import ZapModal from "../../../components/event-zap-modal";
import eventZapsService from "../../../services/event-zaps";
import { getEventUID } from "../../../helpers/nostr/event";
import { getGoalRelays } from "../../../helpers/nostr/goal";
import { useReadRelays } from "../../../hooks/use-client-relays";
import { requestZaps } from "../../../services/event-zaps-loader";
export default function GoalZapButton({
goal,
@ -16,7 +16,7 @@ export default function GoalZapButton({
const onZapped = async () => {
modal.onClose();
setTimeout(() => {
eventZapsService.requestZaps(getEventUID(goal), readRelays, true);
requestZaps(getEventUID(goal), readRelays, true);
}, 1000);
};

View File

@ -9,7 +9,6 @@ import useUserMailboxes from "../../../hooks/use-user-mailboxes";
import { useActiveAccount } from "applesauce-react/hooks";
import { InboxIcon, OutboxIcon } from "../../../components/icons";
import MediaServerFavicon from "../../../components/media-server/media-server-favicon";
import { RelayMode } from "../../../classes/relay";
import { NostrEvent } from "../../../types/nostr-event";
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
import { usePublishEvent } from "../../../providers/global/publish-provider";
@ -19,6 +18,7 @@ import DebugEventButton from "../../../components/debug-modal/debug-event-button
import useReplaceableEvent from "../../../hooks/use-replaceable-event";
import { COMMON_CONTACT_RELAYS } from "../../../const";
import SimpleView from "../../../components/layout/presets/simple-view";
import { RelayMode } from "../../../services/app-relays";
function RelayLine({ relay, mode, list }: { relay: string; mode: RelayMode; list?: NostrEvent }) {
const publish = usePublishEvent();

View File

@ -4,7 +4,6 @@ import { WarningIcon } from "@chakra-ui/icons";
import { RECOMMENDED_READ_RELAYS, RECOMMENDED_WRITE_RELAYS } from "../../../const";
import AddRelayForm from "./add-relay-form";
import { RelayMode } from "../../../classes/relay";
import { useReadRelays, useWriteRelays } from "../../../hooks/use-client-relays";
import { useActiveAccount } from "applesauce-react/hooks";
import RelayControl from "./relay-control";
@ -15,7 +14,7 @@ import { mergeRelaySets, safeRelayUrls } from "../../../helpers/relay";
import HoverLinkOverlay from "../../../components/hover-link-overlay";
import SimpleView from "../../../components/layout/presets/simple-view";
import localSettings from "../../../services/local-settings";
import { addAppRelay } from "../../../services/app-relays";
import { addAppRelay, RelayMode } from "../../../services/app-relays";
import useUserMailboxes from "../../../hooks/use-user-mailboxes";
const JAPANESE_RELAYS = safeRelayUrls([

View File

@ -6,8 +6,7 @@ import RelayFavicon from "../../../components/relay-favicon";
import UploadCloud01 from "../../../components/icons/upload-cloud-01";
import { useWriteRelays } from "../../../hooks/use-client-relays";
import localSettings from "../../../services/local-settings";
import { removeAppRelay } from "../../../services/app-relays";
import { RelayMode } from "../../../classes/relay";
import { RelayMode, removeAppRelay } from "../../../services/app-relays";
export default function RelayControl({ url }: { url: string }) {
const writeRelays = useWriteRelays();

View File

@ -31,7 +31,6 @@ import { useReadRelays } from "../../hooks/use-client-relays";
import UserName from "../../components/user/user-name";
import { getEventCoordinate } from "../../helpers/nostr/event";
import FormatButton from "./components/format-toolbar";
import dictionaryService from "../../services/dictionary";
import { getSharableEventAddress } from "../../services/relay-hints";
export default function CreateWikiPageView() {
@ -109,7 +108,6 @@ export default function CreateWikiPageView() {
}
const pub = await publish("Publish Page", draft, WIKI_RELAYS, false);
dictionaryService.handleEvent(pub.event);
clearFormCache();
navigate(`/wiki/page/${getSharableEventAddress(pub.event)}`, { replace: true });
} catch (error) {

View File

@ -25,7 +25,6 @@ import MarkdownEditor from "./components/markdown-editor";
import { ErrorBoundary } from "../../components/error-boundary";
import { cloneEvent, replaceOrAddSimpleTag } from "../../helpers/nostr/event";
import FormatButton from "./components/format-toolbar";
import dictionaryService from "../../services/dictionary";
import { getSharableEventAddress } from "../../services/relay-hints";
function EditWikiPagePage({ page }: { page: NostrEvent }) {
@ -62,7 +61,6 @@ function EditWikiPagePage({ page }: { page: NostrEvent }) {
replaceOrAddSimpleTag(draft, "summary", values.summary);
const pub = await publish("Publish Page", draft, WIKI_RELAYS, false);
dictionaryService.handleEvent(pub.event);
clearFormCache();
navigate(`/wiki/page/${getSharableEventAddress(pub.event)}`, { replace: true });
} catch (error) {

View File

@ -1,21 +1,20 @@
import { AvatarGroup, Link, Button, Flex, Heading, LinkBox, SimpleGrid, useInterval } from "@chakra-ui/react";
import { AvatarGroup, Link, Button, Flex, Heading, LinkBox, SimpleGrid } from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { useStoreQuery } from "applesauce-react/hooks";
import { NostrEvent } from "nostr-tools";
import { WIKI_RELAYS } from "../../const";
import VerticalPageLayout from "../../components/vertical-page-layout";
import WikiSearchForm from "./components/wiki-search-form";
import { WIKI_PAGE_KIND, validatePage } from "../../helpers/nostr/wiki";
import useTimelineLoader from "../../hooks/use-timeline-loader";
import { useReadRelays } from "../../hooks/use-client-relays";
import TimelineActionAndStatus from "../../components/timeline/timeline-action-and-status";
import { WIKI_RELAYS } from "../../const";
import { ExternalLinkIcon } from "../../components/icons";
import WikiLink from "../../components/markdown/wiki-link";
import { useEffect } from "react";
import dictionaryService from "../../services/dictionary";
import UserAvatar from "../../components/user/user-avatar";
import HoverLinkOverlay from "../../components/hover-link-overlay";
import useForceUpdate from "../../hooks/use-force-update";
import { WikiTopicsQuery } from "../../queries/wiki-topics";
function eventFilter(event: NostrEvent) {
if (!validatePage(event)) return false;
@ -28,16 +27,7 @@ export default function WikiHomeView() {
eventFilter,
});
useEffect(() => {
if (pages) {
for (const page of pages) {
dictionaryService.handleEvent(page);
}
}
}, [pages]);
const update = useForceUpdate();
useInterval(update, 1000);
const topics = useStoreQuery(WikiTopicsQuery, []);
return (
<VerticalPageLayout>
@ -60,23 +50,23 @@ export default function WikiHomeView() {
Recent Updates:
</Heading>
<SimpleGrid spacing="2" columns={{ base: 1, lg: 2, xl: 3 }}>
{Array.from(dictionaryService.topics)
.filter(([_, sub]) => !!sub.value && sub.value.size > 0)
.sort((a, b) => b[1].value!.size - a[1].value!.size)
.map(([topic, sub]) => (
<LinkBox key={topic} p="2">
<Heading size="md">
<HoverLinkOverlay as={RouterLink} to={`/wiki/topic/${topic}`}>
{topic}
</HoverLinkOverlay>
</Heading>
<AvatarGroup size="sm">
{Array.from(sub.value!.values()).map((page) => (
<UserAvatar pubkey={page.pubkey} />
))}
</AvatarGroup>
</LinkBox>
))}
{topics &&
Object.entries(topics)
.sort((a, b) => b[1].length - a[1].length)
.map(([topic, events]) => (
<LinkBox key={topic} p="2">
<Heading size="md">
<HoverLinkOverlay as={RouterLink} to={`/wiki/topic/${topic}`}>
{topic}
</HoverLinkOverlay>
</Heading>
<AvatarGroup size="sm">
{events.map((page) => (
<UserAvatar pubkey={page.pubkey} />
))}
</AvatarGroup>
</LinkBox>
))}
</SimpleGrid>
<TimelineActionAndStatus loader={loader} />
</VerticalPageLayout>

View File

@ -1,4 +1,3 @@
import { useMemo } from "react";
import { NostrEvent, nip19 } from "nostr-tools";
import {
Alert,
@ -14,7 +13,6 @@ import {
Text,
} from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { useObservable } from "applesauce-react/hooks";
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
import useReplaceableEvent from "../../hooks/use-replaceable-event";
@ -35,10 +33,10 @@ import EventQuoteButton from "../../components/note/event-quote-button";
import WikiPageMenu from "./components/wiki-page-menu";
import EventVoteButtons from "../../components/reactions/event-vote-buttions";
import { useActiveAccount } from "applesauce-react/hooks";
import dictionaryService from "../../services/dictionary";
import { useReadRelays } from "../../hooks/use-client-relays";
import { useWebOfTrust } from "../../providers/global/web-of-trust-provider";
import { getSharableEventAddress } from "../../services/relay-hints";
import useWikiPages from "../../hooks/use-wiki-pages";
function ForkAlert({ page, address }: { page: NostrEvent; address: nip19.AddressPointer }) {
const topic = getPageTopic(page);
@ -141,8 +139,7 @@ function WikiPageFooter({ page }: { page: NostrEvent }) {
const topic = getPageTopic(page);
const readRelays = useReadRelays();
const subject = useMemo(() => dictionaryService.requestTopic(topic, readRelays), [topic, readRelays]);
const pages = useObservable(subject);
const pages = useWikiPages(topic, readRelays, true);
let forks = pages ? Array.from(pages.values()).filter((p) => getPageForks(p).address?.pubkey === page.pubkey) : [];
if (webOfTrust) forks = webOfTrust.sortByDistanceAndConnections(forks, (p) => p.pubkey);

View File

@ -13,9 +13,10 @@ import { DEFAULT_SEARCH_RELAYS, WIKI_RELAYS } from "../../const";
import { WIKI_PAGE_KIND } from "../../helpers/nostr/wiki";
import { cacheRelay$ } from "../../services/cache-relay";
import WikiPageResult from "./components/wiki-page-result";
import dictionaryService from "../../services/dictionary";
import { useWebOfTrust } from "../../providers/global/web-of-trust-provider";
import { useObservable } from "applesauce-react/hooks";
import { eventStore } from "../../services/event-store";
import { ErrorBoundary } from "../../components/error-boundary";
export default function WikiSearchView() {
const cacheRelay = useObservable(cacheRelay$);
@ -37,7 +38,8 @@ export default function WikiSearchView() {
const seen = new Set<string>();
const handleEvent = (event: NostrEvent) => {
dictionaryService.handleEvent(event);
eventStore.add(event);
if (seen.has(getEventUID(event))) return;
setResults((arr) => arr.concat(event));
seen.add(getEventUID(event));
@ -82,7 +84,9 @@ export default function WikiSearchView() {
</Flex>
</Flex>
{sorted.map((page) => (
<WikiPageResult key={page.id} page={page} />
<ErrorBoundary key={page.id}>
<WikiPageResult page={page} />
</ErrorBoundary>
))}
</VerticalPageLayout>
);

View File

@ -1,11 +1,8 @@
import { Button, Flex, Heading, Link } from "@chakra-ui/react";
import { Navigate, useParams, Link as RouterLink } from "react-router-dom";
import { useObservable } from "applesauce-react/hooks";
import { NostrEvent } from "nostr-tools";
import VerticalPageLayout from "../../components/vertical-page-layout";
import { useMemo } from "react";
import dictionaryService from "../../services/dictionary";
import { useReadRelays } from "../../hooks/use-client-relays";
import WikiPageHeader from "./components/wiki-page-header";
import UserAvatar from "../../components/user/user-avatar";
@ -14,6 +11,7 @@ import { WikiPagePage } from "./page";
import { useWebOfTrust } from "../../providers/global/web-of-trust-provider";
import useRouteSearchValue from "../../hooks/use-route-search-value";
import { getPageDefer } from "../../helpers/nostr/wiki";
import useWikiPages from "../../hooks/use-wiki-pages";
export default function WikiTopicView() {
const { topic } = useParams();
@ -21,9 +19,7 @@ export default function WikiTopicView() {
const webOfTrust = useWebOfTrust();
const readRelays = useReadRelays();
const subject = useMemo(() => dictionaryService.requestTopic(topic, readRelays, true), [topic, readRelays]);
const pages = useObservable(subject);
const pages = useWikiPages(topic, readRelays, true);
let sorted = pages ? Array.from(pages.values()) : [];
if (webOfTrust) sorted = webOfTrust.sortByDistanceAndConnections(sorted, (p) => p.pubkey);