Refactor storage
This commit is contained in:
+11
-11
@@ -59,17 +59,17 @@
|
||||
"@types/throttle-debounce": "^5.0.2",
|
||||
"@vite-pwa/assets-generator": "^0.2.6",
|
||||
"@vite-pwa/sveltekit": "^0.6.6",
|
||||
"@welshman/app": "^0.4.7",
|
||||
"@welshman/content": "^0.4.7",
|
||||
"@welshman/editor": "^0.4.7",
|
||||
"@welshman/feeds": "^0.4.7",
|
||||
"@welshman/lib": "^0.4.7",
|
||||
"@welshman/net": "^0.4.7",
|
||||
"@welshman/relay": "^0.4.7",
|
||||
"@welshman/router": "^0.4.7",
|
||||
"@welshman/signer": "^0.4.7",
|
||||
"@welshman/store": "^0.4.7",
|
||||
"@welshman/util": "^0.4.7",
|
||||
"@welshman/app": "^0.5.0",
|
||||
"@welshman/content": "^0.5.0",
|
||||
"@welshman/editor": "^0.5.0",
|
||||
"@welshman/feeds": "^0.5.0",
|
||||
"@welshman/lib": "^0.5.0",
|
||||
"@welshman/net": "^0.5.0",
|
||||
"@welshman/relay": "^0.5.0",
|
||||
"@welshman/router": "^0.5.0",
|
||||
"@welshman/signer": "^0.5.0",
|
||||
"@welshman/store": "^0.5.0",
|
||||
"@welshman/util": "^0.5.0",
|
||||
"compressorjs": "^1.2.1",
|
||||
"daisyui": "^4.12.10",
|
||||
"date-picker-svelte": "^2.13.0",
|
||||
|
||||
Generated
+156
-157
@@ -72,38 +72,38 @@ importers:
|
||||
specifier: ^0.6.6
|
||||
version: 0.6.8(@sveltejs/kit@2.20.5(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.25.10)(vite@5.4.17(@types/node@22.14.0)(terser@5.39.0)))(svelte@5.25.10)(vite@5.4.17(@types/node@22.14.0)(terser@5.39.0)))(@vite-pwa/assets-generator@0.2.6)(vite-plugin-pwa@0.21.2(@vite-pwa/assets-generator@0.2.6)(vite@5.4.17(@types/node@22.14.0)(terser@5.39.0))(workbox-build@7.3.0)(workbox-window@7.3.0))
|
||||
'@welshman/app':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/content':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(typescript@5.8.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(typescript@5.8.3)
|
||||
'@welshman/editor':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(@tiptap/extension-image@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(linkifyjs@4.3.1)(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(typescript@5.8.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(@tiptap/extension-image@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(linkifyjs@4.3.2)(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(typescript@5.8.3)
|
||||
'@welshman/feeds':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/lib':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0
|
||||
'@welshman/net':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(typescript@5.8.3)(ws@8.18.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/relay':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(typescript@5.8.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(typescript@5.8.3)
|
||||
'@welshman/router':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(typescript@5.8.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(typescript@5.8.3)
|
||||
'@welshman/signer':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/store':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(typescript@5.8.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(typescript@5.8.3)
|
||||
'@welshman/util':
|
||||
specifier: ^0.4.7
|
||||
version: 0.4.7(typescript@5.8.3)
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(typescript@5.8.3)
|
||||
compressorjs:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
@@ -1100,8 +1100,8 @@ packages:
|
||||
'@noble/curves@1.2.0':
|
||||
resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
|
||||
|
||||
'@noble/curves@1.9.2':
|
||||
resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==}
|
||||
'@noble/curves@1.9.7':
|
||||
resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@noble/hashes@1.3.1':
|
||||
@@ -1430,77 +1430,77 @@ packages:
|
||||
peerDependencies:
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-code-block@2.26.1':
|
||||
resolution: {integrity: sha512-/TDDOwONl0qEUc4+B6V9NnWtSjz95eg7/8uCb8Y8iRbGvI9vT4/znRKofFxstvKmW4URu/H74/g0ywV57h0B+A==}
|
||||
'@tiptap/extension-code-block@2.26.2':
|
||||
resolution: {integrity: sha512-MJZ4QtziIWJ1zuSW2ogAHv+UHGk3DvGbVi+Dfmo0ybonXX7vRVHE+3qT7OcdTRBF+pC2oCnsjzqwFcGBP3BbZw==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-code@2.26.1':
|
||||
resolution: {integrity: sha512-GU9deB1A/Tr4FMPu71CvlcjGKwRhGYz60wQ8m4aM+ELZcVIcZRa1ebR8bExRIEWnvRztQuyRiCQzw2N0xQJ1QQ==}
|
||||
'@tiptap/extension-code@2.26.2':
|
||||
resolution: {integrity: sha512-xnKJvzlAp75dheyaK5tLKAksHf9PtSr8a7OuPjf2IXS5K+QMtnwxx7KAHHijmecfWjLR0wyu9AvT/FWFfKi5LQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
|
||||
'@tiptap/extension-document@2.26.1':
|
||||
resolution: {integrity: sha512-2P2IZp1NRAE+21mRuFBiP3X2WKfZ6kUC23NJKpn8bcOamY3obYqCt0ltGPhE4eR8n8QAl2fI/3jIgjR07dC8ow==}
|
||||
'@tiptap/extension-document@2.26.2':
|
||||
resolution: {integrity: sha512-s0/P3A8zxWL/h3e20xWMTT/rcwD0+57I6mT9JgNBPtvhPePy8d698G6/qFK+x+GdIyjJylfsq2BrSE9H+QhIBg==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
|
||||
'@tiptap/extension-dropcursor@2.26.1':
|
||||
resolution: {integrity: sha512-JkDQU2ZYFOuT5mNYb8OiWGwD1HcjbtmX8tLNugQbToECmz9WvVPqJmn7V/q8VGpP81iEECz/IsyRmuf2kSD4uA==}
|
||||
'@tiptap/extension-dropcursor@2.26.2':
|
||||
resolution: {integrity: sha512-o5j4Gkurb/WBu1wP2tihYnZ8dENzmlxFWWMx++g6abEpn9xdud7VxHT5Ny7mBSBptI8uMwKT53weYC0on38n3g==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-gapcursor@2.26.1':
|
||||
resolution: {integrity: sha512-KOiMZc3PwJS3hR0nSq5d0TJi2jkNZkLZElcT6pCEnhRHzPH6dRMu9GM5Jj798ZRUy0T9UFcKJalFZaDxnmRnpg==}
|
||||
'@tiptap/extension-gapcursor@2.26.2':
|
||||
resolution: {integrity: sha512-a68mi8V0mh058UrBIk23f50K5JGVeRZnF6ViptIleAD/Ny1K6VLjGCz6k190de+Tb9tnQLPEwwwDcy+ZnvCmYQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-hard-break@2.26.1':
|
||||
resolution: {integrity: sha512-d6uStdNKi8kjPlHAyO59M6KGWATNwhLCD7dng0NXfwGndc22fthzIk/6j9F6ltQx30huy5qQram6j3JXwNACoA==}
|
||||
'@tiptap/extension-hard-break@2.26.2':
|
||||
resolution: {integrity: sha512-OLpeTey7p3ChyEsABLPvNv7rD/8E4k1JTt+H+MUjyL0dnrZuIWluckUJCJKnV8PhR9Mifngk1MTFUilpooiv1g==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
|
||||
'@tiptap/extension-history@2.26.1':
|
||||
resolution: {integrity: sha512-m6YR1gkkauIDo3PRl0gP+7Oc4n5OqDzcjVh6LvWREmZP8nmi94hfseYbqOXUb6RPHIc0JKF02eiRifT4MSd2nw==}
|
||||
'@tiptap/extension-history@2.26.2':
|
||||
resolution: {integrity: sha512-X/cu79AV5D2Z1QtuvKo/4/Rgl/Uti/n5V3QgCxFLQRCKTxHOCis+RlBCjBfOPztJX4T9QUE6lq20KqB47rsNwQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-image@2.26.1':
|
||||
resolution: {integrity: sha512-96+MaYBJebQlR/ik5W72GLUfXdEoxFs+6jsoERxbM5qEdhb7TEnodBFtWZOwgDO27kFd6rSNZuW9r5KJNtljEg==}
|
||||
'@tiptap/extension-image@2.26.2':
|
||||
resolution: {integrity: sha512-3gK+ETLiWGAUdyPDXDheNJ38OgQabSzZJ+1nQo9KWjI7P3LQ7/ctxLtT+hAFpxX0qMK4bnu5vZaItSXxE3ZtpQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
|
||||
'@tiptap/extension-link@2.26.1':
|
||||
resolution: {integrity: sha512-7yfum5Jymkue/uOSTQPt2SmkZIdZx7t3QhZLqBU7R9ettkdSCBgEGok6N+scJM1R1Zes+maSckLm0JZw5BKYNA==}
|
||||
'@tiptap/extension-link@2.26.2':
|
||||
resolution: {integrity: sha512-rzYxx5wI1551ubPfW2pJ3V957cX/WAmbUI3q8Un+LlOsSmbddl+5BjlF5t/vl/pwaOv7FJAz9e29n877zkGOVQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-paragraph@2.26.1':
|
||||
resolution: {integrity: sha512-UezvM9VDRAVJlX1tykgHWSD1g3MKfVMWWZ+Tg+PE4+kizOwoYkRWznVPgCAxjmyHajxpCKRXgqTZkOxjJ9Kjzg==}
|
||||
'@tiptap/extension-paragraph@2.26.2':
|
||||
resolution: {integrity: sha512-dccyffm95nNT9arjxGOyv4/cOPF4XS5Osylccp9KYLrmiSTXEuzVIYtMXhXbc0UUdABGvbFQWi88tRxgeDTkgA==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
|
||||
'@tiptap/extension-placeholder@2.26.1':
|
||||
resolution: {integrity: sha512-MBlqbkd+63btY7Qu+SqrXvWjPwooGZDsLTtl7jp52BczBl61cq9yygglt9XpM11TFMBdySgdLHBrLtQ0B7fBlw==}
|
||||
'@tiptap/extension-placeholder@2.26.2':
|
||||
resolution: {integrity: sha512-XBTDcpEo7Zo/1+RhGnRxA2TF0elQW7EayUcV+lJ3f7HQ5lrb5NTnakYc1ydeZ8Ih6vUqbK2CQUsESe3UWHHgHg==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
|
||||
'@tiptap/extension-text@2.26.1':
|
||||
resolution: {integrity: sha512-p2n8WVMd/2vckdJlol24acaTDIZAhI7qle5cM75bn01sOEZoFlSw6SwINOULrUCzNJsYb43qrLEibZb4j2LeQw==}
|
||||
'@tiptap/extension-text@2.26.2':
|
||||
resolution: {integrity: sha512-Rb8Le/Li+EixQNc/pGkEJpLjozTjWYP9glaYfnjPtRVw4tHcd7khVm5mer0TQjonbBUjVC1zSuXv9gifXOv6DQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
|
||||
'@tiptap/pm@2.12.0':
|
||||
resolution: {integrity: sha512-TNzVwpeNzFfHAcYTOKqX9iU4fRxliyoZrCnERR+RRzeg7gWrXrCLubQt1WEx0sojMAfznshSL3M5HGsYjEbYwA==}
|
||||
|
||||
'@tiptap/suggestion@2.26.1':
|
||||
resolution: {integrity: sha512-iNWJdQN7h01keNoVwyCsdI7ZX11YkrexZjCnutWK17Dd72s3NYVTmQXu7saftwddT4nDdlczNxAFosrt0zMhcg==}
|
||||
'@tiptap/suggestion@2.26.2':
|
||||
resolution: {integrity: sha512-BtigI3xOJQbdNh2OeKN5wQDI/EPGN4GXdpoMHhENZeXKrX6PvWNaqjyLVsV3QiLgv6P352nZWcgo51wPXY2JgQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.7.0
|
||||
'@tiptap/pm': ^2.7.0
|
||||
@@ -1659,41 +1659,41 @@ packages:
|
||||
'@vite-pwa/assets-generator':
|
||||
optional: true
|
||||
|
||||
'@welshman/app@0.4.7':
|
||||
resolution: {integrity: sha512-JEgr3NhzDLeOoTSZ4+AESKhW+kwqYClLbLd6ccHV+Wa7hjoPJy2FlY3rDuppw9QSeTNCDEOvqCsjeWYz83lUBA==}
|
||||
'@welshman/app@0.5.0':
|
||||
resolution: {integrity: sha512-Vj5urVSylqmlpmwmZv6Q9u7FzWAW1XfbTytheenfv1gsL3HAfJm9gnW9hInPix9GOC3jdT9XKCZmH9+9Sfn7TA==}
|
||||
|
||||
'@welshman/content@0.4.7':
|
||||
resolution: {integrity: sha512-PF2FqiE3QUybl0CwwaEI2aGCZIis2rbdvBgeafgPiHW7fRYROxUZdtcMy+MyiRfiV40uoBcYwu/N6hHCRU7Pag==}
|
||||
'@welshman/content@0.5.0':
|
||||
resolution: {integrity: sha512-F7B4JoY+OP3ImAfn+wWbBsKw39HaktI5Qi+DE8/KtgnXRTBpJ9XKmvyVEUYvSFysBuckprdHV7ZqVEmc5W24jA==}
|
||||
|
||||
'@welshman/editor@0.4.7':
|
||||
resolution: {integrity: sha512-K6XCLG+vVvVeEYPx+m/+Lfx/JO+NtvvIemCds6gFjY7ac+WaQuEQDP3kFGYQu69XiFXp/UZrIa+t7SezEpnU8A==}
|
||||
'@welshman/editor@0.5.0':
|
||||
resolution: {integrity: sha512-rJWdjbidy+EtoqeDtUsVTeJGHQ9+HznVeLYNli0GfugvJoHlx2NB1pFTSlS2YCvm8QWDsI2ZCZglUeqPMcO2YA==}
|
||||
|
||||
'@welshman/feeds@0.4.7':
|
||||
resolution: {integrity: sha512-aZQuTUD4aSkL0s2BkjwEpo5KTd9BKf/XiOssQrltLdc8NIsz8RIO0XLgCpFb0/dmqHRoJEqU/plIBy7AlleRCQ==}
|
||||
'@welshman/feeds@0.5.0':
|
||||
resolution: {integrity: sha512-bY8mjA+9lJoy6vU2lLpX+2sGp3LKpgyzFRf/oAQ6W/bQTlFLE1VXC4/W3yyVBDlGw8oJM9niaGd0/zCefCeTkg==}
|
||||
|
||||
'@welshman/lib@0.4.7':
|
||||
resolution: {integrity: sha512-VP3WO2ROo5pf2vHwnrdt6lQVTc8Eo52Ie+1/9ZzfTrSxtLrreSSxW3H+1oPDbHl3FXbDnQWdFWbxys6OxzKZWw==}
|
||||
'@welshman/lib@0.5.0':
|
||||
resolution: {integrity: sha512-Sj4zNPpMC3QSi4hu8bjF/qzY+klYf1zlKOhwKKOJJDcSes1/9khT5QB9icJn7ki1a7J7mzYrJaa01hTE9hxkCw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
'@welshman/net@0.4.7':
|
||||
resolution: {integrity: sha512-S0dGVqNAfo5cvBxIuaI2oEX0JUs2FuzkOcYXkMNB1plWzi1mBcskNCBWfFf/zHJYaqUoYjZ/tDARy64lge9m/w==}
|
||||
'@welshman/net@0.5.0':
|
||||
resolution: {integrity: sha512-k/kRaNmP0TC/quoRJPJ+yYk6TSyjB4HX1NaXmFmWoDIOnIUskgbgH83hbklvHoO3TvAgR1r8ENzDtiTnUVryMg==}
|
||||
|
||||
'@welshman/relay@0.4.7':
|
||||
resolution: {integrity: sha512-FkqYswNA3uT1NeJVHdEZ7p9jEPGCFMx4ci2y+h9o25rCDdxg3WUhqDSdc5d85sGTO0qG2pNnvNMfS/Du/nFlOA==}
|
||||
'@welshman/relay@0.5.0':
|
||||
resolution: {integrity: sha512-9sYPz6b8H+zlyAyZZ/zRGwnKN+lWGt/Tn7+pFLCSpdAAHTtRU0T68MaRgnLHJNcLNiMpwjG/He/CZj0PkYL5Bw==}
|
||||
|
||||
'@welshman/router@0.4.7':
|
||||
resolution: {integrity: sha512-HnB1qrKGNxL8HtC6p47yHUnaDHevi+IKtqWEVCIFMRf17GwINBc3wp3+d3pu9KBBXItFZz1awABvZK+pNKQcgg==}
|
||||
'@welshman/router@0.5.0':
|
||||
resolution: {integrity: sha512-ue/8pzVweTfqE1naJ1TzdC+PCWt3Z3gRu1jesXFPXelWb6rhb9eb4Rk91I2TuZLKdJbX5PvaO+d/lbtnnBM6eA==}
|
||||
|
||||
'@welshman/signer@0.4.7':
|
||||
resolution: {integrity: sha512-V5Jdmblb2kPO5bAv1CzVrodZiwKpYYotmS6MFXfWmyrKKp+9B5KoMWzXt6yfd4HWYbEKEjLhbm1gzbckupW8Nw==}
|
||||
'@welshman/signer@0.5.0':
|
||||
resolution: {integrity: sha512-EQhNfV+7nNEXYRc71XNvkgy74tu1IoWrtDZAkASyaCxTzigU8K2R7QfCFQEl3zxWlmu1PZ9Xr1teTeo3OX/IPw==}
|
||||
peerDependencies:
|
||||
nostr-signer-capacitor-plugin: ~0.0.4
|
||||
|
||||
'@welshman/store@0.4.7':
|
||||
resolution: {integrity: sha512-8PniW1AOOYFtLRYMuay62taumW7zgwtBmouwoMh08fBQjLb+c90V4g2cEGVWoyvKXSLzQkQppPlaqYzdSDqgwg==}
|
||||
'@welshman/store@0.5.0':
|
||||
resolution: {integrity: sha512-wdQgUvxWhvi6ybx20Ic9GZMDHmXDs3t9Y6Dp7CUu8xBZsiSIqflMGitjd8ITvH5LBVVMbhqdWAxIat/ihXP/rw==}
|
||||
|
||||
'@welshman/util@0.4.7':
|
||||
resolution: {integrity: sha512-FlmBiZeKlAEAAwyhu7cWtlfAxU3CWX7WQGn0NkCZaAjgGV3n8LIDjT1u9m1PmXirBT0+qFNGLWas3p72IQMLgg==}
|
||||
'@welshman/util@0.5.0':
|
||||
resolution: {integrity: sha512-i/Pg6uy9x8KfOThbvYHpanPX171mkTLaw0JCNIB4ZZAxjYKhpRkczRKpoyw9GQ1yW/ROWzUhYFaPCwU7UUcioA==}
|
||||
|
||||
'@xml-tools/parser@1.0.11':
|
||||
resolution: {integrity: sha512-aKqQ077XnR+oQtHJlrAflaZaL7qZsulWc/i/ZEooar5JiWj1eLt0+Wg28cpa+XLney107wXqneC+oG1IZvxkTA==}
|
||||
@@ -3090,8 +3090,8 @@ packages:
|
||||
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
|
||||
hasBin: true
|
||||
|
||||
js-base64@3.7.7:
|
||||
resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==}
|
||||
js-base64@3.7.8:
|
||||
resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
|
||||
|
||||
js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
@@ -3196,8 +3196,8 @@ packages:
|
||||
linkify-it@5.0.0:
|
||||
resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
|
||||
|
||||
linkifyjs@4.3.1:
|
||||
resolution: {integrity: sha512-DRSlB9DKVW04c4SUdGvKK5FR6be45lTU9M76JnngqPeeGDqPwYc0zdUErtsNVMtxPXgUWV4HbXbnC4sNyBxkYg==}
|
||||
linkifyjs@4.3.2:
|
||||
resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==}
|
||||
|
||||
load-json-file@4.0.0:
|
||||
resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==}
|
||||
@@ -3441,8 +3441,8 @@ packages:
|
||||
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
nostr-editor@1.0.0:
|
||||
resolution: {integrity: sha512-+TL3G0m7WsXeEAitxzQhun7hyARxqRANjGIS2z9CBbniCGvT/Wz6YLgUnUysnBg3tmSgMZg5FWhaDPwfvdvbSw==}
|
||||
nostr-editor@1.0.1:
|
||||
resolution: {integrity: sha512-HXqXjxtIN0CcC7sLV5xYjEsQF0bFYLmNKxS75ya2yZGQ/z16U+uK6bb2Hd72QyqXlHXyWN0m24E5Gcws8/NhRQ==}
|
||||
engines: {node: '>=18.16.1'}
|
||||
peerDependencies:
|
||||
'@tiptap/core': ^2.6.6
|
||||
@@ -5957,7 +5957,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.3.2
|
||||
|
||||
'@noble/curves@1.9.2':
|
||||
'@noble/curves@1.9.7':
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
|
||||
@@ -6255,58 +6255,58 @@ snapshots:
|
||||
dependencies:
|
||||
'@tiptap/pm': 2.12.0
|
||||
|
||||
'@tiptap/extension-code-block@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/extension-code-block@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
|
||||
'@tiptap/extension-code@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
'@tiptap/extension-code@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
|
||||
'@tiptap/extension-document@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
'@tiptap/extension-document@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
|
||||
'@tiptap/extension-dropcursor@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/extension-dropcursor@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
|
||||
'@tiptap/extension-gapcursor@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/extension-gapcursor@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
|
||||
'@tiptap/extension-hard-break@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
'@tiptap/extension-hard-break@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
|
||||
'@tiptap/extension-history@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/extension-history@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
|
||||
'@tiptap/extension-image@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
'@tiptap/extension-image@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
|
||||
'@tiptap/extension-link@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/extension-link@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
linkifyjs: 4.3.1
|
||||
linkifyjs: 4.3.2
|
||||
|
||||
'@tiptap/extension-paragraph@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
'@tiptap/extension-paragraph@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
|
||||
'@tiptap/extension-placeholder@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/extension-placeholder@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
|
||||
'@tiptap/extension-text@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
'@tiptap/extension-text@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
|
||||
@@ -6331,7 +6331,7 @@ snapshots:
|
||||
prosemirror-transform: 1.10.4
|
||||
prosemirror-view: 1.39.3
|
||||
|
||||
'@tiptap/suggestion@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
'@tiptap/suggestion@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
@@ -6542,19 +6542,18 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@vite-pwa/assets-generator': 0.2.6
|
||||
|
||||
'@welshman/app@0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)':
|
||||
'@welshman/app@0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)':
|
||||
dependencies:
|
||||
'@types/throttle-debounce': 5.0.2
|
||||
'@welshman/feeds': 0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/net': 0.4.7(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/relay': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/router': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/signer': 0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/store': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/feeds': 0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/net': 0.5.0(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/relay': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/router': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/signer': 0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/store': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
fuse.js: 7.1.0
|
||||
idb: 8.0.2
|
||||
svelte: 4.2.20
|
||||
throttle-debounce: 5.0.2
|
||||
transitivePeerDependencies:
|
||||
@@ -6562,31 +6561,31 @@ snapshots:
|
||||
- typescript
|
||||
- ws
|
||||
|
||||
'@welshman/content@0.4.7(typescript@5.8.3)':
|
||||
'@welshman/content@0.5.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@braintree/sanitize-url': 7.1.1
|
||||
nostr-tools: 2.14.2(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@welshman/editor@0.4.7(@tiptap/extension-image@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(linkifyjs@4.3.1)(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(typescript@5.8.3)':
|
||||
'@welshman/editor@0.5.0(@tiptap/extension-image@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(linkifyjs@4.3.2)(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-code': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-code-block': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-document': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-dropcursor': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-gapcursor': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-hard-break': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-history': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-paragraph': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-placeholder': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-text': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-code': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-code-block': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-document': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-dropcursor': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-gapcursor': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-hard-break': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-history': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-paragraph': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-placeholder': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-text': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/pm': 2.12.0
|
||||
'@tiptap/suggestion': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
nostr-editor: 1.0.0(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/extension-image@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)(linkifyjs@4.3.1)(nostr-tools@2.14.2(typescript@5.8.3))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))
|
||||
'@tiptap/suggestion': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
nostr-editor: 1.0.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/extension-image@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)(linkifyjs@4.3.2)(nostr-tools@2.14.2(typescript@5.8.3))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))
|
||||
nostr-tools: 2.14.2(typescript@5.8.3)
|
||||
tippy.js: 6.3.7
|
||||
transitivePeerDependencies:
|
||||
@@ -6600,79 +6599,79 @@ snapshots:
|
||||
- tiptap-markdown
|
||||
- typescript
|
||||
|
||||
'@welshman/feeds@0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)':
|
||||
'@welshman/feeds@0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)':
|
||||
dependencies:
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/net': 0.4.7(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/relay': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/router': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/signer': 0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/net': 0.5.0(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/relay': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/router': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/signer': 0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
trava: 1.2.1
|
||||
transitivePeerDependencies:
|
||||
- nostr-signer-capacitor-plugin
|
||||
- typescript
|
||||
- ws
|
||||
|
||||
'@welshman/lib@0.4.7':
|
||||
'@welshman/lib@0.5.0':
|
||||
dependencies:
|
||||
'@scure/base': 1.2.6
|
||||
'@types/events': 3.0.3
|
||||
events: 3.3.0
|
||||
|
||||
'@welshman/net@0.4.7(typescript@5.8.3)(ws@8.18.3)':
|
||||
'@welshman/net@0.5.0(typescript@5.8.3)(ws@8.18.3)':
|
||||
dependencies:
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/relay': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/relay': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
events: 3.3.0
|
||||
isomorphic-ws: 5.0.0(ws@8.18.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
- ws
|
||||
|
||||
'@welshman/relay@0.4.7(typescript@5.8.3)':
|
||||
'@welshman/relay@0.5.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@welshman/router@0.4.7(typescript@5.8.3)':
|
||||
'@welshman/router@0.5.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/relay': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/relay': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@welshman/signer@0.4.7(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)':
|
||||
'@welshman/signer@0.5.0(nostr-signer-capacitor-plugin@0.0.4(@capacitor/core@7.2.0))(typescript@5.8.3)(ws@8.18.3)':
|
||||
dependencies:
|
||||
'@noble/curves': 1.9.2
|
||||
'@noble/curves': 1.9.7
|
||||
'@noble/hashes': 1.8.0
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/net': 0.4.7(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/net': 0.5.0(typescript@5.8.3)(ws@8.18.3)
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
nostr-signer-capacitor-plugin: 0.0.4(@capacitor/core@7.2.0)
|
||||
nostr-tools: 2.14.2(typescript@5.8.3)
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
- ws
|
||||
|
||||
'@welshman/store@0.4.7(typescript@5.8.3)':
|
||||
'@welshman/store@0.5.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@welshman/lib': 0.4.7
|
||||
'@welshman/relay': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/util': 0.4.7(typescript@5.8.3)
|
||||
'@welshman/lib': 0.5.0
|
||||
'@welshman/relay': 0.5.0(typescript@5.8.3)
|
||||
'@welshman/util': 0.5.0(typescript@5.8.3)
|
||||
svelte: 4.2.20
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
'@welshman/util@0.4.7(typescript@5.8.3)':
|
||||
'@welshman/util@0.5.0(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@types/ws': 8.18.1
|
||||
'@welshman/lib': 0.4.7
|
||||
js-base64: 3.7.7
|
||||
'@welshman/lib': 0.5.0
|
||||
js-base64: 3.7.8
|
||||
nostr-tools: 2.14.2(typescript@5.8.3)
|
||||
nostr-wasm: 0.1.0
|
||||
transitivePeerDependencies:
|
||||
@@ -8192,7 +8191,7 @@ snapshots:
|
||||
|
||||
jiti@1.21.7: {}
|
||||
|
||||
js-base64@3.7.7: {}
|
||||
js-base64@3.7.8: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
@@ -8267,7 +8266,7 @@ snapshots:
|
||||
dependencies:
|
||||
uc.micro: 2.1.0
|
||||
|
||||
linkifyjs@4.3.1: {}
|
||||
linkifyjs@4.3.2: {}
|
||||
|
||||
load-json-file@4.0.0:
|
||||
dependencies:
|
||||
@@ -8503,15 +8502,15 @@ snapshots:
|
||||
|
||||
normalize-range@0.1.2: {}
|
||||
|
||||
nostr-editor@1.0.0(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/extension-image@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)(linkifyjs@4.3.1)(nostr-tools@2.14.2(typescript@5.8.3))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))):
|
||||
nostr-editor@1.0.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/extension-image@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0)))(@tiptap/extension-link@2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)(linkifyjs@4.3.2)(nostr-tools@2.14.2(typescript@5.8.3))(prosemirror-markdown@1.13.2)(prosemirror-model@1.25.1)(prosemirror-state@1.4.3)(prosemirror-view@1.39.3)(tiptap-markdown@0.8.10(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))):
|
||||
dependencies:
|
||||
'@tiptap/core': 2.12.0(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-image': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-link': 2.26.1(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/extension-image': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))
|
||||
'@tiptap/extension-link': 2.26.2(@tiptap/core@2.12.0(@tiptap/pm@2.12.0))(@tiptap/pm@2.12.0)
|
||||
'@tiptap/pm': 2.12.0
|
||||
js-base64: 3.7.7
|
||||
js-base64: 3.7.8
|
||||
light-bolt11-decoder: 3.2.0
|
||||
linkifyjs: 4.3.1
|
||||
linkifyjs: 4.3.2
|
||||
nostr-tools: 2.14.2(typescript@5.8.3)
|
||||
prosemirror-markdown: 1.13.2
|
||||
prosemirror-model: 1.25.1
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
Goals
|
||||
{#if $notifications.has(goalsPath)}
|
||||
<div
|
||||
class="absolute -right-3 -top-1 h-2 w-2 rounded-full bg-primary-content"
|
||||
class="absolute -right-3 -top-1 h-2 w-2 rounded-full bg-neutral-content"
|
||||
transition:fade>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -81,7 +81,7 @@
|
||||
Threads
|
||||
{#if $notifications.has(threadsPath)}
|
||||
<div
|
||||
class="absolute -right-3 -top-1 h-2 w-2 rounded-full bg-primary-content"
|
||||
class="absolute -right-3 -top-1 h-2 w-2 rounded-full bg-neutral-content"
|
||||
transition:fade>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -93,7 +93,7 @@
|
||||
Calendar
|
||||
{#if $notifications.has(calendarPath)}
|
||||
<div
|
||||
class="absolute -right-3 -top-1 h-2 w-2 rounded-full bg-primary-content"
|
||||
class="absolute -right-3 -top-1 h-2 w-2 rounded-full bg-neutral-content"
|
||||
transition:fade>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import {updateProfile} from "@app/core/commands"
|
||||
import {clearModals} from "@app/util/modal"
|
||||
import {userProfile, session} from "@welshman/app"
|
||||
import {makeProfile, type NWCInfo} from "@welshman/util"
|
||||
import {makeProfile} from "@welshman/util"
|
||||
|
||||
const lud16 = getWalletAddress($session!.wallet!)
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
import {nwc} from "@getalby/sdk"
|
||||
import {sleep, assoc} from "@welshman/lib"
|
||||
import type {NWCInfo} from "@welshman/util"
|
||||
import {pubkey, userProfile, updateSession, profilesByPubkey} from "@welshman/app"
|
||||
import {makeProfile} from "@welshman/util"
|
||||
import {pubkey, userProfile, updateSession} from "@welshman/app"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import Cpu from "@assets/icons/cpu-bolt.svg?dataurl"
|
||||
import Lock from "@assets/icons/lock-keyhole.svg?dataurl"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import Wallet from "@assets/icons/wallet.svg?dataurl"
|
||||
import CheckCircle from "@assets/icons/check-circle.svg?dataurl"
|
||||
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
|
||||
import {updateProfile} from "@app/core/commands"
|
||||
import {pushToast} from "@app/util/toast"
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ import {
|
||||
userInboxRelaySelections,
|
||||
nip44EncryptToSelf,
|
||||
loadRelay,
|
||||
clearStorage,
|
||||
dropSession,
|
||||
tagEventForComment,
|
||||
tagEventForQuote,
|
||||
@@ -111,7 +110,7 @@ import {
|
||||
} from "@app/core/state"
|
||||
import {loadAlertStatuses} from "@app/core/requests"
|
||||
import {platform, platformName, getPushInfo} from "@app/util/push"
|
||||
import {clearFileStorage, preferencesStorageProvider} from "@src/lib/storage"
|
||||
import {preferencesStorageProvider, collectionStorageProvider} from "@src/lib/storage"
|
||||
|
||||
// Utils
|
||||
|
||||
@@ -154,12 +153,10 @@ export const logout = async () => {
|
||||
dropSession($pubkey)
|
||||
}
|
||||
|
||||
await clearStorage()
|
||||
|
||||
localStorage.clear()
|
||||
await preferencesStorageProvider.clear()
|
||||
|
||||
await clearFileStorage()
|
||||
await preferencesStorageProvider.clear()
|
||||
await collectionStorageProvider.clear()
|
||||
}
|
||||
|
||||
// Synchronization
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
import {on, throttle, fromPairs, batch, sortBy, concat} from "@welshman/lib"
|
||||
import {throttled, freshness} from "@welshman/store"
|
||||
import {
|
||||
PROFILE,
|
||||
FOLLOWS,
|
||||
MUTES,
|
||||
RELAYS,
|
||||
BLOSSOM_SERVERS,
|
||||
INBOX_RELAYS,
|
||||
ROOMS,
|
||||
APP_DATA,
|
||||
ALERT_STATUS,
|
||||
ALERT_EMAIL,
|
||||
ALERT_WEB,
|
||||
ALERT_IOS,
|
||||
ALERT_ANDROID,
|
||||
EVENT_TIME,
|
||||
THREAD,
|
||||
MESSAGE,
|
||||
DIRECT_MESSAGE,
|
||||
DIRECT_MESSAGE_FILE,
|
||||
} from "@welshman/util"
|
||||
import type {Zapper, TrustedEvent} from "@welshman/util"
|
||||
import type {RepositoryUpdate} from "@welshman/relay"
|
||||
import type {Handle, Relay} from "@welshman/app"
|
||||
import {
|
||||
plaintext,
|
||||
tracker,
|
||||
relays,
|
||||
repository,
|
||||
handles,
|
||||
zappers,
|
||||
onZapper,
|
||||
onHandle,
|
||||
} from "@welshman/app"
|
||||
import {collectionStorageProvider} from "@lib/storage"
|
||||
|
||||
const syncEvents = async () => {
|
||||
repository.load(await collectionStorageProvider.get<TrustedEvent>("events"))
|
||||
|
||||
const rankEvent = (event: TrustedEvent) => {
|
||||
switch (event.kind) {
|
||||
case PROFILE:
|
||||
return 1
|
||||
case FOLLOWS:
|
||||
return 1
|
||||
case MUTES:
|
||||
return 1
|
||||
case RELAYS:
|
||||
return 1
|
||||
case BLOSSOM_SERVERS:
|
||||
return 1
|
||||
case INBOX_RELAYS:
|
||||
return 1
|
||||
case ROOMS:
|
||||
return 1
|
||||
case APP_DATA:
|
||||
return 1
|
||||
case ALERT_STATUS:
|
||||
return 1
|
||||
case ALERT_EMAIL:
|
||||
return 1
|
||||
case ALERT_WEB:
|
||||
return 1
|
||||
case ALERT_IOS:
|
||||
return 1
|
||||
case ALERT_ANDROID:
|
||||
return 1
|
||||
case EVENT_TIME:
|
||||
return 0.9
|
||||
case THREAD:
|
||||
return 0.9
|
||||
case MESSAGE:
|
||||
return 0.9
|
||||
case DIRECT_MESSAGE:
|
||||
return 0.9
|
||||
case DIRECT_MESSAGE_FILE:
|
||||
return 0.9
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
return on(
|
||||
repository,
|
||||
"update",
|
||||
batch(3000, async (updates: RepositoryUpdate[]) => {
|
||||
let added: TrustedEvent[] = []
|
||||
const removed = new Set<string>()
|
||||
|
||||
for (const update of updates) {
|
||||
for (const event of update.added) {
|
||||
if (rankEvent(event) > 0) {
|
||||
added.push(event)
|
||||
removed.delete(event.id)
|
||||
}
|
||||
}
|
||||
|
||||
for (const id of update.removed) {
|
||||
added = added.filter(event => !update.removed.has(event.id))
|
||||
removed.add(id)
|
||||
}
|
||||
}
|
||||
|
||||
if (added.length > 0) {
|
||||
let events = concat(await collectionStorageProvider.get<TrustedEvent>("events"), added)
|
||||
|
||||
// If we're well above our retention limit, drop lowest-ranked events
|
||||
if (events.length > 15_000) {
|
||||
events = sortBy(e => -rankEvent(e), events).slice(10_000)
|
||||
}
|
||||
|
||||
await collectionStorageProvider.set("events", events)
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const syncTracker = async () => {
|
||||
const relaysById = new Map<string, Set<string>>()
|
||||
|
||||
for (const [id, relays] of await collectionStorageProvider.get<[string, string[]]>("tracker")) {
|
||||
relaysById.set(id, new Set(relays))
|
||||
}
|
||||
|
||||
tracker.load(relaysById)
|
||||
|
||||
let p = Promise.resolve()
|
||||
|
||||
const updateOne = batch(3000, (ids: string[]) => {
|
||||
p = p.then(() => {
|
||||
collectionStorageProvider.add(
|
||||
"tracker",
|
||||
ids.map(id => [id, Array.from(tracker.getRelays(id))]),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
const updateAll = throttle(3000, () => {
|
||||
p = p.then(() => {
|
||||
collectionStorageProvider.set("tracker", Array.from(tracker.relaysById.entries()))
|
||||
})
|
||||
})
|
||||
|
||||
tracker.on("add", updateOne)
|
||||
tracker.on("remove", updateOne)
|
||||
tracker.on("load", updateAll)
|
||||
tracker.on("clear", updateAll)
|
||||
|
||||
return () => {
|
||||
tracker.off("add", updateOne)
|
||||
tracker.off("remove", updateOne)
|
||||
tracker.off("load", updateAll)
|
||||
tracker.off("clear", updateAll)
|
||||
}
|
||||
}
|
||||
|
||||
const syncRelays = async () => {
|
||||
relays.set(await collectionStorageProvider.get<Relay>("relays"))
|
||||
|
||||
return throttled(3000, relays).subscribe($relays => {
|
||||
collectionStorageProvider.set("relays", $relays)
|
||||
})
|
||||
}
|
||||
|
||||
const syncHandles = async () => {
|
||||
handles.set(await collectionStorageProvider.get<Handle>("handles"))
|
||||
|
||||
return onHandle(
|
||||
batch(3000, async $handles => {
|
||||
await collectionStorageProvider.add("handles", $handles)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const syncZappers = async () => {
|
||||
zappers.set(await collectionStorageProvider.get<Zapper>("zappers"))
|
||||
|
||||
return onZapper(
|
||||
batch(3000, async $zappers => {
|
||||
await collectionStorageProvider.add("zappers", $zappers)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
const syncFreshness = async () => {
|
||||
freshness.set(fromPairs(await collectionStorageProvider.get<[string, number]>("freshness")))
|
||||
|
||||
return throttled(3000, freshness).subscribe($freshness => {
|
||||
collectionStorageProvider.set("freshness", Object.entries($freshness))
|
||||
})
|
||||
}
|
||||
|
||||
const syncPlaintext = async () => {
|
||||
plaintext.set(fromPairs(await collectionStorageProvider.get<[string, string]>("plaintext")))
|
||||
|
||||
return throttled(3000, plaintext).subscribe($plaintext => {
|
||||
collectionStorageProvider.set("plaintext", Object.entries($plaintext))
|
||||
})
|
||||
}
|
||||
|
||||
export const syncDataStores = () =>
|
||||
Promise.all([
|
||||
syncEvents(),
|
||||
syncTracker(),
|
||||
syncRelays(),
|
||||
syncHandles(),
|
||||
syncZappers(),
|
||||
syncFreshness(),
|
||||
syncPlaintext(),
|
||||
])
|
||||
+87
-73
@@ -1,17 +1,11 @@
|
||||
import {parseJson} from "@welshman/lib"
|
||||
import {type StorageProvider} from "@welshman/store"
|
||||
import {Preferences} from "@capacitor/preferences"
|
||||
import type {Unsubscriber} from "svelte/store"
|
||||
import {Encoding, Filesystem, type Directory} from "@capacitor/filesystem"
|
||||
import {EventsStorageProvider} from "@lib/storage/events"
|
||||
import {FreshnessStorageProvider} from "@lib/storage/freshness"
|
||||
import {HandlesStorageProvider} from "@lib/storage/handles"
|
||||
import {PlaintextStorageProvider} from "@lib/storage/plaintext"
|
||||
import {RelaysStorageProvider} from "@lib/storage/relays"
|
||||
import {TrackerStorageProvider} from "@lib/storage/tracker"
|
||||
import {ZappersStorageProvider} from "@lib/storage/zappers"
|
||||
import {repository, tracker, unsubscribers} from "@welshman/app"
|
||||
import {Encoding, Filesystem, Directory} from "@capacitor/filesystem"
|
||||
|
||||
export class PreferencesStorageProvider implements StorageProvider {
|
||||
p = Promise.resolve()
|
||||
|
||||
get = async <T>(key: string): Promise<T | undefined> => {
|
||||
const result = await Preferences.get({key})
|
||||
if (!result.value) return undefined
|
||||
@@ -22,74 +16,94 @@ export class PreferencesStorageProvider implements StorageProvider {
|
||||
}
|
||||
}
|
||||
|
||||
p = Promise.resolve()
|
||||
set = async <T>(key: string, value: T): Promise<void> => {
|
||||
this.p = this.p.then(async () => await Preferences.set({key, value: JSON.stringify(value)}))
|
||||
this.p = this.p.then(() => Preferences.set({key, value: JSON.stringify(value)}))
|
||||
|
||||
await this.p
|
||||
}
|
||||
|
||||
clear = async () => {
|
||||
this.p = this.p.then(() => Preferences.clear())
|
||||
|
||||
await this.p
|
||||
}
|
||||
}
|
||||
|
||||
export const preferencesStorageProvider = new PreferencesStorageProvider()
|
||||
|
||||
export class CollectionStorageProvider implements StorageProvider {
|
||||
p = Promise.resolve()
|
||||
|
||||
get = async <T>(key: string): Promise<T[]> => {
|
||||
try {
|
||||
const file = await Filesystem.readFile({
|
||||
path: key + ".json",
|
||||
directory: Directory.Data,
|
||||
encoding: Encoding.UTF8,
|
||||
})
|
||||
|
||||
const items: T[] = []
|
||||
for (const line of file.data.toString().split("\n")) {
|
||||
const item = parseJson(line)
|
||||
|
||||
if (item) {
|
||||
items.push(item)
|
||||
}
|
||||
}
|
||||
|
||||
return items
|
||||
} catch (err) {
|
||||
// file doesn't exist, or isn't valid json
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
set = async <T>(key: string, value: T[]): Promise<void> => {
|
||||
this.p = this.p.then(async () => {
|
||||
await Filesystem.writeFile({
|
||||
path: key + ".json",
|
||||
directory: Directory.Data,
|
||||
encoding: Encoding.UTF8,
|
||||
data: value.map(v => JSON.stringify(v)).join("\n"),
|
||||
})
|
||||
})
|
||||
|
||||
await this.p
|
||||
}
|
||||
|
||||
add = async <T>(key: string, value: T[]): Promise<void> => {
|
||||
this.p = this.p.then(async () => {
|
||||
await Filesystem.appendFile({
|
||||
path: key + ".json",
|
||||
directory: Directory.Data,
|
||||
encoding: Encoding.UTF8,
|
||||
data: value.map(v => JSON.stringify(v)).join("\n"),
|
||||
})
|
||||
})
|
||||
|
||||
await this.p
|
||||
}
|
||||
|
||||
clear = async (): Promise<void> => {
|
||||
await Preferences.clear()
|
||||
this.p = Promise.resolve()
|
||||
this.p = this.p.then(async () => {
|
||||
try {
|
||||
const res = await Filesystem.readdir({path: "./", directory: Directory.Data})
|
||||
|
||||
await Promise.all(
|
||||
res.files.map(file =>
|
||||
Filesystem.deleteFile({
|
||||
path: file.name + ".json",
|
||||
directory: Directory.Data,
|
||||
}),
|
||||
),
|
||||
)
|
||||
} catch (e) {
|
||||
// Directory might not have been created
|
||||
}
|
||||
})
|
||||
|
||||
await this.p
|
||||
}
|
||||
}
|
||||
|
||||
// singleton instance of PreferencesStorageProvider
|
||||
export const preferencesStorageProvider = new PreferencesStorageProvider()
|
||||
|
||||
export interface FilesystemStorageProvider {
|
||||
initializeState(): Promise<void>
|
||||
sync(): Unsubscriber
|
||||
}
|
||||
|
||||
export const getAllFromFile = async <T>(
|
||||
filepath: string,
|
||||
directory: Directory,
|
||||
encoding: Encoding,
|
||||
): Promise<T[]> => {
|
||||
try {
|
||||
const contents = (
|
||||
await Filesystem.readFile({
|
||||
path: filepath,
|
||||
directory,
|
||||
encoding,
|
||||
})
|
||||
).data.toString()
|
||||
|
||||
if (!contents || contents == "") {
|
||||
return []
|
||||
}
|
||||
|
||||
return JSON.parse(contents)
|
||||
} catch (err) {
|
||||
// file doesn't exist
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultStorageProviders = {
|
||||
relays: new RelaysStorageProvider(),
|
||||
handles: new RelaysStorageProvider(),
|
||||
zappers: new ZappersStorageProvider(),
|
||||
freshness: new FreshnessStorageProvider(),
|
||||
plaintext: new PlaintextStorageProvider(),
|
||||
tracker: new TrackerStorageProvider({tracker}),
|
||||
events: new EventsStorageProvider({limit: 10_000, repository, rankEvent: () => 1}),
|
||||
}
|
||||
|
||||
export const initFileStorage = async (storageProviders: Record<string, FilesystemStorageProvider>) => {
|
||||
await Promise.all(Object.values(storageProviders).map(async provider => {
|
||||
await provider.initializeState()
|
||||
unsubscribers.push(provider.sync())
|
||||
}))
|
||||
}
|
||||
|
||||
export const clearFileStorage = async (): Promise<void> => {
|
||||
await EventsStorageProvider.clearStorage()
|
||||
await FreshnessStorageProvider.clearStorage()
|
||||
await HandlesStorageProvider.clearStorage()
|
||||
await PlaintextStorageProvider.clearStorage()
|
||||
await RelaysStorageProvider.clearStorage()
|
||||
await TrackerStorageProvider.clearStorage()
|
||||
await ZappersStorageProvider.clearStorage()
|
||||
}
|
||||
export const collectionStorageProvider = new CollectionStorageProvider()
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import type {TrustedEvent} from "@welshman/util"
|
||||
import type {Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import type {Repository, RepositoryUpdate} from "@welshman/relay"
|
||||
import {on, sortBy} from "@welshman/lib"
|
||||
|
||||
export class EventsStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "events.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
limit: number
|
||||
repository: Repository
|
||||
rankEvent: (event: TrustedEvent) => number
|
||||
eventCount: number = 0
|
||||
isDeleting = false
|
||||
|
||||
constructor({
|
||||
limit,
|
||||
repository,
|
||||
rankEvent,
|
||||
}: {
|
||||
limit: number
|
||||
repository: Repository
|
||||
rankEvent: (event: TrustedEvent) => number
|
||||
}) {
|
||||
this.limit = limit
|
||||
this.repository = repository
|
||||
this.rankEvent = rankEvent
|
||||
}
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
const events = await this.getAll()
|
||||
this.eventCount = events.length
|
||||
this.repository.load(events)
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
const onUpdate = async ({added, removed}: RepositoryUpdate) => {
|
||||
// Only add events we want to keep
|
||||
const keep = added.filter(e => this.rankEvent(e) > 0)
|
||||
|
||||
// Add new events
|
||||
if (keep.length > 0) {
|
||||
await this.updateEvents(keep)
|
||||
}
|
||||
|
||||
// If we're well above our retention limit, drop lowest-ranked events
|
||||
if (!this.isDeleting && this.eventCount > this.limit * 1.5) {
|
||||
try {
|
||||
this.isDeleting = true
|
||||
|
||||
for (const event of sortBy(e => -this.rankEvent(e), await this.getAll()).slice(
|
||||
this.limit,
|
||||
)) {
|
||||
removed.add(event.id)
|
||||
}
|
||||
|
||||
if (removed.size > 0) {
|
||||
await this.deleteEvents(Array.from(removed))
|
||||
}
|
||||
} finally {
|
||||
this.isDeleting = false
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of our total number of events. This isn't strictly accurate, but it's close enough
|
||||
this.eventCount = this.eventCount + keep.length - removed.size
|
||||
}
|
||||
|
||||
return on(this.repository, "update", onUpdate)
|
||||
}
|
||||
|
||||
async getAll(): Promise<TrustedEvent[]> {
|
||||
return await getAllFromFile(EventsStorageProvider.filepath, EventsStorageProvider.directory, EventsStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(events: TrustedEvent[]) {
|
||||
await Filesystem.writeFile({
|
||||
path: EventsStorageProvider.filepath,
|
||||
directory: EventsStorageProvider.directory,
|
||||
encoding: EventsStorageProvider.encoding,
|
||||
data: JSON.stringify(events),
|
||||
})
|
||||
}
|
||||
|
||||
async updateEvents(events: TrustedEvent[]) {
|
||||
const existing = await this.getAll()
|
||||
const updated = existing.concat(events)
|
||||
await this.writeAll(updated)
|
||||
}
|
||||
|
||||
async deleteEvents(ids: string[]) {
|
||||
const existing = await this.getAll()
|
||||
const updated = existing.filter(e => !ids.includes(e.id))
|
||||
await this.writeAll(updated)
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: EventsStorageProvider.filepath, directory: EventsStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import type {Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import {fromPairs} from "@welshman/lib"
|
||||
import {freshness} from "@welshman/store"
|
||||
|
||||
type KV = {key: string; value: any}
|
||||
|
||||
export class FreshnessStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "freshness.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
const items = await this.getAll()
|
||||
freshness.set(fromPairs(items.map(item => [item.key, item.value])))
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
const interval = setInterval(() => {
|
||||
this.writeAll(freshness.get())
|
||||
}, 10_000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}
|
||||
|
||||
async getAll(): Promise<KV[]> {
|
||||
return await getAllFromFile(FreshnessStorageProvider.filepath, FreshnessStorageProvider.directory, FreshnessStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(items: Record<string, any>) {
|
||||
const kvs = Object.entries(items).map(([key, value]) => ({key, value}))
|
||||
|
||||
await Filesystem.writeFile({
|
||||
path: FreshnessStorageProvider.filepath,
|
||||
directory: FreshnessStorageProvider.directory,
|
||||
encoding: FreshnessStorageProvider.encoding,
|
||||
data: JSON.stringify(kvs),
|
||||
})
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: FreshnessStorageProvider.filepath, directory: FreshnessStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import {get, type Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import {batch} from "@welshman/lib"
|
||||
import {handles, onHandle, type Handle} from "@welshman/app"
|
||||
|
||||
export class HandlesStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "handles.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
handles.set(await this.getAll())
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
return onHandle(batch(300, () => this.saveState()))
|
||||
}
|
||||
|
||||
async getAll(): Promise<Handle[]> {
|
||||
return await getAllFromFile(HandlesStorageProvider.filepath, HandlesStorageProvider.directory, HandlesStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(handles: Handle[]) {
|
||||
await Filesystem.writeFile({
|
||||
path: HandlesStorageProvider.filepath,
|
||||
directory: HandlesStorageProvider.directory,
|
||||
encoding: HandlesStorageProvider.encoding,
|
||||
data: JSON.stringify(handles),
|
||||
})
|
||||
}
|
||||
|
||||
async saveState() {
|
||||
await this.writeAll(get(handles))
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: HandlesStorageProvider.filepath, directory: HandlesStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import type {Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import {fromPairs} from "@welshman/lib"
|
||||
import {plaintext} from "@welshman/app"
|
||||
|
||||
type KV = {key: string; value: any}
|
||||
|
||||
export class PlaintextStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "plaintext.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
const items = await this.getAll()
|
||||
plaintext.set(fromPairs(items.map(item => [item.key, item.value])))
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
const interval = setInterval(() => {
|
||||
this.writeAll(plaintext.get())
|
||||
}, 10_000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}
|
||||
|
||||
async getAll(): Promise<KV[]> {
|
||||
return await getAllFromFile(PlaintextStorageProvider.filepath, PlaintextStorageProvider.directory, PlaintextStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(items: Record<string, any>) {
|
||||
const kvs = Object.entries(items).map(([key, value]) => ({key, value}))
|
||||
|
||||
await Filesystem.writeFile({
|
||||
path: PlaintextStorageProvider.filepath,
|
||||
directory: PlaintextStorageProvider.directory,
|
||||
encoding: PlaintextStorageProvider.encoding,
|
||||
data: JSON.stringify(kvs),
|
||||
})
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: PlaintextStorageProvider.filepath, directory: PlaintextStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import type {Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import {relays, type Relay} from "@welshman/app"
|
||||
import {throttled} from "@welshman/store"
|
||||
|
||||
export class RelaysStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "relays.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
relays.set(await this.getAll())
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
return throttled(3000, relays).subscribe(() => this.saveState())
|
||||
}
|
||||
|
||||
async getAll(): Promise<Relay[]> {
|
||||
return await getAllFromFile(RelaysStorageProvider.filepath, RelaysStorageProvider.directory, RelaysStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(relays: Relay[]) {
|
||||
await Filesystem.writeFile({
|
||||
path: RelaysStorageProvider.filepath,
|
||||
directory: RelaysStorageProvider.directory,
|
||||
encoding: RelaysStorageProvider.encoding,
|
||||
data: JSON.stringify(relays),
|
||||
})
|
||||
}
|
||||
|
||||
async saveState() {
|
||||
await this.writeAll(relays.get())
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: RelaysStorageProvider.filepath, directory: RelaysStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import type {Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import type {Tracker} from "@welshman/net"
|
||||
import {call, on} from "@welshman/lib"
|
||||
|
||||
type Entry = {id: string; relays: string[]}
|
||||
|
||||
export class TrackerStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "tracker.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
tracker: Tracker
|
||||
|
||||
constructor({tracker}: {tracker: Tracker}) {
|
||||
this.tracker = tracker
|
||||
}
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
const relaysByid = new Map<string, Set<string>>()
|
||||
|
||||
for (const {id, relays} of await this.getAll()) {
|
||||
relaysByid.set(id, new Set(relays))
|
||||
}
|
||||
|
||||
this.tracker.load(relaysByid)
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
const updateOne = async (id: string, relay: string) => {
|
||||
const relays = new Set(await this.getAll())
|
||||
relays.add({id, relays: Array.from(this.tracker.getRelays(id))})
|
||||
await this.writeAll([...relays])
|
||||
}
|
||||
|
||||
const updateAll = async () => {
|
||||
await this.writeAll(Array.from(this.tracker.relaysById.entries()).map(([id, relays]) => ({
|
||||
id,
|
||||
relays: Array.from(relays),
|
||||
})))
|
||||
}
|
||||
|
||||
const unsubscribers = [
|
||||
on(this.tracker, "add", updateOne),
|
||||
on(this.tracker, "remove", updateOne),
|
||||
on(this.tracker, "load", updateAll),
|
||||
on(this.tracker, "clear", updateAll),
|
||||
]
|
||||
|
||||
return () => {
|
||||
unsubscribers.forEach(call)
|
||||
}
|
||||
}
|
||||
|
||||
async getAll(): Promise<Entry[]> {
|
||||
return await getAllFromFile(TrackerStorageProvider.filepath, TrackerStorageProvider.directory, TrackerStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(relays: Entry[]) {
|
||||
await Filesystem.writeFile({
|
||||
path: TrackerStorageProvider.filepath,
|
||||
directory: TrackerStorageProvider.directory,
|
||||
encoding: TrackerStorageProvider.encoding,
|
||||
data: JSON.stringify(relays),
|
||||
})
|
||||
}
|
||||
|
||||
async saveState() {
|
||||
await this.writeAll(
|
||||
Array.from(this.tracker.relaysById.entries()).map(([id, relays]) => ({
|
||||
id,
|
||||
relays: Array.from(relays),
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: TrackerStorageProvider.filepath, directory: TrackerStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import {getAllFromFile, type FilesystemStorageProvider} from "@lib/storage"
|
||||
import {get, type Unsubscriber} from "svelte/store"
|
||||
import {Filesystem, Directory, Encoding} from "@capacitor/filesystem"
|
||||
import {onZapper, zappers} from "@welshman/app"
|
||||
import {batch} from "@welshman/lib"
|
||||
import type {Zapper} from "@welshman/util"
|
||||
|
||||
export class ZappersStorageProvider implements FilesystemStorageProvider {
|
||||
static filepath = "zappers.json"
|
||||
static directory = Directory.Data
|
||||
static encoding = Encoding.UTF8
|
||||
|
||||
async initializeState(): Promise<void> {
|
||||
zappers.set(await this.getAll())
|
||||
}
|
||||
|
||||
sync(): Unsubscriber {
|
||||
return onZapper(batch(300, () => this.saveState()))
|
||||
}
|
||||
|
||||
async getAll(): Promise<Zapper[]> {
|
||||
return await getAllFromFile(ZappersStorageProvider.filepath, ZappersStorageProvider.directory, ZappersStorageProvider.encoding)
|
||||
}
|
||||
|
||||
async writeAll(zappers: Zapper[]) {
|
||||
await Filesystem.writeFile({
|
||||
path: ZappersStorageProvider.filepath,
|
||||
directory: ZappersStorageProvider.directory,
|
||||
encoding: ZappersStorageProvider.encoding,
|
||||
data: JSON.stringify(zappers),
|
||||
})
|
||||
}
|
||||
|
||||
async saveState() {
|
||||
await this.writeAll(get(zappers))
|
||||
}
|
||||
|
||||
static async clearStorage(): Promise<void> {
|
||||
await Filesystem.deleteFile({path: ZappersStorageProvider.filepath, directory: ZappersStorageProvider.directory})
|
||||
}
|
||||
}
|
||||
+15
-64
@@ -24,27 +24,7 @@
|
||||
WEEK,
|
||||
} from "@welshman/lib"
|
||||
import type {TrustedEvent, StampedEvent} from "@welshman/util"
|
||||
import {
|
||||
WRAP,
|
||||
ALERT_STATUS,
|
||||
ALERT_EMAIL,
|
||||
ALERT_WEB,
|
||||
ALERT_IOS,
|
||||
ALERT_ANDROID,
|
||||
EVENT_TIME,
|
||||
APP_DATA,
|
||||
THREAD,
|
||||
MESSAGE,
|
||||
INBOX_RELAYS,
|
||||
DIRECT_MESSAGE,
|
||||
DIRECT_MESSAGE_FILE,
|
||||
MUTES,
|
||||
FOLLOWS,
|
||||
PROFILE,
|
||||
RELAYS,
|
||||
BLOSSOM_SERVERS,
|
||||
ROOMS,
|
||||
} from "@welshman/util"
|
||||
import {WRAP} from "@welshman/util"
|
||||
import {Nip46Broker, makeSecret} from "@welshman/signer"
|
||||
import type {Socket, RelayMessage, ClientMessage} from "@welshman/net"
|
||||
import {
|
||||
@@ -61,7 +41,6 @@
|
||||
} from "@welshman/net"
|
||||
import {
|
||||
loadRelay,
|
||||
db,
|
||||
repository,
|
||||
pubkey,
|
||||
session,
|
||||
@@ -71,7 +50,6 @@
|
||||
dropSession,
|
||||
loginWithNip01,
|
||||
loginWithNip46,
|
||||
EventsStorageAdapter,
|
||||
loadRelaySelections,
|
||||
SignerLogEntryStatus,
|
||||
} from "@welshman/app"
|
||||
@@ -83,7 +61,7 @@
|
||||
import * as net from "@welshman/net"
|
||||
import * as app from "@welshman/app"
|
||||
import {nsecDecode} from "@lib/util"
|
||||
import {defaultStorageProviders, initFileStorage, preferencesStorageProvider} from "@lib/storage"
|
||||
import {preferencesStorageProvider} from "@lib/storage"
|
||||
import AppContainer from "@app/components/AppContainer.svelte"
|
||||
import ModalContainer from "@app/components/ModalContainer.svelte"
|
||||
import {setupTracking} from "@app/util/tracking"
|
||||
@@ -105,11 +83,13 @@
|
||||
import {initializePushNotifications} from "@app/util/push"
|
||||
import * as commands from "@app/core/commands"
|
||||
import * as requests from "@app/core/requests"
|
||||
import * as notifications from "@app/util/notifications"
|
||||
import * as appState from "@app/core/state"
|
||||
import {badgeCount, handleBadgeCountChanges} from "@app/util/notifications"
|
||||
import * as notifications from "@app/util/notifications"
|
||||
import * as storage from "@app/util/storage"
|
||||
import NewNotificationSound from "@src/app/components/NewNotificationSound.svelte"
|
||||
import {EventsStorageProvider} from "@lib/storage/events"
|
||||
|
||||
// Migration: delete old indexeddb database
|
||||
indexedDB?.deleteDatabase('flotilla')
|
||||
|
||||
// Migration: old nostrtalk instance used different sessions
|
||||
if ($session && !$signer) {
|
||||
@@ -123,6 +103,8 @@
|
||||
|
||||
const ready = $state(defer<void>())
|
||||
|
||||
let initialized = false
|
||||
|
||||
onMount(async () => {
|
||||
Object.assign(window, {
|
||||
get,
|
||||
@@ -240,7 +222,8 @@
|
||||
document.documentElement.style["font-size"] = `${$userSettingsValues.font_size}rem`
|
||||
})
|
||||
|
||||
if (!db) {
|
||||
if (!initialized) {
|
||||
initialized = true
|
||||
setupTracking()
|
||||
setupAnalytics()
|
||||
|
||||
@@ -279,42 +262,10 @@
|
||||
storage: preferencesStorageProvider,
|
||||
})
|
||||
|
||||
await initFileStorage({...defaultStorageProviders,
|
||||
events: new EventsStorageProvider({
|
||||
limit: 10_000,
|
||||
repository,
|
||||
rankEvent: (e: TrustedEvent) => {
|
||||
if (
|
||||
[
|
||||
PROFILE,
|
||||
FOLLOWS,
|
||||
MUTES,
|
||||
RELAYS,
|
||||
BLOSSOM_SERVERS,
|
||||
INBOX_RELAYS,
|
||||
ROOMS,
|
||||
APP_DATA,
|
||||
ALERT_STATUS,
|
||||
ALERT_EMAIL,
|
||||
ALERT_WEB,
|
||||
ALERT_IOS,
|
||||
ALERT_ANDROID,
|
||||
].includes(e.kind)
|
||||
) {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (
|
||||
[EVENT_TIME, THREAD, MESSAGE, DIRECT_MESSAGE, DIRECT_MESSAGE_FILE].includes(e.kind)
|
||||
) {
|
||||
return 0.9
|
||||
}
|
||||
|
||||
return 0
|
||||
},
|
||||
}),
|
||||
})
|
||||
// Sync application data (relay, events, etc)
|
||||
await storage.syncDataStores()
|
||||
|
||||
// Wait 300 ms for any throttled stores to finish
|
||||
sleep(300).then(() => ready.resolve())
|
||||
|
||||
defaultSocketPolicies.push(
|
||||
@@ -465,7 +416,7 @@
|
||||
)
|
||||
|
||||
// subscribe to badge count for changes
|
||||
badgeCount.subscribe(handleBadgeCountChanges)
|
||||
notifications.badgeCount.subscribe(notifications.handleBadgeCountChanges)
|
||||
|
||||
// Listen for signer errors, report to user via toast
|
||||
signerLog.subscribe(
|
||||
|
||||
Reference in New Issue
Block a user