diff --git a/package.json b/package.json index d562772..52959d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "paravel", - "version": "0.4.6", + "version": "0.4.7", "description": "Yet another toolkit for nostr", "author": "hodlbod", "license": "MIT", diff --git a/src/util/LRUCache.ts b/src/util/LRUCache.ts index 7d566d9..10892c5 100644 --- a/src/util/LRUCache.ts +++ b/src/util/LRUCache.ts @@ -28,18 +28,18 @@ export class LRUCache { } } -export function cached({ +export function cached({ maxSize, getKey, getValue, }: { maxSize: number - getKey: (args: any[]) => T - getValue: (args: any[]) => V + getKey: (args: Args) => T + getValue: (args: Args) => V }) { const cache = new LRUCache(maxSize) - const get = (...args: any[]) => { + const get = (...args: Args) => { const k = getKey(args) let v = cache.get(k) diff --git a/src/util/nostr.ts b/src/util/nostr.ts index f4bde79..f434237 100644 --- a/src/util/nostr.ts +++ b/src/util/nostr.ts @@ -72,10 +72,10 @@ export type CreateEventOpts = { export const createEvent = (kind: number, {content = "", tags = [], created_at = now()}: CreateEventOpts) => ({kind, content, tags, created_at}) -export const hasValidSignature = cached({ +export const hasValidSignature = cached({ maxSize: 10000, - getKey: ([e]: any[]) => [getEventHash(e), e.sig].join(":"), - getValue: ([e]: any[]) => { + getKey: ([e]: [Event]) => [getEventHash(e), e.sig].join(":"), + getValue: ([e]: [Event]) => { try { verifySignature(e) } catch (e) { @@ -180,7 +180,7 @@ export class Tags extends Fluent { // Support the deprecated version where tags are not marked as replies normalize() { - let tags = this.type(["a", "e"]) + const tags = this.type(["a", "e"]) // If we have a mark, we're not using the legacy format if (tags.any(t => t.length === 4 && ["reply", "root", "mention"].includes(last(t)))) { @@ -188,28 +188,30 @@ export class Tags extends Fluent { } // Legacy only supports e tags - tags = tags.type("e") + const replyTags = tags.type("e") + const reply = replyTags.values().last() + const root = replyTags.count() > 1 ? replyTags.values().first() : null - const reply = tags.values().last() - const root = tags.count() > 1 ? tags.values().first() : null + return new Tags([ + ...tags.reject(t => t[0] === "e").all(), + ...replyTags.all().map(t => { + t = t.slice(0, 3) - return new Tags(tags.all().map(t => { - t = t.slice(0, 3) + if (t.length === 2) { + t.push("") + } - if (t.length === 2) { - t.push("") - } + let mark = 'mention' - let mark = 'mention' + if (t[1] === reply) { + mark = 'reply' + } else if (t[1] === root) { + mark = 'root' + } - if (t[1] === reply) { - mark = 'reply' - } else if (t[1] === root) { - mark = 'root' - } - - return [...t, mark] - })) + return [...t, mark] + }) + ]) } getReply = () => { @@ -219,6 +221,8 @@ export class Tags extends Fluent { } getRoot = () => this.normalize().mark('root').values().first() + + getCommunity = () => this.type("a").values().filter(a => a.startsWith('34550:')).first() } // =========================================================================== diff --git a/yarn.lock b/yarn.lock index bd7a97c..33fb0b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -85,23 +85,28 @@ resolved "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.2.0.tgz" integrity sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw== -"@noble/curves@1.1.0", "@noble/curves@~1.1.0": +"@noble/curves@~1.1.0", "@noble/curves@1.1.0": version "1.1.0" resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz" integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== dependencies: "@noble/hashes" "1.3.1" +"@noble/hashes@~1.3.0": + version "1.3.2" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/hashes@~1.3.1": + version "1.3.2" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + "@noble/hashes@1.3.1": version "1.3.1" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== -"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": - version "1.3.2" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -110,7 +115,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -135,16 +140,16 @@ picocolors "^1.0.0" tslib "^2.6.0" -"@scure/base@1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - "@scure/base@~1.1.0": version "1.1.3" resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz" integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== +"@scure/base@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + "@scure/bip32@1.3.1": version "1.3.1" resolved "https://registry.npmjs.org/@scure/bip32/-/bip32-1.3.1.tgz" @@ -215,7 +220,7 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@5.62.0": +"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz" integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== @@ -288,7 +293,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.9.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: version "8.10.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== @@ -472,16 +477,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -651,7 +656,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@8.45.0: +eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", eslint@>=4.19.1, eslint@>=5.16.0, eslint@>=7.0.0, eslint@>=8.0.0, eslint@8.45.0: version "8.45.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz" integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== @@ -1038,7 +1043,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3: +inherits@^2.0.3, inherits@2: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1367,7 +1372,7 @@ normalize-package-data@^3.0.0: normalize-url@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a" + resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz" integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw== nostr-tools@^1.15.0: @@ -1560,7 +1565,7 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@3.0.1: +prettier@>=3.0.0, prettier@3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz" integrity sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ== @@ -1653,7 +1658,7 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@3.0.2, rimraf@^3.0.2: +rimraf@^3.0.2, rimraf@3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -1696,11 +1701,6 @@ safe-buffer@~5.2.0: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -"semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - semver@^6.1.0: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" @@ -1713,6 +1713,11 @@ semver@^7.3.4, semver@^7.3.7: dependencies: lru-cache "^6.0.0" +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -1761,6 +1766,13 @@ spdx-license-ids@^3.0.0: resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.15.tgz" integrity sha512-lpT8hSQp9jAKp9mhtBU4Xjon8LPGBvLIuBiSVhMEtmLecTh2mO0tlqrAMp47tBXzMr13NJMQ2lf7RpQGLJ3HsQ== +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string-to-stream@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/string-to-stream/-/string-to-stream-3.0.1.tgz" @@ -1777,13 +1789,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -1895,7 +1900,12 @@ tsc-multi@^1.1.0: tslib "^2.5.0" yargs "^17.7.1" -tslib@^1.8.1, tslib@^1.9.0: +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^1.9.0: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -1944,7 +1954,7 @@ type-fest@^0.8.1: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typescript@~5.1.6: +"typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=3, typescript@>=4.3.0, typescript@>=5.0.0, typescript@~5.1.6: version "5.1.6" resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== @@ -2003,7 +2013,7 @@ write-file-atomic@^4.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.7" -ws@^8.14.2: +ws@*, ws@^8.14.2: version "8.14.2" resolved "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz" integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==