chore: formatting
continuous-integration/drone/push Build is failing Details

This commit is contained in:
kieran 2024-04-05 14:12:31 +01:00
parent a938e466d7
commit 95b160dd04
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
7 changed files with 127 additions and 110 deletions

View File

@ -65,10 +65,17 @@ function RelayCacheStats() {
<div className="flex justify-between br p bg-superdark"> <div className="flex justify-between br p bg-superdark">
<div className="flex flex-col g4 w-64"> <div className="flex flex-col g4 w-64">
<FormattedMessage defaultMessage="Worker Relay" id="xSoIUU" /> <FormattedMessage defaultMessage="Worker Relay" id="xSoIUU" />
{myEvents && <p> {myEvents && (
<FormattedMessage defaultMessage="My events: {n}" id="lEnclp" values={{ <p>
n: <FormattedNumber value={myEvents} /> <FormattedMessage
}} /></p>} defaultMessage="My events: {n}"
id="lEnclp"
values={{
n: <FormattedNumber value={myEvents} />,
}}
/>
</p>
)}
<table className="text-secondary"> <table className="text-secondary">
<thead> <thead>
<tr> <tr>
@ -99,7 +106,7 @@ function RelayCacheStats() {
</table> </table>
</div> </div>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<AsyncButton onClick={() => { }}> <AsyncButton onClick={() => {}}>
<FormattedMessage defaultMessage="Clear" id="/GCoTA" /> <FormattedMessage defaultMessage="Clear" id="/GCoTA" />
</AsyncButton> </AsyncButton>
<AsyncButton <AsyncButton

View File

@ -23,21 +23,20 @@ const ToolMenuItems = [
iconBg: "bg-green-800", iconBg: "bg-green-800",
message: <FormattedMessage defaultMessage="Follows Relay Health" id="XQiFEl" />, message: <FormattedMessage defaultMessage="Follows Relay Health" id="XQiFEl" />,
path: "follows-relay-health", path: "follows-relay-health",
} },
], ],
}, },
{ {
title: <FormattedMessage defaultMessage="Account Data" id="IIOul1" />, title: <FormattedMessage defaultMessage="Account Data" id="IIOul1" />,
items: [ items: [
{ {
icon: "repost", icon: "repost",
iconBg: "bg-blue-800", iconBg: "bg-blue-800",
message: <FormattedMessage defaultMessage="Sync Account" id="hMQmIw" />, message: <FormattedMessage defaultMessage="Sync Account" id="hMQmIw" />,
path: "sync-account" path: "sync-account",
} },
] ],
} },
] as SettingsMenuItems; ] as SettingsMenuItems;
export const ToolsPages = [ export const ToolsPages = [
@ -62,8 +61,8 @@ export const ToolsPages = [
}, },
{ {
path: "sync-account", path: "sync-account",
element: <SyncAccountTool /> element: <SyncAccountTool />,
} },
] as Array<RouteObject>; ] as Array<RouteObject>;
export function ToolsPage() { export function ToolsPage() {

View File

@ -1,5 +1,5 @@
import { unwrap } from "@snort/shared"; import { unwrap } from "@snort/shared";
import { RangeSync, TaggedNostrEvent } from "@snort/system" import { RangeSync, TaggedNostrEvent } from "@snort/system";
import { SnortContext } from "@snort/system-react"; import { SnortContext } from "@snort/system-react";
import { useContext, useState } from "react"; import { useContext, useState } from "react";
import { FormattedMessage, FormattedNumber } from "react-intl"; import { FormattedMessage, FormattedNumber } from "react-intl";
@ -9,40 +9,56 @@ import useLogin from "@/Hooks/useLogin";
import { SearchRelays } from "@/Utils/Const"; import { SearchRelays } from "@/Utils/Const";
export default function SyncAccountTool() { export default function SyncAccountTool() {
const system = useContext(SnortContext); const system = useContext(SnortContext);
const login = useLogin(); const login = useLogin();
const [scan, setScan] = useState<number>(); const [scan, setScan] = useState<number>();
const [results, setResults] = useState<Array<TaggedNostrEvent>>([]); const [results, setResults] = useState<Array<TaggedNostrEvent>>([]);
async function start() { async function start() {
const relays = Object.entries(login.relays.item).filter(([, v]) => v.write).map(([k,]) => k); const relays = Object.entries(login.relays.item)
const sync = new RangeSync(system); .filter(([, v]) => v.write)
sync.on("event", evs => { .map(([k]) => k);
setResults(r => [...r, ...evs]); const sync = new RangeSync(system);
}); sync.on("event", evs => {
sync.on("scan", t => setScan(t)); setResults(r => [...r, ...evs]);
await sync.sync({ });
authors: [unwrap(login.publicKey)], sync.on("scan", t => setScan(t));
relays: [...relays, ...Object.keys(CONFIG.defaultRelays), ...SearchRelays] await sync.sync({
}) authors: [unwrap(login.publicKey)],
} relays: [...relays, ...Object.keys(CONFIG.defaultRelays), ...SearchRelays],
return <> });
<p> }
<FormattedMessage defaultMessage="Sync all events for your profile into local cache" id="+QM0PJ" /> return (
</p> <>
<p>
<FormattedMessage defaultMessage="Sync all events for your profile into local cache" id="+QM0PJ" />
</p>
{results.length > 0 && <h3> {results.length > 0 && (
<FormattedMessage defaultMessage="Found {n} events" id="ufvXH1" values={{ <h3>
n: <FormattedNumber value={results.length} /> <FormattedMessage
}} /> defaultMessage="Found {n} events"
</h3>} id="ufvXH1"
{scan !== undefined && <h4> values={{
<FormattedMessage defaultMessage="Scanning {date}" id="OxPdQ0" values={{ n: <FormattedNumber value={results.length} />,
date: new Date(scan * 1000).toLocaleDateString() }}
}} /> />
</h4>} </h3>
<AsyncButton onClick={start}> )}
<FormattedMessage defaultMessage="Start" id="mOFG3K" /> {scan !== undefined && (
</AsyncButton> <h4>
<FormattedMessage
defaultMessage="Scanning {date}"
id="OxPdQ0"
values={{
date: new Date(scan * 1000).toLocaleDateString(),
}}
/>
</h4>
)}
<AsyncButton onClick={start}>
<FormattedMessage defaultMessage="Start" id="mOFG3K" />
</AsyncButton>
</> </>
} );
}

View File

@ -31,11 +31,7 @@ export const SnortPubKey = "npub1sn0rtcjcf543gj4wsg7fa59s700d5ztys5ctj0g69g2x680
/** /**
* Default search relays * Default search relays
*/ */
export const SearchRelays = [ export const SearchRelays = ["wss://relay.nostr.band/", "wss://search.nos.today/", "wss://relay.noswhere.com/"];
"wss://relay.nostr.band/",
"wss://search.nos.today/",
"wss://relay.noswhere.com/",
];
export const DeveloperAccounts = [ export const DeveloperAccounts = [
"63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed", // kieran "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed", // kieran

View File

@ -62,7 +62,7 @@ export class OutboxModel extends BaseRequestRouter {
const topRelays = [...relayUserMap.entries()].sort(([, v], [, v1]) => v1.size - v.size); const topRelays = [...relayUserMap.entries()].sort(([, v], [, v1]) => v1.size - v.size);
if (missing.length > 0) { if (missing.length > 0) {
this.#log("No relay metadata found, outbox model will not work for %O", missing) this.#log("No relay metadata found, outbox model will not work for %O", missing);
} }
// <relay, key[]> - count keys per relay // <relay, key[]> - count keys per relay
// <key, relay[]> - pick n top relays // <key, relay[]> - pick n top relays
@ -101,9 +101,11 @@ export class OutboxModel extends BaseRequestRouter {
return [filter]; return [filter];
} }
const topWriteRelays = this.pickTopRelays(unwrap(authors), const topWriteRelays = this.pickTopRelays(
unwrap(authors),
pickN ?? DefaultPickNRelays, pickN ?? DefaultPickNRelays,
pattern === "inbox" ? "read" : "write"); pattern === "inbox" ? "read" : "write",
);
const pickedRelays = dedupe(topWriteRelays.flatMap(a => a.relays)); const pickedRelays = dedupe(topWriteRelays.flatMap(a => a.relays));
const picked = pickedRelays.map(a => { const picked = pickedRelays.map(a => {
@ -111,7 +113,7 @@ export class OutboxModel extends BaseRequestRouter {
return { return {
...filter, ...filter,
[key]: keysOnPickedRelay, [key]: keysOnPickedRelay,
relays: appendDedupe(filter.relays, [a]) relays: appendDedupe(filter.relays, [a]),
} as ReqFilter; } as ReqFilter;
}); });
const noRelays = dedupe(topWriteRelays.filter(a => a.relays.length === 0).map(a => a.key)); const noRelays = dedupe(topWriteRelays.filter(a => a.relays.length === 0).map(a => a.key));
@ -175,7 +177,7 @@ export class OutboxModel extends BaseRequestRouter {
await this.updateRelayLists(recipients); await this.updateRelayLists(recipients);
const relays = this.pickTopRelays(recipients, pickN ?? DefaultPickNRelays, "read"); const relays = this.pickTopRelays(recipients, pickN ?? DefaultPickNRelays, "read");
const ret = removeUndefined(dedupe(relays.map(a => a.relays).flat())); const ret = removeUndefined(dedupe(relays.map(a => a.relays).flat()));
this.#log("Picked: pattern=%s, input=%O, output=%O", "inbox", ev, ret); this.#log("Picked: pattern=%s, input=%O, output=%O", "inbox", ev, ret);
return ret; return ret;
} }

View File

@ -19,10 +19,7 @@ export class ProfileLoaderService extends BackgroundLoader<CachedMetadata> {
override buildSub(missing: string[]): RequestBuilder { override buildSub(missing: string[]): RequestBuilder {
const sub = new RequestBuilder(`profiles`); const sub = new RequestBuilder(`profiles`);
sub.withFilter() sub.withFilter().kinds([EventKind.SetMetadata]).authors(missing).relay(MetadataRelays);
.kinds([EventKind.SetMetadata])
.authors(missing)
.relay(MetadataRelays);
return sub; return sub;
} }

View File

@ -8,63 +8,63 @@ import { ReqFilter, RequestBuilder, SystemInterface, TaggedNostrEvent } from "."
const NostrBirthday: number = new Date(2021, 1, 1).getTime() / 1000; const NostrBirthday: number = new Date(2021, 1, 1).getTime() / 1000;
interface RangeSyncEvents { interface RangeSyncEvents {
event: (ev: Array<TaggedNostrEvent>) => void event: (ev: Array<TaggedNostrEvent>) => void;
scan: (from: number) => void scan: (from: number) => void;
} }
/** /**
* A simple time based sync for pulling lots of data from nostr * A simple time based sync for pulling lots of data from nostr
*/ */
export class RangeSync extends EventEmitter<RangeSyncEvents> { export class RangeSync extends EventEmitter<RangeSyncEvents> {
#start: number = NostrBirthday; #start: number = NostrBirthday;
#windowSize: number = 60 * 60 * 12; #windowSize: number = 60 * 60 * 12;
constructor(readonly system: SystemInterface) { constructor(readonly system: SystemInterface) {
super(); super();
}
/**
* Set window size in seconds
*/
setWindowSize(n: number) {
if (n < 60) {
throw new Error("Window size too small");
}
this.#windowSize = n;
}
/**
* Set start time for range sync
* @param n Unix timestamp
*/
setStartPoint(n: number) {
if (n < NostrBirthday) {
throw new Error("Start point cannot be before nostr's birthday");
}
this.#start = n;
}
/**
* Request to sync with a given filter
*/
async sync(filter: ReqFilter) {
if (filter.since !== undefined || filter.until !== undefined || filter.limit !== undefined) {
throw new Error("Filter must not contain since/until/limit");
} }
/** if (!this.system.requestRouter) {
* Set window size in seconds throw new Error("RangeSync cannot work without request router!");
*/
setWindowSize(n: number) {
if (n < 60) {
throw new Error("Window size too small");
}
this.#windowSize = n;
} }
/** const now = unixNow();
* Set start time for range sync for (let end = now; end > this.#start; end -= this.#windowSize) {
* @param n Unix timestamp const rb = new RequestBuilder(`range-query:${end}`);
*/ rb.withBareFilter(filter)
setStartPoint(n: number) { .since(end - this.#windowSize)
if (n < NostrBirthday) { .until(end);
throw new Error("Start point cannot be before nostr's birthday"); this.emit("scan", end);
} const results = await this.system.Fetch(rb);
this.#start = n; this.emit("event", results);
} }
}
/** }
* Request to sync with a given filter
*/
async sync(filter: ReqFilter) {
if (filter.since !== undefined || filter.until !== undefined || filter.limit !== undefined) {
throw new Error("Filter must not contain since/until/limit");
}
if (!this.system.requestRouter) {
throw new Error("RangeSync cannot work without request router!");
}
const now = unixNow();
for (let end = now; end > this.#start; end -= this.#windowSize) {
const rb = new RequestBuilder(`range-query:${end}`);
rb.withBareFilter(filter)
.since(end - this.#windowSize)
.until(end);
this.emit("scan", end);
const results = await this.system.Fetch(rb);
this.emit("event", results);
}
}
}